Skip to content

Commit 2d64cdd

Browse files
committed
[Z80] Fix flag liveness tracking during frame index elimination
RegScavenger's isRegUsed() can become unreliable during backward scavenging in PEI::replaceFrameIndicesBackward because LiveUnits becomes stale after skipTo() repositions the scavenger without updating liveness for inserted instructions This caused incorrect code gen where flag clobbering add instructions were not wrapped with push and pop whjen flags were actually live Related: llvm#174251
1 parent 2f66fcc commit 2d64cdd

1 file changed

Lines changed: 27 additions & 1 deletion

File tree

llvm/lib/Target/Z80/Z80InstrInfo.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1195,7 +1195,33 @@ bool Z80InstrInfo::rewriteFrameIndex(MachineInstr &MI, unsigned FIOperandNum,
11951195
LLVM_DEBUG(dbgs() << "Z80FrameIndex: Offset " << NewOffset << " not legal for "
11961196
<< TRI.getName(BaseReg) << ", RS=" << (RS ? "yes" : "no") << "\n");
11971197

1198-
bool SaveFlags = RS && RS->isRegUsed(Z80::F);
1198+
// determine if we need to preserve flags (Z80::F) around flag clobbering
1199+
// instructions like ADD. the RegScavenger's isRegUsed() is unreliable during
1200+
// backward scavenging because its LiveUnits can become stale after skipTo()
1201+
// in pei::replaceFrameIndicesBackward. we work around this by forward scanning
1202+
// from the current instruction to find if flags are actually used.
1203+
// see: https://github.com/llvm/llvm-project/issues/174251
1204+
auto isFlagLiveForward = [&]() -> bool {
1205+
if (RS && RS->isRegUsed(Z80::F))
1206+
return true;
1207+
1208+
MachineBasicBlock::iterator ScanStart = II;
1209+
++ScanStart;
1210+
for (MachineBasicBlock::iterator I = ScanStart; I != MBB.end(); ++I) {
1211+
if (I->definesRegister(Z80::F, &TRI))
1212+
return false;
1213+
if (I->readsRegister(Z80::F, &TRI))
1214+
return true;
1215+
}
1216+
1217+
for (MachineBasicBlock *Succ : MBB.successors())
1218+
if (Succ->isLiveIn(Z80::F))
1219+
return true;
1220+
1221+
return false;
1222+
};
1223+
1224+
bool SaveFlags = RS && isFlagLiveForward();
11991225
const TargetRegisterClass *OffsetRC =
12001226
Is24Bit ? &Z80::O24RegClass : &Z80::O16RegClass;
12011227
LLVM_DEBUG({

0 commit comments

Comments
 (0)