[llvm] Consistently respect naked fn attribute in TargetFrameLowering::hasFP() (#106014)

Some targets (e.g. PPC and Hexagon) already did this. I think it's best
to do this consistently so that frontend authors don't run into
inconsistent results when they emit `naked` functions. For example, in
Zig, we had to change our emit code to also set `frame-pointer=none` to
get reliable results across targets.

Note: I don't have commit access.
This commit is contained in:
Alex Rønne Petersen 2024-10-18 07:35:42 +02:00 committed by GitHub
parent b497010854
commit ad4a582fd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
72 changed files with 1085 additions and 90 deletions

View File

@ -280,7 +280,11 @@ public:
/// hasFP - Return true if the specified function should have a dedicated
/// frame pointer register. For most targets this is true only if the function
/// has variable sized allocas or if frame pointer elimination is disabled.
virtual bool hasFP(const MachineFunction &MF) const = 0;
/// For all targets, this is false if the function has the naked attribute
/// since there is no prologue to set up the frame pointer.
bool hasFP(const MachineFunction &MF) const {
return !MF.getFunction().hasFnAttribute(Attribute::Naked) && hasFPImpl(MF);
}
/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
/// not required, we reserve argument space for call sites in the function
@ -477,6 +481,9 @@ public:
/// targets can emit remarks based on the final frame layout.
virtual void emitRemarks(const MachineFunction &MF,
MachineOptimizationRemarkEmitter *ORE) const {};
protected:
virtual bool hasFPImpl(const MachineFunction &MF) const = 0;
};
} // End llvm namespace

View File

@ -480,9 +480,9 @@ bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
getSVEStackSize(MF) || LowerQRegCopyThroughMem);
}
/// hasFP - Return true if the specified function should have a dedicated frame
/// pointer register.
bool AArch64FrameLowering::hasFP(const MachineFunction &MF) const {
/// hasFPImpl - Return true if the specified function should have a dedicated
/// frame pointer register.
bool AArch64FrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();

View File

@ -65,7 +65,6 @@ public:
/// Can this function use the red zone for local allocations.
bool canUseRedZone(const MachineFunction &MF) const;
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool assignCalleeSavedSpillSlots(MachineFunction &MF,
@ -125,6 +124,9 @@ public:
orderFrameObjects(const MachineFunction &MF,
SmallVectorImpl<int> &ObjectsToAllocate) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
private:
/// Returns true if a homogeneous prolog or epilog code can be emitted
/// for the size optimization. If so, HOM_Prolog/HOM_Epilog pseudo

View File

@ -27,9 +27,8 @@ public:
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
Register &FrameReg) const override;
bool hasFP(const MachineFunction &MF) const override {
return false;
}
protected:
bool hasFPImpl(const MachineFunction &MF) const override { return false; }
};
} // end namespace llvm

View File

@ -1805,7 +1805,7 @@ static bool frameTriviallyRequiresSP(const MachineFrameInfo &MFI) {
// The FP for kernels is always known 0, so we never really need to setup an
// explicit register for it. However, DisableFramePointerElim will force us to
// use a register for it.
bool SIFrameLowering::hasFP(const MachineFunction &MF) const {
bool SIFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
// For entry & chain functions we can use an immediate offset in most cases,

View File

@ -66,6 +66,9 @@ public:
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
private:
void emitEntryFunctionFlatScratchInit(MachineFunction &MF,
MachineBasicBlock &MBB,
@ -82,8 +85,6 @@ private:
Register ScratchWaveOffsetReg) const;
public:
bool hasFP(const MachineFunction &MF) const override;
bool requiresStackPointerReference(const MachineFunction &MF) const;
};

View File

@ -487,7 +487,7 @@ MachineBasicBlock::iterator ARCFrameLowering::eliminateCallFramePseudoInstr(
return MBB.erase(I);
}
bool ARCFrameLowering::hasFP(const MachineFunction &MF) const {
bool ARCFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) ||
MF.getFrameInfo().hasVarSizedObjects() ||

View File

@ -54,8 +54,6 @@ public:
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS) const override;
bool hasFP(const MachineFunction &MF) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
@ -64,6 +62,9 @@ public:
llvm::MachineFunction &, const llvm::TargetRegisterInfo *,
std::vector<llvm::CalleeSavedInfo> &) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
private:
void adjustStackToMatchRecords(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,

View File

@ -323,10 +323,10 @@ bool ARMFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const {
return true;
}
/// hasFP - Return true if the specified function should have a dedicated frame
/// pointer register. This is true if the function has variable sized allocas
/// or if frame pointer elimination is disabled.
bool ARMFrameLowering::hasFP(const MachineFunction &MF) const {
/// hasFPImpl - Return true if the specified function should have a dedicated
/// frame pointer register. This is true if the function has variable sized
/// allocas or if frame pointer elimination is disabled.
bool ARMFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
const MachineFrameInfo &MFI = MF.getFrameInfo();

View File

@ -45,7 +45,6 @@ public:
bool enableCalleeSaveSkip(const MachineFunction &MF) const override;
bool hasFP(const MachineFunction &MF) const override;
bool isFPReserved(const MachineFunction &MF) const;
bool requiresAAPCSFrameRecord(const MachineFunction &MF) const;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
@ -87,6 +86,9 @@ public:
const SpillSlot *
getCalleeSavedSpillSlots(unsigned &NumEntries) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
private:
void emitPushInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
ArrayRef<CalleeSavedInfo> CSI, unsigned StmOpc,

View File

@ -232,7 +232,7 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
//
// Notice that strictly this is not a frame pointer because it contains SP after
// frame allocation instead of having the original SP in function entry.
bool AVRFrameLowering::hasFP(const MachineFunction &MF) const {
bool AVRFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const AVRMachineFunctionInfo *FuncInfo = MF.getInfo<AVRMachineFunctionInfo>();
return (FuncInfo->getHasSpills() || FuncInfo->getHasAllocas() ||

View File

@ -21,7 +21,6 @@ public:
public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
bool hasFP(const MachineFunction &MF) const override;
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
ArrayRef<CalleeSavedInfo> CSI,
@ -38,6 +37,9 @@ public:
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
};
} // end namespace llvm

View File

@ -20,7 +20,9 @@
using namespace llvm;
bool BPFFrameLowering::hasFP(const MachineFunction &MF) const { return true; }
bool BPFFrameLowering::hasFPImpl(const MachineFunction &MF) const {
return true;
}
void BPFFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {}

View File

@ -26,7 +26,6 @@ public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
bool hasFP(const MachineFunction &MF) const override;
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS) const override;
@ -35,6 +34,9 @@ public:
MachineBasicBlock::iterator MI) const override {
return MBB.erase(MI);
}
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
};
}
#endif

View File

@ -33,7 +33,7 @@ static Register getFPReg(const CSKYSubtarget &STI) { return CSKY::R8; }
// callee saved register to save the value.
static Register getBPReg(const CSKYSubtarget &STI) { return CSKY::R7; }
bool CSKYFrameLowering::hasFP(const MachineFunction &MF) const {
bool CSKYFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
const MachineFrameInfo &MFI = MF.getFrameInfo();

View File

@ -61,7 +61,6 @@ public:
MutableArrayRef<CalleeSavedInfo> CSI,
const TargetRegisterInfo *TRI) const override;
bool hasFP(const MachineFunction &MF) const override;
bool hasBP(const MachineFunction &MF) const;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
@ -69,6 +68,9 @@ public:
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
};
} // namespace llvm
#endif

