Skip to content

Commit 58dcac3

Browse files
authored
[AArch64] Check X16&X17 in prologue if the fn has an SwiftAsyncContext. (llvm#73945)
StoreSwiftAsyncContext clobbers X16 & X17. Make sure they are available in canUseAsPrologue, to avoid shrink wrapping moving the pseudo to a place where X16 or X17 are live.
1 parent 13da9a5 commit 58dcac3

File tree

2 files changed

+478
-8
lines changed

2 files changed

+478
-8
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,16 @@ void AArch64FrameLowering::emitZeroCallUsedRegs(BitVector RegsToZero,
992992
}
993993
}
994994

995+
static void getLiveRegsForEntryMBB(LivePhysRegs &LiveRegs,
996+
const MachineBasicBlock &MBB) {
997+
const MachineFunction *MF = MBB.getParent();
998+
LiveRegs.addLiveIns(MBB);
999+
// Mark callee saved registers as used so we will not choose them.
1000+
const MCPhysReg *CSRegs = MF->getRegInfo().getCalleeSavedRegs();
1001+
for (unsigned i = 0; CSRegs[i]; ++i)
1002+
LiveRegs.addReg(CSRegs[i]);
1003+
}
1004+
9951005
// Find a scratch register that we can use at the start of the prologue to
9961006
// re-align the stack pointer. We avoid using callee-save registers since they
9971007
// may appear to be free when this is called from canUseAsPrologue (during
@@ -1013,12 +1023,7 @@ static unsigned findScratchNonCalleeSaveRegister(MachineBasicBlock *MBB) {
10131023
const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
10141024
const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
10151025
LivePhysRegs LiveRegs(TRI);
1016-
LiveRegs.addLiveIns(*MBB);
1017-
1018-
// Mark callee saved registers as used so we will not choose them.
1019-
const MCPhysReg *CSRegs = MF->getRegInfo().getCalleeSavedRegs();
1020-
for (unsigned i = 0; CSRegs[i]; ++i)
1021-
LiveRegs.addReg(CSRegs[i]);
1026+
getLiveRegsForEntryMBB(LiveRegs, *MBB);
10221027

10231028
// Prefer X9 since it was historically used for the prologue scratch reg.
10241029
const MachineRegisterInfo &MRI = MF->getRegInfo();
@@ -1039,6 +1044,19 @@ bool AArch64FrameLowering::canUseAsPrologue(
10391044
const AArch64Subtarget &Subtarget = MF->getSubtarget<AArch64Subtarget>();
10401045
const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
10411046
const AArch64TargetLowering *TLI = Subtarget.getTargetLowering();
1047+
const AArch64FunctionInfo *AFI = MF->getInfo<AArch64FunctionInfo>();
1048+
1049+
if (AFI->hasSwiftAsyncContext()) {
1050+
const AArch64RegisterInfo &TRI = *Subtarget.getRegisterInfo();
1051+
const MachineRegisterInfo &MRI = MF->getRegInfo();
1052+
LivePhysRegs LiveRegs(TRI);
1053+
getLiveRegsForEntryMBB(LiveRegs, MBB);
1054+
// The StoreSwiftAsyncContext clobbers X16 and X17. Make sure they are
1055+
// available.
1056+
if (!LiveRegs.available(MRI, AArch64::X16) ||
1057+
!LiveRegs.available(MRI, AArch64::X17))
1058+
return false;
1059+
}
10421060

10431061
// Don't need a scratch register if we're not going to re-align the stack or
10441062
// emit stack probes.

0 commit comments

Comments
 (0)