[llvm] 18ac017 - Revert "[ARM] Fix frame chains with M-profile PACBTI (#110285)"
Oliver Stannard via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 18 01:04:56 PDT 2024
Author: Oliver Stannard
Date: 2024-10-18T09:04:28+01:00
New Revision: 18ac0178ad7f839bdb3376b7a0c6b69a24520a06
URL: https://github.com/llvm/llvm-project/commit/18ac0178ad7f839bdb3376b7a0c6b69a24520a06
DIFF: https://github.com/llvm/llvm-project/commit/18ac0178ad7f839bdb3376b7a0c6b69a24520a06.diff
LOG: Revert "[ARM] Fix frame chains with M-profile PACBTI (#110285)"
Reverting because this is causing failures with MSan:
https://lab.llvm.org/buildbot/#/builders/169/builds/4378
This reverts commit e1f8f84acec05997893c305c78fbf7feecf44dd7.
Added:
Modified:
llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
llvm/lib/Target/ARM/ARMCallingConv.td
llvm/lib/Target/ARM/ARMFrameLowering.cpp
llvm/lib/Target/ARM/ARMSubtarget.cpp
llvm/lib/Target/ARM/ARMSubtarget.h
Removed:
llvm/test/CodeGen/Thumb2/pacbti-m-frame-chain.ll
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index aad305cce03961..3f28ce8ca4b559 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -116,12 +116,9 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
return CSR_iOS_SaveList;
if (PushPopSplit == ARMSubtarget::SplitR7)
- return STI.createAAPCSFrameChain() ? CSR_AAPCS_SplitPush_R7_SaveList
+ return STI.createAAPCSFrameChain() ? CSR_AAPCS_SplitPush_SaveList
: CSR_ATPCS_SplitPush_SaveList;
- if (PushPopSplit == ARMSubtarget::SplitR11AAPCSSignRA)
- return CSR_AAPCS_SplitPush_R11_SaveList;
-
return CSR_AAPCS_SaveList;
}
diff --git a/llvm/lib/Target/ARM/ARMCallingConv.td b/llvm/lib/Target/ARM/ARMCallingConv.td
index 27f175a7003366..d14424c2decac3 100644
--- a/llvm/lib/Target/ARM/ARMCallingConv.td
+++ b/llvm/lib/Target/ARM/ARMCallingConv.td
@@ -301,17 +301,14 @@ def CSR_ATPCS_SplitPush_SwiftError : CalleeSavedRegs<(sub CSR_ATPCS_SplitPush,
def CSR_ATPCS_SplitPush_SwiftTail : CalleeSavedRegs<(sub CSR_ATPCS_SplitPush,
R10)>;
-// Sometimes we need to split the push of the callee-saved GPRs into two
-// regions, to ensure that the frame chain record is set up correctly. These
-// list the callee-saved registers in the order they end up on the stack, which
-// depends on whether the frame pointer is r7 or r11.
-def CSR_AAPCS_SplitPush_R11 : CalleeSavedRegs<(add R10, R9, R8, R7, R6, R5, R4,
- LR, R11,
- (sequence "D%u", 15, 8))>;
-def CSR_AAPCS_SplitPush_R7 : CalleeSavedRegs<(add LR, R11,
- R7, R6, R5, R4,
- R10, R9, R8,
- (sequence "D%u", 15, 8))>;
+// When enforcing an AAPCS compliant frame chain, R11 is used as the frame
+// pointer even for Thumb targets, where split pushes are necessary.
+// This AAPCS alternative makes sure the frame index slots match the push
+// order in that case.
+def CSR_AAPCS_SplitPush : CalleeSavedRegs<(add LR, R11,
+ R7, R6, R5, R4,
+ R10, R9, R8,
+ (sequence "D%u", 15, 8))>;
// Constructors and destructors return 'this' in the ARM C++ ABI; since 'this'
// and the pointer return value are both passed in R0 in these cases, this can
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 82b6f808688eb0..e0703457aa8139 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -199,11 +199,6 @@ SpillArea getSpillArea(Register Reg,
// push {r0-r10, r12} GPRCS1
// vpush {r8-d15} DPRCS1
// push {r11, lr} GPRCS2
- //
- // SplitR11AAPCSSignRA:
- // push {r0-r10, r12} GPRSC1
- // push {r11, lr} GPRCS2
- // vpush {r8-d15} DPRCS1
// If FPCXTNS is spilled (for CMSE secure entryfunctions), it is always at
// the top of the stack frame.
@@ -251,8 +246,7 @@ SpillArea getSpillArea(Register Reg,
return SpillArea::GPRCS1;
case ARM::LR:
- if (Variation == ARMSubtarget::SplitR11WindowsSEH ||
- Variation == ARMSubtarget::SplitR11AAPCSSignRA)
+ if (Variation == ARMSubtarget::SplitR11WindowsSEH)
return SpillArea::GPRCS2;
else
return SpillArea::GPRCS1;
@@ -869,9 +863,6 @@ 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 (PushPopSplit == ARMSubtarget::SplitR11AAPCSSignRA)
- // Here, r11 can be stored below all of r4-r15.
- MaxRegBytes = 11 * 4;
if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
// Here, r11 can be stored below all of r4-r15 plus d8-d15.
MaxRegBytes = 11 * 4 + 8 * 8;
@@ -944,23 +935,17 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
}
// Determine spill area sizes, and some important frame indices.
- SpillArea FramePtrSpillArea;
- bool BeforeFPPush = true;
for (const CalleeSavedInfo &I : CSI) {
Register Reg = I.getReg();
int FI = I.getFrameIdx();
- SpillArea Area = getSpillArea(Reg, PushPopSplit,
- AFI->getNumAlignedDPRCS2Regs(), RegInfo);
-
- if (Reg == FramePtr) {
+ if (Reg == FramePtr)
FramePtrSpillFI = FI;
- FramePtrSpillArea = Area;
- }
if (Reg == ARM::D8)
D8SpillFI = FI;
- switch (Area) {
+ switch (getSpillArea(Reg, PushPopSplit, AFI->getNumAlignedDPRCS2Regs(),
+ RegInfo)) {
case SpillArea::FPCXT:
FPCXTSaveSize += 4;
break;
@@ -987,7 +972,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
// Move past FPCXT area.
if (FPCXTSaveSize > 0) {
LastPush = MBBI++;
- DefCFAOffsetCandidates.addInst(LastPush, FPCXTSaveSize, BeforeFPPush);
+ DefCFAOffsetCandidates.addInst(LastPush, FPCXTSaveSize, true);
}
// Allocate the vararg register save area.
@@ -995,15 +980,13 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -ArgRegsSaveSize,
MachineInstr::FrameSetup);
LastPush = std::prev(MBBI);
- DefCFAOffsetCandidates.addInst(LastPush, ArgRegsSaveSize, BeforeFPPush);
+ DefCFAOffsetCandidates.addInst(LastPush, ArgRegsSaveSize, true);
}
// Move past area 1.
if (GPRCS1Size > 0) {
GPRCS1Push = LastPush = MBBI++;
- DefCFAOffsetCandidates.addInst(LastPush, GPRCS1Size, BeforeFPPush);
- if (FramePtrSpillArea == SpillArea::GPRCS1)
- BeforeFPPush = false;
+ DefCFAOffsetCandidates.addInst(LastPush, GPRCS1Size, true);
}
// Determine starting offsets of spill areas. These offsets are all positive
@@ -1027,6 +1010,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
} else {
DPRCSOffset = GPRCS2Offset - DPRGapSize - DPRCSSize;
}
+ int FramePtrOffsetInPush = 0;
if (HasFP) {
// Offset from the CFA to the saved frame pointer, will be negative.
[[maybe_unused]] int FPOffset = MFI.getObjectOffset(FramePtrSpillFI);
@@ -1034,6 +1018,13 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
<< ", FPOffset: " << FPOffset << "\n");
assert(getMaxFPOffset(STI, *AFI, MF) <= FPOffset &&
"Max FP estimation is wrong");
+ // Offset from the top of the GPRCS1 area to the saved frame pointer, will
+ // be negative.
+ FramePtrOffsetInPush = FPOffset + ArgRegsSaveSize + FPCXTSaveSize;
+ LLVM_DEBUG(dbgs() << "FramePtrOffsetInPush=" << FramePtrOffsetInPush
+ << ", FramePtrSpillOffset="
+ << (MFI.getObjectOffset(FramePtrSpillFI) + NumBytes)
+ << "\n");
AFI->setFramePtrSpillOffset(MFI.getObjectOffset(FramePtrSpillFI) +
NumBytes);
}
@@ -1045,9 +1036,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
// after DPRCS1.
if (GPRCS2Size > 0 && PushPopSplit != ARMSubtarget::SplitR11WindowsSEH) {
GPRCS2Push = LastPush = MBBI++;
- DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size, BeforeFPPush);
- if (FramePtrSpillArea == SpillArea::GPRCS2)
- BeforeFPPush = false;
+ DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size);
}
// Prolog/epilog inserter assumes we correctly align DPRs on the stack, so our
@@ -1060,7 +1049,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
else {
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -DPRGapSize,
MachineInstr::FrameSetup);
- DefCFAOffsetCandidates.addInst(std::prev(MBBI), DPRGapSize, BeforeFPPush);
+ DefCFAOffsetCandidates.addInst(std::prev(MBBI), DPRGapSize);
}
}
@@ -1069,8 +1058,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
// Since vpush register list cannot have gaps, there may be multiple vpush
// instructions in the prologue.
while (MBBI != MBB.end() && MBBI->getOpcode() == ARM::VSTMDDB_UPD) {
- DefCFAOffsetCandidates.addInst(MBBI, sizeOfSPAdjustment(*MBBI),
- BeforeFPPush);
+ DefCFAOffsetCandidates.addInst(MBBI, sizeOfSPAdjustment(*MBBI));
LastPush = MBBI++;
}
}
@@ -1089,9 +1077,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
// Move GPRCS2, if using using SplitR11WindowsSEH.
if (GPRCS2Size > 0 && PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
GPRCS2Push = LastPush = MBBI++;
- DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size, BeforeFPPush);
- if (FramePtrSpillArea == SpillArea::GPRCS2)
- BeforeFPPush = false;
+ DefCFAOffsetCandidates.addInst(LastPush, GPRCS2Size);
}
bool NeedsWinCFIStackAlloc = NeedsWinCFI;
@@ -1192,51 +1178,28 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF,
// into spill area 1, including the FP in R11. In either case, it
// is in area one and the adjustment needs to take place just after
// that push.
+ // FIXME: The above is not necessary true when PACBTI is enabled.
+ // AAPCS requires use of R11, and PACBTI gets in the way of regular pushes,
+ // so FP ends up on area two.
MachineBasicBlock::iterator AfterPush;
if (HasFP) {
- MachineBasicBlock::iterator FPPushInst;
- // Offset from SP immediately after the push which saved the FP to the FP
- // save slot.
- int64_t FPOffsetAfterPush;
- switch (FramePtrSpillArea) {
- case SpillArea::GPRCS1:
- FPPushInst = GPRCS1Push;
- FPOffsetAfterPush = MFI.getObjectOffset(FramePtrSpillFI) +
- ArgRegsSaveSize + FPCXTSaveSize +
- sizeOfSPAdjustment(*FPPushInst);
- LLVM_DEBUG(dbgs() << "Frame pointer in GPRCS1, offset "
- << FPOffsetAfterPush << " after that push\n");
- break;
- case SpillArea::GPRCS2:
- FPPushInst = GPRCS2Push;
- FPOffsetAfterPush = MFI.getObjectOffset(FramePtrSpillFI) +
- ArgRegsSaveSize + FPCXTSaveSize + GPRCS1Size +
- sizeOfSPAdjustment(*FPPushInst);
- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH)
- FPOffsetAfterPush += DPRCSSize + DPRGapSize;
- LLVM_DEBUG(dbgs() << "Frame pointer in GPRCS2, offset "
- << FPOffsetAfterPush << " after that push\n");
- break;
- default:
- llvm_unreachable("frame pointer in unknown spill area");
- break;
+ AfterPush = std::next(GPRCS1Push);
+ unsigned PushSize = sizeOfSPAdjustment(*GPRCS1Push);
+ int FPOffset = PushSize + FramePtrOffsetInPush;
+ if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH) {
+ AfterPush = std::next(GPRCS2Push);
+ emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, AfterPush, dl, TII,
+ FramePtr, ARM::SP, 0, MachineInstr::FrameSetup);
+ } else {
+ emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, AfterPush, dl, TII,
+ FramePtr, ARM::SP, FPOffset,
+ MachineInstr::FrameSetup);
}
- AfterPush = std::next(FPPushInst);
- if (PushPopSplit == ARMSubtarget::SplitR11WindowsSEH)
- assert(FPOffsetAfterPush == 0);
-
- // Emit the MOV or ADD to set up the frame pointer register.
- emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, AfterPush, dl, TII,
- FramePtr, ARM::SP, FPOffsetAfterPush,
- MachineInstr::FrameSetup);
-
if (!NeedsWinCFI) {
- // Emit DWARF info to find the CFA using the frame pointer from this
- // point onward.
- if (FPOffsetAfterPush != 0) {
+ if (FramePtrOffsetInPush + PushSize != 0) {
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
nullptr, MRI->getDwarfRegNum(FramePtr, true),
- -MFI.getObjectOffset(FramePtrSpillFI)));
+ FPCXTSaveSize + ArgRegsSaveSize - FramePtrOffsetInPush));
BuildMI(MBB, AfterPush, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex)
.setMIFlags(MachineInstr::FrameSetup);
@@ -1749,8 +1712,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
if (Reg == ARM::LR && !isTailCall && !isVarArg && !isInterrupt &&
!isCmseEntry && !isTrap && AFI->getArgumentStackToRestore() == 0 &&
STI.hasV5TOps() && MBB.succ_empty() && !hasPAC &&
- (PushPopSplit != ARMSubtarget::SplitR11WindowsSEH &&
- PushPopSplit != ARMSubtarget::SplitR11AAPCSSignRA)) {
+ PushPopSplit != ARMSubtarget::SplitR11WindowsSEH) {
Reg = ARM::PC;
// Fold the return instruction into the LDM.
DeleteRet = true;
@@ -2983,29 +2945,18 @@ bool ARMFrameLowering::assignCalleeSavedSpillSlots(
const auto &AFI = *MF.getInfo<ARMFunctionInfo>();
if (AFI.shouldSignReturnAddress()) {
// The order of register must match the order we push them, because the
- // PEI assigns frame indices in that order. That order depends on the
- // PushPopSplitVariation, there are only two cases which we use with return
- // address signing:
- switch (STI.getPushPopSplitVariation(MF)) {
- case ARMSubtarget::SplitR7:
- // LR, R7, R6, R5, R4, <R12>, R11, R10, R9, R8, D15-D8
- CSI.insert(find_if(CSI,
- [=](const auto &CS) {
- Register Reg = CS.getReg();
- return Reg == ARM::R10 || Reg == ARM::R11 ||
- Reg == ARM::R8 || Reg == ARM::R9 ||
- ARM::DPRRegClass.contains(Reg);
- }),
- CalleeSavedInfo(ARM::R12));
- break;
- case ARMSubtarget::SplitR11AAPCSSignRA:
- // With SplitR11AAPCSSignRA, R12 will always be the highest-addressed CSR
- // on the stack.
- CSI.insert(CSI.begin(), CalleeSavedInfo(ARM::R12));
- break;
- default:
- llvm_unreachable("Unexpected CSR split with return address signing");
- }
+ // PEI assigns frame indices in that order. When compiling for return
+ // address sign and authenication, we use split push, therefore the orders
+ // we want are:
+ // LR, R7, R6, R5, R4, <R12>, R11, R10, R9, R8, D15-D8
+ CSI.insert(find_if(CSI,
+ [=](const auto &CS) {
+ Register Reg = CS.getReg();
+ return Reg == ARM::R10 || Reg == ARM::R11 ||
+ Reg == ARM::R8 || Reg == ARM::R9 ||
+ ARM::DPRRegClass.contains(Reg);
+ }),
+ CalleeSavedInfo(ARM::R12));
}
return false;
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp
index 9adfb1fab5f084..c4a782bc40910a 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.cpp
+++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp
@@ -514,12 +514,5 @@ ARMSubtarget::getPushPopSplitVariation(const MachineFunction &MF) const {
F.needsUnwindTableEntry() &&
(MFI.hasVarSizedObjects() || getRegisterInfo()->hasStackRealignment(MF)))
return SplitR11WindowsSEH;
-
- // 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<ARMFunctionInfo>()->shouldSignReturnAddress() &&
- getFramePointerReg() == ARM::R11)
- return SplitR11AAPCSSignRA;
return NoSplit;
}
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index 214c5f1b45e556..7917ddc17bdb81 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -105,18 +105,6 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
/// vpush {d8-d15}
/// push {r11, lr}
SplitR11WindowsSEH,
-
- /// When generating AAPCS-compilant frame chains, R11 is the frame pointer,
- /// and must be pushed adjacent to the return address (LR). Normally this
- /// isn't a problem, because the only register between them is r12, which is
- /// the intra-procedure-call scratch register, so doesn't need to be saved.
- /// However, when PACBTI is in use, r12 contains the authentication code, so
- /// does need to be saved. This means that we need a separate push for R11
- /// and LR.
- /// push {r0-r10, r12}
- /// push {r11, lr}
- /// vpush {d8-d15}
- SplitR11AAPCSSignRA,
};
protected:
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 8bcf87130c5400..00000000000000
--- a/llvm/test/CodeGen/Thumb2/pacbti-m-frame-chain.ll
+++ /dev/null
@@ -1,150 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc -mtriple=thumbv8.1m.main-none-eabi < %s --force-dwarf-frame-section -frame-pointer=all -mattr=+aapcs-frame-chain | FileCheck %s
-
-; int test1() {
-; return 0;
-; }
-define i32 @test1() "sign-return-address"="non-leaf" {
-; CHECK-LABEL: test1:
-; CHECK: .cfi_sections .debug_frame
-; CHECK-NEXT: .cfi_startproc
-; CHECK-NEXT: @ %bb.0: @ %entry
-; CHECK-NEXT: 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 ra_auth_code, -4
-; CHECK-NEXT: .save {r11, lr}
-; CHECK-NEXT: push.w {r11, lr}
-; CHECK-NEXT: .cfi_def_cfa_offset 12
-; CHECK-NEXT: .cfi_offset lr, -8
-; 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: 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
-entry:
- ret i32 0
-}
-
-; void foo(int n) {
-; int a[n];
-; bar(a);
-; }
-define dso_local void @test2(i32 noundef %n) "sign-return-address"="non-leaf" {
-; CHECK-LABEL: test2:
-; CHECK: .cfi_startproc
-; CHECK-NEXT: @ %bb.0: @ %entry
-; CHECK-NEXT: 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 ra_auth_code, -4
-; CHECK-NEXT: .cfi_offset r7, -8
-; CHECK-NEXT: .cfi_offset r4, -12
-; CHECK-NEXT: .save {r11, lr}
-; CHECK-NEXT: push.w {r11, lr}
-; CHECK-NEXT: .cfi_def_cfa_offset 20
-; CHECK-NEXT: .cfi_offset lr, -16
-; CHECK-NEXT: .cfi_offset r11, -20
-; 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: movs r1, #7
-; CHECK-NEXT: add.w r0, r1, r0, lsl #2
-; CHECK-NEXT: bic r0, r0, #7
-; CHECK-NEXT: sub.w r0, sp, r0
-; CHECK-NEXT: mov sp, r0
-; CHECK-NEXT: bl take_ptr
-; CHECK-NEXT: mov sp, r11
-; CHECK-NEXT: pop.w {r11, lr}
-; CHECK-NEXT: pop.w {r4, r7, r12}
-; CHECK-NEXT: aut r12, lr, sp
-; CHECK-NEXT: bx lr
-entry:
- %vla = alloca i32, i32 %n, align 4
- call void @take_ptr(ptr noundef nonnull %vla)
- ret void
-}
-
-; void test3(int c, float e, int z) {
-; if (c)
-; knr();
-; take_ptr(alloca(z));
-; if (e)
-; knr();
-; }
-define void @test3(i32 noundef %c, float noundef %e, i32 noundef %z) "sign-return-address"="non-leaf" {
-; CHECK-LABEL: test3:
-; CHECK: .cfi_startproc
-; CHECK-NEXT: @ %bb.0: @ %entry
-; CHECK-NEXT: pac r12, lr, sp
-; CHECK-NEXT: .save {r4, r5, r6, r7, ra_auth_code}
-; CHECK-NEXT: push.w {r4, r5, r6, r7, r12}
-; CHECK-NEXT: .cfi_def_cfa_offset 20
-; CHECK-NEXT: .cfi_offset ra_auth_code, -4
-; CHECK-NEXT: .cfi_offset r7, -8
-; CHECK-NEXT: .cfi_offset r6, -12
-; CHECK-NEXT: .cfi_offset r5, -16
-; CHECK-NEXT: .cfi_offset r4, -20
-; CHECK-NEXT: .save {r11, lr}
-; CHECK-NEXT: push.w {r11, lr}
-; CHECK-NEXT: .cfi_def_cfa_offset 28
-; CHECK-NEXT: .cfi_offset lr, -24
-; CHECK-NEXT: .cfi_offset r11, -28
-; 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: cmp r0, #0
-; CHECK-NEXT: mov r5, r2
-; CHECK-NEXT: mov r4, r1
-; CHECK-NEXT: it ne
-; CHECK-NEXT: blne knr
-; CHECK-NEXT: adds r0, r5, #7
-; CHECK-NEXT: bic r0, r0, #7
-; CHECK-NEXT: sub.w r0, sp, r0
-; CHECK-NEXT: mov sp, r0
-; CHECK-NEXT: bl take_ptr
-; CHECK-NEXT: mov r0, r4
-; CHECK-NEXT: movs r1, #0
-; CHECK-NEXT: bl __aeabi_fcmpeq
-; CHECK-NEXT: cmp r0, #0
-; CHECK-NEXT: it eq
-; CHECK-NEXT: bleq knr
-; CHECK-NEXT: mov sp, r11
-; CHECK-NEXT: pop.w {r11, lr}
-; CHECK-NEXT: pop.w {r4, r5, r6, r7, r12}
-; CHECK-NEXT: aut r12, lr, sp
-; CHECK-NEXT: bx lr
-entry:
- %tobool.not = icmp eq i32 %c, 0
- br i1 %tobool.not, label %if.end, label %if.then
-
-if.then: ; preds = %entry
- tail call void @knr()
- br label %if.end
-
-if.end: ; preds = %if.then, %entry
- %0 = alloca i8, i32 %z, align 8
- call void @take_ptr(ptr noundef nonnull %0)
- %tobool1 = fcmp une float %e, 0.000000e+00
- br i1 %tobool1, label %if.then2, label %if.end3
-
-if.then2: ; preds = %if.end
- call void @knr()
- br label %if.end3
-
-if.end3: ; preds = %if.then2, %if.end
- ret void
-}
-
-declare void @knr(...)
-declare void @take_ptr(ptr noundef)
More information about the llvm-commits
mailing list