summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Perron <31666470+s-perron@users.noreply.github.com>2018-08-01 13:47:09 -0400
committerGitHub <noreply@github.com>2018-08-01 13:47:09 -0400
commitc8c724cba71dc59912aefd4dd1730a9a7827971e (patch)
tree82e4138a5d74cd0b893780605e2612a644c41d78
parentab061afc838fb8547c7c8aaebde61a8eac228d04 (diff)
Don't change decorations and names in merge return. (#1777)
When creating a new phi for a value in the function, merge return will rewrite all uses of an id that are no longer dominated by its definition. Uses that are not in a basic block, like OpName or decorations, are not dominated, but they should not be replaced. Fixes #1736.
-rw-r--r--source/opt/merge_return_pass.cpp6
-rw-r--r--test/opt/pass_merge_return_test.cpp112
2 files changed, 109 insertions, 9 deletions
diff --git a/source/opt/merge_return_pass.cpp b/source/opt/merge_return_pass.cpp
index 6d955527..d84c1aed 100644
--- a/source/opt/merge_return_pass.cpp
+++ b/source/opt/merge_return_pass.cpp
@@ -198,7 +198,11 @@ void MergeReturnPass::CreatePhiNodesForInst(BasicBlock* merge_block,
std::vector<Instruction*> users_to_update;
context()->get_def_use_mgr()->ForEachUser(
&inst, [&users_to_update, &dom_tree, inst_bb, this](Instruction* user) {
- if (!dom_tree->Dominates(inst_bb, context()->get_instr_block(user))) {
+ BasicBlock* user_bb = context()->get_instr_block(user);
+ // If |user_bb| is nullptr, then |user| is not in the function. It is
+ // something like an OpName or decoration, which should not be
+ // replaced with the result of the OpPhi.
+ if (user_bb && !dom_tree->Dominates(inst_bb, user_bb)) {
users_to_update.push_back(user);
}
});
diff --git a/test/opt/pass_merge_return_test.cpp b/test/opt/pass_merge_return_test.cpp
index f597d6c9..9da13ebe 100644
--- a/test/opt/pass_merge_return_test.cpp
+++ b/test/opt/pass_merge_return_test.cpp
@@ -268,11 +268,11 @@ TEST_F(MergeReturnPassTest, StructuredControlFlowWithUnreachableMerge) {
; CHECK: OpSelectionMerge [[merge_lab:%\w+]]
; CHECK: OpBranchConditional [[cond:%\w+]] [[if_lab:%\w+]] [[then_lab:%\w+]]
; CHECK: [[if_lab]] = OpLabel
-; CHECK-Next: OpStore [[var]] [[true]]
-; CHECK-Next: OpBranch
+; CHECK-NEXT: OpStore [[var]] [[true]]
+; CHECK-NEXT: OpBranch
; CHECK: [[then_lab]] = OpLabel
-; CHECK-Next: OpStore [[var]] [[true]]
-; CHECK-Next: OpBranch [[merge_lab]]
+; CHECK-NEXT: OpStore [[var]] [[true]]
+; CHECK-NEXT: OpBranch [[merge_lab]]
; CHECK: OpReturn
OpCapability Addresses
OpCapability Shader
@@ -310,11 +310,10 @@ TEST_F(MergeReturnPassTest, StructuredControlFlowAddPhi) {
; CHECK: OpBranchConditional [[cond:%\w+]] [[if_lab:%\w+]] [[then_lab:%\w+]]
; CHECK: [[if_lab]] = OpLabel
; CHECK-NEXT: [[add:%\w+]] = OpIAdd [[type:%\w+]]
-; CHECK-Next: OpStore [[var]] [[true]]
-; CHECK-Next: OpBranch
+; CHECK-NEXT: OpBranch
; CHECK: [[then_lab]] = OpLabel
-; CHECK-Next: OpStore [[var]] [[true]]
-; CHECK-Next: OpBranch [[merge_lab]]
+; CHECK-NEXT: OpStore [[var]] [[true]]
+; CHECK-NEXT: OpBranch [[merge_lab]]
; CHECK: [[merge_lab]] = OpLabel
; CHECK-NEXT: [[phi:%\w+]] = OpPhi [[type]] [[add]] [[if_lab]] [[undef:%\w+]] [[then_lab]]
; CHECK: OpIAdd [[type]] [[phi]] [[phi]]
@@ -347,6 +346,103 @@ OpFunctionEnd
SinglePassRunAndMatch<MergeReturnPass>(before, false);
}
+
+TEST_F(MergeReturnPassTest, StructuredControlDecoration) {
+ const std::string before =
+ R"(
+; CHECK: OpDecorate [[dec_id:%\w+]] RelaxedPrecision
+; CHECK: [[false:%\w+]] = OpConstantFalse
+; CHECK: [[true:%\w+]] = OpConstantTrue
+; CHECK: OpFunction
+; CHECK: [[var:%\w+]] = OpVariable [[:%\w+]] Function [[false]]
+; CHECK: OpSelectionMerge [[merge_lab:%\w+]]
+; CHECK: OpBranchConditional [[cond:%\w+]] [[if_lab:%\w+]] [[then_lab:%\w+]]
+; CHECK: [[if_lab]] = OpLabel
+; CHECK-NEXT: [[dec_id]] = OpIAdd [[type:%\w+]]
+; CHECK-NEXT: OpBranch
+; CHECK: [[then_lab]] = OpLabel
+; CHECK-NEXT: OpStore [[var]] [[true]]
+; CHECK-NEXT: OpBranch [[merge_lab]]
+; CHECK: [[merge_lab]] = OpLabel
+; CHECK: OpReturn
+OpCapability Addresses
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %6 "simple_shader"
+OpDecorate %11 RelaxedPrecision
+%2 = OpTypeVoid
+%3 = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%4 = OpConstantFalse %3
+%1 = OpTypeFunction %2
+%6 = OpFunction %2 None %1
+%7 = OpLabel
+OpSelectionMerge %10 None
+OpBranchConditional %4 %8 %9
+%8 = OpLabel
+%11 = OpIAdd %int %int_0 %int_0
+OpBranch %10
+%9 = OpLabel
+OpReturn
+%10 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<MergeReturnPass>(before, false);
+}
+
+TEST_F(MergeReturnPassTest, StructuredControlDecoration2) {
+ const std::string before =
+ R"(
+; CHECK: OpDecorate [[dec_id:%\w+]] RelaxedPrecision
+; CHECK: [[false:%\w+]] = OpConstantFalse
+; CHECK: [[true:%\w+]] = OpConstantTrue
+; CHECK: OpFunction
+; CHECK: [[var:%\w+]] = OpVariable [[:%\w+]] Function [[false]]
+; CHECK: OpSelectionMerge [[merge_lab:%\w+]]
+; CHECK: OpBranchConditional [[cond:%\w+]] [[if_lab:%\w+]] [[then_lab:%\w+]]
+; CHECK: [[if_lab]] = OpLabel
+; CHECK-NEXT: [[dec_id]] = OpIAdd [[type:%\w+]]
+; CHECK-NEXT: OpBranch
+; CHECK: [[then_lab]] = OpLabel
+; CHECK-NEXT: OpStore [[var]] [[true]]
+; CHECK-NEXT: OpBranch [[merge_lab]]
+; CHECK: [[merge_lab]] = OpLabel
+; CHECK-NEXT: [[phi:%\w+]] = OpPhi [[type]] [[dec_id]] [[if_lab]] [[undef:%\w+]] [[then_lab]]
+; CHECK: OpIAdd [[type]] [[phi]] [[phi]]
+; CHECK: OpReturn
+OpCapability Addresses
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %6 "simple_shader"
+OpDecorate %11 RelaxedPrecision
+%2 = OpTypeVoid
+%3 = OpTypeBool
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%4 = OpConstantFalse %3
+%1 = OpTypeFunction %2
+%6 = OpFunction %2 None %1
+%7 = OpLabel
+OpSelectionMerge %10 None
+OpBranchConditional %4 %8 %9
+%8 = OpLabel
+%11 = OpIAdd %int %int_0 %int_0
+OpBranch %10
+%9 = OpLabel
+OpReturn
+%10 = OpLabel
+%12 = OpIAdd %int %11 %11
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<MergeReturnPass>(before, false);
+}
#endif
TEST_F(MergeReturnPassTest, StructuredControlFlowBothMergeAndHeader) {