tint/sem: Add conversion handling of array types
Required for arrays of, or nested arrays of abstract-numerics,
abstract-numeric vectors and abstract-numeric matrices.
Bug: tint:1628
Change-Id: Ib360c687163d3b88be780fdbc2d3eb1a93689520
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97585
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/sem/type.cc b/src/tint/sem/type.cc
index 7e2c67f..fcc1654 100644
--- a/src/tint/sem/type.cc
+++ b/src/tint/sem/type.cc
@@ -212,6 +212,14 @@
}
return kNoConversion;
},
+ [&](const Array* from_arr) {
+ if (auto* to_arr = to->As<Array>()) {
+ if (from_arr->Count() == to_arr->Count()) {
+ return ConversionRank(from_arr->ElemType(), to_arr->ElemType());
+ }
+ }
+ return kNoConversion;
+ },
[&](Default) { return kNoConversion; });
}
diff --git a/src/tint/sem/type_test.cc b/src/tint/sem/type_test.cc
index 3cd1e01..837579e 100644
--- a/src/tint/sem/type_test.cc
+++ b/src/tint/sem/type_test.cc
@@ -14,34 +14,110 @@
#include "src/tint/sem/abstract_float.h"
#include "src/tint/sem/abstract_int.h"
+#include "src/tint/sem/f16.h"
#include "src/tint/sem/reference.h"
#include "src/tint/sem/test_helper.h"
namespace tint::sem {
namespace {
-using TypeTest = TestHelper;
+struct TypeTest : public TestHelper {
+ const sem::AbstractFloat* af = create<AbstractFloat>();
+ const sem::AbstractInt* ai = create<AbstractInt>();
+ const sem::F32* f32 = create<F32>();
+ const sem::F16* f16 = create<F16>();
+ const sem::I32* i32 = create<I32>();
+ const sem::U32* u32 = create<U32>();
+ const sem::Vector* vec2_f32 = create<Vector>(f32, 2u);
+ const sem::Vector* vec3_f32 = create<Vector>(f32, 3u);
+ const sem::Vector* vec3_f16 = create<Vector>(f16, 3u);
+ const sem::Vector* vec4_f32 = create<Vector>(f32, 4u);
+ const sem::Vector* vec3_u32 = create<Vector>(u32, 3u);
+ const sem::Vector* vec3_i32 = create<Vector>(i32, 3u);
+ const sem::Vector* vec3_af = create<Vector>(af, 3u);
+ const sem::Vector* vec3_ai = create<Vector>(ai, 3u);
+ const sem::Matrix* mat2x4_f32 = create<Matrix>(vec4_f32, 2u);
+ const sem::Matrix* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
+ const sem::Matrix* mat4x2_f32 = create<Matrix>(vec2_f32, 4u);
+ const sem::Matrix* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
+ const sem::Matrix* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
+ const sem::Matrix* mat4x3_af = create<Matrix>(vec3_af, 4u);
+ const sem::Reference* ref_u32 =
+ create<Reference>(u32, ast::StorageClass::kPrivate, ast::Access::kReadWrite);
+ const sem::Struct* str = create<Struct>(nullptr,
+ Sym("s"),
+ StructMemberList{
+ create<StructMember>(
+ /* declaration */ nullptr,
+ /* name */ Sym("x"),
+ /* type */ f16,
+ /* index */ 0u,
+ /* offset */ 0u,
+ /* align */ 4u,
+ /* size */ 4u),
+ },
+ /* align*/ 4u,
+ /* size*/ 4u,
+ /* size_no_padding*/ 4u);
+ const sem::Array* arr_i32 = create<Array>(
+ /* element */ i32,
+ /* count */ 5u,
+ /* align */ 4u,
+ /* size */ 5u * 4u,
+ /* stride */ 5u * 4u,
+ /* implicit_stride */ 5u * 4u);
+ const sem::Array* arr_ai = create<Array>(
+ /* element */ ai,
+ /* count */ 5u,
+ /* align */ 4u,
+ /* size */ 5u * 4u,
+ /* stride */ 5u * 4u,
+ /* implicit_stride */ 5u * 4u);
+ const sem::Array* arr_vec3_i32 = create<Array>(
+ /* element */ vec3_i32,
+ /* count */ 5u,
+ /* align */ 16u,
+ /* size */ 5u * 16u,
+ /* stride */ 5u * 16u,
+ /* implicit_stride */ 5u * 16u);
+ const sem::Array* arr_vec3_ai = create<Array>(
+ /* element */ vec3_ai,
+ /* count */ 5u,
+ /* align */ 16u,
+ /* size */ 5u * 16u,
+ /* stride */ 5u * 16u,
+ /* implicit_stride */ 5u * 16u);
+ const sem::Array* arr_mat4x3_f16 = create<Array>(
+ /* element */ mat4x3_f16,
+ /* count */ 5u,
+ /* align */ 32u,
+ /* size */ 5u * 32u,
+ /* stride */ 5u * 32u,
+ /* implicit_stride */ 5u * 32u);
+ const sem::Array* arr_mat4x3_f32 = create<Array>(
+ /* element */ mat4x3_f32,
+ /* count */ 5u,
+ /* align */ 64u,
+ /* size */ 5u * 64u,
+ /* stride */ 5u * 64u,
+ /* implicit_stride */ 5u * 64u);
+ const sem::Array* arr_mat4x3_af = create<Array>(
+ /* element */ mat4x3_af,
+ /* count */ 5u,
+ /* align */ 64u,
+ /* size */ 5u * 64u,
+ /* stride */ 5u * 64u,
+ /* implicit_stride */ 5u * 64u);
+ const sem::Array* arr_str = create<Array>(
+ /* element */ str,
+ /* count */ 5u,
+ /* align */ 4u,
+ /* size */ 5u * 4u,
+ /* stride */ 5u * 4u,
+ /* implicit_stride */ 5u * 4u);
+};
TEST_F(TypeTest, ConversionRank) {
- auto* af = create<AbstractFloat>();
- auto* ai = create<AbstractInt>();
- auto* f32 = create<F32>();
- auto* f16 = create<F16>();
- auto* i32 = create<I32>();
- auto* u32 = create<U32>();
- auto* vec3_f32 = create<Vector>(f32, 3u);
- auto* vec3_f16 = create<Vector>(f16, 3u);
- auto* vec4_f32 = create<Vector>(f32, 4u);
- auto* vec3_u32 = create<Vector>(u32, 3u);
- auto* vec3_i32 = create<Vector>(i32, 3u);
- auto* vec3_af = create<Vector>(af, 3u);
- auto* vec3_ai = create<Vector>(ai, 3u);
- auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
- auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
- auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
- auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
- auto* ref_u32 = create<Reference>(u32, ast::StorageClass::kPrivate, ast::Access::kReadWrite);
-
EXPECT_EQ(Type::ConversionRank(i32, i32), 0u);
EXPECT_EQ(Type::ConversionRank(f32, f32), 0u);
EXPECT_EQ(Type::ConversionRank(u32, u32), 0u);
@@ -55,17 +131,24 @@
EXPECT_EQ(Type::ConversionRank(mat3x4_f32, mat3x4_f32), 0u);
EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat4x3_f32), 0u);
EXPECT_EQ(Type::ConversionRank(mat4x3_f16, mat4x3_f16), 0u);
+ EXPECT_EQ(Type::ConversionRank(arr_vec3_ai, arr_vec3_ai), 0u);
+ EXPECT_EQ(Type::ConversionRank(arr_mat4x3_f16, arr_mat4x3_f16), 0u);
EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_af), 0u);
+ EXPECT_EQ(Type::ConversionRank(arr_mat4x3_af, arr_mat4x3_af), 0u);
EXPECT_EQ(Type::ConversionRank(ref_u32, u32), 0u);
EXPECT_EQ(Type::ConversionRank(af, f32), 1u);
EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_f32), 1u);
EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_f32), 1u);
+ EXPECT_EQ(Type::ConversionRank(arr_mat4x3_af, arr_mat4x3_f32), 1u);
EXPECT_EQ(Type::ConversionRank(af, f16), 2u);
EXPECT_EQ(Type::ConversionRank(vec3_af, vec3_f16), 2u);
EXPECT_EQ(Type::ConversionRank(mat4x3_af, mat4x3_f16), 2u);
+ EXPECT_EQ(Type::ConversionRank(arr_mat4x3_af, arr_mat4x3_f16), 2u);
EXPECT_EQ(Type::ConversionRank(ai, i32), 3u);
EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_i32), 3u);
+ EXPECT_EQ(Type::ConversionRank(arr_ai, arr_i32), 3u);
+ EXPECT_EQ(Type::ConversionRank(arr_vec3_ai, arr_vec3_i32), 3u);
EXPECT_EQ(Type::ConversionRank(ai, u32), 4u);
EXPECT_EQ(Type::ConversionRank(vec3_ai, vec3_u32), 4u);
EXPECT_EQ(Type::ConversionRank(ai, af), 5u);
@@ -80,6 +163,9 @@
EXPECT_EQ(Type::ConversionRank(mat3x4_f32, mat4x3_f32), Type::kNoConversion);
EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat3x4_f32), Type::kNoConversion);
EXPECT_EQ(Type::ConversionRank(mat4x3_f32, mat4x3_af), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(arr_vec3_i32, arr_vec3_ai), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(arr_mat4x3_f32, arr_mat4x3_af), Type::kNoConversion);
+ EXPECT_EQ(Type::ConversionRank(arr_mat4x3_f16, arr_mat4x3_f32), Type::kNoConversion);
EXPECT_EQ(Type::ConversionRank(f32, af), Type::kNoConversion);
EXPECT_EQ(Type::ConversionRank(f16, af), Type::kNoConversion);
EXPECT_EQ(Type::ConversionRank(vec3_f16, vec3_af), Type::kNoConversion);
@@ -92,61 +178,6 @@
}
TEST_F(TypeTest, ElementOf) {
- auto* f32 = create<F32>();
- auto* f16 = create<F16>();
- auto* i32 = create<I32>();
- auto* u32 = create<U32>();
- auto* vec2_f32 = create<Vector>(f32, 2u);
- auto* vec3_f16 = create<Vector>(f16, 3u);
- auto* vec4_f32 = create<Vector>(f32, 4u);
- auto* vec3_u32 = create<Vector>(u32, 3u);
- auto* vec3_i32 = create<Vector>(i32, 3u);
- auto* mat2x4_f32 = create<Matrix>(vec4_f32, 2u);
- auto* mat4x2_f32 = create<Matrix>(vec2_f32, 4u);
- auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
- auto* str = create<Struct>(nullptr, Sym("s"),
- StructMemberList{
- create<StructMember>(
- /* declaration */ nullptr,
- /* name */ Sym("x"),
- /* type */ f16,
- /* index */ 0u,
- /* offset */ 0u,
- /* align */ 4u,
- /* size */ 4u),
- },
- /* align*/ 4u,
- /* size*/ 4u,
- /* size_no_padding*/ 4u);
- auto* arr_i32 = create<Array>(
- /* element */ i32,
- /* count */ 5u,
- /* align */ 4u,
- /* size */ 5u * 4u,
- /* stride */ 5u * 4u,
- /* implicit_stride */ 5u * 4u);
- auto* arr_vec3_i32 = create<Array>(
- /* element */ vec3_i32,
- /* count */ 5u,
- /* align */ 16u,
- /* size */ 5u * 16u,
- /* stride */ 5u * 16u,
- /* implicit_stride */ 5u * 16u);
- auto* arr_mat4x3_f16 = create<Array>(
- /* element */ mat4x3_f16,
- /* count */ 5u,
- /* align */ 64u,
- /* size */ 5u * 64u,
- /* stride */ 5u * 64u,
- /* implicit_stride */ 5u * 64u);
- auto* arr_str = create<Array>(
- /* element */ str,
- /* count */ 5u,
- /* align */ 4u,
- /* size */ 5u * 4u,
- /* stride */ 5u * 4u,
- /* implicit_stride */ 5u * 4u);
-
// No count
EXPECT_TYPE(Type::ElementOf(f32), f32);
EXPECT_TYPE(Type::ElementOf(f16), f16);
@@ -164,6 +195,7 @@
EXPECT_TYPE(Type::ElementOf(arr_i32), i32);
EXPECT_TYPE(Type::ElementOf(arr_vec3_i32), vec3_i32);
EXPECT_TYPE(Type::ElementOf(arr_mat4x3_f16), mat4x3_f16);
+ EXPECT_TYPE(Type::ElementOf(arr_mat4x3_af), mat4x3_af);
EXPECT_TYPE(Type::ElementOf(arr_str), str);
// With count
@@ -216,66 +248,14 @@
EXPECT_TYPE(Type::ElementOf(arr_mat4x3_f16, &count), mat4x3_f16);
EXPECT_EQ(count, 5u);
count = 42;
+ EXPECT_TYPE(Type::ElementOf(arr_mat4x3_af, &count), mat4x3_af);
+ EXPECT_EQ(count, 5u);
+ count = 42;
EXPECT_TYPE(Type::ElementOf(arr_str, &count), str);
EXPECT_EQ(count, 5u);
}
TEST_F(TypeTest, DeepestElementOf) {
- auto* f32 = create<F32>();
- auto* f16 = create<F16>();
- auto* i32 = create<I32>();
- auto* u32 = create<U32>();
- auto* vec2_f32 = create<Vector>(f32, 2u);
- auto* vec3_f16 = create<Vector>(f16, 3u);
- auto* vec4_f32 = create<Vector>(f32, 4u);
- auto* vec3_u32 = create<Vector>(u32, 3u);
- auto* vec3_i32 = create<Vector>(i32, 3u);
- auto* mat2x4_f32 = create<Matrix>(vec4_f32, 2u);
- auto* mat4x2_f32 = create<Matrix>(vec2_f32, 4u);
- auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
- auto* str = create<Struct>(nullptr, Sym("s"),
- StructMemberList{
- create<StructMember>(
- /* declaration */ nullptr,
- /* name */ Sym("x"),
- /* type */ f16,
- /* index */ 0u,
- /* offset */ 0u,
- /* align */ 4u,
- /* size */ 4u),
- },
- /* align*/ 4u,
- /* size*/ 4u,
- /* size_no_padding*/ 4u);
- auto* arr_i32 = create<Array>(
- /* element */ i32,
- /* count */ 5u,
- /* align */ 4u,
- /* size */ 5u * 4u,
- /* stride */ 5u * 4u,
- /* implicit_stride */ 5u * 4u);
- auto* arr_vec3_i32 = create<Array>(
- /* element */ vec3_i32,
- /* count */ 5u,
- /* align */ 16u,
- /* size */ 5u * 16u,
- /* stride */ 5u * 16u,
- /* implicit_stride */ 5u * 16u);
- auto* arr_mat4x3_f16 = create<Array>(
- /* element */ mat4x3_f16,
- /* count */ 5u,
- /* align */ 64u,
- /* size */ 5u * 64u,
- /* stride */ 5u * 64u,
- /* implicit_stride */ 5u * 64u);
- auto* arr_str = create<Array>(
- /* element */ str,
- /* count */ 5u,
- /* align */ 4u,
- /* size */ 5u * 4u,
- /* stride */ 5u * 4u,
- /* implicit_stride */ 5u * 4u);
-
// No count
EXPECT_TYPE(Type::DeepestElementOf(f32), f32);
EXPECT_TYPE(Type::DeepestElementOf(f16), f16);
@@ -293,6 +273,7 @@
EXPECT_TYPE(Type::DeepestElementOf(arr_i32), i32);
EXPECT_TYPE(Type::DeepestElementOf(arr_vec3_i32), i32);
EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_f16), f16);
+ EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_af), af);
EXPECT_TYPE(Type::DeepestElementOf(arr_str), nullptr);
// With count
@@ -345,18 +326,14 @@
EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_f16, &count), f16);
EXPECT_EQ(count, 60u);
count = 42;
+ EXPECT_TYPE(Type::DeepestElementOf(arr_mat4x3_af, &count), af);
+ EXPECT_EQ(count, 60u);
+ count = 42;
EXPECT_TYPE(Type::DeepestElementOf(arr_str, &count), nullptr);
EXPECT_EQ(count, 0u);
}
TEST_F(TypeTest, Common2) {
- auto* ai = create<AbstractInt>();
- auto* af = create<AbstractFloat>();
- auto* f32 = create<F32>();
- auto* f16 = create<F16>();
- auto* i32 = create<I32>();
- auto* u32 = create<U32>();
-
EXPECT_TYPE(Type::Common(utils::Vector{ai, ai}), ai);
EXPECT_TYPE(Type::Common(utils::Vector{af, af}), af);
EXPECT_TYPE(Type::Common(utils::Vector{f32, f32}), f32);
@@ -393,14 +370,6 @@
EXPECT_TYPE(Type::Common(utils::Vector{af, i32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{af, u32}), nullptr);
- auto* vec3_ai = create<Vector>(ai, 3u);
- auto* vec3_af = create<Vector>(af, 3u);
- auto* vec3_f32 = create<Vector>(f32, 3u);
- auto* vec3_f16 = create<Vector>(f16, 3u);
- auto* vec4_f32 = create<Vector>(f32, 4u);
- auto* vec3_u32 = create<Vector>(u32, 3u);
- auto* vec3_i32 = create<Vector>(i32, 3u);
-
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_ai}), vec3_ai);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_af}), vec3_af);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_f32}), vec3_f32);
@@ -433,11 +402,6 @@
EXPECT_TYPE(Type::Common(utils::Vector{vec3_u32, vec3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_i32, vec3_af}), nullptr);
- auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
- auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
- auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
- auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
-
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_af}), mat4x3_af);
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat3x4_f32}), mat3x4_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_f32}), mat4x3_f32);
@@ -450,16 +414,13 @@
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat4x3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_af}), mat4x3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f16, mat4x3_af}), mat4x3_f16);
+
+ EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f32, arr_mat4x3_f16}), nullptr);
+ EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f32, arr_mat4x3_af}), arr_mat4x3_f32);
+ EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f16, arr_mat4x3_af}), arr_mat4x3_f16);
}
TEST_F(TypeTest, Common3) {
- auto* ai = create<AbstractInt>();
- auto* af = create<AbstractFloat>();
- auto* f32 = create<F32>();
- auto* f16 = create<F16>();
- auto* i32 = create<I32>();
- auto* u32 = create<U32>();
-
EXPECT_TYPE(Type::Common(utils::Vector{ai, ai, ai}), ai);
EXPECT_TYPE(Type::Common(utils::Vector{af, af, af}), af);
EXPECT_TYPE(Type::Common(utils::Vector{f32, f32, f32}), f32);
@@ -504,14 +465,6 @@
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, i32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{ai, af, u32}), nullptr);
- auto* vec3_ai = create<Vector>(ai, 3u);
- auto* vec3_af = create<Vector>(af, 3u);
- auto* vec3_f32 = create<Vector>(f32, 3u);
- auto* vec3_f16 = create<Vector>(f16, 3u);
- auto* vec4_f32 = create<Vector>(f32, 4u);
- auto* vec3_u32 = create<Vector>(u32, 3u);
- auto* vec3_i32 = create<Vector>(i32, 3u);
-
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_ai, vec3_ai}), vec3_ai);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_af, vec3_af, vec3_af}), vec3_af);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_f32, vec3_f32, vec3_f32}), vec3_f32);
@@ -550,11 +503,6 @@
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_u32}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{vec3_ai, vec3_af, vec3_i32}), nullptr);
- auto* mat4x3_af = create<Matrix>(vec3_af, 4u);
- auto* mat3x4_f32 = create<Matrix>(vec4_f32, 3u);
- auto* mat4x3_f32 = create<Matrix>(vec3_f32, 4u);
- auto* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
-
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_af, mat4x3_af}), mat4x3_af);
EXPECT_TYPE(Type::Common(utils::Vector{mat3x4_f32, mat3x4_f32, mat3x4_f32}), mat3x4_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_f32, mat4x3_f32, mat4x3_f32}), mat4x3_f32);
@@ -567,6 +515,13 @@
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat3x4_f32, mat4x3_af}), nullptr);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f32, mat4x3_af}), mat4x3_f32);
EXPECT_TYPE(Type::Common(utils::Vector{mat4x3_af, mat4x3_f16, mat4x3_af}), mat4x3_f16);
+
+ EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_f16, arr_mat4x3_f32, arr_mat4x3_f16}),
+ nullptr);
+ EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_af, arr_mat4x3_f32, arr_mat4x3_af}),
+ arr_mat4x3_f32);
+ EXPECT_TYPE(Type::Common(utils::Vector{arr_mat4x3_af, arr_mat4x3_f16, arr_mat4x3_af}),
+ arr_mat4x3_f16);
}
} // namespace