View File

@ -29,7 +29,8 @@ public:
void emitPrologue(MachineFunction &, MachineBasicBlock &) const override {}
void emitEpilogue(MachineFunction &, MachineBasicBlock &) const override {}
bool hasFP(const MachineFunction &) const override { return false; }
protected:
bool hasFPImpl(const MachineFunction &) const override { return false; }
};
} // namespace llvm
#endif // LLVM_DIRECTX_DIRECTXFRAMELOWERING_H

View File

@ -1144,10 +1144,7 @@ void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB,
}
}
bool HexagonFrameLowering::hasFP(const MachineFunction &MF) const {
if (MF.getFunction().hasFnAttribute(Attribute::Naked))
return false;
bool HexagonFrameLowering::hasFPImpl(const MachineFunction &MF) const {
auto &MFI = MF.getFrameInfo();
auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
bool HasExtraAlign = HRI.hasStackRealignment(MF);

View File

@ -89,7 +89,6 @@ public:
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
Register &FrameReg) const override;
bool hasFP(const MachineFunction &MF) const override;
const SpillSlot *getCalleeSavedSpillSlots(unsigned &NumEntries)
const override {
@ -114,6 +113,9 @@ public:
void insertCFIInstructions(MachineFunction &MF) const;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
private:
using CSIVect = std::vector<CalleeSavedInfo>;

View File

@ -44,10 +44,11 @@ public:
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
bool hasFP(const MachineFunction & /*MF*/) const override { return true; }
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS = nullptr) const override;
protected:
bool hasFPImpl(const MachineFunction & /*MF*/) const override { return true; }
};
} // namespace llvm

View File

@ -31,7 +31,7 @@ using namespace llvm;
// pointer register. This is true if frame pointer elimination is
// disabled, if it needs dynamic stack realignment, if the function has
// variable sized allocas, or if the frame address is taken.
bool LoongArchFrameLowering::hasFP(const MachineFunction &MF) const {
bool LoongArchFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
const MachineFrameInfo &MFI = MF.getFrameInfo();

View File

@ -49,13 +49,15 @@ public:
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
Register &FrameReg) const override;
bool hasFP(const MachineFunction &MF) const override;
bool hasBP(const MachineFunction &MF) const;
uint64_t getFirstSPAdjustAmount(const MachineFunction &MF) const;
bool enableShrinkWrapping(const MachineFunction &MF) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
private:
void determineFrameLayout(MachineFunction &MF) const;
void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,

View File

@ -40,7 +40,7 @@ M68kFrameLowering::M68kFrameLowering(const M68kSubtarget &STI, Align Alignment)
StackPtr = TRI->getStackRegister();
}
bool M68kFrameLowering::hasFP(const MachineFunction &MF) const {
bool M68kFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo *TRI = STI.getRegisterInfo();

View File

@ -121,12 +121,6 @@ public:
MutableArrayRef<CalleeSavedInfo> CSI,
const TargetRegisterInfo *TRI) const override;
/// Return true if the specified function should have a dedicated frame
/// pointer register. This is true if the function has variable sized
/// allocas, if it needs dynamic stack realignment, if frame pointer
/// elimination is disabled, or if the frame address is taken.
bool hasFP(const MachineFunction &MF) const override;
/// Under normal circumstances, when a frame pointer is not required, we
/// reserve argument space for call sites in the function immediately on
/// entry to the current function. This eliminates the need for add/sub sp
@ -166,6 +160,13 @@ public:
/// pointer by a constant value.
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
int64_t NumBytes, bool InEpilogue) const;
protected:
/// Return true if the specified function should have a dedicated frame
/// pointer register. This is true if the function has variable sized
/// allocas, if it needs dynamic stack realignment, if frame pointer
/// elimination is disabled, or if the frame address is taken.
bool hasFPImpl(const MachineFunction &MF) const override;
};
} // namespace llvm

View File

