1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

Relanding r368987 [AArch64] Change location of frame-record within callee-save area.

Changes:
There was a condition for `!NeedsFrameRecord` missing in the assert. The
assert in question has changed to:

+    assert((!RPI.isPaired() || !NeedsFrameRecord || RPI.Reg2 != AArch64::FP ||
+            RPI.Reg1 == AArch64::LR) &&
+           "FrameRecord must be allocated together with LR");

This addresses PR43016.

llvm-svn: 369122
This commit is contained in:
Sander de Smalen 2019-08-16 15:42:28 +00:00
parent 6cab74d622
commit e877a2fb7c
32 changed files with 347 additions and 291 deletions

View File

@ -317,6 +317,12 @@ def CC_AArch64_GHC : CallingConv<[
CCIfType<[i64], CCAssignToReg<[X19, X20, X21, X22, X23, X24, X25, X26, X27, X28]>> CCIfType<[i64], CCAssignToReg<[X19, X20, X21, X22, X23, X24, X25, X26, X27, X28]>>
]>; ]>;
// The order of the callee-saves in this file is important, because the
// FrameLowering code will use this order to determine the layout the
// callee-save area in the stack frame. As can be observed below, Darwin
// requires the frame-record (LR, FP) to be at the top the callee-save area,
// whereas for other platforms they are at the bottom.
// FIXME: LR is only callee-saved in the sense that *we* preserve it and are // FIXME: LR is only callee-saved in the sense that *we* preserve it and are
// presumably a callee to someone. External functions may not do so, but this // presumably a callee to someone. External functions may not do so, but this
// is currently safe since BL has LR as an implicit-def and what happens after a // is currently safe since BL has LR as an implicit-def and what happens after a
@ -325,7 +331,13 @@ def CC_AArch64_GHC : CallingConv<[
// It would be better to model its preservation semantics properly (create a // It would be better to model its preservation semantics properly (create a
// vreg on entry, use it in RET & tail call generation; make that vreg def if we // vreg on entry, use it in RET & tail call generation; make that vreg def if we
// end up saving LR as part of a call frame). Watch this space... // end up saving LR as part of a call frame). Watch this space...
def CSR_AArch64_AAPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21, X22, def CSR_AArch64_AAPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24,
X25, X26, X27, X28, LR, FP,
D8, D9, D10, D11,
D12, D13, D14, D15)>;
// Darwin puts the frame-record at the top of the callee-save area.
def CSR_Darwin_AArch64_AAPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21, X22,
X23, X24, X25, X26, X27, X28, X23, X24, X25, X26, X27, X28,
D8, D9, D10, D11, D8, D9, D10, D11,
D12, D13, D14, D15)>; D12, D13, D14, D15)>;
@ -333,21 +345,21 @@ def CSR_AArch64_AAPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21, X22,
// Win64 has unwinding codes for an (FP,LR) pair, save_fplr and save_fplr_x. // Win64 has unwinding codes for an (FP,LR) pair, save_fplr and save_fplr_x.
// We put FP before LR, so that frame lowering logic generates (FP,LR) pairs, // We put FP before LR, so that frame lowering logic generates (FP,LR) pairs,
// and not (LR,FP) pairs. // and not (LR,FP) pairs.
def CSR_Win_AArch64_AAPCS : CalleeSavedRegs<(add FP, LR, X19, X20, X21, X22, def CSR_Win_AArch64_AAPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24,
X23, X24, X25, X26, X27, X28, X25, X26, X27, X28, FP, LR,
D8, D9, D10, D11, D8, D9, D10, D11,
D12, D13, D14, D15)>; D12, D13, D14, D15)>;
// AArch64 PCS for vector functions (VPCS) // AArch64 PCS for vector functions (VPCS)
// must (additionally) preserve full Q8-Q23 registers // must (additionally) preserve full Q8-Q23 registers
def CSR_AArch64_AAVPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21, X22, def CSR_AArch64_AAVPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24,
X23, X24, X25, X26, X27, X28, X25, X26, X27, X28, LR, FP,
(sequence "Q%u", 8, 23))>; (sequence "Q%u", 8, 23))>;
// Functions taking SVE arguments or returning an SVE type // Functions taking SVE arguments or returning an SVE type
// must (additionally) preserve full Z8-Z23 and predicate registers P4-P15 // must (additionally) preserve full Z8-Z23 and predicate registers P4-P15
def CSR_AArch64_SVE_AAPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21, X22, def CSR_AArch64_SVE_AAPCS : CalleeSavedRegs<(add X19, X20, X21, X22, X23, X24,
X23, X24, X25, X26, X27, X28, X25, X26, X27, X28, LR, FP,
(sequence "Z%u", 8, 23), (sequence "Z%u", 8, 23),
(sequence "P%u", 4, 15))>; (sequence "P%u", 4, 15))>;
@ -362,7 +374,7 @@ def CSR_AArch64_SVE_AAPCS : CalleeSavedRegs<(add LR, FP, X19, X20, X21, X22,
def CSR_AArch64_AAPCS_ThisReturn : CalleeSavedRegs<(add CSR_AArch64_AAPCS, X0)>; def CSR_AArch64_AAPCS_ThisReturn : CalleeSavedRegs<(add CSR_AArch64_AAPCS, X0)>;
def CSR_AArch64_AAPCS_SwiftError def CSR_AArch64_AAPCS_SwiftError
: CalleeSavedRegs<(sub CSR_AArch64_AAPCS, X21)>; : CalleeSavedRegs<(sub CSR_Darwin_AArch64_AAPCS, X21)>;
// The function used by Darwin to obtain the address of a thread-local variable // The function used by Darwin to obtain the address of a thread-local variable
// guarantees more than a normal AAPCS function. x16 and x17 are used on the // guarantees more than a normal AAPCS function. x16 and x17 are used on the
@ -378,7 +390,7 @@ def CSR_AArch64_TLS_Darwin
// fast path calls a function that follows CSR_AArch64_TLS_Darwin, // fast path calls a function that follows CSR_AArch64_TLS_Darwin,
// CSR_AArch64_CXX_TLS_Darwin should be a subset of CSR_AArch64_TLS_Darwin. // CSR_AArch64_CXX_TLS_Darwin should be a subset of CSR_AArch64_TLS_Darwin.
def CSR_AArch64_CXX_TLS_Darwin def CSR_AArch64_CXX_TLS_Darwin
: CalleeSavedRegs<(add CSR_AArch64_AAPCS, : CalleeSavedRegs<(add CSR_Darwin_AArch64_AAPCS,
(sub (sequence "X%u", 1, 28), X15, X16, X17, X18), (sub (sequence "X%u", 1, 28), X15, X16, X17, X18),
(sequence "D%u", 0, 31))>; (sequence "D%u", 0, 31))>;

View File

@ -44,11 +44,15 @@
// | | // | |
// |-----------------------------------| // |-----------------------------------|
// | | // | |
// | prev_fp, prev_lr | // | callee-saved gpr registers | <--.
// | | | On Darwin platforms these
// |- - - - - - - - - - - - - - - - - -| | callee saves are swapped,
// | | | (frame record first)
// | prev_fp, prev_lr | <--'
// | (a.k.a. "frame record") | // | (a.k.a. "frame record") |
// |-----------------------------------| <- fp(=x29) // |-----------------------------------| <- fp(=x29)
// | | // | |
// | other callee-saved registers | // | callee-saved fp/simd/SVE regs |
// | | // | |
// |-----------------------------------| // |-----------------------------------|
// |.empty.space.to.make.part.below....| // |.empty.space.to.make.part.below....|
@ -80,6 +84,20 @@
// * A frame pointer is definitely needed when there are local variables with // * A frame pointer is definitely needed when there are local variables with
// more-than-default alignment requirements. // more-than-default alignment requirements.
// //
// For Darwin platforms the frame-record (fp, lr) is stored at the top of the
// callee-saved area, since the unwind encoding does not allow for encoding
// this dynamically and existing tools depend on this layout. For other
// platforms, the frame-record is stored at the bottom of the (gpr) callee-saved
// area to allow SVE stack objects (allocated directly below the callee-saves,
// if available) to be accessed directly from the framepointer.
// The SVE spill/fill instructions have VL-scaled addressing modes such
// as:
// ldr z8, [fp, #-7 mul vl]
// For SVE the size of the vector length (VL) is not known at compile-time, so
// '#-7 mul vl' is an offset that can only be evaluated at runtime. With this
// layout, we don't need to add an unscaled offset to the framepointer before
// accessing the SVE object in the frame.
//
// In some cases when a base pointer is not strictly needed, it is generated // In some cases when a base pointer is not strictly needed, it is generated
// anyway when offsets from the frame pointer to access local variables become // anyway when offsets from the frame pointer to access local variables become
// so large that the offset can't be encoded in the immediate fields of loads // so large that the offset can't be encoded in the immediate fields of loads
@ -793,6 +811,10 @@ static bool needsWinCFI(const MachineFunction &MF) {
F.needsUnwindTableEntry(); F.needsUnwindTableEntry();
} }
static bool isTargetDarwin(const MachineFunction &MF) {
return MF.getSubtarget<AArch64Subtarget>().isTargetDarwin();
}
void AArch64FrameLowering::emitPrologue(MachineFunction &MF, void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const { MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = MBB.begin(); MachineBasicBlock::iterator MBBI = MBB.begin();
@ -952,9 +974,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
} }
if (HasFP) { if (HasFP) {
// Only set up FP if we actually need to. Frame pointer is fp = // Only set up FP if we actually need to.
// sp - fixedobject - 16. int FPOffset = isTargetDarwin(MF) ? (AFI->getCalleeSavedStackSize() - 16) : 0;
int FPOffset = AFI->getCalleeSavedStackSize() - 16;
if (CombineSPBump) if (CombineSPBump)
FPOffset += AFI->getLocalStackSize(); FPOffset += AFI->getLocalStackSize();
@ -1136,7 +1158,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
if (needsFrameMoves) { if (needsFrameMoves) {
const DataLayout &TD = MF.getDataLayout(); const DataLayout &TD = MF.getDataLayout();
const int StackGrowth = -TD.getPointerSize(0); const int StackGrowth = isTargetDarwin(MF)
? (2 * -TD.getPointerSize(0))
: -AFI->getCalleeSavedStackSize();
Register FramePtr = RegInfo->getFrameRegister(MF); Register FramePtr = RegInfo->getFrameRegister(MF);
// An example of the prologue: // An example of the prologue:
// //
@ -1208,7 +1232,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// Define the current CFA rule to use the provided FP. // Define the current CFA rule to use the provided FP.
unsigned Reg = RegInfo->getDwarfRegNum(FramePtr, true); unsigned Reg = RegInfo->getDwarfRegNum(FramePtr, true);
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa( unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(
nullptr, Reg, 2 * StackGrowth - FixedObject)); nullptr, Reg, StackGrowth - FixedObject));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex) .addCFIIndex(CFIIndex)
.setMIFlags(MachineInstr::FrameSetup); .setMIFlags(MachineInstr::FrameSetup);
@ -1462,11 +1486,13 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
// FIXME: Rather than doing the math here, we should instead just use // FIXME: Rather than doing the math here, we should instead just use
// non-post-indexed loads for the restores if we aren't actually going to // non-post-indexed loads for the restores if we aren't actually going to
// be able to save any instructions. // be able to save any instructions.
if (!IsFunclet && (MFI.hasVarSizedObjects() || AFI->isStackRealigned())) if (!IsFunclet && (MFI.hasVarSizedObjects() || AFI->isStackRealigned())) {
int64_t OffsetToFrameRecord =
isTargetDarwin(MF) ? (-(int64_t)AFI->getCalleeSavedStackSize() + 16) : 0;
emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::FP, emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
{-(int64_t)AFI->getCalleeSavedStackSize() + 16, MVT::i8}, {OffsetToFrameRecord, MVT::i8},
TII, MachineInstr::FrameDestroy, false, NeedsWinCFI); TII, MachineInstr::FrameDestroy, false, NeedsWinCFI);
else if (NumBytes) } else if (NumBytes)
emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP, emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
{NumBytes, MVT::i8}, TII, MachineInstr::FrameDestroy, false, {NumBytes, MVT::i8}, TII, MachineInstr::FrameDestroy, false,
NeedsWinCFI); NeedsWinCFI);
@ -1526,7 +1552,8 @@ static StackOffset getFPOffset(const MachineFunction &MF, int ObjectOffset) {
bool IsWin64 = bool IsWin64 =
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv()); Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
unsigned FixedObject = IsWin64 ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0; unsigned FixedObject = IsWin64 ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
return {ObjectOffset + FixedObject + 16, MVT::i8}; unsigned FPAdjust = isTargetDarwin(MF) ? 16 : AFI->getCalleeSavedStackSize();
return {ObjectOffset + FixedObject + FPAdjust, MVT::i8};
} }
static StackOffset getStackOffset(const MachineFunction &MF, int ObjectOffset) { static StackOffset getStackOffset(const MachineFunction &MF, int ObjectOffset) {
@ -1689,6 +1716,23 @@ static bool invalidateWindowsRegisterPairing(unsigned Reg1, unsigned Reg2,
return true; return true;
} }
/// Returns true if Reg1 and Reg2 cannot be paired using a ldp/stp instruction.
/// WindowsCFI requires that only consecutive registers can be paired.
/// LR and FP need to be allocated together when the frame needs to save
/// the frame-record. This means any other register pairing with LR is invalid.
static bool invalidateRegisterPairing(unsigned Reg1, unsigned Reg2,
bool NeedsWinCFI, bool NeedsFrameRecord) {
if (NeedsWinCFI)
return invalidateWindowsRegisterPairing(Reg1, Reg2, true);
// If we need to store the frame record, don't pair any register
// with LR other than FP.
if (NeedsFrameRecord)
return Reg2 == AArch64::LR;
return false;
}
namespace { namespace {
struct RegPairInfo { struct RegPairInfo {
@ -1708,7 +1752,7 @@ struct RegPairInfo {
static void computeCalleeSaveRegisterPairs( static void computeCalleeSaveRegisterPairs(
MachineFunction &MF, const std::vector<CalleeSavedInfo> &CSI, MachineFunction &MF, const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI, SmallVectorImpl<RegPairInfo> &RegPairs, const TargetRegisterInfo *TRI, SmallVectorImpl<RegPairInfo> &RegPairs,
bool &NeedShadowCallStackProlog) { bool &NeedShadowCallStackProlog, bool NeedsFrameRecord) {
if (CSI.empty()) if (CSI.empty())
return; return;
@ -1750,7 +1794,8 @@ static void computeCalleeSaveRegisterPairs(
switch (RPI.Type) { switch (RPI.Type) {
case RegPairInfo::GPR: case RegPairInfo::GPR:
if (AArch64::GPR64RegClass.contains(NextReg) && if (AArch64::GPR64RegClass.contains(NextReg) &&
!invalidateWindowsRegisterPairing(RPI.Reg1, NextReg, NeedsWinCFI)) !invalidateRegisterPairing(RPI.Reg1, NextReg, NeedsWinCFI,
NeedsFrameRecord))
RPI.Reg2 = NextReg; RPI.Reg2 = NextReg;
break; break;
case RegPairInfo::FPR64: case RegPairInfo::FPR64:
@ -1784,6 +1829,10 @@ static void computeCalleeSaveRegisterPairs(
(CSI[i].getFrameIdx() + 1 == CSI[i + 1].getFrameIdx())) && (CSI[i].getFrameIdx() + 1 == CSI[i + 1].getFrameIdx())) &&
"Out of order callee saved regs!"); "Out of order callee saved regs!");
assert((!RPI.isPaired() || !NeedsFrameRecord || RPI.Reg2 != AArch64::FP ||
RPI.Reg1 == AArch64::LR) &&
"FrameRecord must be allocated together with LR");
// MachO's compact unwind format relies on all registers being stored in // MachO's compact unwind format relies on all registers being stored in
// adjacent register pairs. // adjacent register pairs.
assert((!produceCompactUnwindFrame(MF) || assert((!produceCompactUnwindFrame(MF) ||
@ -1832,7 +1881,7 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters(
bool NeedShadowCallStackProlog = false; bool NeedShadowCallStackProlog = false;
computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs, computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs,
NeedShadowCallStackProlog); NeedShadowCallStackProlog, hasFP(MF));
const MachineRegisterInfo &MRI = MF.getRegInfo(); const MachineRegisterInfo &MRI = MF.getRegInfo();
if (NeedShadowCallStackProlog) { if (NeedShadowCallStackProlog) {
@ -1962,7 +2011,7 @@ bool AArch64FrameLowering::restoreCalleeSavedRegisters(
bool NeedShadowCallStackProlog = false; bool NeedShadowCallStackProlog = false;
computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs, computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs,
NeedShadowCallStackProlog); NeedShadowCallStackProlog, hasFP(MF));
auto EmitMI = [&](const RegPairInfo &RPI) { auto EmitMI = [&](const RegPairInfo &RPI) {
unsigned Reg1 = RPI.Reg1; unsigned Reg1 = RPI.Reg1;

View File

@ -64,8 +64,9 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
return CSR_AArch64_AAPCS_SwiftError_SaveList; return CSR_AArch64_AAPCS_SwiftError_SaveList;
if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost) if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
return CSR_AArch64_RT_MostRegs_SaveList; return CSR_AArch64_RT_MostRegs_SaveList;
else if (MF->getSubtarget<AArch64Subtarget>().isTargetDarwin())
return CSR_AArch64_AAPCS_SaveList; return CSR_Darwin_AArch64_AAPCS_SaveList;
return CSR_AArch64_AAPCS_SaveList;
} }
const MCPhysReg *AArch64RegisterInfo::getCalleeSavedRegsViaCopy( const MCPhysReg *AArch64RegisterInfo::getCalleeSavedRegsViaCopy(

View File

@ -99,18 +99,18 @@ entry:
; CHECK: .cfi_startproc ; CHECK: .cfi_startproc
; Check that used callee-saved registers are saved ; Check that used callee-saved registers are saved
; CHECK: sub sp, sp, #32 ; CHECK: sub sp, sp, #32
; CHECK: stp x19, x30, [sp, #16] ; CHECK: stp x30, x19, [sp, #16]
; Check correctness of cfi pseudo-instructions ; Check correctness of cfi pseudo-instructions
; CHECK: .cfi_def_cfa_offset 32 ; CHECK: .cfi_def_cfa_offset 32
; CHECK: .cfi_offset w30, -8 ; CHECK: .cfi_offset w19, -8
; CHECK: .cfi_offset w19, -16 ; CHECK: .cfi_offset w30, -16
; Check correct access to arguments passed on the stack, through stack pointer ; Check correct access to arguments passed on the stack, through stack pointer
; CHECK: ldr d[[DARG:[0-9]+]], [sp, #56] ; CHECK: ldr d[[DARG:[0-9]+]], [sp, #56]
; CHECK: ldr w[[IARG:[0-9]+]], [sp, #40] ; CHECK: ldr w[[IARG:[0-9]+]], [sp, #40]
; Check correct access to local variable on the stack, through stack pointer ; Check correct access to local variable on the stack, through stack pointer
; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12] ; CHECK: ldr w[[ILOC:[0-9]+]], [sp, #12]
; Check epilogue: ; Check epilogue:
; CHECK: ldp x19, x30, [sp, #16] ; CHECK: ldp x30, x19, [sp, #16]
; CHECK: ret ; CHECK: ret
; CHECK: .cfi_endproc ; CHECK: .cfi_endproc
@ -180,28 +180,28 @@ entry:
; CHECK-LABEL: novla_dynamicrealign_call ; CHECK-LABEL: novla_dynamicrealign_call
; CHECK: .cfi_startproc ; CHECK: .cfi_startproc
; Check that used callee-saved registers are saved ; Check that used callee-saved registers are saved
; CHECK: str x19, [sp, #-32]! ; CHECK: stp x29, x30, [sp, #-32]!
; Check that the frame pointer is created: ; Check that the frame pointer is created:
; CHECK: stp x29, x30, [sp, #16] ; CHECK: str x19, [sp, #16]
; CHECK: add x29, sp, #16 ; CHECK: mov x29, sp
; Check the dynamic realignment of the stack pointer to a 128-byte boundary ; Check the dynamic realignment of the stack pointer to a 128-byte boundary
; CHECK: sub x9, sp, #96 ; CHECK: sub x9, sp, #96
; CHECK: and sp, x9, #0xffffffffffffff80 ; CHECK: and sp, x9, #0xffffffffffffff80
; Check correctness of cfi pseudo-instructions ; Check correctness of cfi pseudo-instructions
; CHECK: .cfi_def_cfa w29, 16 ; CHECK: .cfi_def_cfa w29, 32
; CHECK: .cfi_offset w30, -8 ; CHECK: .cfi_offset w19, -16
; CHECK: .cfi_offset w29, -16 ; CHECK: .cfi_offset w30, -24
; CHECK: .cfi_offset w19, -32 ; CHECK: .cfi_offset w29, -32
; Check correct access to arguments passed on the stack, through frame pointer ; Check correct access to arguments passed on the stack, through frame pointer
; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56]
; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40]
; Check correct access to local variable on the stack, through re-aligned stack pointer ; Check correct access to local variable on the stack, through re-aligned stack pointer
; CHECK: ldr w[[ILOC:[0-9]+]], [sp] ; CHECK: ldr w[[ILOC:[0-9]+]], [sp]
; Check epilogue: ; Check epilogue:
; Check that stack pointer get restored from frame pointer. ; Check that stack pointer get restored from frame pointer.
; CHECK: sub sp, x29, #16 // =16 ; CHECK: mov sp, x29
; CHECK: ldp x29, x30, [sp, #16] ; CHECK: ldr x19, [sp, #16]
; CHECK: ldr x19, [sp], #32 ; CHECK: ldp x29, x30, [sp], #32
; CHECK: ret ; CHECK: ret
; CHECK: .cfi_endproc ; CHECK: .cfi_endproc
@ -284,22 +284,22 @@ entry:
; CHECK-LABEL: vla_nodynamicrealign_call ; CHECK-LABEL: vla_nodynamicrealign_call
; CHECK: .cfi_startproc ; CHECK: .cfi_startproc
; Check that used callee-saved registers are saved ; Check that used callee-saved registers are saved
; CHECK: stp x20, x19, [sp, #-32]! ; CHECK: stp x29, x30, [sp, #-32]!
; Check that the frame pointer is created: ; Check that the frame pointer is created:
; CHECK: stp x29, x30, [sp, #16] ; CHECK: stp x20, x19, [sp, #16]
; CHECK: add x29, sp, #16 ; CHECK: mov x29, sp
; Check that space is reserved on the stack for the local variable, ; Check that space is reserved on the stack for the local variable,
; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned. ; rounded up to a multiple of 16 to keep the stack pointer 16-byte aligned.
; CHECK: sub sp, sp, #16 ; CHECK: sub sp, sp, #16
; Check correctness of cfi pseudo-instructions ; Check correctness of cfi pseudo-instructions
; CHECK: .cfi_def_cfa w29, 16 ; CHECK: .cfi_def_cfa w29, 32
; CHECK: .cfi_offset w30, -8 ; CHECK: .cfi_offset w19, -8
; CHECK: .cfi_offset w29, -16 ; CHECK: .cfi_offset w20, -16
; CHECK: .cfi_offset w19, -24 ; CHECK: .cfi_offset w30, -24
; CHECK: .cfi_offset w20, -32 ; CHECK: .cfi_offset w29, -32
; Check correct access to arguments passed on the stack, through frame pointer ; Check correct access to arguments passed on the stack, through frame pointer
; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40]
; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56]
; Check correct reservation of 16-byte aligned VLA (size in w0) on stack ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
; CHECK: mov w9, w0 ; CHECK: mov w9, w0
; CHECK: mov x10, sp ; CHECK: mov x10, sp
@ -309,14 +309,14 @@ entry:
; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9 ; CHECK: sub x[[VLASPTMP:[0-9]+]], x10, x9
; CHECK: mov sp, x[[VLASPTMP]] ; CHECK: mov sp, x[[VLASPTMP]]
; Check correct access to local variable, through frame pointer ; Check correct access to local variable, through frame pointer
; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-20] ; CHECK: ldur w[[ILOC:[0-9]+]], [x29, #-4]
; Check correct accessing of the VLA variable through the base pointer ; Check correct accessing of the VLA variable through the base pointer
; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
; Check epilogue: ; Check epilogue:
; Check that stack pointer get restored from frame pointer. ; Check that stack pointer get restored from frame pointer.
; CHECK: sub sp, x29, #16 // =16 ; CHECK: mov sp, x29
; CHECK: ldp x29, x30, [sp, #16] ; CHECK: ldp x20, x19, [sp, #16]
; CHECK: ldp x20, x19, [sp], #32 ; CHECK: ldp x29, x30, [sp], #32
; CHECK: ret ; CHECK: ret
; CHECK: .cfi_endproc ; CHECK: .cfi_endproc
@ -385,11 +385,11 @@ entry:
; CHECK-LABEL: vla_dynamicrealign_call ; CHECK-LABEL: vla_dynamicrealign_call
; CHECK: .cfi_startproc ; CHECK: .cfi_startproc
; Check that used callee-saved registers are saved ; Check that used callee-saved registers are saved
; CHECK: str x21, [sp, #-48]! ; CHECK: stp x29, x30, [sp, #-48]!
; CHECK: stp x20, x19, [sp, #16] ; CHECK: str x21, [sp, #16]
; CHECK: stp x20, x19, [sp, #32]
; Check that the frame pointer is created: ; Check that the frame pointer is created:
; CHECK: stp x29, x30, [sp, #32] ; CHECK: mov x29, sp
; CHECK: add x29, sp, #32
; Check that the stack pointer gets re-aligned to 128 ; Check that the stack pointer gets re-aligned to 128
; bytes & the base pointer (x19) gets initialized to ; bytes & the base pointer (x19) gets initialized to
; this 128-byte aligned area for local variables & ; this 128-byte aligned area for local variables &
@ -398,15 +398,15 @@ entry:
; CHECK: and sp, x9, #0xffffffffffffff80 ; CHECK: and sp, x9, #0xffffffffffffff80
; CHECK: mov x19, sp ; CHECK: mov x19, sp
; Check correctness of cfi pseudo-instructions ; Check correctness of cfi pseudo-instructions
; CHECK: .cfi_def_cfa w29, 16 ; CHECK: .cfi_def_cfa w29, 48
; CHECK: .cfi_offset w30, -8 ; CHECK: .cfi_offset w19, -8
; CHECK: .cfi_offset w29, -16 ; CHECK: .cfi_offset w20, -16
; CHECK: .cfi_offset w19, -24 ; CHECK: .cfi_offset w21, -32
; CHECK: .cfi_offset w20, -32 ; CHECK: .cfi_offset w30, -40
; CHECK: .cfi_offset w21, -48 ; CHECK: .cfi_offset w29, -48
; Check correct access to arguments passed on the stack, through frame pointer ; Check correct access to arguments passed on the stack, through frame pointer
; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #56]
; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #72]
; Check correct reservation of 16-byte aligned VLA (size in w0) on stack ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
; and set-up of base pointer (x19). ; and set-up of base pointer (x19).
; CHECK: mov w9, w0 ; CHECK: mov w9, w0
@ -421,10 +421,10 @@ entry:
; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
; Check epilogue: ; Check epilogue:
; Check that stack pointer get restored from frame pointer. ; Check that stack pointer get restored from frame pointer.
; CHECK: sub sp, x29, #32 ; CHECK: mov sp, x29
; CHECK: ldp x29, x30, [sp, #32] ; CHECK: ldp x20, x19, [sp, #32]
; CHECK: ldp x20, x19, [sp, #16] ; CHECK: ldr x21, [sp, #16]
; CHECK: ldr x21, [sp], #48 ; CHECK: ldp x29, x30, [sp], #48
; CHECK: ret ; CHECK: ret
; CHECK: .cfi_endproc ; CHECK: .cfi_endproc
@ -493,10 +493,10 @@ entry:
; CHECK-LABEL: vla_dynamicrealign_nocall ; CHECK-LABEL: vla_dynamicrealign_nocall
; Check that used callee-saved registers are saved ; Check that used callee-saved registers are saved
; CHECK: str x19, [sp, #-32]! ; CHECK: stp x29, x30, [sp, #-32]!
; CHECK: str x19, [sp, #16]
; Check that the frame pointer is created: ; Check that the frame pointer is created:
; CHECK: stp x29, x30, [sp, #16] ; CHECK: mov x29, sp
; CHECK: add x29, sp, #16
; Check that the stack pointer gets re-aligned to 128 ; Check that the stack pointer gets re-aligned to 128
; bytes & the base pointer (x19) gets initialized to ; bytes & the base pointer (x19) gets initialized to
; this 128-byte aligned area for local variables & ; this 128-byte aligned area for local variables &
@ -505,8 +505,8 @@ entry:
; CHECK: and sp, x9, #0xffffffffffffff80 ; CHECK: and sp, x9, #0xffffffffffffff80
; CHECK: mov x19, sp ; CHECK: mov x19, sp
; Check correct access to arguments passed on the stack, through frame pointer ; Check correct access to arguments passed on the stack, through frame pointer
; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40]
; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56]
; Check correct reservation of 16-byte aligned VLA (size in w0) on stack ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
; and set-up of base pointer (x19). ; and set-up of base pointer (x19).
; CHECK: mov w9, w0 ; CHECK: mov w9, w0
@ -521,9 +521,9 @@ entry:
; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
; Check epilogue: ; Check epilogue:
; Check that stack pointer get restored from frame pointer. ; Check that stack pointer get restored from frame pointer.
; CHECK: sub sp, x29, #16 ; CHECK: mov sp, x29
; CHECK: ldp x29, x30, [sp, #16] ; CHECK: ldr x19, [sp, #16]
; CHECK: ldr x19, [sp], #32 ; CHECK: ldp x29, x30, [sp], #32
; CHECK: ret ; CHECK: ret
; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall: ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall:
@ -579,10 +579,10 @@ entry:
; CHECK-LABEL: vla_dynamicrealign_nocall_large_align ; CHECK-LABEL: vla_dynamicrealign_nocall_large_align
; Check that used callee-saved registers are saved ; Check that used callee-saved registers are saved
; CHECK: stp x28, x19, [sp, #-32]! ; CHECK: stp x29, x30, [sp, #-32]!
; CHECK: str x19, [sp, #16]
; Check that the frame pointer is created: ; Check that the frame pointer is created:
; CHECK: stp x29, x30, [sp, #16] ; CHECK: mov x29, sp
; CHECK: add x29, sp, #16
; Check that the stack pointer gets re-aligned to 128 ; Check that the stack pointer gets re-aligned to 128
; bytes & the base pointer (x19) gets initialized to ; bytes & the base pointer (x19) gets initialized to
; this 128-byte aligned area for local variables & ; this 128-byte aligned area for local variables &
@ -591,8 +591,8 @@ entry:
; CHECK: and sp, x9, #0xffffffffffff8000 ; CHECK: and sp, x9, #0xffffffffffff8000
; CHECK: mov x19, sp ; CHECK: mov x19, sp
; Check correct access to arguments passed on the stack, through frame pointer ; Check correct access to arguments passed on the stack, through frame pointer
; CHECK: ldr w[[IARG:[0-9]+]], [x29, #24] ; CHECK: ldr w[[IARG:[0-9]+]], [x29, #40]
; CHECK: ldr d[[DARG:[0-9]+]], [x29, #40] ; CHECK: ldr d[[DARG:[0-9]+]], [x29, #56]
; Check correct reservation of 16-byte aligned VLA (size in w0) on stack ; Check correct reservation of 16-byte aligned VLA (size in w0) on stack
; and set-up of base pointer (x19). ; and set-up of base pointer (x19).
; CHECK: mov w9, w0 ; CHECK: mov w9, w0
@ -607,9 +607,9 @@ entry:
; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]] ; CHECK: ldr w[[VLA:[0-9]+]], [x[[VLASPTMP]]]
; Check epilogue: ; Check epilogue:
; Check that stack pointer get restored from frame pointer. ; Check that stack pointer get restored from frame pointer.
; CHECK: sub sp, x29, #16 ; CHECK: mov sp, x29
; CHECK: ldp x29, x30, [sp, #16] ; CHECK: ldr x19, [sp, #16]
; CHECK: ldp x28, x19, [sp], #32 ; CHECK: ldp x29, x30, [sp], #32
; CHECK: ret ; CHECK: ret
; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align: ; CHECK-MACHO-LABEL: _vla_dynamicrealign_nocall_large_align:

View File

@ -176,12 +176,12 @@ body: |
; CHECK-NEXT: frame-setup STPQi killed $q13, killed $q12, $sp, 11 ; CHECK-NEXT: frame-setup STPQi killed $q13, killed $q12, $sp, 11
; CHECK-NEXT: frame-setup STPQi killed $q11, killed $q10, $sp, 13 ; CHECK-NEXT: frame-setup STPQi killed $q11, killed $q10, $sp, 13
; CHECK-NEXT: frame-setup STPQi killed $q9, killed $q8, $sp, 15 ; CHECK-NEXT: frame-setup STPQi killed $q9, killed $q8, $sp, 15
; CHECK-NEXT: frame-setup STPXi killed $x28, killed $x27, $sp, 34 :: (store 8 into %stack.{{[0-9]+}}), (store 8 into %stack.{{[0-9]+}}) ; CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 34 :: (store 8 into %stack.{{[0-9]+}}), (store 8 into %stack.{{[0-9]+}})
; CHECK-NEXT: frame-setup STPXi killed $x26, killed $x25, $sp, 36 ; CHECK-NEXT: frame-setup STPXi killed $x28, killed $x27, $sp, 36
; CHECK-NEXT: frame-setup STPXi killed $x24, killed $x23, $sp, 38 ; CHECK-NEXT: frame-setup STPXi killed $x26, killed $x25, $sp, 38
; CHECK-NEXT: frame-setup STPXi killed $x22, killed $x21, $sp, 40 ; CHECK-NEXT: frame-setup STPXi killed $x24, killed $x23, $sp, 40
; CHECK-NEXT: frame-setup STPXi killed $x20, killed $x19, $sp, 42 ; CHECK-NEXT: frame-setup STPXi killed $x22, killed $x21, $sp, 42
; CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 44 ; CHECK-NEXT: frame-setup STPXi killed $x20, killed $x19, $sp, 44
... ...
--- ---
@ -242,12 +242,12 @@ body: |
; CHECK-NEXT: frame-setup STPQi killed $q13, killed $q12, $sp, 10 ; CHECK-NEXT: frame-setup STPQi killed $q13, killed $q12, $sp, 10
; CHECK-NEXT: frame-setup STPQi killed $q11, killed $q10, $sp, 12 ; CHECK-NEXT: frame-setup STPQi killed $q11, killed $q10, $sp, 12
; CHECK-NEXT: frame-setup STPQi killed $q9, killed $q8, $sp, 14 ; CHECK-NEXT: frame-setup STPQi killed $q9, killed $q8, $sp, 14
; CHECK-NEXT: frame-setup STPXi killed $x28, killed $x27, $sp, 32 :: (store 8 into %stack.{{[0-9]+}}), (store 8 into %stack.{{[0-9]+}}) ; CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 32 :: (store 8 into %stack.{{[0-9]+}}), (store 8 into %stack.{{[0-9]+}})
; CHECK-NEXT: frame-setup STPXi killed $x26, killed $x25, $sp, 34 ; CHECK-NEXT: frame-setup STPXi killed $x28, killed $x27, $sp, 34
; CHECK-NEXT: frame-setup STPXi killed $x24, killed $x23, $sp, 36 ; CHECK-NEXT: frame-setup STPXi killed $x26, killed $x25, $sp, 36
; CHECK-NEXT: frame-setup STPXi killed $x22, killed $x21, $sp, 38 ; CHECK-NEXT: frame-setup STPXi killed $x24, killed $x23, $sp, 38
; CHECK-NEXT: frame-setup STPXi killed $x20, killed $x19, $sp, 40 ; CHECK-NEXT: frame-setup STPXi killed $x22, killed $x21, $sp, 40
; CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 42 ; CHECK-NEXT: frame-setup STPXi killed $x20, killed $x19, $sp, 42
; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 176, 0 ; CHECK-NEXT: $sp = frame-setup SUBXri $sp, 176, 0
... ...

View File

@ -19,15 +19,15 @@ define i32 @add_const_add_const(i32 %arg) {
define i32 @add_const_add_const_extrause(i32 %arg) { define i32 @add_const_add_const_extrause(i32 %arg) {
; CHECK-LABEL: add_const_add_const_extrause: ; CHECK-LABEL: add_const_add_const_extrause:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: stp x19, x30, [sp, #-16]! // 16-byte Folded Spill ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w19, -8
; CHECK-NEXT: .cfi_offset w19, -16 ; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: mov w19, w0 ; CHECK-NEXT: mov w19, w0
; CHECK-NEXT: add w0, w0, #8 // =8 ; CHECK-NEXT: add w0, w0, #8 // =8
; CHECK-NEXT: bl use ; CHECK-NEXT: bl use
; CHECK-NEXT: add w0, w19, #10 // =10 ; CHECK-NEXT: add w0, w19, #10 // =10
; CHECK-NEXT: ldp x19, x30, [sp], #16 // 16-byte Folded Reload ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%t0 = add i32 %arg, 8 %t0 = add i32 %arg, 8
call void @use(i32 %t0) call void @use(i32 %t0)
@ -96,15 +96,15 @@ define i32 @add_const_sub_const(i32 %arg) {
define i32 @add_const_sub_const_extrause(i32 %arg) { define i32 @add_const_sub_const_extrause(i32 %arg) {
; CHECK-LABEL: add_const_sub_const_extrause: ; CHECK-LABEL: add_const_sub_const_extrause:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: stp x19, x30, [sp, #-16]! // 16-byte Folded Spill ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w19, -8
; CHECK-NEXT: .cfi_offset w19, -16 ; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: mov w19, w0 ; CHECK-NEXT: mov w19, w0
; CHECK-NEXT: add w0, w0, #8 // =8 ; CHECK-NEXT: add w0, w0, #8 // =8
; CHECK-NEXT: bl use ; CHECK-NEXT: bl use
; CHECK-NEXT: add w0, w19, #6 // =6 ; CHECK-NEXT: add w0, w19, #6 // =6
; CHECK-NEXT: ldp x19, x30, [sp], #16 // 16-byte Folded Reload ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%t0 = add i32 %arg, 8 %t0 = add i32 %arg, 8
call void @use(i32 %t0) call void @use(i32 %t0)
@ -174,16 +174,16 @@ define i32 @add_const_const_sub(i32 %arg) {
define i32 @add_const_const_sub_extrause(i32 %arg) { define i32 @add_const_const_sub_extrause(i32 %arg) {
; CHECK-LABEL: add_const_const_sub_extrause: ; CHECK-LABEL: add_const_const_sub_extrause:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: stp x19, x30, [sp, #-16]! // 16-byte Folded Spill ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w19, -8
; CHECK-NEXT: .cfi_offset w19, -16 ; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: mov w19, w0 ; CHECK-NEXT: mov w19, w0
; CHECK-NEXT: add w0, w0, #8 // =8 ; CHECK-NEXT: add w0, w0, #8 // =8
; CHECK-NEXT: bl use ; CHECK-NEXT: bl use
; CHECK-NEXT: mov w8, #-6 ; CHECK-NEXT: mov w8, #-6
; CHECK-NEXT: sub w0, w8, w19 ; CHECK-NEXT: sub w0, w8, w19
; CHECK-NEXT: ldp x19, x30, [sp], #16 // 16-byte Folded Reload ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%t0 = add i32 %arg, 8 %t0 = add i32 %arg, 8
call void @use(i32 %t0) call void @use(i32 %t0)
@ -252,15 +252,15 @@ define i32 @sub_const_add_const(i32 %arg) {
define i32 @sub_const_add_const_extrause(i32 %arg) { define i32 @sub_const_add_const_extrause(i32 %arg) {
; CHECK-LABEL: sub_const_add_const_extrause: ; CHECK-LABEL: sub_const_add_const_extrause:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: stp x19, x30, [sp, #-16]! // 16-byte Folded Spill ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w19, -8
; CHECK-NEXT: .cfi_offset w19, -16 ; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: mov w19, w0 ; CHECK-NEXT: mov w19, w0
; CHECK-NEXT: sub w0, w0, #8 // =8 ; CHECK-NEXT: sub w0, w0, #8 // =8
; CHECK-NEXT: bl use ; CHECK-NEXT: bl use
; CHECK-NEXT: sub w0, w19, #6 // =6 ; CHECK-NEXT: sub w0, w19, #6 // =6
; CHECK-NEXT: ldp x19, x30, [sp], #16 // 16-byte Folded Reload ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%t0 = sub i32 %arg, 8 %t0 = sub i32 %arg, 8
call void @use(i32 %t0) call void @use(i32 %t0)
@ -329,15 +329,15 @@ define i32 @sub_const_sub_const(i32 %arg) {
define i32 @sub_const_sub_const_extrause(i32 %arg) { define i32 @sub_const_sub_const_extrause(i32 %arg) {
; CHECK-LABEL: sub_const_sub_const_extrause: ; CHECK-LABEL: sub_const_sub_const_extrause:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: stp x19, x30, [sp, #-16]! // 16-byte Folded Spill ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w19, -8
; CHECK-NEXT: .cfi_offset w19, -16 ; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: mov w19, w0 ; CHECK-NEXT: mov w19, w0
; CHECK-NEXT: sub w0, w0, #8 // =8 ; CHECK-NEXT: sub w0, w0, #8 // =8
; CHECK-NEXT: bl use ; CHECK-NEXT: bl use
; CHECK-NEXT: sub w0, w19, #10 // =10 ; CHECK-NEXT: sub w0, w19, #10 // =10
; CHECK-NEXT: ldp x19, x30, [sp], #16 // 16-byte Folded Reload ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%t0 = sub i32 %arg, 8 %t0 = sub i32 %arg, 8
call void @use(i32 %t0) call void @use(i32 %t0)
@ -407,16 +407,16 @@ define i32 @sub_const_const_sub(i32 %arg) {
define i32 @sub_const_const_sub_extrause(i32 %arg) { define i32 @sub_const_const_sub_extrause(i32 %arg) {
; CHECK-LABEL: sub_const_const_sub_extrause: ; CHECK-LABEL: sub_const_const_sub_extrause:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: stp x19, x30, [sp, #-16]! // 16-byte Folded Spill ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w19, -8
; CHECK-NEXT: .cfi_offset w19, -16 ; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: mov w19, w0 ; CHECK-NEXT: mov w19, w0
; CHECK-NEXT: sub w0, w0, #8 // =8 ; CHECK-NEXT: sub w0, w0, #8 // =8
; CHECK-NEXT: bl use ; CHECK-NEXT: bl use
; CHECK-NEXT: mov w8, #10 ; CHECK-NEXT: mov w8, #10
; CHECK-NEXT: sub w0, w8, w19 ; CHECK-NEXT: sub w0, w8, w19
; CHECK-NEXT: ldp x19, x30, [sp], #16 // 16-byte Folded Reload ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%t0 = sub i32 %arg, 8 %t0 = sub i32 %arg, 8
call void @use(i32 %t0) call void @use(i32 %t0)
@ -486,17 +486,17 @@ define i32 @const_sub_add_const(i32 %arg) {
define i32 @const_sub_add_const_extrause(i32 %arg) { define i32 @const_sub_add_const_extrause(i32 %arg) {
; CHECK-LABEL: const_sub_add_const_extrause: ; CHECK-LABEL: const_sub_add_const_extrause:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: stp x19, x30, [sp, #-16]! // 16-byte Folded Spill ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w19, -8
; CHECK-NEXT: .cfi_offset w19, -16 ; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: mov w8, #8 ; CHECK-NEXT: mov w8, #8
; CHECK-NEXT: mov w19, w0 ; CHECK-NEXT: mov w19, w0
; CHECK-NEXT: sub w0, w8, w0 ; CHECK-NEXT: sub w0, w8, w0
; CHECK-NEXT: bl use ; CHECK-NEXT: bl use
; CHECK-NEXT: mov w8, #10 ; CHECK-NEXT: mov w8, #10
; CHECK-NEXT: sub w0, w8, w19 ; CHECK-NEXT: sub w0, w8, w19
; CHECK-NEXT: ldp x19, x30, [sp], #16 // 16-byte Folded Reload ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%t0 = sub i32 8, %arg %t0 = sub i32 8, %arg
call void @use(i32 %t0) call void @use(i32 %t0)
@ -566,17 +566,17 @@ define i32 @const_sub_sub_const(i32 %arg) {
define i32 @const_sub_sub_const_extrause(i32 %arg) { define i32 @const_sub_sub_const_extrause(i32 %arg) {
; CHECK-LABEL: const_sub_sub_const_extrause: ; CHECK-LABEL: const_sub_sub_const_extrause:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: stp x19, x30, [sp, #-16]! // 16-byte Folded Spill ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w19, -8
; CHECK-NEXT: .cfi_offset w19, -16 ; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: mov w8, #8 ; CHECK-NEXT: mov w8, #8
; CHECK-NEXT: mov w19, w0 ; CHECK-NEXT: mov w19, w0
; CHECK-NEXT: sub w0, w8, w0 ; CHECK-NEXT: sub w0, w8, w0
; CHECK-NEXT: bl use ; CHECK-NEXT: bl use
; CHECK-NEXT: mov w8, #6 ; CHECK-NEXT: mov w8, #6
; CHECK-NEXT: sub w0, w8, w19 ; CHECK-NEXT: sub w0, w8, w19
; CHECK-NEXT: ldp x19, x30, [sp], #16 // 16-byte Folded Reload ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%t0 = sub i32 8, %arg %t0 = sub i32 8, %arg
call void @use(i32 %t0) call void @use(i32 %t0)
@ -645,17 +645,17 @@ define i32 @const_sub_const_sub(i32 %arg) {
define i32 @const_sub_const_sub_extrause(i32 %arg) { define i32 @const_sub_const_sub_extrause(i32 %arg) {
; CHECK-LABEL: const_sub_const_sub_extrause: ; CHECK-LABEL: const_sub_const_sub_extrause:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: stp x19, x30, [sp, #-16]! // 16-byte Folded Spill ; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill
; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: .cfi_offset w30, -8 ; CHECK-NEXT: .cfi_offset w19, -8
; CHECK-NEXT: .cfi_offset w19, -16 ; CHECK-NEXT: .cfi_offset w30, -16
; CHECK-NEXT: mov w8, #8 ; CHECK-NEXT: mov w8, #8
; CHECK-NEXT: sub w19, w8, w0 ; CHECK-NEXT: sub w19, w8, w0
; CHECK-NEXT: mov w0, w19 ; CHECK-NEXT: mov w0, w19
; CHECK-NEXT: bl use ; CHECK-NEXT: bl use
; CHECK-NEXT: mov w8, #2 ; CHECK-NEXT: mov w8, #2
; CHECK-NEXT: sub w0, w8, w19 ; CHECK-NEXT: sub w0, w8, w19
; CHECK-NEXT: ldp x19, x30, [sp], #16 // 16-byte Folded Reload ; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%t0 = sub i32 8, %arg %t0 = sub i32 8, %arg
call void @use(i32 %t0) call void @use(i32 %t0)

View File

@ -117,9 +117,9 @@ define void @test_alloca_large_frame(i64 %n) {
; CHECK-MACHO-LABEL: test_alloca_large_frame: ; CHECK-MACHO-LABEL: test_alloca_large_frame:
; CHECK: stp x28, x19, [sp, #-32]! ; CHECK: stp x29, x30, [sp, #-32]!
; CHECK: stp x29, x30, [sp, #16] ; CHECK: stp x28, x19, [sp, #16]
; CHECK: add x29, sp, #16 ; CHECK: mov x29, sp
; CHECK: sub sp, sp, #1953, lsl #12 ; CHECK: sub sp, sp, #1953, lsl #12
; CHECK: sub sp, sp, #512 ; CHECK: sub sp, sp, #512
@ -136,9 +136,9 @@ define void @test_alloca_large_frame(i64 %n) {
ret void ret void
; CHECK: sub sp, x29, #16 ; CHECK: mov sp, x29
; CHECK: ldp x29, x30, [sp, #16] ; CHECK: ldp x28, x19, [sp, #16]
; CHECK: ldp x28, x19, [sp], #32 ; CHECK: ldp x29, x30, [sp], #32
; CHECK-MACHO: sub sp, x29, #16 ; CHECK-MACHO: sub sp, x29, #16
; CHECK-MACHO: ldp x29, x30, [sp, #16] ; CHECK-MACHO: ldp x29, x30, [sp, #16]
@ -152,6 +152,7 @@ define void @test_scoped_alloca(i64 %n) {
; CHECK-LABEL: test_scoped_alloca: ; CHECK-LABEL: test_scoped_alloca:
%sp = call i8* @llvm.stacksave() %sp = call i8* @llvm.stacksave()
; CHECK: mov x29, sp
; CHECK: mov [[SAVED_SP:x[0-9]+]], sp ; CHECK: mov [[SAVED_SP:x[0-9]+]], sp
; CHECK: mov [[OLDSP:x[0-9]+]], sp ; CHECK: mov [[OLDSP:x[0-9]+]], sp

View File

@ -1,8 +1,8 @@
; RUN: llc -mtriple=arm64-eabi -mcpu=cyclone < %s | FileCheck %s ; RUN: llc -mtriple=arm64-eabi -mcpu=cyclone < %s | FileCheck %s
; CHECK: foo ; CHECK: foo
; CHECK-DAG: stur w[[REG0:[0-9]+]], [x29, #-24] ; CHECK-DAG: str w[[REG0:[0-9]+]], [x29, #24]
; CHECK-DAG: stur w[[REG0]], [x29, #-20] ; CHECK-DAG: str w[[REG0]], [x29, #28]
define i32 @foo(i32 %a) nounwind { define i32 @foo(i32 %a) nounwind {
%retval = alloca i32, align 4 %retval = alloca i32, align 4
%a.addr = alloca i32, align 4 %a.addr = alloca i32, align 4

View File

@ -151,10 +151,10 @@ end:
define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, i64* %p, i1 %cond) nounwind { define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, i64* %p, i1 %cond) nounwind {
; CHECK-LABEL: usubo_ult_cmp_dominates_i64: ; CHECK-LABEL: usubo_ult_cmp_dominates_i64:
; CHECK: // %bb.0: // %entry ; CHECK: // %bb.0: // %entry
; CHECK-NEXT: str x22, [sp, #-48]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-48]! // 8-byte Folded Spill
; CHECK-NEXT: stp x21, x20, [sp, #16] // 16-byte Folded Spill ; CHECK-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill
; CHECK-NEXT: mov w20, w3 ; CHECK-NEXT: mov w20, w3
; CHECK-NEXT: stp x19, x30, [sp, #32] // 16-byte Folded Spill ; CHECK-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: tbz w3, #0, .LBB8_3 ; CHECK-NEXT: tbz w3, #0, .LBB8_3
; CHECK-NEXT: // %bb.1: // %t ; CHECK-NEXT: // %bb.1: // %t
; CHECK-NEXT: cmp x0, x1 ; CHECK-NEXT: cmp x0, x1
@ -172,9 +172,9 @@ define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, i64* %p, i1 %cond) nounwi
; CHECK-NEXT: .LBB8_3: // %f ; CHECK-NEXT: .LBB8_3: // %f
; CHECK-NEXT: and w0, w20, #0x1 ; CHECK-NEXT: and w0, w20, #0x1
; CHECK-NEXT: .LBB8_4: // %f ; CHECK-NEXT: .LBB8_4: // %f
; CHECK-NEXT: ldp x19, x30, [sp, #32] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
; CHECK-NEXT: ldp x21, x20, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x22, [sp], #48 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #48 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
entry: entry:
br i1 %cond, label %t, label %f br i1 %cond, label %t, label %f

View File

@ -13,6 +13,7 @@
; CHECK-ERRORS: LLVM ERROR: FastISel missed call ; CHECK-ERRORS: LLVM ERROR: FastISel missed call
; CHECK-LABEL: foo: ; CHECK-LABEL: foo:
; CHECK: sub
; CHECK-DAG: mov x[[SP:[0-9]+]], sp ; CHECK-DAG: mov x[[SP:[0-9]+]], sp
; CHECK-DAG: mov [[TMP:w[0-9]+]], #4104 ; CHECK-DAG: mov [[TMP:w[0-9]+]], #4104
; CHECK: mov w[[OFFSET:[0-9]+]], [[TMP]] ; CHECK: mov w[[OFFSET:[0-9]+]], [[TMP]]

View File

@ -35,7 +35,7 @@ entry:
define void @realign() { define void @realign() {
entry: entry:
; CHECK-LABEL: realign: ; CHECK-LABEL: realign:
; CHECK: add x29, sp, #16 ; CHECK: mov x29, sp
; CHECK: and sp, x{{[0-9]*}}, #0xffffffffffffffc0 ; CHECK: and sp, x{{[0-9]*}}, #0xffffffffffffffc0
; CHECK: irg [[R:x[0-9]+]], sp{{$}} ; CHECK: irg [[R:x[0-9]+]], sp{{$}}
; CHECK: addg x0, [[R]], #0, #1 ; CHECK: addg x0, [[R]], #0, #1

View File

@ -5,7 +5,7 @@ declare void @bar()
define void @test_w29_reserved() { define void @test_w29_reserved() {
; CHECK-LABEL: test_w29_reserved: ; CHECK-LABEL: test_w29_reserved:
; CHECK: add x29, sp, #{{[0-9]+}} ; CHECK: mov x29, sp
%val1 = load volatile i32, i32* @var %val1 = load volatile i32, i32* @var
%val2 = load volatile i32, i32* @var %val2 = load volatile i32, i32* @var

View File

@ -97,10 +97,10 @@ body: |
B %bb.1 B %bb.1
bb.1: bb.1:
; CHECK: $x20, $lr = frame-destroy LDPXi $sp, 2 ; CHECK: $x21, $x20 = frame-destroy LDPXi $sp, 2
; BEFORELDSTOPT-NEXT: $x21 = frame-destroy LDRXui $sp, 0 ; BEFORELDSTOPT-NEXT: $lr = frame-destroy LDRXui $sp, 0
; BEFORELDSTOPT-NEXT: $sp = frame-destroy ADDXri $sp, 32, 0 ; BEFORELDSTOPT-NEXT: $sp = frame-destroy ADDXri $sp, 32, 0
; AFTERLDSTOPT-NEXT: early-clobber $sp, $x21 = frame-destroy LDRXpost $sp, 32 ; AFTERLDSTOPT-NEXT: early-clobber $sp, $lr = frame-destroy LDRXpost $sp, 32
RET_ReallyLR RET_ReallyLR
... ...

View File

@ -86,7 +86,7 @@ entry:
define void @stack_realign() #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) { define void @stack_realign() #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
entry: entry:
; CHECK-LABEL: stack_realign ; CHECK-LABEL: stack_realign
; CHECK: add x29, sp, #16 ; CHECK: mov x29, sp
; CHECK: sub x9, sp, #64 ; CHECK: sub x9, sp, #64
; CHECK: and sp, x9, #0xffffffffffffffe0 ; CHECK: and sp, x9, #0xffffffffffffffe0
; CHECK: mov x19, sp ; CHECK: mov x19, sp
@ -205,15 +205,15 @@ entry:
define void @vla_and_realign(i32 %n) #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) { define void @vla_and_realign(i32 %n) #0 personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
entry: entry:
; CHECK-LABEL: vla_and_realign ; CHECK-LABEL: vla_and_realign
; CHECK: add x29, sp, #16 ; CHECK: mov x29, sp
; CHECK: sub x9, sp, #64 ; CHECK: sub x9, sp, #64
; CHECK: and sp, x9, #0xffffffffffffffe0 ; CHECK: and sp, x9, #0xffffffffffffffe0
; CHECK: mov x19, sp ; CHECK: mov x19, sp
; CHECK: mov x1, #-2 ; CHECK: mov x1, #-2
; CHECK: stur x1, [x19] ; CHECK: stur x1, [x19]
; CHECK: .set .Lvla_and_realign$frame_escape_0, 32 ; CHECK: .set .Lvla_and_realign$frame_escape_0, 32
; CHECK: stur w0, [x29, #-4] ; CHECK: str w0, [x29, #28]
; CHECK: ldur w8, [x29, #-4] ; CHECK: ldr w8, [x29, #28]
; CHECK: mov x9, sp ; CHECK: mov x9, sp
; CHECK: str x9, [x19, #24] ; CHECK: str x9, [x19, #24]
; CHECK: str x8, [x19, #16] ; CHECK: str x8, [x19, #16]

View File

@ -41,7 +41,7 @@ define i32 @f4() shadowcallstack {
%res12 = add i32 %res1, %res2 %res12 = add i32 %res1, %res2
%res34 = add i32 %res3, %res4 %res34 = add i32 %res3, %res4
%res1234 = add i32 %res12, %res34 %res1234 = add i32 %res12, %res34
; CHECK: ldp {{.*}}x30, [sp ; CHECK: ldp x30,{{.*}}, [sp
; CHECK: ldr x30, [x18, #-8]! ; CHECK: ldr x30, [x18, #-8]!
; CHECK: ret ; CHECK: ret
ret i32 %res1234 ret i32 %res1234

View File

@ -4,7 +4,7 @@
; CHECK-NOT: stp ; CHECK-NOT: stp
; CHECK-NOT: mov w{{[0-9]+}}, w0 ; CHECK-NOT: mov w{{[0-9]+}}, w0
; CHECK-LABEL: %bb.1: ; CHECK-LABEL: %bb.1:
; CHECK: stp x19 ; CHECK: stp {{.*}}x19
; CHECK: mov w{{[0-9]+}}, w0 ; CHECK: mov w{{[0-9]+}}, w0
define i32 @shrinkwrapme(i32 %paramAcrossCall, i32 %paramNotAcrossCall) { define i32 @shrinkwrapme(i32 %paramAcrossCall, i32 %paramNotAcrossCall) {

View File

@ -13,7 +13,7 @@ frameInfo:
# CHECK: id: 0, name: '', type: default, offset: -64, size: 4, alignment: 64 # CHECK: id: 0, name: '', type: default, offset: -64, size: 4, alignment: 64
# CHECK-NEXT: stack-id: default # CHECK-NEXT: stack-id: default
# CHECK-NEXT: local-offset: -64 # CHECK-NEXT: local-offset: -64
# CHECK: id: 1, name: '', type: default, offset: -20, size: 4, alignment: 4 # CHECK: id: 1, name: '', type: default, offset: -4, size: 4, alignment: 4
# CHECK-NEXT: stack-id: default # CHECK-NEXT: stack-id: default
# CHECK-NEXT: local-offset: -68 # CHECK-NEXT: local-offset: -68
stack: stack:
@ -23,7 +23,7 @@ stack:
# CHECK: body: # CHECK: body:
# CHECK: $sp = ANDXri killed ${{x[0-9]+}}, 7865 # CHECK: $sp = ANDXri killed ${{x[0-9]+}}, 7865
# CHECK: STRSui $s0, $sp, 0 # CHECK: STRSui $s0, $sp, 0
# CHECK: STURSi $s0, $fp, -4 # CHECK: STRSui $s0, $fp, 7
body: | body: |
bb.0.entry: bb.0.entry:
liveins: $s0 liveins: $s0

View File

@ -38,8 +38,8 @@ define dso_local void @foo([24 x i64]*) {
; CHECK: foo: ; CHECK: foo:
; CHECK: sub sp, sp, #448 ; CHECK: sub sp, sp, #448
; CHECK: add x29, sp, #432 ; CHECK: add x29, sp, #416
; CHECK: add x1, x29, #16 ; CHECK: add x1, x29, #32
; CHECK: bl _setjmpex ; CHECK: bl _setjmpex
; NOFP: sub sp, sp, #432 ; NOFP: sub sp, sp, #432

View File

@ -5,4 +5,4 @@
; CHECK-LABEL: fn: ; CHECK-LABEL: fn:
; CHECK: adrp x8, __stack_chk_guard ; CHECK: adrp x8, __stack_chk_guard
; CHECK-NEXT: ldr x8, [x8, :lo12:__stack_chk_guard] ; CHECK-NEXT: ldr x8, [x8, :lo12:__stack_chk_guard]
; CHECK-NEXT: stur x8, [x29, #-24] ; CHECK-NEXT: stur x8, [x29, #-8]

View File

@ -9,7 +9,7 @@
; CHECK: ldr [[GUARD:x[0-9]+]]{{.*}}:lo12:__stack_chk_guard] ; CHECK: ldr [[GUARD:x[0-9]+]]{{.*}}:lo12:__stack_chk_guard]
; Make sure the canary is placed relative to the frame pointer, not ; Make sure the canary is placed relative to the frame pointer, not
; the stack pointer. ; the stack pointer.
; CHECK: stur [[GUARD]], [x29, #-24] ; CHECK: stur [[GUARD]], [x29, #-8]
define void @test(i8* %i, ...) #0 { define void @test(i8* %i, ...) #0 {
entry: entry:
%buf = alloca [10 x i8], align 1 %buf = alloca [10 x i8], align 1

View File

@ -202,16 +202,16 @@ declare void @use32(i32) nounwind
define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind { define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
; CHECK-LABEL: in_multiuse_A_constmask: ; CHECK-LABEL: in_multiuse_A_constmask:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w8, w0, w1 ; CHECK-NEXT: eor w8, w0, w1
; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: and w20, w8, #0xffff00 ; CHECK-NEXT: and w20, w8, #0xffff00
; CHECK-NEXT: mov w0, w20 ; CHECK-NEXT: mov w0, w20
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, 16776960 %n1 = and i32 %n0, 16776960
@ -223,15 +223,15 @@ define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind { define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
; CHECK-LABEL: in_multiuse_B_constmask: ; CHECK-LABEL: in_multiuse_B_constmask:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w0, w0, w1 ; CHECK-NEXT: eor w0, w0, w1
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: and w20, w0, #0xffff00 ; CHECK-NEXT: and w20, w0, #0xffff00
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, 16776960 %n1 = and i32 %n0, 16776960

View File

@ -208,16 +208,16 @@ declare void @use32(i32) nounwind
define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind { define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
; CHECK-LABEL: in_multiuse_A_constmask: ; CHECK-LABEL: in_multiuse_A_constmask:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w8, w0, w1 ; CHECK-NEXT: eor w8, w0, w1
; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: and w20, w8, #0x55555555 ; CHECK-NEXT: and w20, w8, #0x55555555
; CHECK-NEXT: mov w0, w20 ; CHECK-NEXT: mov w0, w20
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, 1431655765 %n1 = and i32 %n0, 1431655765
@ -229,15 +229,15 @@ define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind { define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
; CHECK-LABEL: in_multiuse_B_constmask: ; CHECK-LABEL: in_multiuse_B_constmask:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w0, w0, w1 ; CHECK-NEXT: eor w0, w0, w1
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: and w20, w0, #0x55555555 ; CHECK-NEXT: and w20, w0, #0x55555555
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, 1431655765 %n1 = and i32 %n0, 1431655765

View File

@ -204,16 +204,16 @@ declare void @use32(i32) nounwind
define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind { define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
; CHECK-LABEL: in_multiuse_A_constmask: ; CHECK-LABEL: in_multiuse_A_constmask:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w8, w0, w1 ; CHECK-NEXT: eor w8, w0, w1
; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: and w20, w8, #0xf0f0f0f ; CHECK-NEXT: and w20, w8, #0xf0f0f0f
; CHECK-NEXT: mov w0, w20 ; CHECK-NEXT: mov w0, w20
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, 252645135 %n1 = and i32 %n0, 252645135
@ -225,15 +225,15 @@ define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind { define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
; CHECK-LABEL: in_multiuse_B_constmask: ; CHECK-LABEL: in_multiuse_B_constmask:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w0, w0, w1 ; CHECK-NEXT: eor w0, w0, w1
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: and w20, w0, #0xf0f0f0f ; CHECK-NEXT: and w20, w0, #0xf0f0f0f
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, 252645135 %n1 = and i32 %n0, 252645135

View File

@ -197,16 +197,16 @@ declare void @use32(i32) nounwind
define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind { define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
; CHECK-LABEL: in_multiuse_A_constmask: ; CHECK-LABEL: in_multiuse_A_constmask:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w8, w0, w1 ; CHECK-NEXT: eor w8, w0, w1
; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: and w20, w8, #0xffff ; CHECK-NEXT: and w20, w8, #0xffff
; CHECK-NEXT: mov w0, w20 ; CHECK-NEXT: mov w0, w20
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, 65535 %n1 = and i32 %n0, 65535
@ -218,15 +218,15 @@ define i32 @in_multiuse_A_constmask(i32 %x, i32 %y, i32 %z) nounwind {
define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind { define i32 @in_multiuse_B_constmask(i32 %x, i32 %y, i32 %z) nounwind {
; CHECK-LABEL: in_multiuse_B_constmask: ; CHECK-LABEL: in_multiuse_B_constmask:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w0, w0, w1 ; CHECK-NEXT: eor w0, w0, w1
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: and w20, w0, #0xffff ; CHECK-NEXT: and w20, w0, #0xffff
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, 65535 %n1 = and i32 %n0, 65535

View File

@ -552,16 +552,16 @@ declare void @use32(i32) nounwind
define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
; CHECK-LABEL: in_multiuse_A: ; CHECK-LABEL: in_multiuse_A:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w8, w0, w1 ; CHECK-NEXT: eor w8, w0, w1
; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: and w20, w8, w3 ; CHECK-NEXT: and w20, w8, w3
; CHECK-NEXT: mov w0, w20 ; CHECK-NEXT: mov w0, w20
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, %mask %n1 = and i32 %n0, %mask
@ -572,15 +572,15 @@ define i32 @in_multiuse_A(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind { define i32 @in_multiuse_B(i32 %x, i32 %y, i32 %z, i32 %mask) nounwind {
; CHECK-LABEL: in_multiuse_B: ; CHECK-LABEL: in_multiuse_B:
; CHECK: // %bb.0: ; CHECK: // %bb.0:
; CHECK-NEXT: str x20, [sp, #-32]! // 8-byte Folded Spill ; CHECK-NEXT: str x30, [sp, #-32]! // 8-byte Folded Spill
; CHECK-NEXT: eor w0, w0, w1 ; CHECK-NEXT: eor w0, w0, w1
; CHECK-NEXT: stp x19, x30, [sp, #16] // 16-byte Folded Spill ; CHECK-NEXT: stp x20, x19, [sp, #16] // 16-byte Folded Spill
; CHECK-NEXT: mov w19, w1 ; CHECK-NEXT: mov w19, w1
; CHECK-NEXT: and w20, w0, w3 ; CHECK-NEXT: and w20, w0, w3
; CHECK-NEXT: bl use32 ; CHECK-NEXT: bl use32
; CHECK-NEXT: eor w0, w20, w19 ; CHECK-NEXT: eor w0, w20, w19
; CHECK-NEXT: ldp x19, x30, [sp, #16] // 16-byte Folded Reload ; CHECK-NEXT: ldp x20, x19, [sp, #16] // 16-byte Folded Reload
; CHECK-NEXT: ldr x20, [sp], #32 // 8-byte Folded Reload ; CHECK-NEXT: ldr x30, [sp], #32 // 8-byte Folded Reload
; CHECK-NEXT: ret ; CHECK-NEXT: ret
%n0 = xor i32 %x, %y %n0 = xor i32 %x, %y
%n1 = and i32 %n0, %mask %n1 = and i32 %n0, %mask

View File

@ -14,11 +14,11 @@ stack:
body: | body: |
bb.0: bb.0:
STRXui undef $x8, %stack.0, 0 STRXui undef $x8, %stack.0, 0
; CHECK: STURXi undef $x8, $fp, -24 ; CHECK: STRXui undef $x8, $fp, 0
B %bb.1 B %bb.1
bb.1: bb.1:
liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28, $fp, $lr liveins: $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15, $x16, $x17, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27, $x28
RET_ReallyLR implicit $x21, implicit $x22, implicit $x23, implicit $x24, implicit $x25, implicit $x26, implicit $x27, implicit $x28 RET_ReallyLR implicit $x19, implicit $x20, implicit $x21, implicit $x22, implicit $x23, implicit $x24, implicit $x25, implicit $x26, implicit $x27, implicit $x28
... ...
--- ---
name: fpDoesNotFit name: fpDoesNotFit

View File

@ -103,21 +103,21 @@ declare i32 @__stdio_common_vsprintf(i64, i8*, i64, i8*, i8*, i8*) local_unnamed
declare i64* @__local_stdio_printf_options() local_unnamed_addr #4 declare i64* @__local_stdio_printf_options() local_unnamed_addr #4
; CHECK-LABEL: fp ; CHECK-LABEL: fp
; CHECK: str x21, [sp, #-96]! ; CHECK: stp x29, x30, [sp, #-96]
; CHECK: stp x19, x20, [sp, #16] ; CHECK: str x21, [sp, #16]
; CHECK: stp x29, x30, [sp, #32] ; CHECK: stp x19, x20, [sp, #32]
; CHECK: add x29, sp, #32 ; CHECK: mov x29, sp
; CHECK: add x8, x29, #24 ; CHECK: add x8, x29, #56
; CHECK: mov x19, x2 ; CHECK: mov x19, x2
; CHECK: mov x20, x1 ; CHECK: mov x20, x1
; CHECK: mov x21, x0 ; CHECK: mov x21, x0
; CHECK: stp x3, x4, [x29, #24] ; CHECK: stp x3, x4, [x29, #56]
; CHECK: stp x5, x6, [x29, #40] ; CHECK: stp x5, x6, [x29, #72]
; CHECK: str x7, [x29, #56] ; CHECK: str x7, [x29, #88]
; CHECK: str x8, [sp, #8] ; CHECK: str x8, [x29, #24]
; CHECK: bl __local_stdio_printf_options ; CHECK: bl __local_stdio_printf_options
; CHECK: ldr x8, [x0] ; CHECK: ldr x8, [x0]
; CHECK: add x5, x29, #24 ; CHECK: add x5, x29, #56
; CHECK: mov x1, x21 ; CHECK: mov x1, x21
; CHECK: mov x2, x20 ; CHECK: mov x2, x20
; CHECK: orr x0, x8, #0x2 ; CHECK: orr x0, x8, #0x2
@ -126,9 +126,9 @@ declare i64* @__local_stdio_printf_options() local_unnamed_addr #4
; CHECK: bl __stdio_common_vsprintf ; CHECK: bl __stdio_common_vsprintf
; CHECK: cmp w0, #0 ; CHECK: cmp w0, #0
; CHECK: csinv w0, w0, wzr, ge ; CHECK: csinv w0, w0, wzr, ge
; CHECK: ldp x29, x30, [sp, #32] ; CHECK: ldp x19, x20, [sp, #32]
; CHECK: ldp x19, x20, [sp, #16] ; CHECK: ldr x21, [sp, #16]
; CHECK: ldr x21, [sp], #96 ; CHECK: ldp x29, x30, [sp], #96
; CHECK: ret ; CHECK: ret
define i32 @fp(i8*, i64, i8*, ...) local_unnamed_addr #6 { define i32 @fp(i8*, i64, i8*, ...) local_unnamed_addr #6 {
%4 = alloca i8*, align 8 %4 = alloca i8*, align 8
@ -150,26 +150,26 @@ define i32 @fp(i8*, i64, i8*, ...) local_unnamed_addr #6 {
attributes #6 = { "no-frame-pointer-elim"="true" } attributes #6 = { "no-frame-pointer-elim"="true" }
; CHECK-LABEL: vla ; CHECK-LABEL: vla
; CHECK: str x23, [sp, #-112]! ; CHECK: stp x29, x30, [sp, #-112]!
; CHECK: stp x21, x22, [sp, #16] ; CHECK: str x23, [sp, #16]
; CHECK: stp x19, x20, [sp, #32] ; CHECK: stp x21, x22, [sp, #32]
; CHECK: stp x29, x30, [sp, #48] ; CHECK: stp x19, x20, [sp, #48]
; CHECK: add x29, sp, #48 ; CHECK: mov x29, sp
; CHECK: add x8, x29, #16 ; CHECK: add x8, x29, #64
; CHECK: stur x8, [x29, #-40] ; CHECK: str x8, [x29, #24]
; CHECK: mov w8, w0 ; CHECK: mov w8, w0
; CHECK: add x8, x8, #15 ; CHECK: add x8, x8, #15
; CHECK: lsr x15, x8, #4 ; CHECK: lsr x15, x8, #4
; CHECK: mov x19, x1 ; CHECK: mov x19, x1
; CHECK: mov [[REG2:x[0-9]+]], sp ; CHECK: mov [[REG2:x[0-9]+]], sp
; CHECK: stp x2, x3, [x29, #16] ; CHECK: stp x2, x3, [x29, #64]
; CHECK: stp x4, x5, [x29, #32] ; CHECK: stp x4, x5, [x29, #80]
; CHECK: stp x6, x7, [x29, #48] ; CHECK: stp x6, x7, [x29, #96]
; CHECK: bl __chkstk ; CHECK: bl __chkstk
; CHECK: mov x8, sp ; CHECK: mov x8, sp
; CHECK: sub [[REG:x[0-9]+]], x8, x15, lsl #4 ; CHECK: sub [[REG:x[0-9]+]], x8, x15, lsl #4
; CHECK: mov sp, [[REG]] ; CHECK: mov sp, [[REG]]
; CHECK: ldur [[REG3:x[0-9]+]], [x29, #-40] ; CHECK: ldr [[REG3:x[0-9]+]], [x29, #24]
; CHECK: sxtw [[REG4:x[0-9]+]], w0 ; CHECK: sxtw [[REG4:x[0-9]+]], w0
; CHECK: bl __local_stdio_printf_options ; CHECK: bl __local_stdio_printf_options
; CHECK: ldr x8, [x0] ; CHECK: ldr x8, [x0]
@ -181,11 +181,11 @@ attributes #6 = { "no-frame-pointer-elim"="true" }
; CHECK: mov x5, [[REG3]] ; CHECK: mov x5, [[REG3]]
; CHECK: bl __stdio_common_vsprintf ; CHECK: bl __stdio_common_vsprintf
; CHECK: mov sp, [[REG2]] ; CHECK: mov sp, [[REG2]]
; CHECK: sub sp, x29, #48 ; CHECK: mov sp, x29
; CHECK: ldp x29, x30, [sp, #48] ; CHECK: ldp x19, x20, [sp, #48]
; CHECK: ldp x19, x20, [sp, #32] ; CHECK: ldp x21, x22, [sp, #32]
; CHECK: ldp x21, x22, [sp, #16] ; CHECK: ldr x23, [sp, #16]
; CHECK: ldr x23, [sp], #112 ; CHECK: ldp x29, x30, [sp], #112
; CHECK: ret ; CHECK: ret
define void @vla(i32, i8*, ...) local_unnamed_addr { define void @vla(i32, i8*, ...) local_unnamed_addr {
%3 = alloca i8*, align 8 %3 = alloca i8*, align 8
@ -212,9 +212,9 @@ declare void @llvm.stackrestore(i8*)
; CHECK-LABEL: snprintf ; CHECK-LABEL: snprintf
; CHECK-DAG: sub sp, sp, #96 ; CHECK-DAG: sub sp, sp, #96
; CHECK-DAG: str x21, [sp, #16] ; CHECK-DAG: str x30, [sp, #16]
; CHECK-DAG: stp x19, x20, [sp, #24] ; CHECK-DAG: str x21, [sp, #24]
; CHECK-DAG: str x30, [sp, #40] ; CHECK-DAG: stp x19, x20, [sp, #32]
; CHECK-DAG: add x8, sp, #56 ; CHECK-DAG: add x8, sp, #56
; CHECK-DAG: mov x19, x2 ; CHECK-DAG: mov x19, x2
; CHECK-DAG: mov x20, x1 ; CHECK-DAG: mov x20, x1
@ -232,9 +232,9 @@ declare void @llvm.stackrestore(i8*)
; CHECK-DAG: mov x3, x19 ; CHECK-DAG: mov x3, x19
; CHECK-DAG: mov x4, xzr ; CHECK-DAG: mov x4, xzr
; CHECK-DAG: bl __stdio_common_vsprintf ; CHECK-DAG: bl __stdio_common_vsprintf
; CHECK-DAG: ldr x30, [sp, #40] ; CHECK-DAG: ldr x30, [sp, #16]
; CHECK-DAG: ldp x19, x20, [sp, #24] ; CHECK-DAG: ldr x21, [sp, #24]
; CHECK-DAG: ldr x21, [sp, #16] ; CHECK-DAG: ldp x19, x20, [sp, #32]
; CHECK-DAG: cmp w0, #0 ; CHECK-DAG: cmp w0, #0
; CHECK-DAG: csinv w0, w0, wzr, ge ; CHECK-DAG: csinv w0, w0, wzr, ge
; CHECK-DAG: add sp, sp, #96 ; CHECK-DAG: add sp, sp, #96

View File

@ -3,12 +3,10 @@
# Check multiple epilogues, save_reg, save_reg_x. # Check multiple epilogues, save_reg, save_reg_x.
# CHECK-LABEL: bb.0.entry: # CHECK-LABEL: bb.0.entry:
# CHECK: early-clobber $sp = frame-setup STRXpre killed $x28, $sp, -32 # CHECK: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -4
# CHECK-NEXT: frame-setup SEH_SaveReg_X 28, -32 # CHECK-NEXT: frame-setup SEH_SaveFPLR_X -32
# CHECK-NEXT: frame-setup STRXui killed $x19, $sp, 1 # CHECK-NEXT: frame-setup STRXui killed $x19, $sp, 2
# CHECK-NEXT: frame-setup SEH_SaveReg 19, 8 # CHECK-NEXT: frame-setup SEH_SaveReg 19, 16
# CHECK-NEXT: frame-setup STRXui killed $lr, $sp, 2
# CHECK-NEXT: frame-setup SEH_SaveReg 30, 16
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 496, 0 # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 496, 0
# CHECK-NEXT: frame-setup SEH_StackAlloc 496 # CHECK-NEXT: frame-setup SEH_StackAlloc 496
# CHECK-NEXT: frame-setup SEH_PrologEnd # CHECK-NEXT: frame-setup SEH_PrologEnd
@ -17,12 +15,10 @@
# CHECK: frame-destroy SEH_EpilogStart # CHECK: frame-destroy SEH_EpilogStart
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 496, 0 # CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 496, 0
# CHECK-NEXT: frame-destroy SEH_StackAlloc 496 # CHECK-NEXT: frame-destroy SEH_StackAlloc 496
# CHECK-NEXT: $lr = frame-destroy LDRXui $sp, 2 # CHECK-NEXT: $x19 = frame-destroy LDRXui $sp, 2
# CHECK-NEXT: frame-destroy SEH_SaveReg 30, 16 # CHECK-NEXT: frame-destroy SEH_SaveReg 19, 16
# CHECK-NEXT: $x19 = frame-destroy LDRXui $sp, 1 # CHECK-NEXT: early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 4
# CHECK-NEXT: frame-destroy SEH_SaveReg 19, 8 # CHECK-NEXT: frame-destroy SEH_SaveFPLR_X -32
# CHECK-NEXT: early-clobber $sp, $x28 = frame-destroy LDRXpost $sp, 32
# CHECK-NEXT: frame-destroy SEH_SaveReg_X 28, -32
# CHECK-NEXT: frame-destroy SEH_EpilogEnd # CHECK-NEXT: frame-destroy SEH_EpilogEnd
# CHECK-NEXT: TCRETURNdi @"?func2@@YAHXZ", 0, csr_aarch64_aapcs, implicit $sp # CHECK-NEXT: TCRETURNdi @"?func2@@YAHXZ", 0, csr_aarch64_aapcs, implicit $sp

View File

@ -3,10 +3,8 @@
# Test that stack probe results in Nop unwind codes in the prologue. Test # Test that stack probe results in Nop unwind codes in the prologue. Test
# save_fplr, save_reg_x and stack_alloc with multiple updates. # save_fplr, save_reg_x and stack_alloc with multiple updates.
# CHECK: early-clobber $sp = frame-setup STRXpre killed $x28, $sp, -32 # CHECK: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2
# CHECK-NEXT: frame-setup SEH_SaveReg_X 28, -32 # CHECK-NEXT: frame-setup SEH_SaveFPLR_X -16
# CHECK-NEXT: frame-setup STPXi killed $fp, killed $lr, $sp, 2
# CHECK-NEXT: frame-setup SEH_SaveFPLR 16
# CHECK-NEXT: $x15 = frame-setup MOVZXi 56009, 0 # CHECK-NEXT: $x15 = frame-setup MOVZXi 56009, 0
# CHECK-NEXT: frame-setup SEH_Nop # CHECK-NEXT: frame-setup SEH_Nop
# CHECK-NEXT: $x15 = frame-setup MOVKXi $x15, 2, 16 # CHECK-NEXT: $x15 = frame-setup MOVKXi $x15, 2, 16
@ -21,10 +19,8 @@
# CHECK-NEXT: frame-destroy SEH_StackAlloc 2990080 # CHECK-NEXT: frame-destroy SEH_StackAlloc 2990080
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 3216, 0 # CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 3216, 0
# CHECK-NEXT: frame-destroy SEH_StackAlloc 3216 # CHECK-NEXT: frame-destroy SEH_StackAlloc 3216
# CHECK-NEXT: $fp, $lr = frame-destroy LDPXi $sp, 2 # CHECK-NEXT: early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
# CHECK-NEXT: frame-destroy SEH_SaveFPLR 16 # CHECK-NEXT: frame-destroy SEH_SaveFPLR_X -16
# CHECK-NEXT: early-clobber $sp, $x28 = frame-destroy LDRXpost $sp, 32
# CHECK-NEXT: frame-destroy SEH_SaveReg_X 28, -32
# CHECK-NEXT: frame-destroy SEH_EpilogEnd # CHECK-NEXT: frame-destroy SEH_EpilogEnd
# CHECK-NEXT: RET_ReallyLR implicit killed $w0 # CHECK-NEXT: RET_ReallyLR implicit killed $w0
--- | --- |

View File

@ -9,17 +9,17 @@
; it shouldn't access the parent's frame via sp, and the prologue and ; it shouldn't access the parent's frame via sp, and the prologue and
; epilogue should be symmetrical. ; epilogue should be symmetrical.
; CHECK-LABEL: "?catch$2@?0??a@@YAXXZ@4HA": ; CHECK-LABEL: "?catch$2@?0??a@@YAXXZ@4HA":
; CHECK: str x28, [sp, #-32]! ; CHECK: stp x29, x30, [sp, #-32]!
; CHECK-NEXT: str x19, [sp, #8] ; CHECK-NEXT: str x28, [sp, #16]
; CHECK-NEXT: stp x29, x30, [sp, #16] ; CHECK-NEXT: str x19, [sp, #24]
; CHECK-NEXT: add x0, x19, #64 ; CHECK-NEXT: add x0, x19, #64
; CHECK-NEXT: mov w1, wzr ; CHECK-NEXT: mov w1, wzr
; CHECK-NEXT: bl "?bb@@YAXPEAHH@Z" ; CHECK-NEXT: bl "?bb@@YAXPEAHH@Z"
; CHECK-NEXT: adrp x0, .LBB0_1 ; CHECK-NEXT: adrp x0, .LBB0_1
; CHECK-NEXT: add x0, x0, .LBB0_1 ; CHECK-NEXT: add x0, x0, .LBB0_1
; CHECK-NEXT: ldp x29, x30, [sp, #16] ; CHECK-NEXT: ldr x19, [sp, #24]
; CHECK-NEXT: ldr x19, [sp, #8] ; CHECK-NEXT: ldr x28, [sp, #16]
; CHECK-NEXT: ldr x28, [sp], #32 ; CHECK-NEXT: ldp x29, x30, [sp], #32
; CHECK-NEXT: ret ; CHECK-NEXT: ret

View File

@ -15,11 +15,11 @@
; on-entry sp - 672. We check this offset in the table later on. ; on-entry sp - 672. We check this offset in the table later on.
; CHECK-LABEL: "?func@@YAHXZ": ; CHECK-LABEL: "?func@@YAHXZ":
; CHECK: str x28, [sp, #-48]! ; CHECK: stp x29, x30, [sp, #-48]!
; CHECK: str x21, [sp, #8] ; CHECK: str x28, [sp, #16]
; CHECK: stp x19, x20, [sp, #16] ; CHECK: str x21, [sp, #24]
; CHECK: stp x29, x30, [sp, #32] ; CHECK: stp x19, x20, [sp, #32]
; CHECK: add x29, sp, #32 ; CHECK: mov x29, sp
; CHECK: sub sp, sp, #624 ; CHECK: sub sp, sp, #624
; CHECK: mov x19, sp ; CHECK: mov x19, sp
; CHECK: mov x0, #-2 ; CHECK: mov x0, #-2
@ -47,10 +47,10 @@
; CHECK-LABEL: "?catch$2@?0??func@@YAHXZ@4HA": ; CHECK-LABEL: "?catch$2@?0??func@@YAHXZ@4HA":
; Check that the stack space is allocated only for the callee saved registers. ; Check that the stack space is allocated only for the callee saved registers.
; CHECK: str x28, [sp, #-48]! ; CHECK: stp x29, x30, [sp, #-48]!
; CHECK: str x21, [sp, #8] ; CHECK: str x28, [sp, #16]
; CHECK: stp x19, x20, [sp, #16] ; CHECK: str x21, [sp, #24]
; CHECK: stp x29, x30, [sp, #32] ; CHECK: stp x19, x20, [sp, #32]
; CHECK: add x20, x19, #12 ; CHECK: add x20, x19, #12
; Check that there are no further stack updates. ; Check that there are no further stack updates.
@ -87,18 +87,18 @@
; UNWIND: Prologue [ ; UNWIND: Prologue [
; UNWIND-NEXT: ; nop ; UNWIND-NEXT: ; nop
; UNWIND-NEXT: ; sub sp, #624 ; UNWIND-NEXT: ; sub sp, #624
; UNWIND-NEXT: ; add fp, sp, #32 ; UNWIND-NEXT: ; mov fp, sp
; UNWIND-NEXT: ; stp x29, x30, [sp, #32] ; UNWIND-NEXT: ; stp x19, x20, [sp, #32]
; UNWIND-NEXT: ; stp x19, x20, [sp, #16] ; UNWIND-NEXT: ; str x21, [sp, #24]
; UNWIND-NEXT: ; str x21, [sp, #8] ; UNWIND-NEXT: ; str x28, [sp, #16]
; UNWIND-NEXT: ; str x28, [sp, #48]! ; UNWIND-NEXT: ; stp x29, x30, [sp, #-48]!
; UNWIND-NEXT: ; end ; UNWIND-NEXT: ; end
; UNWIND: Function: ?catch$2@?0??func@@YAHXZ@4HA ; UNWIND: Function: ?catch$2@?0??func@@YAHXZ@4HA
; UNWIND: Prologue [ ; UNWIND: Prologue [
; UNWIND-NEXT: ; stp x29, x30, [sp, #32] ; UNWIND-NEXT: ; stp x19, x20, [sp, #32]
; UNWIND-NEXT: ; stp x19, x20, [sp, #16] ; UNWIND-NEXT: ; str x21, [sp, #24]
; UNWIND-NEXT: ; str x21, [sp, #8] ; UNWIND-NEXT: ; str x28, [sp, #16]
; UNWIND-NEXT: ; str x28, [sp, #48]! ; UNWIND-NEXT: ; stp x29, x30, [sp, #-48]!
; UNWIND-NEXT: ; end ; UNWIND-NEXT: ; end
target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128" target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"

View File

@ -9,14 +9,14 @@
# The same test gets shrink wrapped on Linux ARM64. # The same test gets shrink wrapped on Linux ARM64.
# WIN64-LABEL: bb.0.entry: # WIN64-LABEL: bb.0.entry:
# WIN64: early-clobber $sp = frame-setup STRXpre killed $x28, $sp, -32 # WIN64: early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -4
# WIN64-LABEL: bb.1: # WIN64-LABEL: bb.1:
# WIN64-LABEL: bb.2.if.then: # WIN64-LABEL: bb.2.if.then:
# LINUX-LABEL: bb.0.entry: # LINUX-LABEL: bb.0.entry:
# LINUX-LABEL: bb.1: # LINUX-LABEL: bb.1:
# LINUX-LABEL: bb.2.if.then: # LINUX-LABEL: bb.2.if.then:
# LINUX: early-clobber $sp = frame-setup STRXpre killed $x28, $sp, -32 # LINUX: early-clobber $sp = frame-setup STRXpre killed $fp, $sp, -32
--- | --- |
; ModuleID = 'shrink.cpp' ; ModuleID = 'shrink.cpp'
target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128" target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"