aboutsummaryrefslogtreecommitdiff
path: root/test/opt/wrap_opkill_test.cpp
diff options
context:
space:
mode:
authorSteven Perron <stevenperron@google.com>2019-09-19 22:34:57 -0400
committerSteven Perron <stevenperron@google.com>2019-09-19 22:34:57 -0400
commit87f0fa432f1eeca8bcbfc5ace8ed731239b0e68d (patch)
tree3e31c55627dd3232f339507158cfe0091ed607c8 /test/opt/wrap_opkill_test.cpp
parent08fcf8a4abdc7131033e25694be8cb71f5cf1c0e (diff)
downloadspirv-tools-87f0fa432f1eeca8bcbfc5ace8ed731239b0e68d.tar.gz
Use OpReturn* in wrap-opkill
The warp-opkill pass is generating incorrect code. It is placing an OpUnreachable at the end of a basic block, when the block can be reached. We can't reach the end of the block, but we can reach the end. Instead we will add a return instruction. Fixes #2875.
Diffstat (limited to 'test/opt/wrap_opkill_test.cpp')
-rw-r--r--test/opt/wrap_opkill_test.cpp62
1 files changed, 57 insertions, 5 deletions
diff --git a/test/opt/wrap_opkill_test.cpp b/test/opt/wrap_opkill_test.cpp
index 7162cc56..7e502be1 100644
--- a/test/opt/wrap_opkill_test.cpp
+++ b/test/opt/wrap_opkill_test.cpp
@@ -31,7 +31,7 @@ TEST_F(WrapOpKillTest, SingleOpKill) {
; CHECK: [[orig_kill]] = OpFunction
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
-; CHECK-NEXT: OpUnreachable
+; CHECK-NEXT: OpReturn
; CHECK: [[new_kill]] = OpFunction
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpKill
@@ -83,10 +83,10 @@ TEST_F(WrapOpKillTest, MultipleOpKillInSameFunc) {
; CHECK-NEXT: OpBranchConditional
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
-; CHECK-NEXT: OpUnreachable
+; CHECK-NEXT: OpReturn
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpFunctionCall %void [[new_kill]]
-; CHECK-NEXT: OpUnreachable
+; CHECK-NEXT: OpReturn
; CHECK: [[new_kill]] = OpFunction
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpKill
@@ -143,11 +143,11 @@ TEST_F(WrapOpKillTest, MultipleOpKillInDifferentFunc) {
; CHECK: [[orig_kill1]] = OpFunction
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
-; CHECK-NEXT: OpUnreachable
+; CHECK-NEXT: OpReturn
; CHECK: [[orig_kill2]] = OpFunction
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpFunctionCall %void [[new_kill]]
-; CHECK-NEXT: OpUnreachable
+; CHECK-NEXT: OpReturn
; CHECK: [[new_kill]] = OpFunction
; CHECK-NEXT: OpLabel
; CHECK-NEXT: OpKill
@@ -193,6 +193,58 @@ TEST_F(WrapOpKillTest, MultipleOpKillInDifferentFunc) {
SinglePassRunAndMatch<WrapOpKill>(text, true);
}
+TEST_F(WrapOpKillTest, FuncWithReturnValue) {
+ const std::string text = R"(
+; CHECK: OpEntryPoint Fragment [[main:%\w+]]
+; CHECK: [[main]] = OpFunction
+; CHECK: OpFunctionCall %int [[orig_kill:%\w+]]
+; CHECK: [[orig_kill]] = OpFunction
+; CHECK-NEXT: OpLabel
+; CHECK-NEXT: OpFunctionCall %void [[new_kill:%\w+]]
+; CHECK-NEXT: [[undef:%\w+]] = OpUndef %int
+; CHECK-NEXT: OpReturnValue [[undef]]
+; CHECK: [[new_kill]] = OpFunction
+; CHECK-NEXT: OpLabel
+; CHECK-NEXT: OpKill
+; CHECK-NEXT: OpFunctionEnd
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpSource GLSL 330
+ OpName %main "main"
+ %void = OpTypeVoid
+ %5 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %func_type = OpTypeFunction %int
+ %bool = OpTypeBool
+ %true = OpConstantTrue %bool
+ %main = OpFunction %void None %5
+ %8 = OpLabel
+ OpBranch %9
+ %9 = OpLabel
+ OpLoopMerge %10 %11 None
+ OpBranch %12
+ %12 = OpLabel
+ OpBranchConditional %true %13 %10
+ %13 = OpLabel
+ OpBranch %11
+ %11 = OpLabel
+ %14 = OpFunctionCall %int %kill_
+ OpBranch %9
+ %10 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ %kill_ = OpFunction %int None %func_type
+ %15 = OpLabel
+ OpKill
+ OpFunctionEnd
+ )";
+
+ SinglePassRunAndMatch<WrapOpKill>(text, true);
+}
+
TEST_F(WrapOpKillTest, IdBoundOverflow1) {
const std::string text = R"(
OpCapability GeometryStreams