@ -30,7 +30,7 @@ MSP430FrameLowering::MSP430FrameLowering(const MSP430Subtarget &STI)
Align(2)),
STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
bool MSP430FrameLowering::hasFP(const MachineFunction &MF) const {
bool MSP430FrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
return (MF.getTarget().Options.DisableFramePointerElim(MF) ||

View File

@ -24,6 +24,7 @@ class MSP430RegisterInfo;
class MSP430FrameLowering : public TargetFrameLowering {
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
public:
MSP430FrameLowering(const MSP430Subtarget &STI);
@ -51,7 +52,6 @@ public:
MutableArrayRef<CalleeSavedInfo> CSI,
const TargetRegisterInfo *TRI) const override;
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS = nullptr) const override;

View File

@ -86,11 +86,11 @@ const MipsFrameLowering *MipsFrameLowering::create(const MipsSubtarget &ST) {
return llvm::createMipsSEFrameLowering(ST);
}
// hasFP - Return true if the specified function should have a dedicated frame
// pointer register. This is true if the function has variable sized allocas,
// if it needs dynamic stack realignment, if frame pointer elimination is
// disabled, or if the frame address is taken.
bool MipsFrameLowering::hasFP(const MachineFunction &MF) const {
// hasFPImpl - Return true if the specified function should have a dedicated
// frame pointer register. This is true if the function has variable sized
// allocas, if it needs dynamic stack realignment, if frame pointer elimination
// is disabled, or if the frame address is taken.
bool MipsFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo *TRI = STI.getRegisterInfo();

View File

@ -23,6 +23,8 @@ class MipsFrameLowering : public TargetFrameLowering {
protected:
const MipsSubtarget &STI;
bool hasFPImpl(const MachineFunction &MF) const override;
public:
explicit MipsFrameLowering(const MipsSubtarget &sti, Align Alignment)
: TargetFrameLowering(StackGrowsDown, Alignment, 0, Alignment), STI(sti) {
@ -30,8 +32,6 @@ public:
static const MipsFrameLowering *create(const MipsSubtarget &ST);
bool hasFP(const MachineFunction &MF) const override;
bool hasBP(const MachineFunction &MF) const;
bool allocateScavengingFrameIndexesNearIncomingSP(

View File

@ -27,7 +27,9 @@ using namespace llvm;
NVPTXFrameLowering::NVPTXFrameLowering()
: TargetFrameLowering(TargetFrameLowering::StackGrowsUp, Align(8), 0) {}
bool NVPTXFrameLowering::hasFP(const MachineFunction &MF) const { return true; }
bool NVPTXFrameLowering::hasFPImpl(const MachineFunction &MF) const {
return true;
}
void NVPTXFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {

View File

@ -22,7 +22,6 @@ class NVPTXFrameLowering : public TargetFrameLowering {
public:
explicit NVPTXFrameLowering();
bool hasFP(const MachineFunction &MF) const override;
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
@ -32,6 +31,9 @@ public:
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
};
} // End llvm namespace

View File

@ -355,9 +355,9 @@ PPCFrameLowering::determineFrameLayout(const MachineFunction &MF,
return FrameSize;
}
// hasFP - Return true if the specified function actually has a dedicated frame
// pointer register.
bool PPCFrameLowering::hasFP(const MachineFunction &MF) const {
// hasFPImpl - Return true if the specified function actually has a dedicated
// frame pointer register.
bool PPCFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
// FIXME: This is pretty much broken by design: hasFP() might be called really
// early, before the stack layout was calculated and thus hasFP() might return

View File

@ -107,7 +107,6 @@ public:
void inlineStackProbe(MachineFunction &MF,
MachineBasicBlock &PrologMBB) const override;
bool hasFP(const MachineFunction &MF) const override;
bool needsFP(const MachineFunction &MF) const;
void replaceFPWithRealFP(MachineFunction &MF) const;
@ -176,6 +175,9 @@ public:
void updateCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const;
uint64_t getStackThreshold() const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
};
} // End llvm namespace

View File

@ -309,7 +309,7 @@ static Register getMaxPushPopReg(const MachineFunction &MF,
// pointer register. This is true if frame pointer elimination is
// disabled, if it needs dynamic stack realignment, if the function has
// variable sized allocas, or if the frame address is taken.
bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const {
bool RISCVFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
const MachineFrameInfo &MFI = MF.getFrameInfo();

View File

@ -37,8 +37,6 @@ public:
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS) const override;
bool hasFP(const MachineFunction &MF) const override;
bool hasBP(const MachineFunction &MF) const;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
@ -83,6 +81,8 @@ public:
protected:
const RISCVSubtarget &STI;
bool hasFPImpl(const MachineFunction &MF) const override;
private:
void determineFrameLayout(MachineFunction &MF) const;
void adjustStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,

View File

@ -33,7 +33,8 @@ public:
void emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const override {}
bool hasFP(const MachineFunction &MF) const override { return false; }
protected:
bool hasFPImpl(const MachineFunction &MF) const override { return false; }
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVFRAMELOWERING_H

View File

@ -249,10 +249,10 @@ bool SparcFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
return !MF.getFrameInfo().hasVarSizedObjects();
}
// hasFP - Return true if the specified function should have a dedicated frame
// pointer register. This is true if the function has variable sized allocas or
// if frame pointer elimination is disabled.
bool SparcFrameLowering::hasFP(const MachineFunction &MF) const {
// hasFPImpl - Return true if the specified function should have a dedicated
// frame pointer register. This is true if the function has variable sized
// allocas or if frame pointer elimination is disabled.
bool SparcFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
const MachineFrameInfo &MFI = MF.getFrameInfo();

View File

@ -35,7 +35,6 @@ public:
MachineBasicBlock::iterator I) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool hasFP(const MachineFunction &MF) const override;
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS = nullptr) const override;
@ -47,6 +46,9 @@ public:
/// time).
bool targetHandlesStackFrameRounding() const override { return true; }
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
private:
// Remap input registers to output registers for leaf procedure.
void remapRegsForLeafProc(MachineFunction &MF) const;

View File

@ -832,7 +832,7 @@ void SystemZELFFrameLowering::inlineStackProbe(
}
}
bool SystemZELFFrameLowering::hasFP(const MachineFunction &MF) const {
bool SystemZELFFrameLowering::hasFPImpl(const MachineFunction &MF) const {
return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
MF.getFrameInfo().hasVarSizedObjects());
}
@ -1449,7 +1449,12 @@ void SystemZXPLINKFrameLowering::inlineStackProbe(
fullyRecomputeLiveIns({StackExtMBB, NextMBB});
}
bool SystemZXPLINKFrameLowering::hasFP(const MachineFunction &MF) const {
bool SystemZXPLINKFrameLowering::hasFPImpl(const MachineFunction &MF) const {
// Naked functions have no stack frame pushed, so we don't have a frame
// pointer.
if (MF.getFunction().hasFnAttribute(Attribute::Naked))
return false;
return (MF.getFrameInfo().hasVarSizedObjects());
}

View File

@ -86,7 +86,6 @@ public:
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void inlineStackProbe(MachineFunction &MF,
MachineBasicBlock &PrologMBB) const override;
bool hasFP(const MachineFunction &MF) const override;
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,
Register &FrameReg) const override;
void
@ -113,6 +112,9 @@ public:
// Get or create the frame index of where the old frame pointer is stored.
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
};
class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
@ -147,8 +149,6 @@ public:
void inlineStackProbe(MachineFunction &MF,
MachineBasicBlock &PrologMBB) const override;
bool hasFP(const MachineFunction &MF) const override;
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS) const override;
@ -167,6 +167,9 @@ public:
// Get or create the frame index of where the old frame pointer is stored.
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
};
} // end namespace llvm

View File

@ -415,10 +415,10 @@ void VEFrameLowering::emitEpilogue(MachineFunction &MF,
emitEpilogueInsns(MF, MBB, MBBI, NumBytes, true);
}
// hasFP - Return true if the specified function should have a dedicated frame
// pointer register. This is true if the function has variable sized allocas
// or if frame pointer elimination is disabled.
bool VEFrameLowering::hasFP(const MachineFunction &MF) const {
// hasFPImpl - Return true if the specified function should have a dedicated
// frame pointer register. This is true if the function has variable sized
// allocas or if frame pointer elimination is disabled.
bool VEFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
const MachineFrameInfo &MFI = MF.getFrameInfo();

View File

@ -39,7 +39,6 @@ public:
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
bool hasFP(const MachineFunction &MF) const override;
bool hasBP(const MachineFunction &MF) const;
bool hasGOT(const MachineFunction &MF) const;
@ -69,6 +68,8 @@ public:
protected:
const VESubtarget &STI;
bool hasFPImpl(const MachineFunction &MF) const override;
private:
// Returns true if MF is a leaf procedure.
bool isLeafProc(MachineFunction &MF) const;

View File

@ -98,7 +98,7 @@ bool WebAssemblyFrameLowering::hasBP(const MachineFunction &MF) const {
/// Return true if the specified function should have a dedicated frame pointer
/// register.
bool WebAssemblyFrameLowering::hasFP(const MachineFunction &MF) const {
bool WebAssemblyFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
// When we have var-sized objects, we move the stack pointer by an unknown

View File

@ -41,7 +41,6 @@ public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool isSupportedStackID(TargetStackID::Value ID) const override;
DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const override;
@ -68,6 +67,9 @@ public:
static unsigned getOpcGlobGet(const MachineFunction &MF);
static unsigned getOpcGlobSet(const MachineFunction &MF);
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
private:
bool hasBP(const MachineFunction &MF) const;
bool needsSPForLocalFrame(const MachineFunction &MF) const;

View File

@ -91,10 +91,10 @@ bool X86FrameLowering::needsFrameIndexResolution(
MF.getInfo<X86MachineFunctionInfo>()->getHasPushSequences();
}
/// hasFP - Return true if the specified function should have a dedicated frame
/// pointer register. This is true if the function has variable sized allocas
/// or if frame pointer elimination is disabled.
bool X86FrameLowering::hasFP(const MachineFunction &MF) const {
/// hasFPImpl - Return true if the specified function should have a dedicated
/// frame pointer register. This is true if the function has variable sized
/// allocas or if frame pointer elimination is disabled.
bool X86FrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
TRI->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||

View File

@ -105,7 +105,6 @@ public:
void spillFPBP(MachineFunction &MF) const override;
bool hasFP(const MachineFunction &MF) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
bool needsFrameIndexResolution(const MachineFunction &MF) const override;
@ -201,6 +200,9 @@ public:
/// frame of the top of stack function) as part of it's ABI.
bool has128ByteRedZone(const MachineFunction& MF) const;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
private:
bool isWin64Prologue(const MachineFunction &MF) const;

View File

@ -215,7 +215,7 @@ XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti)
// Do nothing
}
bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const {
bool XCoreFrameLowering::hasFPImpl(const MachineFunction &MF) const {
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
MF.getFrameInfo().hasVarSizedObjects();
}

View File

@ -46,8 +46,6 @@ namespace llvm {
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const override;
bool hasFP(const MachineFunction &MF) const override;
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS = nullptr) const override;
@ -58,6 +56,9 @@ namespace llvm {
static int stackSlotSize() {
return 4;
}
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
};
}

View File

@ -27,7 +27,7 @@ XtensaFrameLowering::XtensaFrameLowering(const XtensaSubtarget &STI)
Align(4)),
TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
bool XtensaFrameLowering::hasFP(const MachineFunction &MF) const {
bool XtensaFrameLowering::hasFPImpl(const MachineFunction &MF) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
MFI.hasVarSizedObjects();

View File

@ -24,8 +24,6 @@ class XtensaFrameLowering : public TargetFrameLowering {
public:
XtensaFrameLowering(const XtensaSubtarget &STI);
bool hasFP(const MachineFunction &MF) const override;
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function.
void emitPrologue(MachineFunction &, MachineBasicBlock &) const override;
@ -50,6 +48,9 @@ public:
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS) const override;
protected:
bool hasFPImpl(const MachineFunction &MF) const override;
};
} // namespace llvm

