tint/resolver: Materialize array size expression
Bug: tint:1504 Change-Id: If67228f18b26f718689f641beae95d281baf9c0c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/91962 Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
b1f9f9fd8e
commit
649d3d9602
|
@ -766,8 +766,8 @@ constexpr Method kScalarMethods[] = {
|
|||
};
|
||||
|
||||
/// Methods that support abstract-integer materialization
|
||||
/// Note: Doesn't contain kWorkgroupSize as @workgroup_size has tighter constraints on the range of
|
||||
/// allowed integer values.
|
||||
/// Note: Doesn't contain kWorkgroupSize or kArrayLength as they have tighter constraints on the
|
||||
/// range of allowed integer values.
|
||||
constexpr Method kAIntMethods[] = {
|
||||
Method::kSwitch,
|
||||
Method::kIndex,
|
||||
|
@ -854,6 +854,18 @@ INSTANTIATE_TEST_SUITE_P(MaterializeAInt,
|
|||
Types<i32, AInt>(AInt(kLowestI32), kLowestI32), //
|
||||
})));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
MaterializeArrayLength,
|
||||
MaterializeAbstractNumericToDefaultType,
|
||||
testing::Combine(testing::Values(Expectation::kMaterialize),
|
||||
testing::Values(Method::kArrayLength),
|
||||
testing::ValuesIn(std::vector<Data>{
|
||||
Types<i32, AInt>(1_a, 1.0), //
|
||||
Types<i32, AInt>(10_a, 10.0), //
|
||||
Types<i32, AInt>(1000_a, 1000.0), //
|
||||
// Note: kHighestI32 cannot be used due to max-byte-size validation
|
||||
})));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(MaterializeWorkgroupSize,
|
||||
MaterializeAbstractNumericToDefaultType,
|
||||
testing::Combine(testing::Values(Expectation::kMaterialize),
|
||||
|
@ -914,6 +926,14 @@ INSTANTIATE_TEST_SUITE_P(WorkgroupSizeValueCannotBeRepresented,
|
|||
Types<i32, AInt>(0_a, kLowestI32 - 1), //
|
||||
})));
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ArrayLengthValueCannotBeRepresented,
|
||||
MaterializeAbstractNumericToDefaultType,
|
||||
testing::Combine(testing::Values(Expectation::kValueCannotBeRepresented),
|
||||
testing::Values(Method::kArrayLength),
|
||||
testing::ValuesIn(std::vector<Data>{
|
||||
Types<i32, AInt>(0_a, kHighestI32 + 1), //
|
||||
})));
|
||||
|
||||
} // namespace materialize_abstract_numeric_to_default_type
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -2030,7 +2030,7 @@ sem::Array* Resolver::Array(const ast::Array* arr) {
|
|||
// sem::Array uses a size of 0 for a runtime-sized array.
|
||||
uint32_t count = 0;
|
||||
if (auto* count_expr = arr->count) {
|
||||
auto* count_sem = Expression(count_expr);
|
||||
const auto* count_sem = Materialize(Expression(count_expr));
|
||||
if (!count_sem) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ TEST_F(ResolverTypeValidationTest, VariableDeclNoConstructor_Pass) {
|
|||
ASSERT_NE(TypeOf(rhs), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, GlobalConstantNoConstructor_Pass) {
|
||||
TEST_F(ResolverTypeValidationTest, GlobalOverrideNoConstructor_Pass) {
|
||||
// @id(0) override a :i32;
|
||||
Override(Source{{12, 34}}, "a", ty.i32(), nullptr, ast::AttributeList{Id(0)});
|
||||
|
||||
|
@ -87,8 +87,8 @@ TEST_F(ResolverTypeValidationTest, GlobalVariableWithStorageClass_Pass) {
|
|||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, GlobalConstantWithStorageClass_Fail) {
|
||||
// const<private> global_var: f32;
|
||||
TEST_F(ResolverTypeValidationTest, GlobalLetWithStorageClass_Fail) {
|
||||
// let<private> global_var: f32;
|
||||
AST().AddGlobalVariable(create<ast::Variable>(
|
||||
Source{{12, 34}}, Symbols().Register("global_var"), ast::StorageClass::kPrivate,
|
||||
ast::Access::kUndefined, ty.f32(), true, false, Expr(1.23_f), ast::AttributeList{}));
|
||||
|
@ -188,6 +188,12 @@ TEST_F(ResolverTypeValidationTest, RedeclaredIdentifierDifferentFunctions_Pass)
|
|||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Pass) {
|
||||
// var<private> a : array<f32, 4>;
|
||||
Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_a)), ast::StorageClass::kPrivate);
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Pass) {
|
||||
// var<private> a : array<f32, 4u>;
|
||||
Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_u)), ast::StorageClass::kPrivate);
|
||||
|
@ -200,7 +206,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Pass) {
|
|||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConstant_Pass) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLet_Pass) {
|
||||
// let size = 4u;
|
||||
// var<private> a : array<f32, size>;
|
||||
GlobalConst("size", nullptr, Expr(4_u));
|
||||
|
@ -208,7 +214,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConstant_Pass) {
|
|||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Pass) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Pass) {
|
||||
// let size = 4i;
|
||||
// var<private> a : array<f32, size>;
|
||||
GlobalConst("size", nullptr, Expr(4_i));
|
||||
|
@ -216,6 +222,13 @@ TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Pass) {
|
|||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Zero) {
|
||||
// var<private> a : array<f32, 0>;
|
||||
Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_a)), ast::StorageClass::kPrivate);
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Zero) {
|
||||
// var<private> a : array<f32, 0u>;
|
||||
Global("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), ast::StorageClass::kPrivate);
|
||||
|
@ -237,7 +250,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Negative) {
|
|||
EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConstant_Zero) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLet_Zero) {
|
||||
// let size = 0u;
|
||||
// var<private> a : array<f32, size>;
|
||||
GlobalConst("size", nullptr, Expr(0_u));
|
||||
|
@ -246,7 +259,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedConstant_Zero) {
|
|||
EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Zero) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Zero) {
|
||||
// let size = 0i;
|
||||
// var<private> a : array<f32, size>;
|
||||
GlobalConst("size", nullptr, Expr(0_i));
|
||||
|
@ -255,7 +268,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Zero) {
|
|||
EXPECT_EQ(r()->error(), "12:34 error: array size must be at least 1");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_SignedConstant_Negative) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_SignedLet_Negative) {
|
||||
// let size = -10i;
|
||||
// var<private> a : array<f32, size>;
|
||||
GlobalConst("size", nullptr, Expr(-10_i));
|
||||
|
@ -279,7 +292,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_IVecLiteral) {
|
|||
EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_FloatConstant) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_FloatLet) {
|
||||
// let size = 10.0;
|
||||
// var<private> a : array<f32, size>;
|
||||
GlobalConst("size", nullptr, Expr(10_f));
|
||||
|
@ -288,7 +301,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_FloatConstant) {
|
|||
EXPECT_EQ(r()->error(), "12:34 error: array size must be integer scalar");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_IVecConstant) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_IVecLet) {
|
||||
// let size = vec2<i32>(100, 100);
|
||||
// var<private> a : array<f32, size>;
|
||||
GlobalConst("size", nullptr, Construct(ty.vec2<i32>(), 100_i, 100_i));
|
||||
|
@ -315,7 +328,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ExplicitStride) {
|
|||
"is 0x100000000");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_OverridableConstant) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Overridable) {
|
||||
// override size = 10i;
|
||||
// var<private> a : array<f32, size>;
|
||||
Override("size", nullptr, Expr(10_i));
|
||||
|
@ -333,7 +346,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_ModuleVar) {
|
|||
EXPECT_EQ(r()->error(), "12:34 error: array size identifier must be a module-scope constant");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_FunctionConstant) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_FunctionLet) {
|
||||
// {
|
||||
// let size = 10;
|
||||
// var a : array<f32, size>;
|
||||
|
|
Loading…
Reference in New Issue