mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2025-01-11 17:10:06 +00:00
Handle execution termination instructions when building edges.
This fixes issue https://github.com/KhronosGroup/SPIRV-Tools/issues/1153. When building CFG edges, edges out of a OpKill and OpUnreachable instruction should be directed to the CFG's pseudo exit block.
This commit is contained in:
parent
135150a1a8
commit
5f100789fb
@ -413,9 +413,13 @@ bool spvOpcodeIsReturn(SpvOp opcode) {
|
||||
}
|
||||
}
|
||||
|
||||
bool spvOpcodeIsReturnOrAbort(SpvOp opcode) {
|
||||
return spvOpcodeIsReturn(opcode) || opcode == SpvOpKill ||
|
||||
opcode == SpvOpUnreachable;
|
||||
}
|
||||
|
||||
bool spvOpcodeIsBlockTerminator(SpvOp opcode) {
|
||||
return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturn(opcode) ||
|
||||
opcode == SpvOpKill || opcode == SpvOpUnreachable;
|
||||
return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
|
||||
}
|
||||
|
||||
bool spvOpcodeIsBaseOpaqueType(SpvOp opcode) {
|
||||
|
@ -103,6 +103,10 @@ bool spvOpcodeIsBranch(SpvOp opcode);
|
||||
// Returns true if the given opcode is a return instruction.
|
||||
bool spvOpcodeIsReturn(SpvOp opcode);
|
||||
|
||||
// Returns true if the given opcode is a return instruction or it aborts
|
||||
// execution.
|
||||
bool spvOpcodeIsReturnOrAbort(SpvOp opcode);
|
||||
|
||||
// Returns true if the given opcode is a basic block terminator.
|
||||
bool spvOpcodeIsBlockTerminator(SpvOp opcode);
|
||||
|
||||
|
@ -147,6 +147,9 @@ class BasicBlock {
|
||||
// caller.
|
||||
bool IsReturn() const { return ctail()->IsReturn(); }
|
||||
|
||||
// Returns true if this basic block exits this function or aborts execution.
|
||||
bool IsReturnOrAbort() const { return ctail()->IsReturnOrAbort(); }
|
||||
|
||||
private:
|
||||
// The enclosing function.
|
||||
Function* function_;
|
||||
|
@ -317,6 +317,9 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
|
||||
// and return to its caller
|
||||
bool IsReturn() const { return spvOpcodeIsReturn(opcode()); }
|
||||
|
||||
// Returns true if this instruction exits this function or aborts execution.
|
||||
bool IsReturnOrAbort() const { return spvOpcodeIsReturnOrAbort(opcode()); }
|
||||
|
||||
// Returns the id for the |element|'th subtype. If the |this| is not a
|
||||
// composite type, this function returns 0.
|
||||
uint32_t GetTypeComponent(uint32_t element) const;
|
||||
|
@ -193,7 +193,7 @@ void SSAPropagator::Initialize(ir::Function* fn) {
|
||||
bb_succs_[&block].push_back(Edge(&block, succ_bb));
|
||||
bb_preds_[succ_bb].push_back(Edge(succ_bb, &block));
|
||||
});
|
||||
if (block.IsReturn()) {
|
||||
if (block.IsReturnOrAbort()) {
|
||||
bb_succs_[&block].push_back(
|
||||
Edge(&block, ctx_->cfg()->pseudo_exit_block()));
|
||||
bb_preds_[ctx_->cfg()->pseudo_exit_block()].push_back(
|
||||
|
@ -381,6 +381,40 @@ TEST_F(CCPTest, NoLoadStorePropagation) {
|
||||
|
||||
SinglePassRunAndMatch<opt::CCPPass>(spv_asm, true);
|
||||
}
|
||||
|
||||
TEST_F(CCPTest, HandleAbortInstructions) {
|
||||
const std::string spv_asm = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %main "main"
|
||||
OpExecutionMode %main OriginUpperLeft
|
||||
OpSource HLSL 500
|
||||
OpName %main "main"
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%int = OpTypeInt 32 1
|
||||
%bool = OpTypeBool
|
||||
; CHECK: %true = OpConstantTrue %bool
|
||||
%int_3 = OpConstant %int 3
|
||||
%int_1 = OpConstant %int 1
|
||||
%main = OpFunction %void None %3
|
||||
%4 = OpLabel
|
||||
%9 = OpIAdd %int %int_3 %int_1
|
||||
%6 = OpSGreaterThan %bool %9 %int_3
|
||||
OpSelectionMerge %23 None
|
||||
; CHECK: OpBranchConditional %true {{%\d+}} {{%\d+}}
|
||||
OpBranchConditional %6 %22 %23
|
||||
%22 = OpLabel
|
||||
OpKill
|
||||
%23 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndMatch<opt::CCPPass>(spv_asm, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user