View File

@ -0,0 +1,39 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple aarch64 | FileCheck %s -check-prefixes=CHECK-LE
; RUN: llc < %s -mtriple aarch64_be | FileCheck %s -check-prefixes=CHECK-BE
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LE-LABEL: naked:
; CHECK-LE: // %bb.0:
; CHECK-LE-NEXT: bl main
;
; CHECK-BE-LABEL: naked:
; CHECK-BE: // %bb.0:
; CHECK-BE-NEXT: bl main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LE-LABEL: normal:
; CHECK-LE: // %bb.0:
; CHECK-LE-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
; CHECK-LE-NEXT: mov x29, sp
; CHECK-LE-NEXT: .cfi_def_cfa w29, 16
; CHECK-LE-NEXT: .cfi_offset w30, -8
; CHECK-LE-NEXT: .cfi_offset w29, -16
; CHECK-LE-NEXT: bl main
;
; CHECK-BE-LABEL: normal:
; CHECK-BE: // %bb.0:
; CHECK-BE-NEXT: stp x29, x30, [sp, #-16]! // 16-byte Folded Spill
; CHECK-BE-NEXT: mov x29, sp
; CHECK-BE-NEXT: .cfi_def_cfa w29, 16
; CHECK-BE-NEXT: .cfi_offset w30, -8
; CHECK-BE-NEXT: .cfi_offset w29, -16
; CHECK-BE-NEXT: bl main
call void @main()
unreachable
}

View File

@ -0,0 +1,42 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple amdgcn | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: naked$local:
; CHECK-NEXT: .type naked$local,@function
; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT: s_getpc_b64 s[16:17]
; CHECK-NEXT: s_add_u32 s16, s16, main@rel32@lo+4
; CHECK-NEXT: s_addc_u32 s17, s17, main@rel32@hi+12
; CHECK-NEXT: s_swappc_b64 s[30:31], s[16:17]
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: normal$local:
; CHECK-NEXT: .type normal$local,@function
; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; CHECK-NEXT: s_mov_b32 s16, s33
; CHECK-NEXT: s_mov_b32 s33, s32
; CHECK-NEXT: s_or_saveexec_b64 s[18:19], -1
; CHECK-NEXT: buffer_store_dword v40, off, s[0:3], s33 ; 4-byte Folded Spill
; CHECK-NEXT: s_mov_b64 exec, s[18:19]
; CHECK-NEXT: s_waitcnt expcnt(0)
; CHECK-NEXT: v_writelane_b32 v40, s16, 2
; CHECK-NEXT: s_addk_i32 s32, 0x400
; CHECK-NEXT: v_writelane_b32 v40, s30, 0
; CHECK-NEXT: v_writelane_b32 v40, s31, 1
; CHECK-NEXT: s_getpc_b64 s[16:17]
; CHECK-NEXT: s_add_u32 s16, s16, main@rel32@lo+4
; CHECK-NEXT: s_addc_u32 s17, s17, main@rel32@hi+12
; CHECK-NEXT: s_swappc_b64 s[30:31], s[16:17]
call void @main()
unreachable
}

View File

@ -0,0 +1,55 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple arm | FileCheck %s -check-prefixes=CHECK-ALE
; RUN: llc < %s -mtriple armeb | FileCheck %s -check-prefixes=CHECK-ABE
; RUN: llc < %s -mtriple thumb | FileCheck %s -check-prefixes=CHECK-TLE
; RUN: llc < %s -mtriple thumbeb | FileCheck %s -check-prefixes=CHECK-TBE
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-ALE-LABEL: naked:
; CHECK-ALE: @ %bb.0:
; CHECK-ALE-NEXT: bl main
;
; CHECK-ABE-LABEL: naked:
; CHECK-ABE: @ %bb.0:
; CHECK-ABE-NEXT: bl main
;
; CHECK-TLE-LABEL: naked:
; CHECK-TLE: @ %bb.0:
; CHECK-TLE-NEXT: bl main
;
; CHECK-TBE-LABEL: naked:
; CHECK-TBE: @ %bb.0:
; CHECK-TBE-NEXT: bl main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-ALE-LABEL: normal:
; CHECK-ALE: @ %bb.0:
; CHECK-ALE-NEXT: push {r11, lr}
; CHECK-ALE-NEXT: mov r11, sp
; CHECK-ALE-NEXT: bl main
;
; CHECK-ABE-LABEL: normal:
; CHECK-ABE: @ %bb.0:
; CHECK-ABE-NEXT: push {r11, lr}
; CHECK-ABE-NEXT: mov r11, sp
; CHECK-ABE-NEXT: bl main
;
; CHECK-TLE-LABEL: normal:
; CHECK-TLE: @ %bb.0:
; CHECK-TLE-NEXT: push {r7, lr}
; CHECK-TLE-NEXT: add r7, sp, #0
; CHECK-TLE-NEXT: bl main
;
; CHECK-TBE-LABEL: normal:
; CHECK-TBE: @ %bb.0:
; CHECK-TBE-NEXT: push {r7, lr}
; CHECK-TBE-NEXT: add r7, sp, #0
; CHECK-TBE-NEXT: bl main
call void @main()
unreachable
}

View File

@ -0,0 +1,20 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple avr | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: ; %bb.0:
; CHECK-NEXT: rcall main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: ; %bb.0:
; CHECK-NEXT: rcall main
call void @main()
unreachable
}

