diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc index cf98b5d64e..5bc26868e5 100644 --- a/src/tint/writer/spirv/builder.cc +++ b/src/tint/writer/spirv/builder.cc @@ -245,7 +245,7 @@ Builder::AccessorInfo::~AccessorInfo() {} Builder::Builder(const Program* program, bool zero_initialize_workgroup_memory) : builder_(ProgramBuilder::Wrap(program)), - scope_stack_({}), + scope_stack_{Scope{}}, zero_initialize_workgroup_memory_(zero_initialize_workgroup_memory) {} Builder::~Builder() = default; @@ -279,6 +279,30 @@ bool Builder::Build() { return true; } +void Builder::RegisterVariable(const sem::Variable* var, uint32_t id) { + var_to_id_.emplace(var, id); + id_to_var_.emplace(id, var); +} + +uint32_t Builder::LookupVariableID(const sem::Variable* var) { + auto it = var_to_id_.find(var); + if (it == var_to_id_.end()) { + error_ = "unable to find ID for variable: " + + builder_.Symbols().NameFor(var->Declaration()->symbol); + return 0; + } + return it->second; +} + +void Builder::PushScope() { + // Push a new scope, by copying the top-most stack + scope_stack_.push_back(scope_stack_.back()); +} + +void Builder::PopScope() { + scope_stack_.pop_back(); +} + Operand Builder::result_op() { return Operand::Int(next_id()); } @@ -441,7 +465,7 @@ bool Builder::GenerateEntryPoint(const ast::Function* func, uint32_t id) { continue; } - uint32_t var_id = scope_stack_.Get(var->Declaration()->symbol); + uint32_t var_id = LookupVariableID(var); if (var_id == 0) { error_ = "unable to find ID for global variable: " + builder_.Symbols().NameFor(var->Declaration()->symbol); @@ -588,8 +612,8 @@ bool Builder::GenerateFunction(const ast::Function* func_ast) { return false; } - scope_stack_.Push(); - TINT_DEFER(scope_stack_.Pop()); + PushScope(); + TINT_DEFER(PopScope()); auto definition_inst = Instruction{ spv::Op::OpFunction, @@ -612,7 +636,7 @@ bool Builder::GenerateFunction(const ast::Function* func_ast) { params.push_back(Instruction{spv::Op::OpFunctionParameter, {Operand::Int(param_type_id), param_op}}); - scope_stack_.Set(param->Declaration()->symbol, param_id); + RegisterVariable(param, param_id); } push_function(Function{definition_inst, result_op(), std::move(params)}); @@ -680,20 +704,21 @@ bool Builder::GenerateFunctionVariable(const ast::Variable* var) { } } + auto* sem = builder_.Sem().Get(var); + if (var->is_const) { if (!var->constructor) { error_ = "missing constructor for constant"; return false; } - scope_stack_.Set(var->symbol, init_id); - spirv_id_to_variable_[init_id] = var; + RegisterVariable(sem, init_id); return true; } auto result = result_op(); auto var_id = result.to_i(); auto sc = ast::StorageClass::kFunction; - auto* type = builder_.Sem().Get(var)->Type(); + auto* type = sem->Type(); auto type_id = GenerateTypeIfNeeded(type); if (type_id == 0) { return false; @@ -719,8 +744,7 @@ bool Builder::GenerateFunctionVariable(const ast::Variable* var) { } } - scope_stack_.Set(var->symbol, var_id); - spirv_id_to_variable_[var_id] = var; + RegisterVariable(sem, var_id); return true; } @@ -775,8 +799,7 @@ bool Builder::GenerateGlobalVariable(const ast::Variable* var) { {Operand::Int(init_id), Operand::String(builder_.Symbols().NameFor(var->symbol))}); - scope_stack_.Set(var->symbol, init_id); - spirv_id_to_variable_[init_id] = var; + RegisterVariable(sem, init_id); return true; } @@ -898,8 +921,7 @@ bool Builder::GenerateGlobalVariable(const ast::Variable* var) { } } - scope_stack_.Set(var->symbol, var_id); - spirv_id_to_variable_[var_id] = var; + RegisterVariable(sem, var_id); return true; } @@ -1174,12 +1196,13 @@ uint32_t Builder::GenerateAccessorExpression(const ast::Expression* expr) { uint32_t Builder::GenerateIdentifierExpression( const ast::IdentifierExpression* expr) { - uint32_t val = scope_stack_.Get(expr->symbol); - if (val == 0) { - error_ = "unable to find variable with identifier: " + - builder_.Symbols().NameFor(expr->symbol); + auto* sem = builder_.Sem().Get(expr); + if (auto* user = sem->As()) { + return LookupVariableID(user->Variable()); } - return val; + error_ = "identifier '" + builder_.Symbols().NameFor(expr->symbol) + + "' does not resolve to a variable"; + return 0; } uint32_t Builder::GenerateExpressionWithLoadIfNeeded( @@ -1479,8 +1502,12 @@ uint32_t Builder::GenerateTypeConstructorOrConversion( } } + auto& stack = (result_is_spec_composite || result_is_constant_composite) + ? scope_stack_[0] // Global scope + : scope_stack_.back(); // Lexical scope + return utils::GetOrCreate( - type_constructor_to_id_, OperandListKey{ops}, [&]() -> uint32_t { + stack.type_ctor_to_id_, OperandListKey{ops}, [&]() -> uint32_t { auto result = result_op(); ops[kOpsResultIdx] = result; @@ -2193,8 +2220,8 @@ uint32_t Builder::GenerateBinaryExpression(const ast::BinaryExpression* expr) { } bool Builder::GenerateBlockStatement(const ast::BlockStatement* stmt) { - scope_stack_.Push(); - TINT_DEFER(scope_stack_.Pop()); + PushScope(); + TINT_DEFER(PopScope()); return GenerateBlockStatementWithoutScoping(stmt); } @@ -3653,8 +3680,8 @@ bool Builder::GenerateLoopStatement(const ast::LoopStatement* stmt) { // We need variables from the body to be visible in the continuing block, so // manage scope outside of GenerateBlockStatement. { - scope_stack_.Push(); - TINT_DEFER(scope_stack_.Pop()); + PushScope(); + TINT_DEFER(PopScope()); if (!GenerateBlockStatementWithoutScoping(stmt->body)) { return false; diff --git a/src/tint/writer/spirv/builder.h b/src/tint/writer/spirv/builder.h index cf07e27156..cb3ba30ff3 100644 --- a/src/tint/writer/spirv/builder.h +++ b/src/tint/writer/spirv/builder.h @@ -584,6 +584,22 @@ class Builder { uint32_t GenerateConstantVectorSplatIfNeeded(const sem::Vector* type, uint32_t value_id); + /// Registers the semantic variable to the given SPIR-V ID + /// @param var the semantic variable + /// @param id the generated SPIR-V identifier for the variable + void RegisterVariable(const sem::Variable* var, uint32_t id); + + /// Looks up the SPIR-V ID for the variable, which must have been registered + /// with a call to RegisterVariable() + /// @returns the SPIR-V ID, or 0 if the variable was not found + uint32_t LookupVariableID(const sem::Variable* var); + + /// Pushes a new scope + void PushScope(); + + /// Pops the top-most scope + void PopScope(); + ProgramBuilder builder_; std::string error_; uint32_t next_id_ = 1; @@ -599,18 +615,23 @@ class Builder { InstructionList annotations_; std::vector functions_; + // Scope holds per-block information + struct Scope { + std::unordered_map type_ctor_to_id_; + }; + + std::unordered_map var_to_id_; + std::unordered_map id_to_var_; std::unordered_map import_name_to_id_; std::unordered_map func_symbol_to_id_; std::unordered_map func_sig_to_id_; std::unordered_map type_to_id_; std::unordered_map const_to_id_; - std::unordered_map type_constructor_to_id_; std::unordered_map const_null_to_id_; std::unordered_map const_splat_to_id_; std::unordered_map texture_type_to_sampled_image_type_id_; - ScopeStack scope_stack_; - std::unordered_map spirv_id_to_variable_; + std::vector scope_stack_; std::vector merge_stack_; std::vector continue_stack_; std::unordered_set capability_set_; diff --git a/src/tint/writer/spirv/builder_constructor_expression_test.cc b/src/tint/writer/spirv/builder_constructor_expression_test.cc index 495f1c4f5e..ae56e5db16 100644 --- a/src/tint/writer/spirv/builder_constructor_expression_test.cc +++ b/src/tint/writer/spirv/builder_constructor_expression_test.cc @@ -1850,5 +1850,99 @@ TEST_F(SpvBuilderConstructorTest, EXPECT_FALSE(b.has_error()); } +TEST_F(SpvBuilderConstructorTest, ConstantCompositeScoping) { + // if (true) { + // let x = vec3(1.0, 2.0, 3.0); + // } + // let y = vec3(1.0, 2.0, 3.0); // Reuses the ID 'x' + + WrapInFunction( + If(true, Block(Decl(Let("x", nullptr, vec3(1.f, 2.f, 3.f))))), + Decl(Let("y", nullptr, vec3(1.f, 2.f, 3.f)))); + + spirv::Builder& b = SanitizeAndBuild(); + ASSERT_TRUE(b.Build()); + + EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %3 "test_function" +OpExecutionMode %3 LocalSize 1 1 1 +OpName %3 "test_function" +%2 = OpTypeVoid +%1 = OpTypeFunction %2 +%5 = OpTypeBool +%6 = OpConstantTrue %5 +%10 = OpTypeFloat 32 +%9 = OpTypeVector %10 3 +%11 = OpConstant %10 1 +%12 = OpConstant %10 2 +%13 = OpConstant %10 3 +%14 = OpConstantComposite %9 %11 %12 %13 +%3 = OpFunction %2 None %1 +%4 = OpLabel +OpSelectionMerge %7 None +OpBranchConditional %6 %8 %7 +%8 = OpLabel +OpBranch %7 +%7 = OpLabel +OpReturn +OpFunctionEnd +)"); + Validate(b); +} + +// TODO(crbug.com/tint/1155) Implement when overrides are fully implemented. +// TEST_F(SpvBuilderConstructorTest, SpecConstantCompositeScoping) + +TEST_F(SpvBuilderConstructorTest, CompositeConstructScoping) { + // var one = 1.0; + // if (true) { + // let x = vec3(one, 2.0, 3.0); + // } + // let y = vec3(one, 2.0, 3.0); // Mustn't reuse the ID 'x' + + WrapInFunction( + Decl(Var("one", nullptr, Expr(1.f))), + If(true, Block(Decl(Let("x", nullptr, vec3("one", 2.f, 3.f))))), + Decl(Let("y", nullptr, vec3("one", 2.f, 3.f)))); + + spirv::Builder& b = SanitizeAndBuild(); + ASSERT_TRUE(b.Build()); + + EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint GLCompute %3 "test_function" +OpExecutionMode %3 LocalSize 1 1 1 +OpName %3 "test_function" +OpName %7 "one" +%2 = OpTypeVoid +%1 = OpTypeFunction %2 +%5 = OpTypeFloat 32 +%6 = OpConstant %5 1 +%8 = OpTypePointer Function %5 +%9 = OpConstantNull %5 +%10 = OpTypeBool +%11 = OpConstantTrue %10 +%14 = OpTypeVector %5 3 +%16 = OpConstant %5 2 +%17 = OpConstant %5 3 +%3 = OpFunction %2 None %1 +%4 = OpLabel +%7 = OpVariable %8 Function %9 +OpStore %7 %6 +OpSelectionMerge %12 None +OpBranchConditional %11 %13 %12 +%13 = OpLabel +%15 = OpLoad %5 %7 +%18 = OpCompositeConstruct %14 %15 %16 %17 +OpBranch %12 +%12 = OpLabel +%19 = OpLoad %5 %7 +%20 = OpCompositeConstruct %14 %19 %16 %17 +OpReturn +OpFunctionEnd +)"); + Validate(b); +} } // namespace } // namespace tint::writer::spirv diff --git a/test/tint/bug/tint/1520.spvasm b/test/tint/bug/tint/1520.spvasm new file mode 100644 index 0000000000..a9071c2c0c --- /dev/null +++ b/test/tint/bug/tint/1520.spvasm @@ -0,0 +1,248 @@ +OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" %sk_FragColor %sk_Clockwise %vcolor_S0 +OpExecutionMode %main OriginUpperLeft +OpName %UniformBuffer "UniformBuffer" +OpMemberName %UniformBuffer 0 "unknownInput_S1_c0" +OpMemberName %UniformBuffer 1 "ucolorRed_S1_c0" +OpMemberName %UniformBuffer 2 "ucolorGreen_S1_c0" +OpMemberName %UniformBuffer 3 "umatrix_S1" +OpName %sk_FragColor "sk_FragColor" +OpName %sk_Clockwise "sk_Clockwise" +OpName %vcolor_S0 "vcolor_S0" +OpName %test_int_S1_c0_b "test_int_S1_c0_b" +OpName %unknown "unknown" +OpName %ok "ok" +OpName %val "val" +OpName %main "main" +OpName %outputColor_S0 "outputColor_S0" +OpName %output_S1 "output_S1" +OpName %_8_unknown "_8_unknown" +OpName %_9_ok "_9_ok" +OpName %_10_val "_10_val" +OpMemberDecorate %UniformBuffer 0 Offset 16 +OpMemberDecorate %UniformBuffer 0 RelaxedPrecision +OpMemberDecorate %UniformBuffer 1 Offset 32 +OpMemberDecorate %UniformBuffer 1 RelaxedPrecision +OpMemberDecorate %UniformBuffer 2 Offset 48 +OpMemberDecorate %UniformBuffer 2 RelaxedPrecision +OpMemberDecorate %UniformBuffer 3 Offset 64 +OpMemberDecorate %UniformBuffer 3 ColMajor +OpMemberDecorate %UniformBuffer 3 MatrixStride 16 +OpDecorate %UniformBuffer Block +OpDecorate %4 Binding 0 +OpDecorate %4 DescriptorSet 0 +OpDecorate %sk_FragColor RelaxedPrecision +OpDecorate %sk_FragColor Location 0 +OpDecorate %sk_FragColor Index 0 +OpDecorate %sk_Clockwise BuiltIn FrontFacing +OpDecorate %vcolor_S0 RelaxedPrecision +OpDecorate %vcolor_S0 Location 0 +OpDecorate %26 RelaxedPrecision +OpDecorate %outputColor_S0 RelaxedPrecision +OpDecorate %72 RelaxedPrecision +OpDecorate %output_S1 RelaxedPrecision +OpDecorate %_8_unknown RelaxedPrecision +OpDecorate %77 RelaxedPrecision +OpDecorate %83 RelaxedPrecision +OpDecorate %84 RelaxedPrecision +OpDecorate %_10_val RelaxedPrecision +OpDecorate %89 RelaxedPrecision +OpDecorate %92 RelaxedPrecision +OpDecorate %93 RelaxedPrecision +OpDecorate %94 RelaxedPrecision +OpDecorate %95 RelaxedPrecision +OpDecorate %103 RelaxedPrecision +OpDecorate %104 RelaxedPrecision +OpDecorate %105 RelaxedPrecision +OpDecorate %106 RelaxedPrecision +OpDecorate %122 RelaxedPrecision +OpDecorate %124 RelaxedPrecision +OpDecorate %125 RelaxedPrecision +%float = OpTypeFloat 32 +%v4float = OpTypeVector %float 4 +%v3float = OpTypeVector %float 3 +%mat3v3float = OpTypeMatrix %v3float 3 +%UniformBuffer = OpTypeStruct %float %v4float %v4float %mat3v3float +%_ptr_Uniform_UniformBuffer = OpTypePointer Uniform %UniformBuffer +%4 = OpVariable %_ptr_Uniform_UniformBuffer Uniform +%_ptr_Output_v4float = OpTypePointer Output %v4float +%sk_FragColor = OpVariable %_ptr_Output_v4float Output +%bool = OpTypeBool +%_ptr_Input_bool = OpTypePointer Input %bool +%sk_Clockwise = OpVariable %_ptr_Input_bool Input +%_ptr_Input_v4float = OpTypePointer Input %v4float +%vcolor_S0 = OpVariable %_ptr_Input_v4float Input +%18 = OpTypeFunction %bool +%int = OpTypeInt 32 1 +%_ptr_Function_int = OpTypePointer Function %int +%int_0 = OpConstant %int 0 +%_ptr_Uniform_float = OpTypePointer Uniform %float +%_ptr_Function_bool = OpTypePointer Function %bool +%true = OpConstantTrue %bool +%false = OpConstantFalse %bool +%v4int = OpTypeVector %int 4 +%35 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0 +%v4bool = OpTypeVector %bool 4 +%_ptr_Function_v4int = OpTypePointer Function %v4int +%int_1 = OpConstant %int 1 +%46 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 +%int_2 = OpConstant %int 2 +%57 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 +%void = OpTypeVoid +%68 = OpTypeFunction %void +%_ptr_Function_v4float = OpTypePointer Function %v4float +%_ptr_Function_float = OpTypePointer Function %float +%float_0 = OpConstant %float 0 +%82 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 +%float_1 = OpConstant %float 1 +%91 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 +%float_2 = OpConstant %float 2 +%102 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 +%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float +%test_int_S1_c0_b = OpFunction %bool None %18 +%19 = OpLabel +%unknown = OpVariable %_ptr_Function_int Function +%ok = OpVariable %_ptr_Function_bool Function +%val = OpVariable %_ptr_Function_v4int Function +%24 = OpAccessChain %_ptr_Uniform_float %4 %int_0 +%26 = OpLoad %float %24 +%27 = OpConvertFToS %int %26 +OpStore %unknown %27 +OpStore %ok %true +OpSelectionMerge %33 None +OpBranchConditional %true %32 %33 +%32 = OpLabel +%36 = OpCompositeConstruct %v4int %27 %27 %27 %27 +%37 = OpSDiv %v4int %35 %36 +%38 = OpIEqual %v4bool %37 %35 +%40 = OpAll %bool %38 +OpBranch %33 +%33 = OpLabel +%41 = OpPhi %bool %false %19 %40 %32 +OpStore %ok %41 +%44 = OpCompositeConstruct %v4int %27 %27 %27 %27 +OpStore %val %44 +%47 = OpIAdd %v4int %44 %46 +OpStore %val %47 +%48 = OpISub %v4int %47 %46 +OpStore %val %48 +%49 = OpIAdd %v4int %48 %46 +OpStore %val %49 +%50 = OpISub %v4int %49 %46 +OpStore %val %50 +OpSelectionMerge %52 None +OpBranchConditional %41 %51 %52 +%51 = OpLabel +%53 = OpIEqual %v4bool %50 %44 +%54 = OpAll %bool %53 +OpBranch %52 +%52 = OpLabel +%55 = OpPhi %bool %false %33 %54 %51 +OpStore %ok %55 +%58 = OpIMul %v4int %50 %57 +OpStore %val %58 +%59 = OpSDiv %v4int %58 %57 +OpStore %val %59 +%60 = OpIMul %v4int %59 %57 +OpStore %val %60 +%61 = OpSDiv %v4int %60 %57 +OpStore %val %61 +OpSelectionMerge %63 None +OpBranchConditional %55 %62 %63 +%62 = OpLabel +%64 = OpIEqual %v4bool %61 %44 +%65 = OpAll %bool %64 +OpBranch %63 +%63 = OpLabel +%66 = OpPhi %bool %false %52 %65 %62 +OpStore %ok %66 +OpReturnValue %66 +OpFunctionEnd +%main = OpFunction %void None %68 +%69 = OpLabel +%outputColor_S0 = OpVariable %_ptr_Function_v4float Function +%output_S1 = OpVariable %_ptr_Function_v4float Function +%_8_unknown = OpVariable %_ptr_Function_float Function +%_9_ok = OpVariable %_ptr_Function_bool Function +%_10_val = OpVariable %_ptr_Function_v4float Function +%116 = OpVariable %_ptr_Function_v4float Function +%72 = OpLoad %v4float %vcolor_S0 +OpStore %outputColor_S0 %72 +%76 = OpAccessChain %_ptr_Uniform_float %4 %int_0 +%77 = OpLoad %float %76 +OpStore %_8_unknown %77 +OpStore %_9_ok %true +OpSelectionMerge %80 None +OpBranchConditional %true %79 %80 +%79 = OpLabel +%83 = OpCompositeConstruct %v4float %77 %77 %77 %77 +%84 = OpFDiv %v4float %82 %83 +%85 = OpFOrdEqual %v4bool %84 %82 +%86 = OpAll %bool %85 +OpBranch %80 +%80 = OpLabel +%87 = OpPhi %bool %false %69 %86 %79 +OpStore %_9_ok %87 +%89 = OpCompositeConstruct %v4float %77 %77 %77 %77 +OpStore %_10_val %89 +%92 = OpFAdd %v4float %89 %91 +OpStore %_10_val %92 +%93 = OpFSub %v4float %92 %91 +OpStore %_10_val %93 +%94 = OpFAdd %v4float %93 %91 +OpStore %_10_val %94 +%95 = OpFSub %v4float %94 %91 +OpStore %_10_val %95 +OpSelectionMerge %97 None +OpBranchConditional %87 %96 %97 +%96 = OpLabel +%98 = OpFOrdEqual %v4bool %95 %89 +%99 = OpAll %bool %98 +OpBranch %97 +%97 = OpLabel +%100 = OpPhi %bool %false %80 %99 %96 +OpStore %_9_ok %100 +%103 = OpFMul %v4float %95 %102 +OpStore %_10_val %103 +%104 = OpFDiv %v4float %103 %102 +OpStore %_10_val %104 +%105 = OpFMul %v4float %104 %102 +OpStore %_10_val %105 +%106 = OpFDiv %v4float %105 %102 +OpStore %_10_val %106 +OpSelectionMerge %108 None +OpBranchConditional %100 %107 %108 +%107 = OpLabel +%109 = OpFOrdEqual %v4bool %106 %89 +%110 = OpAll %bool %109 +OpBranch %108 +%108 = OpLabel +%111 = OpPhi %bool %false %97 %110 %107 +OpStore %_9_ok %111 +OpSelectionMerge %113 None +OpBranchConditional %111 %112 %113 +%112 = OpLabel +%114 = OpFunctionCall %bool %test_int_S1_c0_b +OpBranch %113 +%113 = OpLabel +%115 = OpPhi %bool %false %108 %114 %112 +OpSelectionMerge %119 None +OpBranchConditional %115 %117 %118 +%117 = OpLabel +%120 = OpAccessChain %_ptr_Uniform_v4float %4 %int_2 +%122 = OpLoad %v4float %120 +OpStore %116 %122 +OpBranch %119 +%118 = OpLabel +%123 = OpAccessChain %_ptr_Uniform_v4float %4 %int_1 +%124 = OpLoad %v4float %123 +OpStore %116 %124 +OpBranch %119 +%119 = OpLabel +%125 = OpLoad %v4float %116 +OpStore %output_S1 %125 +OpStore %sk_FragColor %125 +OpReturn +OpFunctionEnd diff --git a/test/tint/bug/tint/1520.spvasm.expected.glsl b/test/tint/bug/tint/1520.spvasm.expected.glsl new file mode 100644 index 0000000000..358bd77bbf --- /dev/null +++ b/test/tint/bug/tint/1520.spvasm.expected.glsl @@ -0,0 +1,171 @@ +#version 310 es +precision mediump float; + +layout(location = 0) in vec4 vcolor_S0_param_1; +layout(location = 0) out vec4 sk_FragColor_1_1; +struct UniformBuffer { + float unknownInput_S1_c0; + vec4 ucolorRed_S1_c0; + vec4 ucolorGreen_S1_c0; + mat3 umatrix_S1; +}; + +layout(binding = 0) uniform UniformBuffer_1 { + float unknownInput_S1_c0; + vec4 ucolorRed_S1_c0; + vec4 ucolorGreen_S1_c0; + mat3 umatrix_S1; +} x_4; + +vec4 sk_FragColor = vec4(0.0f, 0.0f, 0.0f, 0.0f); +bool sk_Clockwise = false; +vec4 vcolor_S0 = vec4(0.0f, 0.0f, 0.0f, 0.0f); +bool test_int_S1_c0_b() { + int unknown = 0; + bool ok = false; + ivec4 val = ivec4(0, 0, 0, 0); + bool x_40 = false; + bool x_54 = false; + bool x_65 = false; + bool x_41_phi = false; + bool x_55_phi = false; + bool x_66_phi = false; + float x_26 = x_4.unknownInput_S1_c0; + int x_27 = int(x_26); + unknown = x_27; + ok = true; + x_41_phi = false; + if (true) { + x_40 = all(equal((ivec4(0, 0, 0, 0) / ivec4(x_27, x_27, x_27, x_27)), ivec4(0, 0, 0, 0))); + x_41_phi = x_40; + } + bool x_41 = x_41_phi; + ok = x_41; + ivec4 x_44 = ivec4(x_27, x_27, x_27, x_27); + val = x_44; + ivec4 x_47 = (x_44 + ivec4(1, 1, 1, 1)); + val = x_47; + ivec4 x_48 = (x_47 - ivec4(1, 1, 1, 1)); + val = x_48; + ivec4 x_49 = (x_48 + ivec4(1, 1, 1, 1)); + val = x_49; + ivec4 x_50 = (x_49 - ivec4(1, 1, 1, 1)); + val = x_50; + x_55_phi = false; + if (x_41) { + x_54 = all(equal(x_50, x_44)); + x_55_phi = x_54; + } + bool x_55 = x_55_phi; + ok = x_55; + ivec4 x_58 = (x_50 * ivec4(2, 2, 2, 2)); + val = x_58; + ivec4 x_59 = (x_58 / ivec4(2, 2, 2, 2)); + val = x_59; + ivec4 x_60 = (x_59 * ivec4(2, 2, 2, 2)); + val = x_60; + ivec4 x_61 = (x_60 / ivec4(2, 2, 2, 2)); + val = x_61; + x_66_phi = false; + if (x_55) { + x_65 = all(equal(x_61, x_44)); + x_66_phi = x_65; + } + bool x_66 = x_66_phi; + ok = x_66; + return x_66; +} + +void main_1() { + vec4 outputColor_S0 = vec4(0.0f, 0.0f, 0.0f, 0.0f); + vec4 output_S1 = vec4(0.0f, 0.0f, 0.0f, 0.0f); + float x_8_unknown = 0.0f; + bool x_9_ok = false; + vec4 x_10_val = vec4(0.0f, 0.0f, 0.0f, 0.0f); + vec4 x_116 = vec4(0.0f, 0.0f, 0.0f, 0.0f); + bool x_86 = false; + bool x_99 = false; + bool x_110 = false; + bool x_114 = false; + bool x_87_phi = false; + bool x_100_phi = false; + bool x_111_phi = false; + bool x_115_phi = false; + outputColor_S0 = vcolor_S0; + float x_77 = x_4.unknownInput_S1_c0; + x_8_unknown = x_77; + x_9_ok = true; + x_87_phi = false; + if (true) { + x_86 = all(equal((vec4(0.0f, 0.0f, 0.0f, 0.0f) / vec4(x_77, x_77, x_77, x_77)), vec4(0.0f, 0.0f, 0.0f, 0.0f))); + x_87_phi = x_86; + } + bool x_87 = x_87_phi; + x_9_ok = x_87; + vec4 x_89 = vec4(x_77, x_77, x_77, x_77); + x_10_val = x_89; + vec4 x_92 = (x_89 + vec4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_92; + vec4 x_93 = (x_92 - vec4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_93; + vec4 x_94 = (x_93 + vec4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_94; + vec4 x_95 = (x_94 - vec4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_95; + x_100_phi = false; + if (x_87) { + x_99 = all(equal(x_95, x_89)); + x_100_phi = x_99; + } + bool x_100 = x_100_phi; + x_9_ok = x_100; + vec4 x_103 = (x_95 * vec4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_103; + vec4 x_104 = (x_103 / vec4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_104; + vec4 x_105 = (x_104 * vec4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_105; + vec4 x_106 = (x_105 / vec4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_106; + x_111_phi = false; + if (x_100) { + x_110 = all(equal(x_106, x_89)); + x_111_phi = x_110; + } + bool x_111 = x_111_phi; + x_9_ok = x_111; + x_115_phi = false; + if (x_111) { + x_114 = test_int_S1_c0_b(); + x_115_phi = x_114; + } + if (x_115_phi) { + vec4 x_122 = x_4.ucolorGreen_S1_c0; + x_116 = x_122; + } else { + vec4 x_124 = x_4.ucolorRed_S1_c0; + x_116 = x_124; + } + vec4 x_125 = x_116; + output_S1 = x_125; + sk_FragColor = x_125; + return; +} + +struct main_out { + vec4 sk_FragColor_1; +}; + +main_out tint_symbol(bool sk_Clockwise_param, vec4 vcolor_S0_param) { + sk_Clockwise = sk_Clockwise_param; + vcolor_S0 = vcolor_S0_param; + main_1(); + main_out tint_symbol_1 = main_out(sk_FragColor); + return tint_symbol_1; +} + +void main() { + main_out inner_result = tint_symbol(gl_FrontFacing, vcolor_S0_param_1); + sk_FragColor_1_1 = inner_result.sk_FragColor_1; + return; +} diff --git a/test/tint/bug/tint/1520.spvasm.expected.hlsl b/test/tint/bug/tint/1520.spvasm.expected.hlsl new file mode 100644 index 0000000000..052cd99b88 --- /dev/null +++ b/test/tint/bug/tint/1520.spvasm.expected.hlsl @@ -0,0 +1,168 @@ +int4 value_or_one_if_zero_int4(int4 value) { + return value == int4(0, 0, 0, 0) ? int4(1, 1, 1, 1) : value; +} + +cbuffer cbuffer_x_4 : register(b0, space0) { + uint4 x_4[7]; +}; +static float4 sk_FragColor = float4(0.0f, 0.0f, 0.0f, 0.0f); +static bool sk_Clockwise = false; +static float4 vcolor_S0 = float4(0.0f, 0.0f, 0.0f, 0.0f); + +bool test_int_S1_c0_b() { + int unknown = 0; + bool ok = false; + int4 val = int4(0, 0, 0, 0); + bool x_40 = false; + bool x_54 = false; + bool x_65 = false; + bool x_41_phi = false; + bool x_55_phi = false; + bool x_66_phi = false; + const float x_26 = asfloat(x_4[1].x); + const int x_27 = int(x_26); + unknown = x_27; + ok = true; + x_41_phi = false; + if (true) { + x_40 = all(((int4(0, 0, 0, 0) / value_or_one_if_zero_int4(int4(x_27, x_27, x_27, x_27))) == int4(0, 0, 0, 0))); + x_41_phi = x_40; + } + const bool x_41 = x_41_phi; + ok = x_41; + const int4 x_44 = int4(x_27, x_27, x_27, x_27); + val = x_44; + const int4 x_47 = (x_44 + int4(1, 1, 1, 1)); + val = x_47; + const int4 x_48 = (x_47 - int4(1, 1, 1, 1)); + val = x_48; + const int4 x_49 = (x_48 + int4(1, 1, 1, 1)); + val = x_49; + const int4 x_50 = (x_49 - int4(1, 1, 1, 1)); + val = x_50; + x_55_phi = false; + if (x_41) { + x_54 = all((x_50 == x_44)); + x_55_phi = x_54; + } + const bool x_55 = x_55_phi; + ok = x_55; + const int4 x_58 = (x_50 * int4(2, 2, 2, 2)); + val = x_58; + const int4 x_59 = (x_58 / int4(2, 2, 2, 2)); + val = x_59; + const int4 x_60 = (x_59 * int4(2, 2, 2, 2)); + val = x_60; + const int4 x_61 = (x_60 / int4(2, 2, 2, 2)); + val = x_61; + x_66_phi = false; + if (x_55) { + x_65 = all((x_61 == x_44)); + x_66_phi = x_65; + } + const bool x_66 = x_66_phi; + ok = x_66; + return x_66; +} + +void main_1() { + float4 outputColor_S0 = float4(0.0f, 0.0f, 0.0f, 0.0f); + float4 output_S1 = float4(0.0f, 0.0f, 0.0f, 0.0f); + float x_8_unknown = 0.0f; + bool x_9_ok = false; + float4 x_10_val = float4(0.0f, 0.0f, 0.0f, 0.0f); + float4 x_116 = float4(0.0f, 0.0f, 0.0f, 0.0f); + bool x_86 = false; + bool x_99 = false; + bool x_110 = false; + bool x_114 = false; + bool x_87_phi = false; + bool x_100_phi = false; + bool x_111_phi = false; + bool x_115_phi = false; + outputColor_S0 = vcolor_S0; + const float x_77 = asfloat(x_4[1].x); + x_8_unknown = x_77; + x_9_ok = true; + x_87_phi = false; + if (true) { + x_86 = all(((float4(0.0f, 0.0f, 0.0f, 0.0f) / float4(x_77, x_77, x_77, x_77)) == float4(0.0f, 0.0f, 0.0f, 0.0f))); + x_87_phi = x_86; + } + const bool x_87 = x_87_phi; + x_9_ok = x_87; + const float4 x_89 = float4(x_77, x_77, x_77, x_77); + x_10_val = x_89; + const float4 x_92 = (x_89 + float4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_92; + const float4 x_93 = (x_92 - float4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_93; + const float4 x_94 = (x_93 + float4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_94; + const float4 x_95 = (x_94 - float4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_95; + x_100_phi = false; + if (x_87) { + x_99 = all((x_95 == x_89)); + x_100_phi = x_99; + } + const bool x_100 = x_100_phi; + x_9_ok = x_100; + const float4 x_103 = (x_95 * float4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_103; + const float4 x_104 = (x_103 / float4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_104; + const float4 x_105 = (x_104 * float4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_105; + const float4 x_106 = (x_105 / float4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_106; + x_111_phi = false; + if (x_100) { + x_110 = all((x_106 == x_89)); + x_111_phi = x_110; + } + const bool x_111 = x_111_phi; + x_9_ok = x_111; + x_115_phi = false; + if (x_111) { + x_114 = test_int_S1_c0_b(); + x_115_phi = x_114; + } + if (x_115_phi) { + const float4 x_122 = asfloat(x_4[3]); + x_116 = x_122; + } else { + const float4 x_124 = asfloat(x_4[2]); + x_116 = x_124; + } + const float4 x_125 = x_116; + output_S1 = x_125; + sk_FragColor = x_125; + return; +} + +struct main_out { + float4 sk_FragColor_1; +}; +struct tint_symbol_1 { + float4 vcolor_S0_param : TEXCOORD0; + bool sk_Clockwise_param : SV_IsFrontFace; +}; +struct tint_symbol_2 { + float4 sk_FragColor_1 : SV_Target0; +}; + +main_out main_inner(bool sk_Clockwise_param, float4 vcolor_S0_param) { + sk_Clockwise = sk_Clockwise_param; + vcolor_S0 = vcolor_S0_param; + main_1(); + const main_out tint_symbol_5 = {sk_FragColor}; + return tint_symbol_5; +} + +tint_symbol_2 main(tint_symbol_1 tint_symbol) { + const main_out inner_result = main_inner(tint_symbol.sk_Clockwise_param, tint_symbol.vcolor_S0_param); + tint_symbol_2 wrapper_result = (tint_symbol_2)0; + wrapper_result.sk_FragColor_1 = inner_result.sk_FragColor_1; + return wrapper_result; +} diff --git a/test/tint/bug/tint/1520.spvasm.expected.msl b/test/tint/bug/tint/1520.spvasm.expected.msl new file mode 100644 index 0000000000..3e2b30a23b --- /dev/null +++ b/test/tint/bug/tint/1520.spvasm.expected.msl @@ -0,0 +1,176 @@ +#include + +using namespace metal; +struct UniformBuffer { + /* 0x0000 */ int8_t tint_pad[16]; + /* 0x0010 */ float unknownInput_S1_c0; + /* 0x0014 */ int8_t tint_pad_1[12]; + /* 0x0020 */ float4 ucolorRed_S1_c0; + /* 0x0030 */ float4 ucolorGreen_S1_c0; + /* 0x0040 */ float3x3 umatrix_S1; +}; + +bool test_int_S1_c0_b(const constant UniformBuffer* const tint_symbol_5) { + int unknown = 0; + bool ok = false; + int4 val = 0; + bool x_40 = false; + bool x_54 = false; + bool x_65 = false; + bool x_41_phi = false; + bool x_55_phi = false; + bool x_66_phi = false; + float const x_26 = (*(tint_symbol_5)).unknownInput_S1_c0; + int const x_27 = int(x_26); + unknown = x_27; + ok = true; + x_41_phi = false; + if (true) { + x_40 = all(((int4(0, 0, 0, 0) / int4(x_27, x_27, x_27, x_27)) == int4(0, 0, 0, 0))); + x_41_phi = x_40; + } + bool const x_41 = x_41_phi; + ok = x_41; + int4 const x_44 = int4(x_27, x_27, x_27, x_27); + val = x_44; + int4 const x_47 = as_type((as_type(x_44) + as_type(int4(1, 1, 1, 1)))); + val = x_47; + int4 const x_48 = as_type((as_type(x_47) - as_type(int4(1, 1, 1, 1)))); + val = x_48; + int4 const x_49 = as_type((as_type(x_48) + as_type(int4(1, 1, 1, 1)))); + val = x_49; + int4 const x_50 = as_type((as_type(x_49) - as_type(int4(1, 1, 1, 1)))); + val = x_50; + x_55_phi = false; + if (x_41) { + x_54 = all((x_50 == x_44)); + x_55_phi = x_54; + } + bool const x_55 = x_55_phi; + ok = x_55; + int4 const x_58 = as_type((as_type(x_50) * as_type(int4(2, 2, 2, 2)))); + val = x_58; + int4 const x_59 = (x_58 / int4(2, 2, 2, 2)); + val = x_59; + int4 const x_60 = as_type((as_type(x_59) * as_type(int4(2, 2, 2, 2)))); + val = x_60; + int4 const x_61 = (x_60 / int4(2, 2, 2, 2)); + val = x_61; + x_66_phi = false; + if (x_55) { + x_65 = all((x_61 == x_44)); + x_66_phi = x_65; + } + bool const x_66 = x_66_phi; + ok = x_66; + return x_66; +} + +void main_1(thread float4* const tint_symbol_6, const constant UniformBuffer* const tint_symbol_7, thread float4* const tint_symbol_8) { + float4 outputColor_S0 = 0.0f; + float4 output_S1 = 0.0f; + float x_8_unknown = 0.0f; + bool x_9_ok = false; + float4 x_10_val = 0.0f; + float4 x_116 = 0.0f; + bool x_86 = false; + bool x_99 = false; + bool x_110 = false; + bool x_114 = false; + bool x_87_phi = false; + bool x_100_phi = false; + bool x_111_phi = false; + bool x_115_phi = false; + float4 const x_72 = *(tint_symbol_6); + outputColor_S0 = x_72; + float const x_77 = (*(tint_symbol_7)).unknownInput_S1_c0; + x_8_unknown = x_77; + x_9_ok = true; + x_87_phi = false; + if (true) { + x_86 = all(((float4(0.0f, 0.0f, 0.0f, 0.0f) / float4(x_77, x_77, x_77, x_77)) == float4(0.0f, 0.0f, 0.0f, 0.0f))); + x_87_phi = x_86; + } + bool const x_87 = x_87_phi; + x_9_ok = x_87; + float4 const x_89 = float4(x_77, x_77, x_77, x_77); + x_10_val = x_89; + float4 const x_92 = (x_89 + float4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_92; + float4 const x_93 = (x_92 - float4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_93; + float4 const x_94 = (x_93 + float4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_94; + float4 const x_95 = (x_94 - float4(1.0f, 1.0f, 1.0f, 1.0f)); + x_10_val = x_95; + x_100_phi = false; + if (x_87) { + x_99 = all((x_95 == x_89)); + x_100_phi = x_99; + } + bool const x_100 = x_100_phi; + x_9_ok = x_100; + float4 const x_103 = (x_95 * float4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_103; + float4 const x_104 = (x_103 / float4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_104; + float4 const x_105 = (x_104 * float4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_105; + float4 const x_106 = (x_105 / float4(2.0f, 2.0f, 2.0f, 2.0f)); + x_10_val = x_106; + x_111_phi = false; + if (x_100) { + x_110 = all((x_106 == x_89)); + x_111_phi = x_110; + } + bool const x_111 = x_111_phi; + x_9_ok = x_111; + x_115_phi = false; + if (x_111) { + x_114 = test_int_S1_c0_b(tint_symbol_7); + x_115_phi = x_114; + } + bool const x_115 = x_115_phi; + if (x_115) { + float4 const x_122 = (*(tint_symbol_7)).ucolorGreen_S1_c0; + x_116 = x_122; + } else { + float4 const x_124 = (*(tint_symbol_7)).ucolorRed_S1_c0; + x_116 = x_124; + } + float4 const x_125 = x_116; + output_S1 = x_125; + *(tint_symbol_8) = x_125; + return; +} + +struct main_out { + float4 sk_FragColor_1; +}; + +struct tint_symbol_2 { + float4 vcolor_S0_param [[user(locn0)]]; +}; + +struct tint_symbol_3 { + float4 sk_FragColor_1 [[color(0)]]; +}; + +main_out tint_symbol_inner(bool sk_Clockwise_param, float4 vcolor_S0_param, thread bool* const tint_symbol_9, thread float4* const tint_symbol_10, const constant UniformBuffer* const tint_symbol_11, thread float4* const tint_symbol_12) { + *(tint_symbol_9) = sk_Clockwise_param; + *(tint_symbol_10) = vcolor_S0_param; + main_1(tint_symbol_10, tint_symbol_11, tint_symbol_12); + main_out const tint_symbol_4 = {.sk_FragColor_1=*(tint_symbol_12)}; + return tint_symbol_4; +} + +fragment tint_symbol_3 tint_symbol(const constant UniformBuffer* tint_symbol_15 [[buffer(0)]], bool sk_Clockwise_param [[front_facing]], tint_symbol_2 tint_symbol_1 [[stage_in]]) { + thread bool tint_symbol_13 = false; + thread float4 tint_symbol_14 = 0.0f; + thread float4 tint_symbol_16 = 0.0f; + main_out const inner_result = tint_symbol_inner(sk_Clockwise_param, tint_symbol_1.vcolor_S0_param, &(tint_symbol_13), &(tint_symbol_14), tint_symbol_15, &(tint_symbol_16)); + tint_symbol_3 wrapper_result = {}; + wrapper_result.sk_FragColor_1 = inner_result.sk_FragColor_1; + return wrapper_result; +} + diff --git a/test/tint/bug/tint/1520.spvasm.expected.spvasm b/test/tint/bug/tint/1520.spvasm.expected.spvasm new file mode 100644 index 0000000000..ad913296c2 --- /dev/null +++ b/test/tint/bug/tint/1520.spvasm.expected.spvasm @@ -0,0 +1,330 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 175 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %sk_Clockwise_param_1 %vcolor_S0_param_1 %sk_FragColor_1_1 + OpExecutionMode %main OriginUpperLeft + OpName %sk_Clockwise_param_1 "sk_Clockwise_param_1" + OpName %vcolor_S0_param_1 "vcolor_S0_param_1" + OpName %sk_FragColor_1_1 "sk_FragColor_1_1" + OpName %UniformBuffer "UniformBuffer" + OpMemberName %UniformBuffer 0 "unknownInput_S1_c0" + OpMemberName %UniformBuffer 1 "ucolorRed_S1_c0" + OpMemberName %UniformBuffer 2 "ucolorGreen_S1_c0" + OpMemberName %UniformBuffer 3 "umatrix_S1" + OpName %x_4 "x_4" + OpName %sk_FragColor "sk_FragColor" + OpName %sk_Clockwise "sk_Clockwise" + OpName %vcolor_S0 "vcolor_S0" + OpName %test_int_S1_c0_b "test_int_S1_c0_b" + OpName %unknown "unknown" + OpName %ok "ok" + OpName %val "val" + OpName %x_40 "x_40" + OpName %x_54 "x_54" + OpName %x_65 "x_65" + OpName %x_41_phi "x_41_phi" + OpName %x_55_phi "x_55_phi" + OpName %x_66_phi "x_66_phi" + OpName %main_1 "main_1" + OpName %outputColor_S0 "outputColor_S0" + OpName %output_S1 "output_S1" + OpName %x_8_unknown "x_8_unknown" + OpName %x_9_ok "x_9_ok" + OpName %x_10_val "x_10_val" + OpName %x_116 "x_116" + OpName %x_86 "x_86" + OpName %x_99 "x_99" + OpName %x_110 "x_110" + OpName %x_114 "x_114" + OpName %x_87_phi "x_87_phi" + OpName %x_100_phi "x_100_phi" + OpName %x_111_phi "x_111_phi" + OpName %x_115_phi "x_115_phi" + OpName %main_out "main_out" + OpMemberName %main_out 0 "sk_FragColor_1" + OpName %main_inner "main_inner" + OpName %sk_Clockwise_param "sk_Clockwise_param" + OpName %vcolor_S0_param "vcolor_S0_param" + OpName %main "main" + OpDecorate %sk_Clockwise_param_1 BuiltIn FrontFacing + OpDecorate %vcolor_S0_param_1 Location 0 + OpDecorate %sk_FragColor_1_1 Location 0 + OpDecorate %UniformBuffer Block + OpMemberDecorate %UniformBuffer 0 Offset 16 + OpMemberDecorate %UniformBuffer 1 Offset 32 + OpMemberDecorate %UniformBuffer 2 Offset 48 + OpMemberDecorate %UniformBuffer 3 Offset 64 + OpMemberDecorate %UniformBuffer 3 ColMajor + OpMemberDecorate %UniformBuffer 3 MatrixStride 16 + OpDecorate %x_4 NonWritable + OpDecorate %x_4 Binding 0 + OpDecorate %x_4 DescriptorSet 0 + OpMemberDecorate %main_out 0 Offset 0 + %bool = OpTypeBool +%_ptr_Input_bool = OpTypePointer Input %bool +%sk_Clockwise_param_1 = OpVariable %_ptr_Input_bool Input + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Input_v4float = OpTypePointer Input %v4float +%vcolor_S0_param_1 = OpVariable %_ptr_Input_v4float Input +%_ptr_Output_v4float = OpTypePointer Output %v4float + %10 = OpConstantNull %v4float +%sk_FragColor_1_1 = OpVariable %_ptr_Output_v4float Output %10 + %v3float = OpTypeVector %float 3 +%mat3v3float = OpTypeMatrix %v3float 3 +%UniformBuffer = OpTypeStruct %float %v4float %v4float %mat3v3float +%_ptr_Uniform_UniformBuffer = OpTypePointer Uniform %UniformBuffer + %x_4 = OpVariable %_ptr_Uniform_UniformBuffer Uniform +%_ptr_Private_v4float = OpTypePointer Private %v4float +%sk_FragColor = OpVariable %_ptr_Private_v4float Private %10 +%_ptr_Private_bool = OpTypePointer Private %bool + %20 = OpConstantNull %bool +%sk_Clockwise = OpVariable %_ptr_Private_bool Private %20 + %vcolor_S0 = OpVariable %_ptr_Private_v4float Private %10 + %22 = OpTypeFunction %bool + %int = OpTypeInt 32 1 +%_ptr_Function_int = OpTypePointer Function %int + %28 = OpConstantNull %int +%_ptr_Function_bool = OpTypePointer Function %bool + %v4int = OpTypeVector %int 4 +%_ptr_Function_v4int = OpTypePointer Function %v4int + %34 = OpConstantNull %v4int + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 +%_ptr_Uniform_float = OpTypePointer Uniform %float + %true = OpConstantTrue %bool + %false = OpConstantFalse %bool + %int_0 = OpConstant %int 0 + %53 = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0 + %v4bool = OpTypeVector %bool 4 + %int_1 = OpConstant %int 1 + %62 = OpConstantComposite %v4int %int_1 %int_1 %int_1 %int_1 + %int_2 = OpConstant %int 2 + %74 = OpConstantComposite %v4int %int_2 %int_2 %int_2 %int_2 + %void = OpTypeVoid + %85 = OpTypeFunction %void +%_ptr_Function_v4float = OpTypePointer Function %v4float +%_ptr_Function_float = OpTypePointer Function %float + %94 = OpConstantNull %float + %float_0 = OpConstant %float 0 + %113 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 + %float_1 = OpConstant %float 1 + %121 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1 + %float_2 = OpConstant %float 2 + %133 = OpConstantComposite %v4float %float_2 %float_2 %float_2 %float_2 + %uint_2 = OpConstant %uint 2 +%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float + %uint_1 = OpConstant %uint 1 + %main_out = OpTypeStruct %v4float + %160 = OpTypeFunction %main_out %bool %v4float +%test_int_S1_c0_b = OpFunction %bool None %22 + %24 = OpLabel + %unknown = OpVariable %_ptr_Function_int Function %28 + %ok = OpVariable %_ptr_Function_bool Function %20 + %val = OpVariable %_ptr_Function_v4int Function %34 + %x_40 = OpVariable %_ptr_Function_bool Function %20 + %x_54 = OpVariable %_ptr_Function_bool Function %20 + %x_65 = OpVariable %_ptr_Function_bool Function %20 + %x_41_phi = OpVariable %_ptr_Function_bool Function %20 + %x_55_phi = OpVariable %_ptr_Function_bool Function %20 + %x_66_phi = OpVariable %_ptr_Function_bool Function %20 + %44 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 + %45 = OpLoad %float %44 + %46 = OpConvertFToS %int %45 + OpStore %unknown %46 + OpStore %ok %true + OpStore %x_41_phi %false + OpSelectionMerge %49 None + OpBranchConditional %true %50 %49 + %50 = OpLabel + %54 = OpCompositeConstruct %v4int %46 %46 %46 %46 + %55 = OpSDiv %v4int %53 %54 + %56 = OpIEqual %v4bool %55 %53 + %51 = OpAll %bool %56 + OpStore %x_40 %51 + %58 = OpLoad %bool %x_40 + OpStore %x_41_phi %58 + OpBranch %49 + %49 = OpLabel + %59 = OpLoad %bool %x_41_phi + OpStore %ok %59 + %60 = OpCompositeConstruct %v4int %46 %46 %46 %46 + OpStore %val %60 + %63 = OpIAdd %v4int %60 %62 + OpStore %val %63 + %64 = OpISub %v4int %63 %62 + OpStore %val %64 + %65 = OpIAdd %v4int %64 %62 + OpStore %val %65 + %66 = OpISub %v4int %65 %62 + OpStore %val %66 + OpStore %x_55_phi %false + OpSelectionMerge %67 None + OpBranchConditional %59 %68 %67 + %68 = OpLabel + %70 = OpIEqual %v4bool %66 %60 + %69 = OpAll %bool %70 + OpStore %x_54 %69 + %71 = OpLoad %bool %x_54 + OpStore %x_55_phi %71 + OpBranch %67 + %67 = OpLabel + %72 = OpLoad %bool %x_55_phi + OpStore %ok %72 + %75 = OpIMul %v4int %66 %74 + OpStore %val %75 + %76 = OpSDiv %v4int %75 %74 + OpStore %val %76 + %77 = OpIMul %v4int %76 %74 + OpStore %val %77 + %78 = OpSDiv %v4int %77 %74 + OpStore %val %78 + OpStore %x_66_phi %false + OpSelectionMerge %79 None + OpBranchConditional %72 %80 %79 + %80 = OpLabel + %82 = OpIEqual %v4bool %78 %60 + %81 = OpAll %bool %82 + OpStore %x_65 %81 + %83 = OpLoad %bool %x_65 + OpStore %x_66_phi %83 + OpBranch %79 + %79 = OpLabel + %84 = OpLoad %bool %x_66_phi + OpStore %ok %84 + OpReturnValue %84 + OpFunctionEnd + %main_1 = OpFunction %void None %85 + %88 = OpLabel +%outputColor_S0 = OpVariable %_ptr_Function_v4float Function %10 + %output_S1 = OpVariable %_ptr_Function_v4float Function %10 +%x_8_unknown = OpVariable %_ptr_Function_float Function %94 + %x_9_ok = OpVariable %_ptr_Function_bool Function %20 + %x_10_val = OpVariable %_ptr_Function_v4float Function %10 + %x_116 = OpVariable %_ptr_Function_v4float Function %10 + %x_86 = OpVariable %_ptr_Function_bool Function %20 + %x_99 = OpVariable %_ptr_Function_bool Function %20 + %x_110 = OpVariable %_ptr_Function_bool Function %20 + %x_114 = OpVariable %_ptr_Function_bool Function %20 + %x_87_phi = OpVariable %_ptr_Function_bool Function %20 + %x_100_phi = OpVariable %_ptr_Function_bool Function %20 + %x_111_phi = OpVariable %_ptr_Function_bool Function %20 + %x_115_phi = OpVariable %_ptr_Function_bool Function %20 + %106 = OpLoad %v4float %vcolor_S0 + OpStore %outputColor_S0 %106 + %107 = OpAccessChain %_ptr_Uniform_float %x_4 %uint_0 + %108 = OpLoad %float %107 + OpStore %x_8_unknown %108 + OpStore %x_9_ok %true + OpStore %x_87_phi %false + OpSelectionMerge %109 None + OpBranchConditional %true %110 %109 + %110 = OpLabel + %114 = OpCompositeConstruct %v4float %108 %108 %108 %108 + %115 = OpFDiv %v4float %113 %114 + %116 = OpFOrdEqual %v4bool %115 %113 + %111 = OpAll %bool %116 + OpStore %x_86 %111 + %117 = OpLoad %bool %x_86 + OpStore %x_87_phi %117 + OpBranch %109 + %109 = OpLabel + %118 = OpLoad %bool %x_87_phi + OpStore %x_9_ok %118 + %119 = OpCompositeConstruct %v4float %108 %108 %108 %108 + OpStore %x_10_val %119 + %122 = OpFAdd %v4float %119 %121 + OpStore %x_10_val %122 + %123 = OpFSub %v4float %122 %121 + OpStore %x_10_val %123 + %124 = OpFAdd %v4float %123 %121 + OpStore %x_10_val %124 + %125 = OpFSub %v4float %124 %121 + OpStore %x_10_val %125 + OpStore %x_100_phi %false + OpSelectionMerge %126 None + OpBranchConditional %118 %127 %126 + %127 = OpLabel + %129 = OpFOrdEqual %v4bool %125 %119 + %128 = OpAll %bool %129 + OpStore %x_99 %128 + %130 = OpLoad %bool %x_99 + OpStore %x_100_phi %130 + OpBranch %126 + %126 = OpLabel + %131 = OpLoad %bool %x_100_phi + OpStore %x_9_ok %131 + %134 = OpFMul %v4float %125 %133 + OpStore %x_10_val %134 + %135 = OpFDiv %v4float %134 %133 + OpStore %x_10_val %135 + %136 = OpFMul %v4float %135 %133 + OpStore %x_10_val %136 + %137 = OpFDiv %v4float %136 %133 + OpStore %x_10_val %137 + OpStore %x_111_phi %false + OpSelectionMerge %138 None + OpBranchConditional %131 %139 %138 + %139 = OpLabel + %141 = OpFOrdEqual %v4bool %137 %119 + %140 = OpAll %bool %141 + OpStore %x_110 %140 + %142 = OpLoad %bool %x_110 + OpStore %x_111_phi %142 + OpBranch %138 + %138 = OpLabel + %143 = OpLoad %bool %x_111_phi + OpStore %x_9_ok %143 + OpStore %x_115_phi %false + OpSelectionMerge %144 None + OpBranchConditional %143 %145 %144 + %145 = OpLabel + %146 = OpFunctionCall %bool %test_int_S1_c0_b + OpStore %x_114 %146 + %147 = OpLoad %bool %x_114 + OpStore %x_115_phi %147 + OpBranch %144 + %144 = OpLabel + %148 = OpLoad %bool %x_115_phi + OpSelectionMerge %149 None + OpBranchConditional %148 %150 %151 + %150 = OpLabel + %154 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_2 + %155 = OpLoad %v4float %154 + OpStore %x_116 %155 + OpBranch %149 + %151 = OpLabel + %157 = OpAccessChain %_ptr_Uniform_v4float %x_4 %uint_1 + %158 = OpLoad %v4float %157 + OpStore %x_116 %158 + OpBranch %149 + %149 = OpLabel + %159 = OpLoad %v4float %x_116 + OpStore %output_S1 %159 + OpStore %sk_FragColor %159 + OpReturn + OpFunctionEnd + %main_inner = OpFunction %main_out None %160 +%sk_Clockwise_param = OpFunctionParameter %bool +%vcolor_S0_param = OpFunctionParameter %v4float + %165 = OpLabel + OpStore %sk_Clockwise %sk_Clockwise_param + OpStore %vcolor_S0 %vcolor_S0_param + %166 = OpFunctionCall %void %main_1 + %167 = OpLoad %v4float %sk_FragColor + %168 = OpCompositeConstruct %main_out %167 + OpReturnValue %168 + OpFunctionEnd + %main = OpFunction %void None %85 + %170 = OpLabel + %172 = OpLoad %bool %sk_Clockwise_param_1 + %173 = OpLoad %v4float %vcolor_S0_param_1 + %171 = OpFunctionCall %main_out %main_inner %172 %173 + %174 = OpCompositeExtract %v4float %171 0 + OpStore %sk_FragColor_1_1 %174 + OpReturn + OpFunctionEnd diff --git a/test/tint/bug/tint/1520.spvasm.expected.wgsl b/test/tint/bug/tint/1520.spvasm.expected.wgsl new file mode 100644 index 0000000000..359389ea1b --- /dev/null +++ b/test/tint/bug/tint/1520.spvasm.expected.wgsl @@ -0,0 +1,165 @@ +struct UniformBuffer { + @size(16) + padding : u32, + unknownInput_S1_c0 : f32, + @size(12) + padding_1 : u32, + ucolorRed_S1_c0 : vec4, + ucolorGreen_S1_c0 : vec4, + umatrix_S1 : mat3x3, +} + +@binding(0) @group(0) var x_4 : UniformBuffer; + +var sk_FragColor : vec4; + +var sk_Clockwise : bool; + +var vcolor_S0 : vec4; + +fn test_int_S1_c0_b() -> bool { + var unknown : i32; + var ok : bool; + var val : vec4; + var x_40 : bool; + var x_54 : bool; + var x_65 : bool; + var x_41_phi : bool; + var x_55_phi : bool; + var x_66_phi : bool; + let x_26 : f32 = x_4.unknownInput_S1_c0; + let x_27 : i32 = i32(x_26); + unknown = x_27; + ok = true; + x_41_phi = false; + if (true) { + x_40 = all(((vec4(0, 0, 0, 0) / vec4(x_27, x_27, x_27, x_27)) == vec4(0, 0, 0, 0))); + x_41_phi = x_40; + } + let x_41 : bool = x_41_phi; + ok = x_41; + let x_44 : vec4 = vec4(x_27, x_27, x_27, x_27); + val = x_44; + let x_47 : vec4 = (x_44 + vec4(1, 1, 1, 1)); + val = x_47; + let x_48 : vec4 = (x_47 - vec4(1, 1, 1, 1)); + val = x_48; + let x_49 : vec4 = (x_48 + vec4(1, 1, 1, 1)); + val = x_49; + let x_50 : vec4 = (x_49 - vec4(1, 1, 1, 1)); + val = x_50; + x_55_phi = false; + if (x_41) { + x_54 = all((x_50 == x_44)); + x_55_phi = x_54; + } + let x_55 : bool = x_55_phi; + ok = x_55; + let x_58 : vec4 = (x_50 * vec4(2, 2, 2, 2)); + val = x_58; + let x_59 : vec4 = (x_58 / vec4(2, 2, 2, 2)); + val = x_59; + let x_60 : vec4 = (x_59 * vec4(2, 2, 2, 2)); + val = x_60; + let x_61 : vec4 = (x_60 / vec4(2, 2, 2, 2)); + val = x_61; + x_66_phi = false; + if (x_55) { + x_65 = all((x_61 == x_44)); + x_66_phi = x_65; + } + let x_66 : bool = x_66_phi; + ok = x_66; + return x_66; +} + +fn main_1() { + var outputColor_S0 : vec4; + var output_S1 : vec4; + var x_8_unknown : f32; + var x_9_ok : bool; + var x_10_val : vec4; + var x_116 : vec4; + var x_86 : bool; + var x_99 : bool; + var x_110 : bool; + var x_114 : bool; + var x_87_phi : bool; + var x_100_phi : bool; + var x_111_phi : bool; + var x_115_phi : bool; + let x_72 : vec4 = vcolor_S0; + outputColor_S0 = x_72; + let x_77 : f32 = x_4.unknownInput_S1_c0; + x_8_unknown = x_77; + x_9_ok = true; + x_87_phi = false; + if (true) { + x_86 = all(((vec4(0.0, 0.0, 0.0, 0.0) / vec4(x_77, x_77, x_77, x_77)) == vec4(0.0, 0.0, 0.0, 0.0))); + x_87_phi = x_86; + } + let x_87 : bool = x_87_phi; + x_9_ok = x_87; + let x_89 : vec4 = vec4(x_77, x_77, x_77, x_77); + x_10_val = x_89; + let x_92 : vec4 = (x_89 + vec4(1.0, 1.0, 1.0, 1.0)); + x_10_val = x_92; + let x_93 : vec4 = (x_92 - vec4(1.0, 1.0, 1.0, 1.0)); + x_10_val = x_93; + let x_94 : vec4 = (x_93 + vec4(1.0, 1.0, 1.0, 1.0)); + x_10_val = x_94; + let x_95 : vec4 = (x_94 - vec4(1.0, 1.0, 1.0, 1.0)); + x_10_val = x_95; + x_100_phi = false; + if (x_87) { + x_99 = all((x_95 == x_89)); + x_100_phi = x_99; + } + let x_100 : bool = x_100_phi; + x_9_ok = x_100; + let x_103 : vec4 = (x_95 * vec4(2.0, 2.0, 2.0, 2.0)); + x_10_val = x_103; + let x_104 : vec4 = (x_103 / vec4(2.0, 2.0, 2.0, 2.0)); + x_10_val = x_104; + let x_105 : vec4 = (x_104 * vec4(2.0, 2.0, 2.0, 2.0)); + x_10_val = x_105; + let x_106 : vec4 = (x_105 / vec4(2.0, 2.0, 2.0, 2.0)); + x_10_val = x_106; + x_111_phi = false; + if (x_100) { + x_110 = all((x_106 == x_89)); + x_111_phi = x_110; + } + let x_111 : bool = x_111_phi; + x_9_ok = x_111; + x_115_phi = false; + if (x_111) { + x_114 = test_int_S1_c0_b(); + x_115_phi = x_114; + } + let x_115 : bool = x_115_phi; + if (x_115) { + let x_122 : vec4 = x_4.ucolorGreen_S1_c0; + x_116 = x_122; + } else { + let x_124 : vec4 = x_4.ucolorRed_S1_c0; + x_116 = x_124; + } + let x_125 : vec4 = x_116; + output_S1 = x_125; + sk_FragColor = x_125; + return; +} + +struct main_out { + @location(0) + sk_FragColor_1 : vec4, +} + +@stage(fragment) +fn main(@builtin(front_facing) sk_Clockwise_param : bool, @location(0) vcolor_S0_param : vec4) -> main_out { + sk_Clockwise = sk_Clockwise_param; + vcolor_S0 = vcolor_S0_param; + main_1(); + return main_out(sk_FragColor); +}