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
%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
)";
%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
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<opt::LocalMultiStoreElimPass>(
+ 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