View File

@ -0,0 +1,41 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple bpfel | FileCheck %s -check-prefixes=CHECK-LE
; RUN: llc < %s -mtriple bpfeb | FileCheck %s -check-prefixes=CHECK-BE
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LE-LABEL: naked:
; CHECK-LE: .Lnaked$local:
; CHECK-LE-NEXT: .type .Lnaked$local,@function
; CHECK-LE-NEXT: .cfi_startproc
; CHECK-LE-NEXT: # %bb.0:
; CHECK-LE-NEXT: call main
;
; CHECK-BE-LABEL: naked:
; CHECK-BE: .Lnaked$local:
; CHECK-BE-NEXT: .type .Lnaked$local,@function
; CHECK-BE-NEXT: .cfi_startproc
; CHECK-BE-NEXT: # %bb.0:
; CHECK-BE-NEXT: call main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LE-LABEL: normal:
; CHECK-LE: .Lnormal$local:
; CHECK-LE-NEXT: .type .Lnormal$local,@function
; CHECK-LE-NEXT: .cfi_startproc
; CHECK-LE-NEXT: # %bb.0:
; CHECK-LE-NEXT: call main
;
; CHECK-BE-LABEL: normal:
; CHECK-BE: .Lnormal$local:
; CHECK-BE-NEXT: .type .Lnormal$local,@function
; CHECK-BE-NEXT: .cfi_startproc
; CHECK-BE-NEXT: # %bb.0:
; CHECK-BE-NEXT: call main
call void @main()
unreachable
}

View File

@ -0,0 +1,41 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple csky | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: # %bb.0:
; CHECK-NEXT: lrw a0, [.LCPI0_0]
; CHECK-NEXT: jsr16 a0
; CHECK-NEXT: .p2align 1
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: .p2align 2, 0x0
; CHECK-NEXT: .LCPI0_0:
; CHECK-NEXT: .long main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: # %bb.0:
; CHECK-NEXT: subi16 sp, sp, 8
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: st32.w lr, (sp, 4) # 4-byte Folded Spill
; CHECK-NEXT: st32.w l4, (sp, 0) # 4-byte Folded Spill
; CHECK-NEXT: .cfi_offset lr, -4
; CHECK-NEXT: .cfi_offset l4, -8
; CHECK-NEXT: mov16 l4, sp
; CHECK-NEXT: .cfi_def_cfa_register l4
; CHECK-NEXT: subi16 sp, sp, 4
; CHECK-NEXT: lrw a0, [.LCPI1_0]
; CHECK-NEXT: jsr16 a0
; CHECK-NEXT: .p2align 1
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: .p2align 2, 0x0
; CHECK-NEXT: .LCPI1_0:
; CHECK-NEXT: .long main
call void @main()
unreachable
}

View File

@ -0,0 +1,30 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple hexagon | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: {
; CHECK-NEXT: call main
; CHECK-NEXT: }
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: .cfi_def_cfa r30, 8
; CHECK-NEXT: .cfi_offset r31, -4
; CHECK-NEXT: .cfi_offset r30, -8
; CHECK-NEXT: {
; CHECK-NEXT: call main
; CHECK-NEXT: allocframe(r29,#0):raw
; CHECK-NEXT: }
call void @main()
unreachable
}

View File

@ -0,0 +1,35 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple lanai | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: .Lnaked$local:
; CHECK-NEXT: .type .Lnaked$local,@function
; CHECK-NEXT: .cfi_startproc
; CHECK-NEXT: ! %bb.0:
; CHECK-NEXT: add %pc, 0x10, %rca
; CHECK-NEXT: st %rca, [--%sp]
; CHECK-NEXT: bt main
; CHECK-NEXT: nop
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: .Lnormal$local:
; CHECK-NEXT: .type .Lnormal$local,@function
; CHECK-NEXT: .cfi_startproc
; CHECK-NEXT: ! %bb.0:
; CHECK-NEXT: st %fp, [--%sp]
; CHECK-NEXT: add %sp, 0x8, %fp
; CHECK-NEXT: sub %sp, 0x8, %sp
; CHECK-NEXT: add %pc, 0x10, %rca
; CHECK-NEXT: st %rca, [--%sp]
; CHECK-NEXT: bt main
; CHECK-NEXT: nop
call void @main()
unreachable
}

View File

@ -0,0 +1,45 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple loongarch32 -mattr +d | FileCheck %s -check-prefixes=CHECK-32
; RUN: llc < %s -mtriple loongarch64 -mattr +d | FileCheck %s -check-prefixes=CHECK-64
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-32-LABEL: naked:
; CHECK-32: # %bb.0:
; CHECK-32-NEXT: bl main
;
; CHECK-64-LABEL: naked:
; CHECK-64: # %bb.0:
; CHECK-64-NEXT: bl main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-32-LABEL: normal:
; CHECK-32: # %bb.0:
; CHECK-32-NEXT: addi.w $sp, $sp, -16
; CHECK-32-NEXT: .cfi_def_cfa_offset 16
; CHECK-32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
; CHECK-32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill
; CHECK-32-NEXT: .cfi_offset 1, -4
; CHECK-32-NEXT: .cfi_offset 22, -8
; CHECK-32-NEXT: addi.w $fp, $sp, 16
; CHECK-32-NEXT: .cfi_def_cfa 22, 0
; CHECK-32-NEXT: bl main
;
; CHECK-64-LABEL: normal:
; CHECK-64: # %bb.0:
; CHECK-64-NEXT: addi.d $sp, $sp, -16
; CHECK-64-NEXT: .cfi_def_cfa_offset 16
; CHECK-64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
; CHECK-64-NEXT: st.d $fp, $sp, 0 # 8-byte Folded Spill
; CHECK-64-NEXT: .cfi_offset 1, -8
; CHECK-64-NEXT: .cfi_offset 22, -16
; CHECK-64-NEXT: addi.d $fp, $sp, 16
; CHECK-64-NEXT: .cfi_def_cfa 22, 0
; CHECK-64-NEXT: bl main
call void @main()
unreachable
}

View File

@ -0,0 +1,26 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple m68k | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: .cfi_startproc
; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: jsr main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: .cfi_startproc
; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: link.w %a6, #0
; CHECK-NEXT: .cfi_def_cfa_offset -8
; CHECK-NEXT: .cfi_offset %a6, -8
; CHECK-NEXT: .cfi_def_cfa_register %a6
; CHECK-NEXT: jsr main
call void @main()
unreachable
}

View File

@ -0,0 +1,27 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple msp430 | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: .cfi_startproc
; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: call #main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: .cfi_startproc
; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: push r4
; CHECK-NEXT: .cfi_def_cfa_offset 4
; CHECK-NEXT: .cfi_offset r4, -4
; CHECK-NEXT: mov r1, r4
; CHECK-NEXT: .cfi_def_cfa_register r4
; CHECK-NEXT: call #main
call void @main()
unreachable
}

View File

