diff options
author | Steven Perron <stevenperron@google.com> | 2019-09-19 22:34:57 -0400 |
---|---|---|
committer | Steven Perron <stevenperron@google.com> | 2019-09-19 22:34:57 -0400 |
commit | 87f0fa432f1eeca8bcbfc5ace8ed731239b0e68d (patch) | |
tree | 3e31c55627dd3232f339507158cfe0091ed607c8 /test/opt/wrap_opkill_test.cpp | |
parent | 08fcf8a4abdc7131033e25694be8cb71f5cf1c0e (diff) | |
download | spirv-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.cpp | 62 |
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 |