[llvm] [ARM] R11 not pushed adjacent to link register with PAC-M and AAPCS frame chain fix (PR #82801)
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 29 14:32:48 PST 2024
================
@@ -494,11 +494,55 @@ bool ARMSubtarget::ignoreCSRForAllocationOrder(const MachineFunction &MF,
ARM::GPRRegClass.contains(PhysReg);
}
-bool ARMSubtarget::splitFramePointerPush(const MachineFunction &MF) const {
+ARMSubtarget::PushPopSplitVariation
+ARMSubtarget::getPushPopSplitVariation(const MachineFunction &MF) const {
const Function &F = MF.getFunction();
- if (!MF.getTarget().getMCAsmInfo()->usesWindowsCFI() ||
- !F.needsUnwindTableEntry())
- return false;
const MachineFrameInfo &MFI = MF.getFrameInfo();
- return MFI.hasVarSizedObjects() || getRegisterInfo()->hasStackRealignment(MF);
+ const std::vector<CalleeSavedInfo> 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<ARMFunctionInfo>()->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 (CSI.size() > 1 &&
----------------
efriedma-quic wrote:
Can we simplify this code? It seems sort of awkward to dig through the callee-saves here. And given the normal way this works, the only register that can show up between R11 and LR (R14), is R12.
https://github.com/llvm/llvm-project/pull/82801
More information about the llvm-commits
mailing list