@ -0,0 +1,87 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple mips | FileCheck %s -check-prefixes=CHECK-32-BE
; RUN: llc < %s -mtriple mipsel | FileCheck %s -check-prefixes=CHECK-32-LE
; RUN: llc < %s -mtriple mips64 | FileCheck %s -check-prefixes=CHECK-64-BE
; RUN: llc < %s -mtriple mips64el | FileCheck %s -check-prefixes=CHECK-64-LE
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-32-BE-LABEL: naked:
; CHECK-32-BE: # %bb.0:
; CHECK-32-BE-NEXT: jal main
; CHECK-32-BE-NEXT: nop
;
; CHECK-32-LE-LABEL: naked:
; CHECK-32-LE: # %bb.0:
; CHECK-32-LE-NEXT: jal main
; CHECK-32-LE-NEXT: nop
;
; CHECK-64-BE-LABEL: naked:
; CHECK-64-BE: # %bb.0:
; CHECK-64-BE-NEXT: jal main
; CHECK-64-BE-NEXT: nop
;
; CHECK-64-LE-LABEL: naked:
; CHECK-64-LE: # %bb.0:
; CHECK-64-LE-NEXT: jal main
; CHECK-64-LE-NEXT: nop
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-32-BE-LABEL: normal:
; CHECK-32-BE: # %bb.0:
; CHECK-32-BE-NEXT: addiu $sp, $sp, -24
; CHECK-32-BE-NEXT: .cfi_def_cfa_offset 24
; CHECK-32-BE-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
; CHECK-32-BE-NEXT: sw $fp, 16($sp) # 4-byte Folded Spill
; CHECK-32-BE-NEXT: .cfi_offset 31, -4
; CHECK-32-BE-NEXT: .cfi_offset 30, -8
; CHECK-32-BE-NEXT: move $fp, $sp
; CHECK-32-BE-NEXT: .cfi_def_cfa_register 30
; CHECK-32-BE-NEXT: jal main
; CHECK-32-BE-NEXT: nop
;
; CHECK-32-LE-LABEL: normal:
; CHECK-32-LE: # %bb.0:
; CHECK-32-LE-NEXT: addiu $sp, $sp, -24
; CHECK-32-LE-NEXT: .cfi_def_cfa_offset 24
; CHECK-32-LE-NEXT: sw $ra, 20($sp) # 4-byte Folded Spill
; CHECK-32-LE-NEXT: sw $fp, 16($sp) # 4-byte Folded Spill
; CHECK-32-LE-NEXT: .cfi_offset 31, -4
; CHECK-32-LE-NEXT: .cfi_offset 30, -8
; CHECK-32-LE-NEXT: move $fp, $sp
; CHECK-32-LE-NEXT: .cfi_def_cfa_register 30
; CHECK-32-LE-NEXT: jal main
; CHECK-32-LE-NEXT: nop
;
; CHECK-64-BE-LABEL: normal:
; CHECK-64-BE: # %bb.0:
; CHECK-64-BE-NEXT: daddiu $sp, $sp, -16
; CHECK-64-BE-NEXT: .cfi_def_cfa_offset 16
; CHECK-64-BE-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
; CHECK-64-BE-NEXT: sd $fp, 0($sp) # 8-byte Folded Spill
; CHECK-64-BE-NEXT: .cfi_offset 31, -8
; CHECK-64-BE-NEXT: .cfi_offset 30, -16
; CHECK-64-BE-NEXT: move $fp, $sp
; CHECK-64-BE-NEXT: .cfi_def_cfa_register 30
; CHECK-64-BE-NEXT: jal main
; CHECK-64-BE-NEXT: nop
;
; CHECK-64-LE-LABEL: normal:
; CHECK-64-LE: # %bb.0:
; CHECK-64-LE-NEXT: daddiu $sp, $sp, -16
; CHECK-64-LE-NEXT: .cfi_def_cfa_offset 16
; CHECK-64-LE-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
; CHECK-64-LE-NEXT: sd $fp, 0($sp) # 8-byte Folded Spill
; CHECK-64-LE-NEXT: .cfi_offset 31, -8
; CHECK-64-LE-NEXT: .cfi_offset 30, -16
; CHECK-64-LE-NEXT: move $fp, $sp
; CHECK-64-LE-NEXT: .cfi_def_cfa_register 30
; CHECK-64-LE-NEXT: jal main
; CHECK-64-LE-NEXT: nop
call void @main()
unreachable
}

View File

