From 78c025abe9cb7452568b0a1710b7c31fc345433e Mon Sep 17 00:00:00 2001 From: GregF Date: Fri, 8 Dec 2017 10:44:15 -0700 Subject: [PATCH] MultiStore: Support OpVariable Initialization Treat an OpVariable with initialization as if it was an OpStore. With PR #1073, this completes work for issue #1017. --- source/opt/mem_pass.cpp | 10 +++ test/opt/local_ssa_elim_test.cpp | 143 +++++++++++++++++++++++++++++-- 2 files changed, 146 insertions(+), 7 deletions(-) diff --git a/source/opt/mem_pass.cpp b/source/opt/mem_pass.cpp index 2a815d705..b21bf00bc 100644 --- a/source/opt/mem_pass.cpp +++ b/source/opt/mem_pass.cpp @@ -34,6 +34,7 @@ const uint32_t kStorePtrIdInIdx = 0; const uint32_t kStoreValIdInIdx = 1; const uint32_t kTypePointerStorageClassInIdx = 0; const uint32_t kTypePointerTypeIdInIdx = 1; +const uint32_t kVariableInitIdInIdx = 1; } // namespace @@ -582,6 +583,15 @@ Pass::Status MemPass::InsertPhiInstructions(ir::Function* func) { label2ssa_map_[label][varId] = inst->GetSingleWordInOperand(kStoreValIdInIdx); } break; + case SpvOpVariable: { + // Treat initialized OpVariable like an OpStore + if (inst->NumInOperands() < 2) break; + uint32_t varId = inst->result_id(); + if (!IsTargetVar(varId)) break; + // Register new stored value for the variable + label2ssa_map_[label][varId] = + inst->GetSingleWordInOperand(kVariableInitIdInIdx); + } break; case SpvOpLoad: { uint32_t varId; (void)GetPtr(inst, &varId); diff --git a/test/opt/local_ssa_elim_test.cpp b/test/opt/local_ssa_elim_test.cpp index c79ef57ac..4813a16df 100644 --- a/test/opt/local_ssa_elim_test.cpp +++ b/test/opt/local_ssa_elim_test.cpp @@ -524,7 +524,7 @@ OpLoopMerge %27 %28 None OpBranch %29 %29 = OpLabel %30 = OpLoad %int %i -%31 = OpLoad %int %ie +%31 = OpLoad %int %ie %32 = OpSLessThan %bool %30 %31 OpBranchConditional %32 %33 %27 %33 = OpLabel @@ -932,20 +932,20 @@ OpDecorate %OutColor Location 0 %21 = OpLoad %float %f %22 = OpFOrdGreaterThanEqual %bool %21 %float_0 OpSelectionMerge %23 None -OpBranchConditional %22 %24 %25 +OpBranchConditional %22 %24 %25 %24 = OpLabel %26 = OpLoad %v4float %BaseColor %27 = OpVectorTimesScalar %v4float %26 %float_0_5 -OpStore %v %27 +OpStore %v %27 OpBranch %23 %25 = OpLabel %28 = OpLoad %v4float %BaseColor %29 = OpFAdd %v4float %28 %18 -OpStore %v %29 +OpStore %v %29 OpBranch %23 %23 = OpLabel %30 = OpLoad %v4float %v -OpStore %OutColor %30 +OpStore %OutColor %30 OpReturn OpFunctionEnd )"; @@ -1306,12 +1306,12 @@ OpBranch %25 %32 = OpLoad %v4float %v %33 = OpCompositeConstruct %v4float %float_0_1 %float_0_1 %float_0_1 %float_0_1 %34 = OpFAdd %v4float %32 %33 -OpStore %v %34 +OpStore %v %34 OpBranch %29 %29 = OpLabel %35 = OpLoad %v4float %v %36 = OpVectorTimesScalar %v4float %35 %float_0_7 -OpStore %v %36 +OpStore %v %36 OpBranch %25 %25 = OpLabel %37 = OpLoad %v4float %v @@ -1384,6 +1384,135 @@ OpFunctionEnd true); } +TEST_F(LocalSSAElimTest, OptInitializedVariableLikeStore) { + // Note: SPIR-V edited to change store to v into variable initialization + // + // #version 450 + // + // layout (location=0) in vec4 iColor; + // layout (location=1) in float fi; + // layout (location=0) out vec4 oColor; + // + // void main() + // { + // vec4 v = vec4(0.0); + // if (fi < 0.0) + // v.x = iColor.x; + // oColor = v; + // } + + const std::string predefs_before = + R"(OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" %fi %iColor %oColor +OpExecutionMode %main OriginUpperLeft +OpSource GLSL 450 +OpName %main "main" +OpName %v "v" +OpName %fi "fi" +OpName %iColor "iColor" +OpName %oColor "oColor" +OpDecorate %fi Location 1 +OpDecorate %iColor Location 0 +OpDecorate %oColor Location 0 +%void = OpTypeVoid +%8 = OpTypeFunction %void +%float = OpTypeFloat 32 +%v4float = OpTypeVector %float 4 +%_ptr_Function_v4float = OpTypePointer Function %v4float +%float_0 = OpConstant %float 0 +%13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 +%_ptr_Input_float = OpTypePointer Input %float +%fi = OpVariable %_ptr_Input_float Input +%bool = OpTypeBool +%_ptr_Input_v4float = OpTypePointer Input %v4float +%iColor = OpVariable %_ptr_Input_v4float Input +%uint = OpTypeInt 32 0 +%uint_0 = OpConstant %uint 0 +%_ptr_Function_float = OpTypePointer Function %float +%_ptr_Output_v4float = OpTypePointer Output %v4float +%oColor = OpVariable %_ptr_Output_v4float Output +)"; + + const std::string predefs_after = + R"(OpCapability Shader +%1 = OpExtInstImport "GLSL.std.450" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %main "main" %fi %iColor %oColor +OpExecutionMode %main OriginUpperLeft +OpSource GLSL 450 +OpName %main "main" +OpName %fi "fi" +OpName %iColor "iColor" +OpName %oColor "oColor" +OpDecorate %fi Location 1 +OpDecorate %iColor Location 0 +OpDecorate %oColor Location 0 +%void = OpTypeVoid +%8 = OpTypeFunction %void +%float = OpTypeFloat 32 +%v4float = OpTypeVector %float 4 +%_ptr_Function_v4float = OpTypePointer Function %v4float +%float_0 = OpConstant %float 0 +%13 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 +%_ptr_Input_float = OpTypePointer Input %float +%fi = OpVariable %_ptr_Input_float Input +%bool = OpTypeBool +%_ptr_Input_v4float = OpTypePointer Input %v4float +%iColor = OpVariable %_ptr_Input_v4float Input +%uint = OpTypeInt 32 0 +%uint_0 = OpConstant %uint 0 +%_ptr_Function_float = OpTypePointer Function %float +%_ptr_Output_v4float = OpTypePointer Output %v4float +%oColor = OpVariable %_ptr_Output_v4float Output +)"; + + const std::string func_before = + R"(%main = OpFunction %void None %8 +%21 = OpLabel +%v = OpVariable %_ptr_Function_v4float Function %13 +%22 = OpLoad %float %fi +%23 = OpFOrdLessThan %bool %22 %float_0 +OpSelectionMerge %24 None +OpBranchConditional %23 %25 %24 +%25 = OpLabel +%26 = OpAccessChain %_ptr_Input_float %iColor %uint_0 +%27 = OpLoad %float %26 +%28 = OpLoad %v4float %v +%29 = OpCompositeInsert %v4float %27 %28 0 +OpStore %v %29 +OpBranch %24 +%24 = OpLabel +%30 = OpLoad %v4float %v +OpStore %oColor %30 +OpReturn +OpFunctionEnd +)"; + + const std::string func_after = + R"(%main = OpFunction %void None %8 +%21 = OpLabel +%22 = OpLoad %float %fi +%23 = OpFOrdLessThan %bool %22 %float_0 +OpSelectionMerge %24 None +OpBranchConditional %23 %25 %24 +%25 = OpLabel +%26 = OpAccessChain %_ptr_Input_float %iColor %uint_0 +%27 = OpLoad %float %26 +%29 = OpCompositeInsert %v4float %27 %13 0 +OpBranch %24 +%24 = OpLabel +%31 = OpPhi %v4float %13 %21 %29 %25 +OpStore %oColor %31 +OpReturn +OpFunctionEnd +)"; + + SinglePassRunAndCheck( + predefs_before + func_before, predefs_after + func_after, true, true); +} + // TODO(greg-lunarg): Add tests to verify handling of these cases: // // No optimization in the presence of