Handle empty infinite loops in SPIR-V disassembler

This commit is contained in:
baldurk
2021-03-23 11:39:14 +00:00
parent 47ebc9f5c2
commit 261be0e597
@@ -799,27 +799,33 @@ rdcstr Reflector::Disassemble(const rdcstr &entryPoint,
{
OpBranch decodedbranch(it);
ConstIter nextit = it;
nextit++;
while(nextit.opcode() == Op::Line || nextit.opcode() == Op::NoLine)
nextit++;
// we can now ignore everything between us and the label of this branch, which is almost
// always going to be the very next label.
//
// The reasoning is this:
// - assume the next block is not the one we are jumping to
// - all blocks inside the loop must only ever branch backwards to the header block
// (that's this one) so the block can't be jumped to from within the loop
// - it's also illegal to jump into a structured control flow construct from outside, so
// it can't be jumped to from outside the loop
// - that means it is completely inaccessible from everywhere, so we can skip it
while(nextit.opcode() != Op::Label || OpLabel(nextit).result != decodedbranch.targetLabel)
// if the first branch after the loopmerge is to the continue target, this is an empty
// infinite loop. Don't try and detect the branch, just make an empty loop and exit.
if(decodedbranch.targetLabel != decoded.continueTarget)
{
ConstIter nextit = it;
nextit++;
it++;
instructionLines[it.offs()] = lineNum;
while(nextit.opcode() == Op::Line || nextit.opcode() == Op::NoLine)
nextit++;
// we can now ignore everything between us and the label of this branch, which is
// almost always going to be the very next label.
//
// The reasoning is this:
// - assume the next block is not the one we are jumping to
// - all blocks inside the loop must only ever branch backwards to the header block
// (that's this one) so the block can't be jumped to from within the loop
// - it's also illegal to jump into a structured control flow construct from outside,
// so it can't be jumped to from outside the loop
// - that means it is completely inaccessible from everywhere, so we can skip it
while(nextit.opcode() != Op::Label ||
OpLabel(nextit).result != decodedbranch.targetLabel)
{
nextit++;
it++;
instructionLines[it.offs()] = lineNum;
}
}
}
else