@ -0,0 +1,73 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple nvptx | FileCheck %s -check-prefixes=CHECK-32
; RUN: llc < %s -mtriple nvptx64 | FileCheck %s -check-prefixes=CHECK-64
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-32-LABEL: naked(
; CHECK-32: {
; CHECK-32-EMPTY:
; CHECK-32-EMPTY:
; CHECK-32-NEXT: // %bb.0:
; CHECK-32-NEXT: { // callseq 0, 0
; CHECK-32-NEXT: call.uni
; CHECK-32-NEXT: main,
; CHECK-32-NEXT: (
; CHECK-32-NEXT: );
; CHECK-32-NEXT: } // callseq 0
; CHECK-32-NEXT: // begin inline asm
; CHECK-32-NEXT: exit;
; CHECK-32-NEXT: // end inline asm
;
; CHECK-64-LABEL: naked(
; CHECK-64: {
; CHECK-64-EMPTY:
; CHECK-64-EMPTY:
; CHECK-64-NEXT: // %bb.0:
; CHECK-64-NEXT: { // callseq 0, 0
; CHECK-64-NEXT: call.uni
; CHECK-64-NEXT: main,
; CHECK-64-NEXT: (
; CHECK-64-NEXT: );
; CHECK-64-NEXT: } // callseq 0
; CHECK-64-NEXT: // begin inline asm
; CHECK-64-NEXT: exit;
; CHECK-64-NEXT: // end inline asm
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-32-LABEL: normal(
; CHECK-32: {
; CHECK-32-EMPTY:
; CHECK-32-EMPTY:
; CHECK-32-NEXT: // %bb.0:
; CHECK-32-NEXT: { // callseq 1, 0
; CHECK-32-NEXT: call.uni
; CHECK-32-NEXT: main,
; CHECK-32-NEXT: (
; CHECK-32-NEXT: );
; CHECK-32-NEXT: } // callseq 1
; CHECK-32-NEXT: // begin inline asm
; CHECK-32-NEXT: exit;
; CHECK-32-NEXT: // end inline asm
;
; CHECK-64-LABEL: normal(
; CHECK-64: {
; CHECK-64-EMPTY:
; CHECK-64-EMPTY:
; CHECK-64-NEXT: // %bb.0:
; CHECK-64-NEXT: { // callseq 1, 0
; CHECK-64-NEXT: call.uni
; CHECK-64-NEXT: main,
; CHECK-64-NEXT: (
; CHECK-64-NEXT: );
; CHECK-64-NEXT: } // callseq 1
; CHECK-64-NEXT: // begin inline asm
; CHECK-64-NEXT: exit;
; CHECK-64-NEXT: // end inline asm
call void @main()
unreachable
}

View File

@ -0,0 +1,87 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple powerpc | FileCheck %s -check-prefixes=CHECK-32-BE
; RUN: llc < %s -mtriple powerpcle | FileCheck %s -check-prefixes=CHECK-32-LE
; RUN: llc < %s -mtriple powerpc64 | FileCheck %s -check-prefixes=CHECK-64-BE
; RUN: llc < %s -mtriple powerpc64le | FileCheck %s -check-prefixes=CHECK-64-LE
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-32-BE-LABEL: naked:
; CHECK-32-BE: # %bb.0:
; CHECK-32-BE-NEXT: bl main
;
; CHECK-32-LE-LABEL: naked:
; CHECK-32-LE: # %bb.0:
; CHECK-32-LE-NEXT: bl main
;
; CHECK-64-BE-LABEL: naked:
; CHECK-64-BE: # %bb.0:
; CHECK-64-BE-NEXT: bl main
; CHECK-64-BE-NEXT: nop
;
; CHECK-64-LE-LABEL: naked:
; CHECK-64-LE: # %bb.0:
; CHECK-64-LE-NEXT: bl main
; CHECK-64-LE-NEXT: nop
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-32-BE-LABEL: normal:
; CHECK-32-BE: # %bb.0:
; CHECK-32-BE-NEXT: mflr 0
; CHECK-32-BE-NEXT: stwu 1, -16(1)
; CHECK-32-BE-NEXT: stw 31, 12(1)
; CHECK-32-BE-NEXT: stw 0, 20(1)
; CHECK-32-BE-NEXT: .cfi_def_cfa_offset 16
; CHECK-32-BE-NEXT: .cfi_offset r31, -4
; CHECK-32-BE-NEXT: .cfi_offset lr, 4
; CHECK-32-BE-NEXT: mr 31, 1
; CHECK-32-BE-NEXT: .cfi_def_cfa_register r31
; CHECK-32-BE-NEXT: bl main
;
; CHECK-32-LE-LABEL: normal:
; CHECK-32-LE: # %bb.0:
; CHECK-32-LE-NEXT: mflr 0
; CHECK-32-LE-NEXT: stwu 1, -16(1)
; CHECK-32-LE-NEXT: stw 31, 12(1)
; CHECK-32-LE-NEXT: stw 0, 20(1)
; CHECK-32-LE-NEXT: .cfi_def_cfa_offset 16
; CHECK-32-LE-NEXT: .cfi_offset r31, -4
; CHECK-32-LE-NEXT: .cfi_offset lr, 4
; CHECK-32-LE-NEXT: mr 31, 1
; CHECK-32-LE-NEXT: .cfi_def_cfa_register r31
; CHECK-32-LE-NEXT: bl main
;
; CHECK-64-BE-LABEL: normal:
; CHECK-64-BE: # %bb.0:
; CHECK-64-BE-NEXT: mflr 0
; CHECK-64-BE-NEXT: std 31, -8(1)
; CHECK-64-BE-NEXT: stdu 1, -128(1)
; CHECK-64-BE-NEXT: std 0, 144(1)
; CHECK-64-BE-NEXT: .cfi_def_cfa_offset 128
; CHECK-64-BE-NEXT: .cfi_offset r31, -8
; CHECK-64-BE-NEXT: .cfi_offset lr, 16
; CHECK-64-BE-NEXT: mr 31, 1
; CHECK-64-BE-NEXT: .cfi_def_cfa_register r31
; CHECK-64-BE-NEXT: bl main
; CHECK-64-BE-NEXT: nop
;
; CHECK-64-LE-LABEL: normal:
; CHECK-64-LE: # %bb.0:
; CHECK-64-LE-NEXT: mflr 0
; CHECK-64-LE-NEXT: std 31, -8(1)
; CHECK-64-LE-NEXT: stdu 1, -48(1)
; CHECK-64-LE-NEXT: std 0, 64(1)
; CHECK-64-LE-NEXT: .cfi_def_cfa_offset 48
; CHECK-64-LE-NEXT: .cfi_offset r31, -8
; CHECK-64-LE-NEXT: .cfi_offset lr, 16
; CHECK-64-LE-NEXT: mr 31, 1
; CHECK-64-LE-NEXT: .cfi_def_cfa_register r31
; CHECK-64-LE-NEXT: bl main
; CHECK-64-LE-NEXT: nop
call void @main()
unreachable
}

View File

@ -0,0 +1,45 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple riscv32 | FileCheck %s -check-prefixes=CHECK-32
; RUN: llc < %s -mtriple riscv64 | FileCheck %s -check-prefixes=CHECK-64
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-32-LABEL: naked:
; CHECK-32: # %bb.0:
; CHECK-32-NEXT: call main
;
; CHECK-64-LABEL: naked:
; CHECK-64: # %bb.0:
; CHECK-64-NEXT: call main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-32-LABEL: normal:
; CHECK-32: # %bb.0:
; CHECK-32-NEXT: addi sp, sp, -16
; CHECK-32-NEXT: .cfi_def_cfa_offset 16
; CHECK-32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; CHECK-32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
; CHECK-32-NEXT: .cfi_offset ra, -4
; CHECK-32-NEXT: .cfi_offset s0, -8
; CHECK-32-NEXT: addi s0, sp, 16
; CHECK-32-NEXT: .cfi_def_cfa s0, 0
; CHECK-32-NEXT: call main
;
; CHECK-64-LABEL: normal:
; CHECK-64: # %bb.0:
; CHECK-64-NEXT: addi sp, sp, -16
; CHECK-64-NEXT: .cfi_def_cfa_offset 16
; CHECK-64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
; CHECK-64-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
; CHECK-64-NEXT: .cfi_offset ra, -8
; CHECK-64-NEXT: .cfi_offset s0, -16
; CHECK-64-NEXT: addi s0, sp, 16
; CHECK-64-NEXT: .cfi_def_cfa s0, 0
; CHECK-64-NEXT: call main
call void @main()
unreachable
}

View File

@ -0,0 +1,45 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple sparc | FileCheck %s -check-prefixes=CHECK-32
; RUN: llc < %s -mtriple sparc64 | FileCheck %s -check-prefixes=CHECK-64
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-32-LABEL: naked:
; CHECK-32: .cfi_startproc
; CHECK-32-NEXT: ! %bb.0:
; CHECK-32-NEXT: call main
; CHECK-32-NEXT: nop
;
; CHECK-64-LABEL: naked:
; CHECK-64: .cfi_startproc
; CHECK-64-NEXT: ! %bb.0:
; CHECK-64-NEXT: call main
; CHECK-64-NEXT: nop
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-32-LABEL: normal:
; CHECK-32: .cfi_startproc
; CHECK-32-NEXT: ! %bb.0:
; CHECK-32-NEXT: save %sp, -96, %sp
; CHECK-32-NEXT: .cfi_def_cfa_register %fp
; CHECK-32-NEXT: .cfi_window_save
; CHECK-32-NEXT: .cfi_register %o7, %i7
; CHECK-32-NEXT: call main
; CHECK-32-NEXT: nop
;
; CHECK-64-LABEL: normal:
; CHECK-64: .cfi_startproc
; CHECK-64-NEXT: ! %bb.0:
; CHECK-64-NEXT: save %sp, -176, %sp
; CHECK-64-NEXT: .cfi_def_cfa_register %fp
; CHECK-64-NEXT: .cfi_window_save
; CHECK-64-NEXT: .cfi_register %o7, %i7
; CHECK-64-NEXT: call main
; CHECK-64-NEXT: nop
call void @main()
unreachable
}

View File

@ -0,0 +1,28 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple s390x | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: # %bb.0:
; CHECK-NEXT: brasl %r14, main@PLT
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: # %bb.0:
; CHECK-NEXT: stmg %r11, %r15, 88(%r15)
; CHECK-NEXT: .cfi_offset %r11, -72
; CHECK-NEXT: .cfi_offset %r14, -48
; CHECK-NEXT: .cfi_offset %r15, -40
; CHECK-NEXT: aghi %r15, -160
; CHECK-NEXT: .cfi_def_cfa_offset 320
; CHECK-NEXT: lgr %r11, %r15
; CHECK-NEXT: .cfi_def_cfa_register %r11
; CHECK-NEXT: brasl %r14, main@PLT
call void @main()
unreachable
}

View File

@ -0,0 +1,41 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple ve | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: # %bb.0:
; CHECK-NEXT: lea %s0, main@lo
; CHECK-NEXT: and %s0, %s0, (32)0
; CHECK-NEXT: lea.sl %s12, main@hi(, %s0)
; CHECK-NEXT: bsic %s10, (, %s12)
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: # %bb.0:
; CHECK-NEXT: st %s9, (, %s11)
; CHECK-NEXT: st %s10, 8(, %s11)
; CHECK-NEXT: or %s9, 0, %s11
; CHECK-NEXT: lea %s11, -240(, %s11)
; CHECK-NEXT: brge.l.t %s11, %s8, .LBB1_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: ld %s61, 24(, %s14)
; CHECK-NEXT: or %s62, 0, %s0
; CHECK-NEXT: lea %s63, 315
; CHECK-NEXT: shm.l %s63, (%s61)
; CHECK-NEXT: shm.l %s8, 8(%s61)
; CHECK-NEXT: shm.l %s11, 16(%s61)
; CHECK-NEXT: monc
; CHECK-NEXT: or %s0, 0, %s62
; CHECK-NEXT: .LBB1_2:
; CHECK-NEXT: lea %s0, main@lo
; CHECK-NEXT: and %s0, %s0, (32)0
; CHECK-NEXT: lea.sl %s12, main@hi(, %s0)
; CHECK-NEXT: bsic %s10, (, %s12)
call void @main()
unreachable
}

View File

@ -0,0 +1,37 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple wasm32 | FileCheck %s -check-prefixes=CHECK-32
; RUN: llc < %s -mtriple wasm64 | FileCheck %s -check-prefixes=CHECK-64
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-32-LABEL: naked:
; CHECK-32: .functype naked () -> ()
; CHECK-32-NEXT: # %bb.0:
; CHECK-32-NEXT: call main
; CHECK-32-NEXT: unreachable
;
; CHECK-64-LABEL: naked:
; CHECK-64: .functype naked () -> ()
; CHECK-64-NEXT: # %bb.0:
; CHECK-64-NEXT: call main
; CHECK-64-NEXT: unreachable
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-32-LABEL: normal:
; CHECK-32: .functype normal () -> ()
; CHECK-32-NEXT: # %bb.0:
; CHECK-32-NEXT: call main
; CHECK-32-NEXT: unreachable
;
; CHECK-64-LABEL: normal:
; CHECK-64: .functype normal () -> ()
; CHECK-64-NEXT: # %bb.0:
; CHECK-64-NEXT: call main
; CHECK-64-NEXT: unreachable
call void @main()
unreachable
}

View File

@ -0,0 +1,39 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple i386 | FileCheck %s -check-prefixes=CHECK-32
; RUN: llc < %s -mtriple x86_64 | FileCheck %s -check-prefixes=CHECK-64
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-32-LABEL: naked:
; CHECK-32: # %bb.0:
; CHECK-32-NEXT: calll main
;
; CHECK-64-LABEL: naked:
; CHECK-64: # %bb.0:
; CHECK-64-NEXT: callq main
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-32-LABEL: normal:
; CHECK-32: # %bb.0:
; CHECK-32-NEXT: pushl %ebp
; CHECK-32-NEXT: .cfi_def_cfa_offset 8
; CHECK-32-NEXT: .cfi_offset %ebp, -8
; CHECK-32-NEXT: movl %esp, %ebp
; CHECK-32-NEXT: .cfi_def_cfa_register %ebp
; CHECK-32-NEXT: calll main
;
; CHECK-64-LABEL: normal:
; CHECK-64: # %bb.0:
; CHECK-64-NEXT: pushq %rbp
; CHECK-64-NEXT: .cfi_def_cfa_offset 16
; CHECK-64-NEXT: .cfi_offset %rbp, -16
; CHECK-64-NEXT: movq %rsp, %rbp
; CHECK-64-NEXT: .cfi_def_cfa_register %rbp
; CHECK-64-NEXT: callq main
call void @main()
unreachable
}

