summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorJulius Ikkala <julius.ikkala@gmail.com>2025-06-25 20:15:08 +0300
committerGitHub <noreply@github.com>2025-06-25 17:15:08 +0000
commitee51fe592747fc66bd0b5757207583198068b5bd (patch)
tree4fb830633880fcad3cce473cd8dc094321f85477 /source
parentd48f050cb0209a4ba9819a094ffd1e7a7c2524ee (diff)
Fix Phi elimination pass sometimes leaving broken insts in release builds (#7499)
* Make phi elimination pass modify branches in-place * Add test and fix formatting * Avoid double removal of param insts
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-ir-eliminate-phis.cpp45
1 files changed, 16 insertions, 29 deletions
diff --git a/source/slang/slang-ir-eliminate-phis.cpp b/source/slang/slang-ir-eliminate-phis.cpp
index 1ea1673f4..a16446319 100644
--- a/source/slang/slang-ir-eliminate-phis.cpp
+++ b/source/slang/slang-ir-eliminate-phis.cpp
@@ -569,6 +569,10 @@ struct PhiEliminationContext
// to keep `param` around.
//
param->removeAndDeallocate();
+
+ // Avoid referencing `param` after it's been deallocated. There
+ // should be no uses left.
+ m_registerAllocation.mapInstToRegister.remove(param);
}
}
@@ -904,20 +908,21 @@ struct PhiEliminationContext
}
// Once we are sure all the assignment operations have been performed,
- // we can set about replacing the unconditional branch itself.
+ // we can set about removing the phi arguments from the unconditional
+ // branch itself.
//
- replaceBranch(branch);
+ updateBranch(branch);
}
- // Replacing the branch instruction at the end of a predecessor block
+ // Updating the branch instruction at the end of a predecessor block
// is relatively simple, and just a bit of busy-work.
//
- void replaceBranch(IRUnconditionalBranch* oldBranch)
+ void updateBranch(IRUnconditionalBranch* branch)
{
// When creating a replacement instruction here, we need to make sure
// that we keep all the operands that weren't phi arguments.
//
- Count oldOperandCount = oldBranch->getOperandCount();
+ Count oldOperandCount = branch->getOperandCount();
Count paramCount = getParamCount();
Count newOperandCount = oldOperandCount - paramCount;
@@ -934,32 +939,14 @@ struct PhiEliminationContext
static const Count kMaxNewOperandCount = 3;
SLANG_ASSERT(newOperandCount <= kMaxNewOperandCount);
- ShortList<IRInst*> newOperands;
- for (Index i = 0; i < newOperandCount; ++i)
- {
- newOperands.add(oldBranch->getOperand(i));
- }
-
- // Add operands for any remaining phi parameters that has not been eliminated.
- for (UInt i = 0; i < (UInt)phiInfos.getCount(); i++)
+ // Eliminate phi parameters
+ for (UInt i = 0, j = 0; i < (UInt)phiInfos.getCount(); i++)
{
- if (!phiInfos[i].param.temp)
- newOperands.add(oldBranch->getArg(i));
+ if (phiInfos[i].param.temp)
+ branch->removeOperand(newOperandCount + j);
+ else
+ ++j;
}
-
- auto newBranch = m_builder.emitIntrinsicInst(
- oldBranch->getFullType(),
- oldBranch->getOp(),
- newOperands.getCount(),
- newOperands.getArrayView().getBuffer());
- oldBranch->transferDecorationsTo(newBranch);
- newBranch->sourceLoc = oldBranch->sourceLoc;
-
- // TODO: We could consider just modifying `branch` in-place by clearing
- // the relevant operands for the phi arguments and setting its operand
- // count to a lower value.
- //
- oldBranch->removeAndDeallocate();
}
bool canLoadBeFoldedAtInst(IRInst* load, IRInst* useSite)