From c1cb9dc1a5c038ad2d3bad0edc852688f638d9ac Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Thu, 23 Jun 2022 15:46:54 +0000 Subject: [PATCH] tint/resolver: Evaluate constant index accessors If the object and index are both constant expressions, resolve the index as a constant. Note: Expectations have been updated for indexing on 'let's. Once 'const' is introduced, 'let' will no longer be treated as a constant expression, and these expectations will be reverted. Bug: tint:1580 Change-Id: I42793d36c1a5f82890ccaa5dbbb71b4346493bef Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94329 Kokoro: Kokoro Reviewed-by: Dan Sinclair Commit-Queue: Ben Clayton --- src/tint/resolver/resolver.h | 56 +++++---- src/tint/resolver/resolver_constants.cc | 51 ++++++++- src/tint/resolver/resolver_constants_test.cc | 108 ++++++++++++++++++ .../access/let/matrix.spvasm.expected.glsl | 2 +- .../access/let/matrix.spvasm.expected.hlsl | 2 +- .../access/let/matrix.spvasm.expected.msl | 2 +- .../tint/access/let/matrix.wgsl.expected.glsl | 4 +- .../tint/access/let/matrix.wgsl.expected.hlsl | 4 +- test/tint/access/let/matrix.wgsl.expected.msl | 4 +- .../access/let/matrix.wgsl.expected.spvasm | 6 +- test/tint/bug/tint/764.wgsl.expected.glsl | 4 +- test/tint/bug/tint/764.wgsl.expected.hlsl | 4 +- test/tint/bug/tint/764.wgsl.expected.msl | 4 +- test/tint/bug/tint/764.wgsl.expected.spvasm | 6 +- .../let/let/literal/matrix.wgsl.expected.glsl | 2 +- .../let/let/literal/matrix.wgsl.expected.hlsl | 2 +- .../let/let/literal/matrix.wgsl.expected.msl | 2 +- .../let/literal/matrix.wgsl.expected.spvasm | 5 +- .../let/let/literal/vector.wgsl.expected.glsl | 2 +- .../let/let/literal/vector.wgsl.expected.hlsl | 2 +- .../let/let/literal/vector.wgsl.expected.msl | 2 +- .../let/literal/vector.wgsl.expected.spvasm | 5 +- .../let/literal/matrix.wgsl.expected.glsl | 2 +- .../let/literal/matrix.wgsl.expected.hlsl | 2 +- .../let/literal/matrix.wgsl.expected.msl | 2 +- .../let/literal/matrix.wgsl.expected.spvasm | 7 +- .../let/literal/vector.wgsl.expected.glsl | 2 +- .../let/literal/vector.wgsl.expected.hlsl | 2 +- .../let/literal/vector.wgsl.expected.msl | 2 +- .../let/literal/vector.wgsl.expected.spvasm | 7 +- 30 files changed, 230 insertions(+), 75 deletions(-) diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h index 0b52ec9c50..961de41317 100644 --- a/src/tint/resolver/resolver.h +++ b/src/tint/resolver/resolver.h @@ -171,17 +171,25 @@ class Resolver { const ast::ExpressionList& params, uint32_t* id); - ////////////////////////////////////////////////////////////////////////////// - // AST and Type traversal methods - ////////////////////////////////////////////////////////////////////////////// + /// Expression traverses the graph of expressions starting at `expr`, building a postordered + /// list (leaf-first) of all the expression nodes. Each of the expressions are then resolved by + /// dispatching to the appropriate expression handlers below. + /// @returns the resolved semantic node for the expression `expr`, or nullptr on failure. + sem::Expression* Expression(const ast::Expression* expr); + //////////////////////////////////////////////////////////////////////////////////////////////// // Expression resolving methods + // // Returns the semantic node pointer on success, nullptr on failure. + // + // These methods are invoked by Expression(), in postorder (child-first). These methods should + // not attempt to resolve their children. This design avoids recursion, which is a common cause + // of stack-overflows. + //////////////////////////////////////////////////////////////////////////////////////////////// sem::Expression* IndexAccessor(const ast::IndexAccessorExpression*); sem::Expression* Binary(const ast::BinaryExpression*); sem::Expression* Bitcast(const ast::BitcastExpression*); sem::Call* Call(const ast::CallExpression*); - sem::Expression* Expression(const ast::Expression*); sem::Function* Function(const ast::Function*); sem::Call* FunctionCall(const ast::CallExpression*, sem::Function* target, @@ -195,6 +203,29 @@ class Resolver { sem::Expression* MemberAccessor(const ast::MemberAccessorExpression*); sem::Expression* UnaryOp(const ast::UnaryOpExpression*); + //////////////////////////////////////////////////////////////////////////////////////////////// + /// Constant value evaluation methods + /// + /// These methods are called from the expression resolving methods, and so child-expression + /// nodes are guaranteed to have been already resolved and any constant values calculated. + //////////////////////////////////////////////////////////////////////////////////////////////// + sem::Constant EvaluateConstantValue(const ast::Expression* expr, const sem::Type* type); + sem::Constant EvaluateConstantValue(const ast::LiteralExpression* literal, + const sem::Type* type); + sem::Constant EvaluateConstantValue(const ast::CallExpression* call, const sem::Type* type); + sem::Constant EvaluateConstantValue(const ast::IndexAccessorExpression* call, + const sem::Type* type); + + /// The result type of a ConstantEvaluation method. Holds the constant value and a boolean, + /// which is true on success, false on an error. + using ConstantResult = utils::Result; + + /// Convert the `value` to `target_type` + /// @return the converted value + ConstantResult ConvertValue(const sem::Constant& value, + const sem::Type* target_type, + const Source& source); + /// If `expr` is not of an abstract-numeric type, then Materialize() will just return `expr`. /// If `expr` is of an abstract-numeric type: /// * Materialize will create and return a sem::Materialize node wrapping `expr`. @@ -379,23 +410,6 @@ class Resolver { /// Adds the given note message to the diagnostics void AddNote(const std::string& msg, const Source& source) const; - ////////////////////////////////////////////////////////////////////////////// - /// Constant value evaluation methods - ////////////////////////////////////////////////////////////////////////////// - /// The result type of a ConstantEvaluation method. Holds the constant value and a boolean, - /// which is true on success, false on an error. - using ConstantResult = utils::Result; - - /// Convert the `value` to `target_type` - /// @return the converted value - ConstantResult ConvertValue(const sem::Constant& value, - const sem::Type* target_type, - const Source& source); - sem::Constant EvaluateConstantValue(const ast::Expression* expr, const sem::Type* type); - sem::Constant EvaluateConstantValue(const ast::LiteralExpression* literal, - const sem::Type* type); - sem::Constant EvaluateConstantValue(const ast::CallExpression* call, const sem::Type* type); - /// @returns true if the symbol is the name of a builtin function. bool IsBuiltin(Symbol) const; diff --git a/src/tint/resolver/resolver_constants.cc b/src/tint/resolver/resolver_constants.cc index ad89f3e334..cf93c6e73a 100644 --- a/src/tint/resolver/resolver_constants.cc +++ b/src/tint/resolver/resolver_constants.cc @@ -155,7 +155,8 @@ sem::Constant Resolver::EvaluateConstantValue(const ast::Expression* expr, const return Switch( expr, // [&](const ast::LiteralExpression* e) { return EvaluateConstantValue(e, type); }, - [&](const ast::CallExpression* e) { return EvaluateConstantValue(e, type); }); + [&](const ast::CallExpression* e) { return EvaluateConstantValue(e, type); }, + [&](const ast::IndexAccessorExpression* e) { return EvaluateConstantValue(e, type); }); } sem::Constant Resolver::EvaluateConstantValue(const ast::LiteralExpression* literal, @@ -255,6 +256,54 @@ sem::Constant Resolver::EvaluateConstantValue(const ast::CallExpression* call, elements.value()); } +sem::Constant Resolver::EvaluateConstantValue(const ast::IndexAccessorExpression* accessor, + const sem::Type* el_ty) { + auto* obj_sem = builder_->Sem().Get(accessor->object); + if (!obj_sem) { + return {}; + } + + auto obj_val = obj_sem->ConstantValue(); + if (!obj_val) { + return {}; + } + + auto* idx_sem = builder_->Sem().Get(accessor->index); + if (!idx_sem) { + return {}; + } + + auto idx_val = idx_sem->ConstantValue(); + if (!idx_val || idx_val.ElementCount() != 1) { + return {}; + } + + AInt idx = idx_val.Element(0); + + // The immediate child element count. + uint32_t el_count = 0; + sem::Type::ElementOf(obj_val.Type(), &el_count); + + // The total number of most-nested elements per child element type. + uint32_t step = 0; + sem::Type::DeepestElementOf(el_ty, &step); + + if (idx < 0 || idx >= el_count) { + auto clamped = std::min(std::max(idx, 0), el_count - 1); + AddWarning("index " + std::to_string(idx) + " out of bounds [0.." + + std::to_string(el_count - 1) + "]. Clamping index to " + + std::to_string(clamped), + accessor->index->source); + idx = clamped; + } + + return sem::Constant{el_ty, obj_val.WithElements([&](auto&& v) { + using VEC = std::decay_t; + return sem::Constant::Elements( + VEC(v.begin() + (idx * step), v.begin() + (idx + 1) * step)); + })}; +} + utils::Result Resolver::ConvertValue(const sem::Constant& value, const sem::Type* ty, const Source& source) { diff --git a/src/tint/resolver/resolver_constants_test.cc b/src/tint/resolver/resolver_constants_test.cc index c937fa1ff7..d1f43b7300 100644 --- a/src/tint/resolver/resolver_constants_test.cc +++ b/src/tint/resolver/resolver_constants_test.cc @@ -608,5 +608,113 @@ TEST_F(ResolverConstantsTest, Mat3x2_Construct_Columns_af) { EXPECT_EQ(sem->ConstantValue().Element(5).value, 6._a); } +TEST_F(ResolverConstantsTest, Vec3_Index) { + auto* expr = IndexAccessor(vec3(1_i, 2_i, 3_i), 2_i); + WrapInFunction(expr); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); + + auto* sem = Sem().Get(expr); + EXPECT_NE(sem, nullptr); + ASSERT_TRUE(sem->Type()->Is()); + EXPECT_EQ(sem->ConstantValue().Type(), sem->Type()); + EXPECT_TRUE(sem->ConstantValue().ElementType()->Is()); + ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u); + EXPECT_EQ(sem->ConstantValue().Element(0).value, 3_i); +} + +TEST_F(ResolverConstantsTest, Vec3_Index_OOB_High) { + auto* expr = IndexAccessor(vec3(1_i, 2_i, 3_i), Expr(Source{{12, 34}}, 3_i)); + WrapInFunction(expr); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); + EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2"); + + auto* sem = Sem().Get(expr); + EXPECT_NE(sem, nullptr); + ASSERT_TRUE(sem->Type()->Is()); + EXPECT_EQ(sem->ConstantValue().Type(), sem->Type()); + EXPECT_TRUE(sem->ConstantValue().ElementType()->Is()); + ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u); + EXPECT_EQ(sem->ConstantValue().Element(0).value, 3_i); +} + +TEST_F(ResolverConstantsTest, Vec3_Index_OOB_Low) { + auto* expr = IndexAccessor(vec3(1_i, 2_i, 3_i), Expr(Source{{12, 34}}, -3_i)); + WrapInFunction(expr); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); + EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0"); + + auto* sem = Sem().Get(expr); + EXPECT_NE(sem, nullptr); + ASSERT_TRUE(sem->Type()->Is()); + EXPECT_EQ(sem->ConstantValue().Type(), sem->Type()); + EXPECT_TRUE(sem->ConstantValue().ElementType()->Is()); + ASSERT_EQ(sem->ConstantValue().ElementCount(), 1u); + EXPECT_EQ(sem->ConstantValue().Element(0).value, 1_i); +} + +TEST_F(ResolverConstantsTest, Mat3x2_Index) { + auto* expr = IndexAccessor( + mat3x2(vec2(1._a, 2._a), vec2(3._a, 4._a), vec2(5._a, 6._a)), 2_i); + WrapInFunction(expr); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); + + auto* sem = Sem().Get(expr); + EXPECT_NE(sem, nullptr); + auto* vec = sem->Type()->As(); + ASSERT_NE(vec, nullptr); + EXPECT_EQ(vec->Width(), 2u); + EXPECT_EQ(sem->ConstantValue().Type(), sem->Type()); + EXPECT_TRUE(sem->ConstantValue().ElementType()->Is()); + ASSERT_EQ(sem->ConstantValue().ElementCount(), 2u); + EXPECT_EQ(sem->ConstantValue().Element(0).value, 5._a); + EXPECT_EQ(sem->ConstantValue().Element(1).value, 6._a); +} + +TEST_F(ResolverConstantsTest, Mat3x2_Index_OOB_High) { + auto* expr = IndexAccessor( + mat3x2(vec2(1._a, 2._a), vec2(3._a, 4._a), vec2(5._a, 6._a)), + Expr(Source{{12, 34}}, 3_i)); + WrapInFunction(expr); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); + EXPECT_EQ(r()->error(), "12:34 warning: index 3 out of bounds [0..2]. Clamping index to 2"); + + auto* sem = Sem().Get(expr); + EXPECT_NE(sem, nullptr); + auto* vec = sem->Type()->As(); + ASSERT_NE(vec, nullptr); + EXPECT_EQ(vec->Width(), 2u); + EXPECT_EQ(sem->ConstantValue().Type(), sem->Type()); + EXPECT_TRUE(sem->ConstantValue().ElementType()->Is()); + ASSERT_EQ(sem->ConstantValue().ElementCount(), 2u); + EXPECT_EQ(sem->ConstantValue().Element(0).value, 5._a); + EXPECT_EQ(sem->ConstantValue().Element(1).value, 6._a); +} + +TEST_F(ResolverConstantsTest, Mat3x2_Index_OOB_Low) { + auto* expr = IndexAccessor( + mat3x2(vec2(1._a, 2._a), vec2(3._a, 4._a), vec2(5._a, 6._a)), + Expr(Source{{12, 34}}, -3_i)); + WrapInFunction(expr); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); + EXPECT_EQ(r()->error(), "12:34 warning: index -3 out of bounds [0..2]. Clamping index to 0"); + + auto* sem = Sem().Get(expr); + EXPECT_NE(sem, nullptr); + auto* vec = sem->Type()->As(); + ASSERT_NE(vec, nullptr); + EXPECT_EQ(vec->Width(), 2u); + EXPECT_EQ(sem->ConstantValue().Type(), sem->Type()); + EXPECT_TRUE(sem->ConstantValue().ElementType()->Is()); + ASSERT_EQ(sem->ConstantValue().ElementCount(), 2u); + EXPECT_EQ(sem->ConstantValue().Element(0).value, 1._a); + EXPECT_EQ(sem->ConstantValue().Element(1).value, 2._a); +} + } // namespace } // namespace tint::resolver diff --git a/test/tint/access/let/matrix.spvasm.expected.glsl b/test/tint/access/let/matrix.spvasm.expected.glsl index 8292f8948d..f4bf9ccb58 100644 --- a/test/tint/access/let/matrix.spvasm.expected.glsl +++ b/test/tint/access/let/matrix.spvasm.expected.glsl @@ -1,7 +1,7 @@ #version 310 es void main_1() { - float x_24 = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f))[1u].y; + float x_24 = vec3(4.0f, 5.0f, 6.0f).y; return; } diff --git a/test/tint/access/let/matrix.spvasm.expected.hlsl b/test/tint/access/let/matrix.spvasm.expected.hlsl index 7f13ac2aae..164f0209e7 100644 --- a/test/tint/access/let/matrix.spvasm.expected.hlsl +++ b/test/tint/access/let/matrix.spvasm.expected.hlsl @@ -1,5 +1,5 @@ void main_1() { - const float x_24 = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1u].y; + const float x_24 = float3(4.0f, 5.0f, 6.0f).y; return; } diff --git a/test/tint/access/let/matrix.spvasm.expected.msl b/test/tint/access/let/matrix.spvasm.expected.msl index 74a4b931c4..ca54fa670e 100644 --- a/test/tint/access/let/matrix.spvasm.expected.msl +++ b/test/tint/access/let/matrix.spvasm.expected.msl @@ -2,7 +2,7 @@ using namespace metal; void main_1() { - float const x_24 = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1u][1]; + float const x_24 = float3(4.0f, 5.0f, 6.0f)[1]; return; } diff --git a/test/tint/access/let/matrix.wgsl.expected.glsl b/test/tint/access/let/matrix.wgsl.expected.glsl index 590ce6f046..6f4717bac1 100644 --- a/test/tint/access/let/matrix.wgsl.expected.glsl +++ b/test/tint/access/let/matrix.wgsl.expected.glsl @@ -2,8 +2,8 @@ void tint_symbol() { mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f)); - vec3 v = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f))[1]; - float f = v[1]; + vec3 v = vec3(4.0f, 5.0f, 6.0f); + float f = 5.0f; } layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; diff --git a/test/tint/access/let/matrix.wgsl.expected.hlsl b/test/tint/access/let/matrix.wgsl.expected.hlsl index 8b6bb55591..4dcc54ee2a 100644 --- a/test/tint/access/let/matrix.wgsl.expected.hlsl +++ b/test/tint/access/let/matrix.wgsl.expected.hlsl @@ -1,7 +1,7 @@ [numthreads(1, 1, 1)] void main() { const float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f)); - const float3 v = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1]; - const float f = v[1]; + const float3 v = float3(4.0f, 5.0f, 6.0f); + const float f = 5.0f; return; } diff --git a/test/tint/access/let/matrix.wgsl.expected.msl b/test/tint/access/let/matrix.wgsl.expected.msl index eecf61ae45..a1b3e45c08 100644 --- a/test/tint/access/let/matrix.wgsl.expected.msl +++ b/test/tint/access/let/matrix.wgsl.expected.msl @@ -3,8 +3,8 @@ using namespace metal; kernel void tint_symbol() { float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f)); - float3 const v = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1]; - float const f = v[1]; + float3 const v = float3(4.0f, 5.0f, 6.0f); + float const f = 5.0f; return; } diff --git a/test/tint/access/let/matrix.wgsl.expected.spvasm b/test/tint/access/let/matrix.wgsl.expected.spvasm index cbc5aca903..47263bffa8 100644 --- a/test/tint/access/let/matrix.wgsl.expected.spvasm +++ b/test/tint/access/let/matrix.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 25 +; Bound: 21 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -26,11 +26,7 @@ %float_9 = OpConstant %float 9 %19 = OpConstantComposite %v3float %float_7 %float_8 %float_9 %20 = OpConstantComposite %mat3v3float %11 %15 %19 - %int = OpTypeInt 32 1 - %int_1 = OpConstant %int 1 %main = OpFunction %void None %1 %4 = OpLabel - %23 = OpCompositeExtract %v3float %20 1 - %24 = OpCompositeExtract %float %23 1 OpReturn OpFunctionEnd diff --git a/test/tint/bug/tint/764.wgsl.expected.glsl b/test/tint/bug/tint/764.wgsl.expected.glsl index 1b62f398fd..347d829fd8 100644 --- a/test/tint/bug/tint/764.wgsl.expected.glsl +++ b/test/tint/bug/tint/764.wgsl.expected.glsl @@ -6,7 +6,7 @@ void unused_entry_point() { } void f() { mat4 m = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f)); - vec4 v1 = mat4(vec4(1.0f), vec4(1.0f), vec4(1.0f), vec4(1.0f))[0]; - float a = v1[0]; + vec4 v1 = vec4(1.0f); + float a = 1.0f; } diff --git a/test/tint/bug/tint/764.wgsl.expected.hlsl b/test/tint/bug/tint/764.wgsl.expected.hlsl index 236bed1eb8..e4e19f78ba 100644 --- a/test/tint/bug/tint/764.wgsl.expected.hlsl +++ b/test/tint/bug/tint/764.wgsl.expected.hlsl @@ -5,6 +5,6 @@ void unused_entry_point() { void f() { const float4x4 m = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx); - const float4 v1 = float4x4((1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx, (1.0f).xxxx)[0]; - const float a = v1[0]; + const float4 v1 = (1.0f).xxxx; + const float a = 1.0f; } diff --git a/test/tint/bug/tint/764.wgsl.expected.msl b/test/tint/bug/tint/764.wgsl.expected.msl index f70d7447c4..aa71892d2c 100644 --- a/test/tint/bug/tint/764.wgsl.expected.msl +++ b/test/tint/bug/tint/764.wgsl.expected.msl @@ -3,7 +3,7 @@ using namespace metal; void f() { float4x4 const m = float4x4(float4(1.0f), float4(1.0f), float4(1.0f), float4(1.0f)); - float4 const v1 = float4x4(float4(1.0f), float4(1.0f), float4(1.0f), float4(1.0f))[0]; - float const a = v1[0]; + float4 const v1 = float4(1.0f); + float const a = 1.0f; } diff --git a/test/tint/bug/tint/764.wgsl.expected.spvasm b/test/tint/bug/tint/764.wgsl.expected.spvasm index 329c64e7df..f5a8869441 100644 --- a/test/tint/bug/tint/764.wgsl.expected.spvasm +++ b/test/tint/bug/tint/764.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 13 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -17,15 +17,11 @@ %float_1 = OpConstant %float 1 %11 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 %12 = OpConstantComposite %mat4v4float %11 %11 %11 %11 - %int = OpTypeInt 32 1 - %14 = OpConstantNull %int %unused_entry_point = OpFunction %void None %1 %4 = OpLabel OpReturn OpFunctionEnd %f = OpFunction %void None %1 %6 = OpLabel - %15 = OpCompositeExtract %v4float %12 0 - %16 = OpCompositeExtract %float %15 0 OpReturn OpFunctionEnd diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.glsl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.glsl index b6b4777c6a..a88b339b70 100644 --- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.glsl +++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.glsl @@ -6,6 +6,6 @@ void unused_entry_point() { } vec3 f() { mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f)); - return mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f))[1]; + return vec3(4.0f, 5.0f, 6.0f); } diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.hlsl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.hlsl index 60abcc6f5d..a730c4e430 100644 --- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.hlsl +++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.hlsl @@ -5,5 +5,5 @@ void unused_entry_point() { float3 f() { const float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f)); - return float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1]; + return float3(4.0f, 5.0f, 6.0f); } diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.msl b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.msl index 606211b848..6cc482625a 100644 --- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.msl +++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.msl @@ -4,6 +4,6 @@ using namespace metal; float3 f() { float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f)); int const i = 1; - return float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1]; + return float3(4.0f, 5.0f, 6.0f); } diff --git a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.spvasm index 0e46829aaf..9e8d909c7b 100644 --- a/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.spvasm +++ b/test/tint/expressions/index/let/let/literal/matrix.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 27 +; Bound: 26 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -36,6 +36,5 @@ OpFunctionEnd %f = OpFunction %v3float None %5 %9 = OpLabel - %26 = OpCompositeExtract %v3float %23 1 - OpReturnValue %26 + OpReturnValue %18 OpFunctionEnd diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.glsl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.glsl index 4a858dfa6e..0d061634fd 100644 --- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.glsl +++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.glsl @@ -6,6 +6,6 @@ void unused_entry_point() { } float f() { vec3 v = vec3(1.0f, 2.0f, 3.0f); - return vec3(1.0f, 2.0f, 3.0f)[1]; + return 2.0f; } diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.hlsl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.hlsl index de48383baf..04d609c507 100644 --- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.hlsl +++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.hlsl @@ -5,5 +5,5 @@ void unused_entry_point() { float f() { const float3 v = float3(1.0f, 2.0f, 3.0f); - return float3(1.0f, 2.0f, 3.0f)[1]; + return 2.0f; } diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.msl b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.msl index 578bbe1130..2218b65113 100644 --- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.msl +++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.msl @@ -4,6 +4,6 @@ using namespace metal; float f() { float3 const v = float3(1.0f, 2.0f, 3.0f); int const i = 1; - return float3(1.0f, 2.0f, 3.0f)[1]; + return 2.0f; } diff --git a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.spvasm b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.spvasm index d274e46e20..91f8eeae02 100644 --- a/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.spvasm +++ b/test/tint/expressions/index/let/let/literal/vector.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 16 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -26,6 +26,5 @@ OpFunctionEnd %f = OpFunction %float None %5 %8 = OpLabel - %16 = OpCompositeExtract %float %13 1 - OpReturnValue %16 + OpReturnValue %float_2 OpFunctionEnd diff --git a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.glsl b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.glsl index b6b4777c6a..a88b339b70 100644 --- a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.glsl +++ b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.glsl @@ -6,6 +6,6 @@ void unused_entry_point() { } vec3 f() { mat3 m = mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f)); - return mat3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f), vec3(7.0f, 8.0f, 9.0f))[1]; + return vec3(4.0f, 5.0f, 6.0f); } diff --git a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.hlsl b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.hlsl index 60abcc6f5d..a730c4e430 100644 --- a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.hlsl +++ b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.hlsl @@ -5,5 +5,5 @@ void unused_entry_point() { float3 f() { const float3x3 m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f)); - return float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1]; + return float3(4.0f, 5.0f, 6.0f); } diff --git a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.msl b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.msl index f987c403f5..cd5b0bf19b 100644 --- a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.msl +++ b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.msl @@ -3,6 +3,6 @@ using namespace metal; float3 f() { float3x3 const m = float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f)); - return float3x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f), float3(7.0f, 8.0f, 9.0f))[1]; + return float3(4.0f, 5.0f, 6.0f); } diff --git a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.spvasm b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.spvasm index 0e46829aaf..362678cfa6 100644 --- a/test/tint/expressions/index/let/literal/matrix.wgsl.expected.spvasm +++ b/test/tint/expressions/index/let/literal/matrix.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 27 +; Bound: 24 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -28,14 +28,11 @@ %float_9 = OpConstant %float 9 %22 = OpConstantComposite %v3float %float_7 %float_8 %float_9 %23 = OpConstantComposite %mat3v3float %14 %18 %22 - %int = OpTypeInt 32 1 - %int_1 = OpConstant %int 1 %unused_entry_point = OpFunction %void None %1 %4 = OpLabel OpReturn OpFunctionEnd %f = OpFunction %v3float None %5 %9 = OpLabel - %26 = OpCompositeExtract %v3float %23 1 - OpReturnValue %26 + OpReturnValue %18 OpFunctionEnd diff --git a/test/tint/expressions/index/let/literal/vector.wgsl.expected.glsl b/test/tint/expressions/index/let/literal/vector.wgsl.expected.glsl index 4a858dfa6e..0d061634fd 100644 --- a/test/tint/expressions/index/let/literal/vector.wgsl.expected.glsl +++ b/test/tint/expressions/index/let/literal/vector.wgsl.expected.glsl @@ -6,6 +6,6 @@ void unused_entry_point() { } float f() { vec3 v = vec3(1.0f, 2.0f, 3.0f); - return vec3(1.0f, 2.0f, 3.0f)[1]; + return 2.0f; } diff --git a/test/tint/expressions/index/let/literal/vector.wgsl.expected.hlsl b/test/tint/expressions/index/let/literal/vector.wgsl.expected.hlsl index de48383baf..04d609c507 100644 --- a/test/tint/expressions/index/let/literal/vector.wgsl.expected.hlsl +++ b/test/tint/expressions/index/let/literal/vector.wgsl.expected.hlsl @@ -5,5 +5,5 @@ void unused_entry_point() { float f() { const float3 v = float3(1.0f, 2.0f, 3.0f); - return float3(1.0f, 2.0f, 3.0f)[1]; + return 2.0f; } diff --git a/test/tint/expressions/index/let/literal/vector.wgsl.expected.msl b/test/tint/expressions/index/let/literal/vector.wgsl.expected.msl index 70f2313f56..cb5b4bbb6e 100644 --- a/test/tint/expressions/index/let/literal/vector.wgsl.expected.msl +++ b/test/tint/expressions/index/let/literal/vector.wgsl.expected.msl @@ -3,6 +3,6 @@ using namespace metal; float f() { float3 const v = float3(1.0f, 2.0f, 3.0f); - return float3(1.0f, 2.0f, 3.0f)[1]; + return 2.0f; } diff --git a/test/tint/expressions/index/let/literal/vector.wgsl.expected.spvasm b/test/tint/expressions/index/let/literal/vector.wgsl.expected.spvasm index d274e46e20..0c4b98e647 100644 --- a/test/tint/expressions/index/let/literal/vector.wgsl.expected.spvasm +++ b/test/tint/expressions/index/let/literal/vector.wgsl.expected.spvasm @@ -1,7 +1,7 @@ ; SPIR-V ; Version: 1.3 ; Generator: Google Tint Compiler; 0 -; Bound: 17 +; Bound: 14 ; Schema: 0 OpCapability Shader OpMemoryModel Logical GLSL450 @@ -18,14 +18,11 @@ %float_2 = OpConstant %float 2 %float_3 = OpConstant %float 3 %13 = OpConstantComposite %v3float %float_1 %float_2 %float_3 - %int = OpTypeInt 32 1 - %int_1 = OpConstant %int 1 %unused_entry_point = OpFunction %void None %1 %4 = OpLabel OpReturn OpFunctionEnd %f = OpFunction %float None %5 %8 = OpLabel - %16 = OpCompositeExtract %float %13 1 - OpReturnValue %16 + OpReturnValue %float_2 OpFunctionEnd