View File

@ -0,0 +1,31 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -march xcore | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: # %bb.0:
; CHECK-NEXT: bl main
; CHECK-NEXT: .cc_bottom naked.function
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: # %bb.0:
; CHECK-NEXT: entsp 2
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: .cfi_offset 15, 0
; CHECK-NEXT: stw r10, sp[1] # 4-byte Folded Spill
; CHECK-NEXT: .cfi_offset 10, -4
; CHECK-NEXT: ldaw r10, sp[0]
; CHECK-NEXT: .cfi_def_cfa_register 10
; CHECK-NEXT: extsp 1
; CHECK-NEXT: bl main
; CHECK-NEXT: ldaw sp, sp[1]
; CHECK-NEXT: .cc_bottom normal.function
call void @main()
unreachable
}

View File

@ -0,0 +1,31 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -march xtensa | FileCheck %s -check-prefixes=CHECK
declare dso_local void @main()
define dso_local void @naked() naked "frame-pointer"="all" {
; CHECK-LABEL: naked:
; CHECK: # %bb.0:
; CHECK-NEXT: l32r a8, {{\.?LCPI[0-9]+_[0-9]+}}
; CHECK-NEXT: callx0 a8
call void @main()
unreachable
}
define dso_local void @normal() "frame-pointer"="all" {
; CHECK-LABEL: normal:
; CHECK: # %bb.0:
; CHECK-NEXT: addi a8, a1, -16
; CHECK-NEXT: or a1, a8, a8
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: s32i a0, a1, 4 # 4-byte Folded Spill
; CHECK-NEXT: s32i a15, a1, 0 # 4-byte Folded Spill
; CHECK-NEXT: .cfi_offset a0, -4
; CHECK-NEXT: .cfi_offset a15, -8
; CHECK-NEXT: or a15, a1, a1
; CHECK-NEXT: .cfi_def_cfa_register a15
; CHECK-NEXT: l32r a8, {{\.?LCPI[0-9]+_[0-9]+}}
; CHECK-NEXT: callx0 a8
call void @main()
unreachable
}

View File

@ -14,7 +14,9 @@ public:
MachineBasicBlock &MBB) const override {}
void emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const override {}
bool hasFP(const MachineFunction &MF) const override { return false; }
protected:
bool hasFPImpl(const MachineFunction &MF) const override { return false; }
};
static TargetRegisterClass *const BogusRegisterClasses[] = {nullptr};