mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 18:59:21 +00:00
tint/resolver: Allow array sizes to be unnamed override-expressions
I got the rules around this wrong. This should be allowed, but the array types cannot compare equal if they are unnamed override-expressions. Fixed tint:1737 Change-Id: I83dc49703eed015e9c183e804474886da5dad7b9 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/107685 Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Auto-Submit: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Dawn LUCI CQ
parent
cc85ed6dd1
commit
22c4850b06
@@ -2710,14 +2710,15 @@ utils::Result<sem::ArrayCount> Resolver::ArrayCount(const ast::Expression* count
|
||||
return utils::Failure;
|
||||
}
|
||||
|
||||
// Note: If the array count is an 'override', but not a identifier expression, we do not return
|
||||
// here, but instead continue to the ConstantValue() check below.
|
||||
if (auto* user = count_sem->UnwrapMaterialize()->As<sem::VariableUser>()) {
|
||||
if (auto* global = user->Variable()->As<sem::GlobalVariable>()) {
|
||||
if (global->Declaration()->Is<ast::Override>()) {
|
||||
return sem::ArrayCount{sem::OverrideArrayCount{global}};
|
||||
if (count_sem->Stage() == sem::EvaluationStage::kOverride) {
|
||||
// array count is an override expression.
|
||||
// Is the count a named 'override'?
|
||||
if (auto* user = count_sem->UnwrapMaterialize()->As<sem::VariableUser>()) {
|
||||
if (auto* global = user->Variable()->As<sem::GlobalVariable>()) {
|
||||
return sem::ArrayCount{sem::NamedOverrideArrayCount{global}};
|
||||
}
|
||||
}
|
||||
return sem::ArrayCount{sem::UnnamedOverrideArrayCount{count_sem}};
|
||||
}
|
||||
|
||||
auto* count_val = count_sem->ConstantValue();
|
||||
|
||||
@@ -486,8 +486,8 @@ TEST_F(ResolverTest, ArraySize_SignedConst) {
|
||||
EXPECT_EQ(ary->Count(), sem::ConstantArrayCount{10u});
|
||||
}
|
||||
|
||||
TEST_F(ResolverTest, ArraySize_Override) {
|
||||
// override size = 0;
|
||||
TEST_F(ResolverTest, ArraySize_NamedOverride) {
|
||||
// override size = 10i;
|
||||
// var<workgroup> a : array<f32, size>;
|
||||
auto* override = Override("size", Expr(10_i));
|
||||
auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kWorkgroup);
|
||||
@@ -500,11 +500,11 @@ TEST_F(ResolverTest, ArraySize_Override) {
|
||||
auto* ary = ref->StoreType()->As<sem::Array>();
|
||||
auto* sem_override = Sem().Get<sem::GlobalVariable>(override);
|
||||
ASSERT_NE(sem_override, nullptr);
|
||||
EXPECT_EQ(ary->Count(), sem::OverrideArrayCount{sem_override});
|
||||
EXPECT_EQ(ary->Count(), sem::NamedOverrideArrayCount{sem_override});
|
||||
}
|
||||
|
||||
TEST_F(ResolverTest, ArraySize_Override_Equivalence) {
|
||||
// override size = 0;
|
||||
TEST_F(ResolverTest, ArraySize_NamedOverride_Equivalence) {
|
||||
// override size = 10i;
|
||||
// var<workgroup> a : array<f32, size>;
|
||||
// var<workgroup> b : array<f32, size>;
|
||||
auto* override = Override("size", Expr(10_i));
|
||||
@@ -525,11 +525,58 @@ TEST_F(ResolverTest, ArraySize_Override_Equivalence) {
|
||||
|
||||
auto* sem_override = Sem().Get<sem::GlobalVariable>(override);
|
||||
ASSERT_NE(sem_override, nullptr);
|
||||
EXPECT_EQ(ary_a->Count(), sem::OverrideArrayCount{sem_override});
|
||||
EXPECT_EQ(ary_b->Count(), sem::OverrideArrayCount{sem_override});
|
||||
EXPECT_EQ(ary_a->Count(), sem::NamedOverrideArrayCount{sem_override});
|
||||
EXPECT_EQ(ary_b->Count(), sem::NamedOverrideArrayCount{sem_override});
|
||||
EXPECT_EQ(ary_a, ary_b);
|
||||
}
|
||||
|
||||
TEST_F(ResolverTest, ArraySize_UnnamedOverride) {
|
||||
// override size = 10i;
|
||||
// var<workgroup> a : array<f32, size*2>;
|
||||
auto* override = Override("size", Expr(10_i));
|
||||
auto* cnt = Mul("size", 2_a);
|
||||
auto* a = GlobalVar("a", ty.array(ty.f32(), cnt), ast::AddressSpace::kWorkgroup);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(a), nullptr);
|
||||
auto* ref = TypeOf(a)->As<sem::Reference>();
|
||||
ASSERT_NE(ref, nullptr);
|
||||
auto* ary = ref->StoreType()->As<sem::Array>();
|
||||
auto* sem_override = Sem().Get<sem::GlobalVariable>(override);
|
||||
ASSERT_NE(sem_override, nullptr);
|
||||
EXPECT_EQ(ary->Count(), sem::UnnamedOverrideArrayCount{Sem().Get(cnt)});
|
||||
}
|
||||
|
||||
TEST_F(ResolverTest, ArraySize_UnamedOverride_Equivalence) {
|
||||
// override size = 10i;
|
||||
// var<workgroup> a : array<f32, size>;
|
||||
// var<workgroup> b : array<f32, size>;
|
||||
auto* override = Override("size", Expr(10_i));
|
||||
auto* a_cnt = Mul("size", 2_a);
|
||||
auto* b_cnt = Mul("size", 2_a);
|
||||
auto* a = GlobalVar("a", ty.array(ty.f32(), a_cnt), ast::AddressSpace::kWorkgroup);
|
||||
auto* b = GlobalVar("b", ty.array(ty.f32(), b_cnt), ast::AddressSpace::kWorkgroup);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(a), nullptr);
|
||||
auto* ref_a = TypeOf(a)->As<sem::Reference>();
|
||||
ASSERT_NE(ref_a, nullptr);
|
||||
auto* ary_a = ref_a->StoreType()->As<sem::Array>();
|
||||
|
||||
ASSERT_NE(TypeOf(b), nullptr);
|
||||
auto* ref_b = TypeOf(b)->As<sem::Reference>();
|
||||
ASSERT_NE(ref_b, nullptr);
|
||||
auto* ary_b = ref_b->StoreType()->As<sem::Array>();
|
||||
|
||||
auto* sem_override = Sem().Get<sem::GlobalVariable>(override);
|
||||
ASSERT_NE(sem_override, nullptr);
|
||||
EXPECT_EQ(ary_a->Count(), sem::UnnamedOverrideArrayCount{Sem().Get(a_cnt)});
|
||||
EXPECT_EQ(ary_b->Count(), sem::UnnamedOverrideArrayCount{Sem().Get(b_cnt)});
|
||||
EXPECT_NE(ary_a, ary_b);
|
||||
}
|
||||
|
||||
TEST_F(ResolverTest, Expr_Bitcast) {
|
||||
GlobalVar("name", ty.f32(), ast::AddressSpace::kPrivate);
|
||||
|
||||
@@ -2331,8 +2378,8 @@ TEST_F(ResolverTest, Literal_F16WithExtension) {
|
||||
EXPECT_TRUE(r()->Resolve());
|
||||
}
|
||||
|
||||
// Windows debug builds have significantly smaller stack than other builds, and these tests will stack
|
||||
// overflow.
|
||||
// Windows debug builds have significantly smaller stack than other builds, and these tests will
|
||||
// stack overflow.
|
||||
#if !defined(NDEBUG)
|
||||
|
||||
TEST_F(ResolverTest, ScopeDepth_NestedBlocks) {
|
||||
|
||||
@@ -371,7 +371,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ExplicitStride) {
|
||||
"12:34 error: array byte size (0x7a1185ee00) must not exceed 0xffffffff bytes");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_PrivateVar) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_PrivateVar) {
|
||||
// override size = 10i;
|
||||
// var<private> a : array<f32, size>;
|
||||
Override("size", Expr(10_i));
|
||||
@@ -382,19 +382,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_PrivateVar) {
|
||||
"type of a 'var<workgroup>'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_ComplexExpr) {
|
||||
// override size = 10i;
|
||||
// var<workgroup> a : array<f32, size + 1>;
|
||||
Override("size", Expr(10_i));
|
||||
GlobalVar("a", ty.array(ty.f32(), Add(Source{{12, 34}}, "size", 1_i)),
|
||||
ast::AddressSpace::kWorkgroup);
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: array count must evaluate to a constant integer expression or override "
|
||||
"variable");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_InArray) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_InArray) {
|
||||
// override size = 10i;
|
||||
// var<workgroup> a : array<array<f32, size>, 4>;
|
||||
Override("size", Expr(10_i));
|
||||
@@ -406,7 +394,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_InArray) {
|
||||
"type of a 'var<workgroup>'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_InStruct) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_InStruct) {
|
||||
// override size = 10i;
|
||||
// struct S {
|
||||
// a : array<f32, size>
|
||||
@@ -419,7 +407,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_InStruct) {
|
||||
"type of a 'var<workgroup>'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionVar_Explicit) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionVar_Explicit) {
|
||||
// override size = 10i;
|
||||
// fn f() {
|
||||
// var a : array<f32, size>;
|
||||
@@ -435,7 +423,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionVar_Explicit) {
|
||||
"type of a 'var<workgroup>'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionLet_Explicit) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionLet_Explicit) {
|
||||
// override size = 10i;
|
||||
// fn f() {
|
||||
// var a : array<f32, size>;
|
||||
@@ -451,7 +439,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionLet_Explicit) {
|
||||
"type of a 'var<workgroup>'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionVar_Implicit) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionVar_Implicit) {
|
||||
// override size = 10i;
|
||||
// var<workgroup> w : array<f32, size>;
|
||||
// fn f() {
|
||||
@@ -469,7 +457,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionVar_Implicit) {
|
||||
"type of a 'var<workgroup>'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionLet_Implicit) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionLet_Implicit) {
|
||||
// override size = 10i;
|
||||
// var<workgroup> w : array<f32, size>;
|
||||
// fn f() {
|
||||
@@ -487,7 +475,24 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionLet_Implicit) {
|
||||
"type of a 'var<workgroup>'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_Param) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_UnnamedOverride_Equivalence) {
|
||||
// override size = 10i;
|
||||
// var<workgroup> a : array<f32, size + 1>;
|
||||
// var<workgroup> b : array<f32, size + 1>;
|
||||
// fn f() {
|
||||
// a = b;
|
||||
// }
|
||||
Override("size", Expr(10_i));
|
||||
GlobalVar("a", ty.array(ty.f32(), Add("size", 1_i)), ast::AddressSpace::kWorkgroup);
|
||||
GlobalVar("b", ty.array(ty.f32(), Add("size", 1_i)), ast::AddressSpace::kWorkgroup);
|
||||
WrapInFunction(Assign(Source{{12, 34}}, "a", "b"));
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(),
|
||||
"12:34 error: cannot assign 'array<f32, [unnamed override-expression]>' to "
|
||||
"'array<f32, [unnamed override-expression]>'");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_Param) {
|
||||
// override size = 10i;
|
||||
// fn f(a : array<f32, size>) {
|
||||
// }
|
||||
@@ -498,7 +503,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_Param) {
|
||||
EXPECT_EQ(r()->error(), "12:34 error: type of function parameter must be constructible");
|
||||
}
|
||||
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_Override_ReturnType) {
|
||||
TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_ReturnType) {
|
||||
// override size = 10i;
|
||||
// fn f() -> array<f32, size> {
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user