diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 4971281ec2388..9adf758b46c48 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -62,16 +62,14 @@ ARMBaseRegisterInfo::ARMBaseRegisterInfo() const MCPhysReg* ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { const ARMSubtarget &STI = MF->getSubtarget(); - bool UseSplitPush = (STI.getPushPopSplitVariation(*MF) == - ARMSubtarget::PushPopSplitVariation::R7Split); + bool UseSplitPush = STI.splitFramePushPop(*MF); const Function &F = MF->getFunction(); if (F.getCallingConv() == CallingConv::GHC) { // GHC set of callee saved regs is empty as all those regs are // used for passing STG regs around return CSR_NoRegs_SaveList; - } else if (STI.getPushPopSplitVariation(*MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { + } else if (STI.splitFramePointerPush(*MF)) { return CSR_Win_SplitFP_SaveList; } else if (F.getCallingConv() == CallingConv::CFGuard_Check) { return CSR_Win_AAPCS_CFGuard_Check_SaveList; diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index d251ad5543baf..9b54dd4e4e618 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -718,14 +718,9 @@ static int getMaxFPOffset(const ARMSubtarget &STI, const ARMFunctionInfo &AFI, // This is a conservative estimation: Assume the frame pointer being r7 and // pc("r15") up to r8 getting spilled before (= 8 registers). int MaxRegBytes = 8 * 4; - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitAAPCSBranchSigning) + if (STI.splitFramePointerPush(MF)) { // Here, r11 can be stored below all of r4-r15 (3 registers more than - // above). - MaxRegBytes = 11 * 4; - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { - // Here, r11 can be stored below all of r4-r15 plus d8-d15. + // above), plus d8-d15. MaxRegBytes = 11 * 4 + 8 * 8; } int FPCXTSaveSize = @@ -793,10 +788,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, } // Determine spill area sizes. - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitAAPCSBranchSigning || - STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { + if (STI.splitFramePointerPush(MF)) { for (const CalleeSavedInfo &I : CSI) { Register Reg = I.getReg(); int FI = I.getFrameIdx(); @@ -842,8 +834,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, case ARM::R10: case ARM::R11: case ARM::R12: - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R7Split) { + if (STI.splitFramePushPop(MF)) { GPRCS2Size += 4; break; } @@ -906,15 +897,13 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, unsigned GPRCS2Offset = GPRCS1Offset - GPRCS2Size; Align DPRAlign = DPRCSSize ? std::min(Align(8), Alignment) : Align(4); unsigned DPRGapSize = GPRCS1Size + FPCXTSaveSize + ArgRegsSaveSize; - if (STI.getPushPopSplitVariation(MF) != - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { + if (!STI.splitFramePointerPush(MF)) { DPRGapSize += GPRCS2Size; } DPRGapSize %= DPRAlign.value(); unsigned DPRCSOffset; - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { + if (STI.splitFramePointerPush(MF)) { DPRCSOffset = GPRCS1Offset - DPRGapSize - DPRCSSize; GPRCS2Offset = DPRCSOffset - GPRCS2Size; } else { @@ -933,10 +922,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); - // Move past area 2, unless following the CSR_Win_SplitFP calling convention. - if (GPRCS2Size > 0 && - STI.getPushPopSplitVariation(MF) != - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { + // Move past area 2. + if (GPRCS2Size > 0 && !STI.splitFramePointerPush(MF)) { GPRCS2Push = LastPush = MBBI++; DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size); } @@ -976,18 +963,13 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, } else NumBytes = DPRCSOffset; - // Move past area 2 if following the CSR_Win_SplitFP calling convention. - if (GPRCS2Size > 0 && - STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { + if (GPRCS2Size > 0 && STI.splitFramePointerPush(MF)) { GPRCS2Push = LastPush = MBBI++; DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size); } bool NeedsWinCFIStackAlloc = NeedsWinCFI; - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind && - HasFP) + if (STI.splitFramePointerPush(MF) && HasFP) NeedsWinCFIStackAlloc = false; if (STI.isTargetWindows() && WindowsRequiresStackProbe(MF, NumBytes)) { @@ -1092,10 +1074,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, AfterPush = std::next(GPRCS1Push); unsigned PushSize = sizeOfSPAdjustment(*GPRCS1Push); int FPOffset = PushSize + FramePtrOffsetInPush; - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitAAPCSBranchSigning || - STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { + if (STI.splitFramePointerPush(MF)) { AfterPush = std::next(GPRCS2Push); emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, AfterPush, dl, TII, FramePtr, ARM::SP, 0, MachineInstr::FrameSetup); @@ -1127,9 +1106,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, // instructions below don't need to be replayed to unwind the stack. if (NeedsWinCFI && MBBI != MBB.begin()) { MachineBasicBlock::iterator End = MBBI; - if (HasFP && - STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) + if (HasFP && STI.splitFramePointerPush(MF)) End = AfterPush; insertSEHRange(MBB, {}, End, TII, MachineInstr::FrameSetup); BuildMI(MBB, End, dl, TII.get(ARM::SEH_PrologEnd)) @@ -1141,103 +1118,51 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, // the necessary DWARF cf instructions to describe the situation. Start by // recording where each register ended up: if (GPRCS1Size > 0 && !NeedsWinCFI) { - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitAAPCSBranchSigning) { - MachineBasicBlock::iterator Pos = std::next(GPRCS1Push); - int CFIIndex; - for (const auto &Entry : CSI) { - Register Reg = Entry.getReg(); - int FI = Entry.getFrameIdx(); - switch (Reg) { - case ARM::R0: - case ARM::R1: - case ARM::R2: - case ARM::R3: - case ARM::R4: - case ARM::R5: - case ARM::R6: - case ARM::R7: - case ARM::R8: - case ARM::R9: - case ARM::R10: - case ARM::R12: - CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( - nullptr, MRI->getDwarfRegNum(Reg, true), - MFI.getObjectOffset(FI))); - BuildMI(MBB, Pos, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameSetup); - break; - } - } - } else { - MachineBasicBlock::iterator Pos = std::next(GPRCS1Push); - int CFIIndex; - for (const auto &Entry : CSI) { - Register Reg = Entry.getReg(); - int FI = Entry.getFrameIdx(); - switch (Reg) { - case ARM::R8: - case ARM::R9: - case ARM::R10: - case ARM::R11: - case ARM::R12: - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R7Split) - break; - [[fallthrough]]; - case ARM::R0: - case ARM::R1: - case ARM::R2: - case ARM::R3: - case ARM::R4: - case ARM::R5: - case ARM::R6: - case ARM::R7: - case ARM::LR: - CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( - nullptr, MRI->getDwarfRegNum(Reg, true), - MFI.getObjectOffset(FI))); - BuildMI(MBB, Pos, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameSetup); + MachineBasicBlock::iterator Pos = std::next(GPRCS1Push); + int CFIIndex; + for (const auto &Entry : CSI) { + Register Reg = Entry.getReg(); + int FI = Entry.getFrameIdx(); + switch (Reg) { + case ARM::R8: + case ARM::R9: + case ARM::R10: + case ARM::R11: + case ARM::R12: + if (STI.splitFramePushPop(MF)) break; - } + [[fallthrough]]; + case ARM::R0: + case ARM::R1: + case ARM::R2: + case ARM::R3: + case ARM::R4: + case ARM::R5: + case ARM::R6: + case ARM::R7: + case ARM::LR: + CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( + nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI))); + BuildMI(MBB, Pos, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) + .addCFIIndex(CFIIndex) + .setMIFlags(MachineInstr::FrameSetup); + break; } } } if (GPRCS2Size > 0 && !NeedsWinCFI) { MachineBasicBlock::iterator Pos = std::next(GPRCS2Push); - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitAAPCSBranchSigning) { - for (const auto &Entry : CSI) { - Register Reg = Entry.getReg(); - int FI = Entry.getFrameIdx(); - switch (Reg) { - case ARM::R11: - case ARM::LR: - unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true); - unsigned Offset = MFI.getObjectOffset(FI); - unsigned CFIIndex = MF.addFrameInst( - MCCFIInstruction::createOffset(nullptr, DwarfReg, Offset)); - BuildMI(MBB, Pos, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) - .addCFIIndex(CFIIndex) - .setMIFlags(MachineInstr::FrameSetup); - break; - } - } - } else { - MachineBasicBlock::iterator Pos = std::next(GPRCS2Push); - for (const auto &Entry : CSI) { - Register Reg = Entry.getReg(); - int FI = Entry.getFrameIdx(); - switch (Reg) { - case ARM::R8: - case ARM::R9: - case ARM::R10: - case ARM::R11: - case ARM::R12: + for (const auto &Entry : CSI) { + Register Reg = Entry.getReg(); + int FI = Entry.getFrameIdx(); + switch (Reg) { + case ARM::R8: + case ARM::R9: + case ARM::R10: + case ARM::R11: + case ARM::R12: + if (STI.splitFramePushPop(MF)) { unsigned DwarfReg = MRI->getDwarfRegNum( Reg == ARM::R12 ? ARM::RA_AUTH_CODE : Reg, true); unsigned Offset = MFI.getObjectOffset(FI); @@ -1246,8 +1171,8 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, BuildMI(MBB, Pos, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex) .setMIFlags(MachineInstr::FrameSetup); - break; } + break; } } } @@ -1457,9 +1382,7 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF, MachineInstr::FrameDestroy); // Increment past our save areas. - if (AFI->getGPRCalleeSavedArea2Size() && - STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) + if (AFI->getGPRCalleeSavedArea2Size() && STI.splitFramePointerPush(MF)) MBBI++; if (MBBI != MBB.end() && AFI->getDPRCalleeSavedAreaSize()) { @@ -1476,9 +1399,7 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF, MachineInstr::FrameDestroy); } - if (AFI->getGPRCalleeSavedArea2Size() && - STI.getPushPopSplitVariation(MF) != - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) + if (AFI->getGPRCalleeSavedArea2Size() && !STI.splitFramePointerPush(MF)) MBBI++; if (AFI->getGPRCalleeSavedArea1Size()) MBBI++; @@ -1618,9 +1539,7 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, unsigned LastReg = 0; for (; i != 0; --i) { Register Reg = CSI[i-1].getReg(); - if (!(Func)(Reg, STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R7Split)) - continue; + if (!(Func)(Reg, STI.splitFramePushPop(MF))) continue; // D-registers in the aligned area DPRCS2 are NOT spilled here. if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs) @@ -1713,9 +1632,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, for (; i != 0; --i) { CalleeSavedInfo &Info = CSI[i-1]; Register Reg = Info.getReg(); - if (!(Func)(Reg, STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R7Split)) - continue; + if (!(Func)(Reg, STI.splitFramePushPop(MF))) continue; // The aligned reloads from area DPRCS2 are not inserted here. if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs) @@ -1723,11 +1640,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt && !isCmseEntry && !isTrap && AFI->getArgumentStackToRestore() == 0 && STI.hasV5TOps() && MBB.succ_empty() && !hasPAC && - (STI.getPushPopSplitVariation(MF) != - ARMSubtarget::PushPopSplitVariation:: - R11SplitAAPCSBranchSigning && - STI.getPushPopSplitVariation(MF) != - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind)) { + !STI.splitFramePointerPush(MF)) { Reg = ARM::PC; // Fold the return instruction into the LDM. DeleteRet = true; @@ -2088,10 +2001,7 @@ bool ARMFrameLowering::spillCalleeSavedRegisters( .addImm(-4) .add(predOps(ARMCC::AL)); } - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitAAPCSBranchSigning || - STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { + if (STI.splitFramePointerPush(MF)) { emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isSplitFPArea1Register, 0, MachineInstr::FrameSetup); emitPushInst(MBB, MI, CSI, FltOpc, 0, true, &isARMArea3Register, @@ -2136,10 +2046,7 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters( unsigned LdrOpc = AFI->isThumbFunction() ? ARM::t2LDR_POST : ARM::LDR_POST_IMM; unsigned FltOpc = ARM::VLDMDIA_UPD; - if (STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitAAPCSBranchSigning || - STI.getPushPopSplitVariation(MF) == - ARMSubtarget::PushPopSplitVariation::R11SplitWindowsSEHUnwind) { + if (STI.splitFramePointerPush(MF)) { emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, &isSplitFPArea2Register, 0); emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, &isARMArea3Register, @@ -2455,8 +2362,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, if (Spilled) { NumGPRSpills++; - if (STI.getPushPopSplitVariation(MF) != - ARMSubtarget::PushPopSplitVariation::R7Split) { + if (!STI.splitFramePushPop(MF)) { if (Reg == ARM::LR) LRSpilled = true; CS1Spilled = true; @@ -2478,8 +2384,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, break; } } else { - if (STI.getPushPopSplitVariation(MF) != - ARMSubtarget::PushPopSplitVariation::R7Split) { + if (!STI.splitFramePushPop(MF)) { UnspilledCS1GPRs.push_back(Reg); continue; } diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp index b9e63ab3afc53..691715dc29637 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.cpp +++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp @@ -493,38 +493,11 @@ bool ARMSubtarget::ignoreCSRForAllocationOrder(const MachineFunction &MF, ARM::GPRRegClass.contains(PhysReg); } -ARMSubtarget::PushPopSplitVariation -ARMSubtarget::getPushPopSplitVariation(const MachineFunction &MF) const { +bool ARMSubtarget::splitFramePointerPush(const MachineFunction &MF) const { const Function &F = MF.getFunction(); + if (!MF.getTarget().getMCAsmInfo()->usesWindowsCFI() || + !F.needsUnwindTableEntry()) + return false; const MachineFrameInfo &MFI = MF.getFrameInfo(); - const std::vector CSI = - MF.getFrameInfo().getCalleeSavedInfo(); - // Returns R7Split if the frame setup must be split into two separate pushes - // of r0-r7,lr and another containing r8-r11 (+r12 if necessary). This is - // always required on Thumb1-only targets, as the push and pop instructions - // can't access the high registers. This is also required when R7 is the frame - // pointer and frame pointer elimiination is disabled, or branch signing is - // enabled and AAPCS is disabled. - if ((MF.getInfo()->shouldSignReturnAddress() && - !createAAPCSFrameChain()) || - (getFramePointerReg() == ARM::R7 && - MF.getTarget().Options.DisableFramePointerElim(MF)) || - isThumb1Only()) - return R7Split; - // Returns R11SplitWindowsSEHUnwind when the stack pointer needs to be - // restored from the frame pointer r11 + an offset and Windows CFI is enabled. - // This stack unwinding cannot be expressed with SEH unwind opcodes when done - // with a single push, making it necessary to split the push into r4-r10, and - // another containing r11+lr. - if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI() && - F.needsUnwindTableEntry() && - (MFI.hasVarSizedObjects() || getRegisterInfo()->hasStackRealignment(MF))) - return R11SplitWindowsSEHUnwind; - // Returns R11SplitAAPCSBranchSigning if R11 and lr are not adjacent to each - // other in the list of callee saved registers in a frame, and branch - // signing is enabled. - if (MF.getInfo()->shouldSignReturnAddress() && - getFramePointerReg() == ARM::R11) - return R11SplitAAPCSBranchSigning; - return NoSplit; + return MFI.hasVarSizedObjects() || getRegisterInfo()->hasStackRealignment(MF); } diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index 435a2d2c5f1eb..044b1c4c54e0c 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -150,26 +150,6 @@ class ARMSubtarget : public ARMGenSubtargetInfo { SingleIssuePlusExtras, }; - /// How the pushing and popping of callee saved registers to and from the - /// stack should be split. - enum PushPopSplitVariation { - /// r4-r11+lr (+r12 if necessary) can be pushed in a single instruction. - NoSplit, - /// The registers need to be split into a push of r4-r7+lr and another - /// containing r8-r11 (+r12 if necessary). Due to Thumb1FrameLowering - /// having separate handling of AAPCS being enabled, and therefore r11+lr - /// needing to be in a separate push, this value is also used as the push - /// variation in that case. - R7Split, - /// The registers need to be split into a push containing r4-r10+r12 and - /// another containing r11 + lr. - R11SplitAAPCSBranchSigning, - /// The registers need to be split into a push containing r4-r10 and another - /// containing r11 + lr. In this case, the floating point registers are - /// pushed between these two pushes. - R11SplitWindowsSEHUnwind - }; - protected: // Bool members corresponding to the SubtargetFeatures defined in tablegen #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \ @@ -467,8 +447,19 @@ class ARMSubtarget : public ARMGenSubtargetInfo { return ARM::R11; } - enum PushPopSplitVariation - getPushPopSplitVariation(const MachineFunction &MF) const; + /// Returns true if the frame setup is split into two separate pushes (first + /// r0-r7,lr then r8-r11), principally so that the frame pointer is adjacent + /// to lr. This is always required on Thumb1-only targets, as the push and + /// pop instructions can't access the high registers. + bool splitFramePushPop(const MachineFunction &MF) const { + if (MF.getInfo()->shouldSignReturnAddress()) + return true; + return (getFramePointerReg() == ARM::R7 && + MF.getTarget().Options.DisableFramePointerElim(MF)) || + isThumb1Only(); + } + + bool splitFramePointerPush(const MachineFunction &MF) const; bool useStride4VFPs() const; diff --git a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp index f1558e64ed3ee..0f4ece64bff53 100644 --- a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp +++ b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -222,8 +222,11 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF, case ARM::R8: case ARM::R9: case ARM::R10: - GPRCS2Size += 4; - break; + if (STI.splitFramePushPop(MF)) { + GPRCS2Size += 4; + break; + } + [[fallthrough]]; case ARM::LR: if (HasFrameRecordArea) { FRSize += 4; @@ -358,6 +361,14 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF, Register Reg = I.getReg(); int FI = I.getFrameIdx(); switch (Reg) { + case ARM::R8: + case ARM::R9: + case ARM::R10: + case ARM::R11: + case ARM::R12: + if (STI.splitFramePushPop(MF)) + break; + [[fallthrough]]; case ARM::R0: case ARM::R1: case ARM::R2: diff --git a/llvm/test/CodeGen/Thumb2/pacbti-m-frame-chain.ll b/llvm/test/CodeGen/Thumb2/pacbti-m-frame-chain.ll deleted file mode 100644 index 77759355e576a..0000000000000 --- a/llvm/test/CodeGen/Thumb2/pacbti-m-frame-chain.ll +++ /dev/null @@ -1,82 +0,0 @@ -; RUN: llc -filetype asm -o - %s --frame-pointer=all -mattr=+aapcs-frame-chain -mattr=+aapcs-frame-chain-leaf -force-dwarf-frame-section | FileCheck %s -target triple = "thumbv8m.main-none-none-eabi" - -; int f() { -; return 0; -; } -; -; int x(int, char *); -; int y(int n) { -; char a[n]; -; return 1 + x(n, a); -; } - -define hidden i32 @f() local_unnamed_addr { -entry: - ret i32 0; -} - -define hidden i32 @x(i32 noundef %n) local_unnamed_addr { -entry: - %vla = alloca i8, i32 %n, align 1 - %call = call i32 @y(i32 noundef %n, ptr noundef nonnull %vla) - %add = add nsw i32 %call, 1 - ret i32 %add -} - -declare dso_local i32 @y(i32 noundef, ptr noundef) local_unnamed_addr - -; CHECK-LABEL: f: -; CHECK: pac r12, lr, sp -; CHECK-NEXT: .save {ra_auth_code} -; CHECK-NEXT: str r12, [sp, #-4]! -; CHECK-NEXT: .cfi_def_cfa_offset 4 -; CHECK-NEXT: .cfi_offset r12, -8 -; CHECK-NEXT: .save {r11, lr} -; CHECK-NEXT: push.w {r11, lr} -; CHECK-NEXT: .cfi_offset lr, -4 -; CHECK-NEXT: .cfi_offset r11, -12 -; CHECK-NEXT: .setfp r11, sp -; CHECK-NEXT: mov r11, sp -; CHECK-NEXT: .cfi_def_cfa r11, 12 -; CHECK-NEXT: movs r0, #0 -; CHECK-NEXT: pop.w {r11, lr} -; CHECK-NEXT: ldr r12, [sp], #4 -; CHECK-NEXT: aut r12, lr, sp -; CHECK-NEXT: bx lr - -; CHECK-LABEL: x: -; CHECK: pac r12, lr, sp -; CHECK-NEXT: .save {r4, r7, ra_auth_code} -; CHECK-NEXT: push.w {r4, r7, r12} -; CHECK-NEXT: .cfi_def_cfa_offset 12 -; CHECK-NEXT: .cfi_offset r12, -8 -; CHECK-NEXT: .cfi_offset r7, -16 -; CHECK-NEXT: .cfi_offset r4, -20 -; CHECK-NEXT: .save {r11, lr} -; CHECK-NEXT: push.w {r11, lr} -; CHECK-NEXT: .cfi_offset lr, -4 -; CHECK-NEXT: .cfi_offset r11, -12 -; CHECK-NEXT: .setfp r11, sp -; CHECK-NEXT: mov r11, sp -; CHECK-NEXT: .cfi_def_cfa_register r11 -; CHECK-NEXT: .pad #4 -; CHECK-NEXT: sub sp, #4 -; CHECK-NEXT: adds r1, r0, #7 -; CHECK-NEXT: bic r1, r1, #7 -; CHECK-NEXT: sub.w r1, sp, r1 -; CHECK-NEXT: mov sp, r1 -; CHECK-NEXT: bl y -; CHECK-NEXT: sub.w r4, r11, #8 -; CHECK-NEXT: adds r0, #1 -; CHECK-NEXT: mov sp, r4 -; CHECK-NEXT: pop.w {r11, lr} -; CHECK-NEXT: pop.w {r4, r7, r12} -; CHECK-NEXT: aut r12, lr, sp -; CHECK-NEXT: bx lr - -!llvm.module.flags = !{!0, !1, !2} - -!0 = !{i32 8, !"sign-return-address", i32 1} -!1 = !{i32 8, !"sign-return-address-all", i32 0} -!2 = !{i32 8, !"branch-target-enforcement", i32 0}