-
Notifications
You must be signed in to change notification settings - Fork 664
inliner generates invalid OpLabel if callee has single return in block that does not appear last #755
Copy link
Copy link
Closed
Labels
Description
Example code:
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main"
OpSource GLSL 450
OpName %main "main"
OpName %foo_ "foo("
%void = OpTypeVoid
%3 = OpTypeFunction %void
%bool = OpTypeBool
%true = OpConstantTrue %bool
%main = OpFunction %void None %3
%5 = OpLabel
%12 = OpFunctionCall %void %foo_
OpReturn
OpFunctionEnd
%foo_ = OpFunction %void None %3
%7 = OpLabel
OpSelectionMerge %11 None
OpBranchConditional %true %10 %11
%11 = OpLabel
OpReturn ; This causes returnLabelId to be non-zero, but earlyReturn is false.
%10 = OpLabel
OpBranch %11
OpFunctionEnd
It's generated from this vertex shader, but where I reorder, in the SPIR-V assembly, the last two basic blocks of the "foo" function:
#version 450
void foo() {
if (true) {
}
}
void main() {
foo();
}
When running spirv-opt with inline-entry-points-exhaustive:
- returnLabelId is non-zero since we encountered an OpReturn well before the OpFunctionEnd
- but earlyReturn is false
- but at OpFunctionEnd we generate "continue target" with OpLabel for result id singleTripLoopContinueId. But that is still zero.
- this causes a new instruction with OpLabel opcode, but zero result Id, and generates a 1-word OpLabel instruction, which is invalid.
Likely remedy is to guard the codegen of continue target block by earlyReturn. Still have to create the block with label Id returnLabelId.
Reactions are currently unavailable