Delete decorations before replaces uses in dead branch elim (#4598)
If we do not delete the decoration before all ReplaceAllUses, the decorations will be transferred to the new id. This can cause problems.
Fixes #4442.
diff --git a/source/opt/dead_branch_elim_pass.cpp b/source/opt/dead_branch_elim_pass.cpp
index 0054f57..1913414 100644
--- a/source/opt/dead_branch_elim_pass.cpp
+++ b/source/opt/dead_branch_elim_pass.cpp
@@ -346,6 +346,7 @@
if (operands.size() == 4) {
// First input data operands is at index 2.
uint32_t replId = operands[2u].words[0];
+ context()->KillNamesAndDecorates(inst->result_id());
context()->ReplaceAllUsesWith(inst->result_id(), replId);
iter = context()->KillInst(&*inst);
} else {
diff --git a/test/opt/dead_branch_elim_test.cpp b/test/opt/dead_branch_elim_test.cpp
index f89befb..9c49f49 100644
--- a/test/opt/dead_branch_elim_test.cpp
+++ b/test/opt/dead_branch_elim_test.cpp
@@ -3403,6 +3403,45 @@
SinglePassRunAndMatch<DeadBranchElimPass>(text, true);
}
+TEST_F(DeadBranchElimTest, DontTransferDecorations) {
+ // When replacing %4 with %14, we don't want %14 to inherit %4's decorations.
+ const std::string text = R"(
+; CHECK-NOT: OpDecorate {{%\w+}} RelaxedPrecision
+; CHECK: [[div:%\w+]] = OpFDiv
+; CHECK: {{%\w+}} = OpCopyObject %float [[div]]
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main"
+ OpExecutionMode %2 OriginUpperLeft
+ %3 = OpString "STEVEN"
+ OpDecorate %4 RelaxedPrecision
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %void = OpTypeVoid
+ %float_1 = OpConstant %float 1
+ %uint_0 = OpConstant %uint 0
+ %10 = OpTypeFunction %void
+ %2 = OpFunction %void None %10
+ %11 = OpLabel
+ OpSelectionMerge %12 None
+ OpSwitch %uint_0 %13
+ %13 = OpLabel
+ %14 = OpFDiv %float %float_1 %float_1
+ OpLine %3 0 0
+ OpBranch %12
+ %15 = OpLabel
+ OpBranch %12
+ %12 = OpLabel
+ %4 = OpPhi %float %float_1 %15 %14 %13
+ %16 = OpCopyObject %float %4
+ OpReturn
+ OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<DeadBranchElimPass>(text, true);
+}
+
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// More complex control flow