diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index ba6cfaaa6f..3252829599 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -2710,14 +2710,15 @@ utils::Result 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()) { - if (auto* global = user->Variable()->As()) { - if (global->Declaration()->Is()) { - 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()) { + if (auto* global = user->Variable()->As()) { + return sem::ArrayCount{sem::NamedOverrideArrayCount{global}}; } } + return sem::ArrayCount{sem::UnnamedOverrideArrayCount{count_sem}}; } auto* count_val = count_sem->ConstantValue(); diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc index 935833ab85..13b1da1e0a 100644 --- a/src/tint/resolver/resolver_test.cc +++ b/src/tint/resolver/resolver_test.cc @@ -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 a : array; 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(); auto* sem_override = Sem().Get(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 a : array; // var b : array; auto* override = Override("size", Expr(10_i)); @@ -525,11 +525,58 @@ TEST_F(ResolverTest, ArraySize_Override_Equivalence) { auto* sem_override = Sem().Get(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 a : array; + 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(); + ASSERT_NE(ref, nullptr); + auto* ary = ref->StoreType()->As(); + auto* sem_override = Sem().Get(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 a : array; + // var b : array; + 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(); + ASSERT_NE(ref_a, nullptr); + auto* ary_a = ref_a->StoreType()->As(); + + ASSERT_NE(TypeOf(b), nullptr); + auto* ref_b = TypeOf(b)->As(); + ASSERT_NE(ref_b, nullptr); + auto* ary_b = ref_b->StoreType()->As(); + + auto* sem_override = Sem().Get(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) { diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc index d2587c5de1..b539e494e3 100644 --- a/src/tint/resolver/type_validation_test.cc +++ b/src/tint/resolver/type_validation_test.cc @@ -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 a : array; Override("size", Expr(10_i)); @@ -382,19 +382,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_PrivateVar) { "type of a 'var'"); } -TEST_F(ResolverTypeValidationTest, ArraySize_Override_ComplexExpr) { - // override size = 10i; - // var a : array; - 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 a : array, 4>; Override("size", Expr(10_i)); @@ -406,7 +394,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_InArray) { "type of a 'var'"); } -TEST_F(ResolverTypeValidationTest, ArraySize_Override_InStruct) { +TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_InStruct) { // override size = 10i; // struct S { // a : array @@ -419,7 +407,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_InStruct) { "type of a 'var'"); } -TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionVar_Explicit) { +TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionVar_Explicit) { // override size = 10i; // fn f() { // var a : array; @@ -435,7 +423,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionVar_Explicit) { "type of a 'var'"); } -TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionLet_Explicit) { +TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionLet_Explicit) { // override size = 10i; // fn f() { // var a : array; @@ -451,7 +439,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionLet_Explicit) { "type of a 'var'"); } -TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionVar_Implicit) { +TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionVar_Implicit) { // override size = 10i; // var w : array; // fn f() { @@ -469,7 +457,7 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionVar_Implicit) { "type of a 'var'"); } -TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionLet_Implicit) { +TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_FunctionLet_Implicit) { // override size = 10i; // var w : array; // fn f() { @@ -487,7 +475,24 @@ TEST_F(ResolverTypeValidationTest, ArraySize_Override_FunctionLet_Implicit) { "type of a 'var'"); } -TEST_F(ResolverTypeValidationTest, ArraySize_Override_Param) { +TEST_F(ResolverTypeValidationTest, ArraySize_UnnamedOverride_Equivalence) { + // override size = 10i; + // var a : array; + // var b : array; + // 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' to " + "'array'"); +} + +TEST_F(ResolverTypeValidationTest, ArraySize_NamedOverride_Param) { // override size = 10i; // fn f(a : array) { // } @@ -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 { // } diff --git a/src/tint/sem/array.cc b/src/tint/sem/array.cc index 1cd6515b27..d61d430784 100644 --- a/src/tint/sem/array.cc +++ b/src/tint/sem/array.cc @@ -40,7 +40,8 @@ TypeFlags FlagsFrom(const Type* element, ArrayCount count) { } } if (std::holds_alternative(count) || - std::holds_alternative(count)) { + std::holds_alternative(count) || + std::holds_alternative(count)) { if (element->HasFixedFootprint()) { flags.Add(TypeFlag::kFixedFootprint); } @@ -92,8 +93,10 @@ std::string Array::FriendlyName(const SymbolTable& symbols) const { out << "array<" << element_->FriendlyName(symbols); if (auto* const_count = std::get_if(&count_)) { out << ", " << const_count->value; - } else if (auto* override_count = std::get_if(&count_)) { - out << ", " << symbols.NameFor(override_count->variable->Declaration()->symbol); + } else if (auto* named_override_count = std::get_if(&count_)) { + out << ", " << symbols.NameFor(named_override_count->variable->Declaration()->symbol); + } else if (std::holds_alternative(count_)) { + out << ", [unnamed override-expression]"; } out << ">"; return out.str(); diff --git a/src/tint/sem/array.h b/src/tint/sem/array.h index 24b2ee84c9..88e63739ce 100644 --- a/src/tint/sem/array.h +++ b/src/tint/sem/array.h @@ -26,6 +26,7 @@ // Forward declarations namespace tint::sem { +class Expression; class GlobalVariable; } // namespace tint::sem @@ -48,11 +49,33 @@ struct ConstantArrayCount { /// override N : i32; /// type arr = array /// ``` -struct OverrideArrayCount { +struct NamedOverrideArrayCount { /// The `override` variable. const GlobalVariable* variable; }; +/// The variant of an ArrayCount when the count is an unnamed override variable. +/// Example: +/// ``` +/// override N : i32; +/// type arr = array +/// ``` +struct UnnamedOverrideArrayCount { + /// The unnamed override expression. + /// Note: Each AST expression gets a unique semantic expression node, so two equivalent AST + /// expressions will not result in the same `expr` pointer. This property is important to ensure + /// that two array declarations with equivalent AST expressions do not compare equal. + /// For example, consider: + /// ``` + /// override size : u32; + /// var a : array; + /// var b : array; + /// ``` + // The array count for `a` and `b` have equivalent AST expressions, but the types for `a` and + // `b` must not compare equal. + const Expression* expr; +}; + /// The variant of an ArrayCount when the array is is runtime-sized. /// Example: /// ``` @@ -60,8 +83,12 @@ struct OverrideArrayCount { /// ``` struct RuntimeArrayCount {}; -/// An array count is either a constant-expression value, an override identifier, or runtime-sized. -using ArrayCount = std::variant; +/// An array count is either a constant-expression value, a named override identifier, an unnamed +/// override identifier, or runtime-sized. +using ArrayCount = std::variant; /// Equality operator /// @param a the LHS ConstantArrayCount @@ -75,10 +102,18 @@ inline bool operator==(const ConstantArrayCount& a, const ConstantArrayCount& b) /// @param a the LHS OverrideArrayCount /// @param b the RHS OverrideArrayCount /// @returns true if @p a is equal to @p b -inline bool operator==(const OverrideArrayCount& a, const OverrideArrayCount& b) { +inline bool operator==(const NamedOverrideArrayCount& a, const NamedOverrideArrayCount& b) { return a.variable == b.variable; } +/// Equality operator +/// @param a the LHS OverrideArrayCount +/// @param b the RHS OverrideArrayCount +/// @returns true if @p a is equal to @p b +inline bool operator==(const UnnamedOverrideArrayCount& a, const UnnamedOverrideArrayCount& b) { + return a.expr == b.expr; +} + /// Equality operator /// @returns true inline bool operator==(const RuntimeArrayCount&, const RuntimeArrayCount&) { @@ -90,9 +125,9 @@ inline bool operator==(const RuntimeArrayCount&, const RuntimeArrayCount&) { /// @param b the RHS count /// @returns true if @p a is equal to @p b template || - std::is_same_v || - std::is_same_v>> + typename = std::enable_if_t< + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v>> inline bool operator==(const ArrayCount& a, const T& b) { TINT_BEGIN_DISABLE_WARNING(UNREACHABLE_CODE); return std::visit( @@ -178,8 +213,18 @@ class Array final : public Castable { /// @returns true if this array is sized using an const-expression bool IsConstantSized() const { return std::holds_alternative(count_); } - /// @returns true if this array is sized using an override variable - bool IsOverrideSized() const { return std::holds_alternative(count_); } + /// @returns true if this array is sized using a named override variable + bool IsNamedOverrideSized() const { + return std::holds_alternative(count_); + } + + /// @returns true if this array is sized using an unnamed override variable + bool IsUnnamedOverrideSized() const { + return std::holds_alternative(count_); + } + + /// @returns true if this array is sized using a named or unnamed override variable + bool IsOverrideSized() const { return IsNamedOverrideSized() || IsUnnamedOverrideSized(); } /// @returns true if this array is runtime sized bool IsRuntimeSized() const { return std::holds_alternative(count_); } @@ -213,17 +258,28 @@ class hash { } }; -/// Custom std::hash specialization for tint::sem::OverrideArrayCount. +/// Custom std::hash specialization for tint::sem::NamedOverrideArrayCount. template <> -class hash { +class hash { public: /// @param count the count to hash /// @return the hash value - inline std::size_t operator()(const tint::sem::OverrideArrayCount& count) const { + inline std::size_t operator()(const tint::sem::NamedOverrideArrayCount& count) const { return std::hash()(count.variable); } }; +/// Custom std::hash specialization for tint::sem::UnnamedOverrideArrayCount. +template <> +class hash { + public: + /// @param count the count to hash + /// @return the hash value + inline std::size_t operator()(const tint::sem::UnnamedOverrideArrayCount& count) const { + return std::hash()(count.expr); + } +}; + /// Custom std::hash specialization for tint::sem::RuntimeArrayCount. template <> class hash { diff --git a/src/tint/sem/array_test.cc b/src/tint/sem/array_test.cc index 51c1894339..a51b492239 100644 --- a/src/tint/sem/array_test.cc +++ b/src/tint/sem/array_test.cc @@ -127,31 +127,43 @@ TEST_F(ArrayTest, FriendlyNameStaticSizedNonImplicitStride) { TEST_F(ArrayTest, IsConstructable) { auto* fixed_sized = create(create(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u); - auto* override_sized = create(create(), OverrideArrayCount{}, 4u, 8u, 32u, 16u); + auto* named_override_sized = + create(create(), NamedOverrideArrayCount{}, 4u, 8u, 32u, 16u); + auto* unnamed_override_sized = + create(create(), UnnamedOverrideArrayCount{}, 4u, 8u, 32u, 16u); auto* runtime_sized = create(create(), RuntimeArrayCount{}, 4u, 8u, 32u, 16u); EXPECT_TRUE(fixed_sized->IsConstructible()); - EXPECT_FALSE(override_sized->IsConstructible()); + EXPECT_FALSE(named_override_sized->IsConstructible()); + EXPECT_FALSE(unnamed_override_sized->IsConstructible()); EXPECT_FALSE(runtime_sized->IsConstructible()); } TEST_F(ArrayTest, HasCreationFixedFootprint) { auto* fixed_sized = create(create(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u); - auto* override_sized = create(create(), OverrideArrayCount{}, 4u, 8u, 32u, 16u); + auto* named_override_sized = + create(create(), NamedOverrideArrayCount{}, 4u, 8u, 32u, 16u); + auto* unnamed_override_sized = + create(create(), UnnamedOverrideArrayCount{}, 4u, 8u, 32u, 16u); auto* runtime_sized = create(create(), RuntimeArrayCount{}, 4u, 8u, 32u, 16u); EXPECT_TRUE(fixed_sized->HasCreationFixedFootprint()); - EXPECT_FALSE(override_sized->HasCreationFixedFootprint()); + EXPECT_FALSE(named_override_sized->HasCreationFixedFootprint()); + EXPECT_FALSE(unnamed_override_sized->HasCreationFixedFootprint()); EXPECT_FALSE(runtime_sized->HasCreationFixedFootprint()); } TEST_F(ArrayTest, HasFixedFootprint) { auto* fixed_sized = create(create(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u); - auto* override_sized = create(create(), OverrideArrayCount{}, 4u, 8u, 32u, 16u); + auto* named_override_sized = + create(create(), NamedOverrideArrayCount{}, 4u, 8u, 32u, 16u); + auto* unnamed_override_sized = + create(create(), UnnamedOverrideArrayCount{}, 4u, 8u, 32u, 16u); auto* runtime_sized = create(create(), RuntimeArrayCount{}, 4u, 8u, 32u, 16u); EXPECT_TRUE(fixed_sized->HasFixedFootprint()); - EXPECT_TRUE(override_sized->HasFixedFootprint()); + EXPECT_TRUE(named_override_sized->HasFixedFootprint()); + EXPECT_TRUE(unnamed_override_sized->HasFixedFootprint()); EXPECT_FALSE(runtime_sized->HasFixedFootprint()); } diff --git a/src/tint/transform/transform.cc b/src/tint/transform/transform.cc index 3bcac6bd3b..3e034112b5 100644 --- a/src/tint/transform/transform.cc +++ b/src/tint/transform/transform.cc @@ -114,10 +114,14 @@ const ast::Type* Transform::CreateASTTypeFor(CloneContext& ctx, const sem::Type* if (a->IsRuntimeSized()) { return ctx.dst->ty.array(el, nullptr, std::move(attrs)); } - if (auto* override = std::get_if(&a->Count())) { + if (auto* override = std::get_if(&a->Count())) { auto* count = ctx.Clone(override->variable->Declaration()); return ctx.dst->ty.array(el, count, std::move(attrs)); } + if (auto* override = std::get_if(&a->Count())) { + auto* count = ctx.Clone(override->expr->Declaration()); + return ctx.dst->ty.array(el, count, std::move(attrs)); + } if (auto count = a->ConstantCount()) { return ctx.dst->ty.array(el, u32(count.value()), std::move(attrs)); } diff --git a/test/tint/bug/tint/1737.wgsl b/test/tint/bug/tint/1737.wgsl new file mode 100644 index 0000000000..ea0899d7e2 --- /dev/null +++ b/test/tint/bug/tint/1737.wgsl @@ -0,0 +1,10 @@ +// flags: --overrides wgsize=10 + +override wgsize : u32; +var a : array; // Accepted +var b : array; // Rejected + +fn f() { + let x = a[0]; + let y = b[0]; +} diff --git a/test/tint/bug/tint/1737.wgsl.expected.dxc.hlsl b/test/tint/bug/tint/1737.wgsl.expected.dxc.hlsl new file mode 100644 index 0000000000..436f4ac3ac --- /dev/null +++ b/test/tint/bug/tint/1737.wgsl.expected.dxc.hlsl @@ -0,0 +1,12 @@ +[numthreads(1, 1, 1)] +void unused_entry_point() { + return; +} + +groupshared float a[10]; +groupshared float b[20]; + +void f() { + const float x = a[0]; + const float y = b[0]; +} diff --git a/test/tint/bug/tint/1737.wgsl.expected.fxc.hlsl b/test/tint/bug/tint/1737.wgsl.expected.fxc.hlsl new file mode 100644 index 0000000000..436f4ac3ac --- /dev/null +++ b/test/tint/bug/tint/1737.wgsl.expected.fxc.hlsl @@ -0,0 +1,12 @@ +[numthreads(1, 1, 1)] +void unused_entry_point() { + return; +} + +groupshared float a[10]; +groupshared float b[20]; + +void f() { + const float x = a[0]; + const float y = b[0]; +} diff --git a/test/tint/bug/tint/1737.wgsl.expected.glsl b/test/tint/bug/tint/1737.wgsl.expected.glsl new file mode 100644 index 0000000000..43f1f25e37 --- /dev/null +++ b/test/tint/bug/tint/1737.wgsl.expected.glsl @@ -0,0 +1,13 @@ +#version 310 es + +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; +void unused_entry_point() { + return; +} +shared float a[10]; +shared float b[20]; +void f() { + float x = a[0]; + float y = b[0]; +} + diff --git a/test/tint/bug/tint/1737.wgsl.expected.msl b/test/tint/bug/tint/1737.wgsl.expected.msl new file mode 100644 index 0000000000..d8f8c1e473 --- /dev/null +++ b/test/tint/bug/tint/1737.wgsl.expected.msl @@ -0,0 +1,21 @@ +#include + +using namespace metal; + +template +struct tint_array { + const constant T& operator[](size_t i) const constant { return elements[i]; } + device T& operator[](size_t i) device { return elements[i]; } + const device T& operator[](size_t i) const device { return elements[i]; } + thread T& operator[](size_t i) thread { return elements[i]; } + const thread T& operator[](size_t i) const thread { return elements[i]; } + threadgroup T& operator[](size_t i) threadgroup { return elements[i]; } + const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; } + T elements[N]; +}; + +void f(threadgroup tint_array* const tint_symbol, threadgroup tint_array* const tint_symbol_1) { + float const x = (*(tint_symbol))[0]; + float const y = (*(tint_symbol_1))[0]; +} + diff --git a/test/tint/bug/tint/1737.wgsl.expected.spvasm b/test/tint/bug/tint/1737.wgsl.expected.spvasm new file mode 100644 index 0000000000..1933b2787b --- /dev/null +++ b/test/tint/bug/tint/1737.wgsl.expected.spvasm @@ -0,0 +1,42 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 24 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %unused_entry_point "unused_entry_point" + OpExecutionMode %unused_entry_point LocalSize 1 1 1 + OpName %a "a" + OpName %b "b" + OpName %unused_entry_point "unused_entry_point" + OpName %f "f" + OpDecorate %_arr_float_uint_10 ArrayStride 4 + OpDecorate %_arr_float_uint_20 ArrayStride 4 + %float = OpTypeFloat 32 + %uint = OpTypeInt 32 0 + %uint_10 = OpConstant %uint 10 +%_arr_float_uint_10 = OpTypeArray %float %uint_10 +%_ptr_Workgroup__arr_float_uint_10 = OpTypePointer Workgroup %_arr_float_uint_10 + %a = OpVariable %_ptr_Workgroup__arr_float_uint_10 Workgroup + %uint_20 = OpConstant %uint 20 +%_arr_float_uint_20 = OpTypeArray %float %uint_20 +%_ptr_Workgroup__arr_float_uint_20 = OpTypePointer Workgroup %_arr_float_uint_20 + %b = OpVariable %_ptr_Workgroup__arr_float_uint_20 Workgroup + %void = OpTypeVoid + %11 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %18 = OpConstantNull %int +%_ptr_Workgroup_float = OpTypePointer Workgroup %float +%unused_entry_point = OpFunction %void None %11 + %14 = OpLabel + OpReturn + OpFunctionEnd + %f = OpFunction %void None %11 + %16 = OpLabel + %20 = OpAccessChain %_ptr_Workgroup_float %a %18 + %21 = OpLoad %float %20 + %22 = OpAccessChain %_ptr_Workgroup_float %b %18 + %23 = OpLoad %float %22 + OpReturn + OpFunctionEnd diff --git a/test/tint/bug/tint/1737.wgsl.expected.wgsl b/test/tint/bug/tint/1737.wgsl.expected.wgsl new file mode 100644 index 0000000000..ff19d2ac20 --- /dev/null +++ b/test/tint/bug/tint/1737.wgsl.expected.wgsl @@ -0,0 +1,10 @@ +const wgsize : u32 = 10u; + +var a : array; + +var b : array; + +fn f() { + let x = a[0]; + let y = b[0]; +}