mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-22 11:40:05 +00:00
Fix OpLine bug of merge-blocks pass (#3130)
As explained in #3118, spirv-opt merge-blocks pass causes a spirv-val error when an OpBranch has an OpLine in front of it. OpLoopMerge OpBranch ; Will be killed by merge-blocks pass OpLabel ; Will be killed by merge-blocks pass OpLine ; will be placed between OpLoopMerge and OpBranch - error! OpBranch To fix this issue, this commit moves line info of OpBranch to OpLoopMerge. Fixes #3118
This commit is contained in:
parent
8013d477ae
commit
f8d7df760c
@ -171,8 +171,17 @@ void MergeWithSuccessor(IRContext* context, Function* func,
|
||||
// flow declaration.
|
||||
context->KillInst(merge_inst);
|
||||
} else {
|
||||
// Move OpLine/OpNoLine information to merge_inst. This solves
|
||||
// the validation error that OpLine is placed between OpLoopMerge
|
||||
// and OpBranchConditional.
|
||||
auto terminator = bi->terminator();
|
||||
auto& vec = terminator->dbg_line_insts();
|
||||
auto& new_vec = merge_inst->dbg_line_insts();
|
||||
new_vec.insert(new_vec.end(), vec.begin(), vec.end());
|
||||
terminator->clear_dbg_line_insts();
|
||||
|
||||
// Move the merge instruction to just before the terminator.
|
||||
merge_inst->InsertBefore(bi->terminator());
|
||||
merge_inst->InsertBefore(terminator);
|
||||
}
|
||||
}
|
||||
context->ReplaceAllUsesWith(lab_id, bi->id());
|
||||
|
@ -172,6 +172,9 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
|
||||
return dbg_line_insts_;
|
||||
}
|
||||
|
||||
// Clear line-related debug instructions attached to this instruction.
|
||||
void clear_dbg_line_insts() { dbg_line_insts_.clear(); }
|
||||
|
||||
// Same semantics as in the base class except the list the InstructionList
|
||||
// containing |pos| will now assume ownership of |this|.
|
||||
// inline void MoveBefore(Instruction* pos);
|
||||
|
@ -423,6 +423,42 @@ OpFunctionEnd
|
||||
SinglePassRunAndMatch<BlockMergePass>(text, true);
|
||||
}
|
||||
|
||||
TEST_F(BlockMergeTest, MergeContinueWithOpLine) {
|
||||
const std::string text = R"(
|
||||
; CHECK: OpBranch [[header:%\w+]]
|
||||
; CHECK: [[header]] = OpLabel
|
||||
; CHECK-NEXT: OpLogicalAnd
|
||||
; CHECK-NEXT: OpLine {{%\w+}} 1 1
|
||||
; CHECK-NEXT: OpLoopMerge {{%\w+}} [[header]] None
|
||||
; CHECK-NEXT: OpBranch [[header]]
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %func "func"
|
||||
OpExecutionMode %func OriginUpperLeft
|
||||
%src = OpString "test.shader"
|
||||
%void = OpTypeVoid
|
||||
%bool = OpTypeBool
|
||||
%true = OpConstantTrue %bool
|
||||
%false = OpConstantFalse %bool
|
||||
%functy = OpTypeFunction %void
|
||||
%func = OpFunction %void None %functy
|
||||
%entry = OpLabel
|
||||
OpBranch %header
|
||||
%header = OpLabel
|
||||
OpLoopMerge %merge %continue None
|
||||
OpBranch %continue
|
||||
%continue = OpLabel
|
||||
%op = OpLogicalAnd %bool %true %false
|
||||
OpLine %src 1 1
|
||||
OpBranch %header
|
||||
%merge = OpLabel
|
||||
OpUnreachable
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
SinglePassRunAndMatch<BlockMergePass>(text, true);
|
||||
}
|
||||
|
||||
TEST_F(BlockMergeTest, TwoHeadersCannotBeMerged) {
|
||||
const std::string text = R"(
|
||||
; CHECK: OpBranch [[loop_header:%\w+]]
|
||||
|
Loading…
Reference in New Issue
Block a user