Skip to content

Commit fcf0ce5

Browse files
committed
Avoid unsafe subs
1 parent c965294 commit fcf0ce5

File tree

4 files changed

+452
-25
lines changed

4 files changed

+452
-25
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,13 +2541,33 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
25412541
if (AFI->isStackRealigned() || MFI.hasVarSizedObjects()) {
25422542
if (int64_t SVECalleeSavedSize = AFI->getSVECalleeSavedStackSize()) {
25432543
// Set SP to start of SVE callee-save area from which they can
2544-
// be reloaded. The code below will deallocate the stack space
2545-
// space by moving FP -> SP.
2546-
emitFrameOffset(
2547-
MBB, RestoreBegin, DL, AArch64::SP, AArch64::FP,
2548-
StackOffset::get(-AFI->getCalleeSaveBaseToFrameRecordOffset(),
2549-
-SVECalleeSavedSize),
2550-
TII, MachineInstr::FrameDestroy);
2544+
// be reloaded.
2545+
const AArch64RegisterInfo *RegInfo = Subtarget.getRegisterInfo();
2546+
if (!AFI->isStackRealigned() && RegInfo->hasBasePointer(MF)) {
2547+
// If the stack is not realigned we can use the base pointer to find
2548+
// the start of the SVE callee-saves.
2549+
emitFrameOffset(
2550+
MBB, RestoreBegin, DL, AArch64::SP, RegInfo->getBaseRegister(),
2551+
StackOffset::getFixed(NumBytes), TII, MachineInstr::FrameDestroy);
2552+
} else {
2553+
Register CalleeSaveBase = AArch64::FP;
2554+
if (int64_t CalleeSaveBaseOffset =
2555+
AFI->getCalleeSaveBaseToFrameRecordOffset()) {
2556+
assert(RegInfo->hasBasePointer(MF) && "Expected base pointer!");
2557+
// NOTE: This base pointer is clobbered from this point on! The next
2558+
// step in eplilogue emission restoring callee-saves, so it should
2559+
// not be used after this point anyway.
2560+
CalleeSaveBase = RegInfo->getBaseRegister();
2561+
emitFrameOffset(MBB, RestoreBegin, DL, CalleeSaveBase, AArch64::FP,
2562+
StackOffset::getFixed(-CalleeSaveBaseOffset), TII,
2563+
MachineInstr::FrameDestroy);
2564+
}
2565+
// The code below will deallocate the stack space space by moving FP
2566+
// -> SP.
2567+
emitFrameOffset(MBB, RestoreBegin, DL, AArch64::SP, CalleeSaveBase,
2568+
StackOffset::getScalable(-SVECalleeSavedSize), TII,
2569+
MachineInstr::FrameDestroy);
2570+
}
25512571
}
25522572
} else {
25532573
if (AFI->getSVECalleeSavedStackSize()) {

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -635,31 +635,33 @@ bool AArch64RegisterInfo::hasBasePointer(const MachineFunction &MF) const {
635635
// Furthermore, if both variable sized objects are present, and the
636636
// stack needs to be dynamically re-aligned, the base pointer is the only
637637
// reliable way to reference the locals.
638-
if (MFI.hasVarSizedObjects() || MF.hasEHFunclets()) {
639-
if (hasStackRealignment(MF))
640-
return true;
641-
642-
auto &ST = MF.getSubtarget<AArch64Subtarget>();
643-
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
644-
if (ST.hasSVE() || ST.isStreaming()) {
645-
// Frames that have variable sized objects and scalable SVE objects,
646-
// should always use a basepointer.
647-
if (!AFI->hasCalculatedStackSizeSVE() || AFI->getStackSizeSVE())
648-
return true;
649-
}
650-
638+
bool CannotUseSPForSVERestore =
639+
MFI.hasVarSizedObjects() || hasStackRealignment(MF);
640+
if (CannotUseSPForSVERestore || MF.hasEHFunclets()) {
651641
// Frames with hazard padding can have a large offset between the frame
652642
// pointer and GPR locals, which includes the emergency spill slot. If the
653643
// emergency spill slot is not within range of the load/store instructions
654644
// (which have a signed 9-bit range), we will fail to compile if it is used.
655645
// Since hasBasePointer() is called before we know if we have hazard padding
656646
// or an emergency spill slot we need to enable the basepointer
657647
// conservatively.
648+
auto &ST = MF.getSubtarget<AArch64Subtarget>();
649+
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
658650
if (ST.getStreamingHazardSize() &&
659651
!AFI->getSMEFnAttrs().hasNonStreamingInterfaceAndBody()) {
660652
return true;
661653
}
662654

655+
if (hasStackRealignment(MF))
656+
return MFI.hasVarSizedObjects() || MF.hasEHFunclets();
657+
658+
if (ST.hasSVE() || ST.isStreaming()) {
659+
// Frames that have variable sized objects and scalable SVE objects,
660+
// should always use a basepointer.
661+
if (!AFI->hasCalculatedStackSizeSVE() || AFI->getStackSizeSVE())
662+
return true;
663+
}
664+
663665
// Conservatively estimate whether the negative offset from the frame
664666
// pointer will be sufficient to reach. If a function has a smallish
665667
// frame, it's less likely to have lots of spills and callee saved

0 commit comments

Comments
 (0)