// Only analyze the phi define now; analyze the phi uses after the
// phi backedge predecessor value is patched.
get_def_use_mgr()->AnalyzeInstDef(&*newPhi);
+ context()->set_instr_block(&*newPhi, *block_itr);
insertItr = insertItr.InsertBefore(std::move(newPhi));
++insertItr;
label2ssa_map_[label].insert({varId, phiId});
std::unique_ptr<ir::Instruction> newPhi(new ir::Instruction(
context(), SpvOpPhi, typeId, phiId, phi_in_operands));
get_def_use_mgr()->AnalyzeInstDefUse(&*newPhi);
+ context()->set_instr_block(&*newPhi, block_ptr);
insertItr = insertItr.InsertBefore(std::move(newPhi));
++insertItr;
label2ssa_map_[label].insert({varId, phiId});
true);
}
+TEST_F(LocalSSAElimTest, VerifyInstToBlockMap) {
+ // #version 140
+ //
+ // in vec4 BC;
+ // out float fo;
+ //
+ // void main()
+ // {
+ // float f = 0.0;
+ // for (int i=0; i<4; i++) {
+ // f = f + BC[i];
+ // }
+ // fo = f;
+ // }
+
+ const std::string text = R"(
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %BC %fo
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 140
+OpName %main "main"
+OpName %f "f"
+OpName %i "i"
+OpName %BC "BC"
+OpName %fo "fo"
+%void = OpTypeVoid
+%8 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%float_0 = OpConstant %float 0
+%int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+%int_0 = OpConstant %int 0
+%int_4 = OpConstant %int 4
+%bool = OpTypeBool
+%v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%BC = OpVariable %_ptr_Input_v4float Input
+%_ptr_Input_float = OpTypePointer Input %float
+%int_1 = OpConstant %int 1
+%_ptr_Output_float = OpTypePointer Output %float
+%fo = OpVariable %_ptr_Output_float Output
+%main = OpFunction %void None %8
+%22 = OpLabel
+%f = OpVariable %_ptr_Function_float Function
+%i = OpVariable %_ptr_Function_int Function
+OpStore %f %float_0
+OpStore %i %int_0
+OpBranch %23
+%23 = OpLabel
+OpLoopMerge %24 %25 None
+OpBranch %26
+%26 = OpLabel
+%27 = OpLoad %int %i
+%28 = OpSLessThan %bool %27 %int_4
+OpBranchConditional %28 %29 %24
+%29 = OpLabel
+%30 = OpLoad %float %f
+%31 = OpLoad %int %i
+%32 = OpAccessChain %_ptr_Input_float %BC %31
+%33 = OpLoad %float %32
+%34 = OpFAdd %float %30 %33
+OpStore %f %34
+OpBranch %25
+%25 = OpLabel
+%35 = OpLoad %int %i
+%36 = OpIAdd %int %35 %int_1
+OpStore %i %36
+OpBranch %23
+%24 = OpLabel
+%37 = OpLoad %float %f
+OpStore %fo %37
+OpReturn
+OpFunctionEnd
+)";
+
+ std::unique_ptr<ir::IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ EXPECT_NE(nullptr, context);
+
+ // Force the instruction to block mapping to get built.
+ context->get_instr_block(27u);
+
+ auto pass = MakeUnique<opt::LocalMultiStoreElimPass>();
+ pass->SetMessageConsumer(nullptr);
+ const auto status = pass->Run(context.get());
+ EXPECT_TRUE(status == opt::Pass::Status::SuccessWithChange);
+}
+
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// No optimization in the presence of