[llvm] [llvm] Consistently respect `naked` fn attribute in `TargetFrameLowering::hasFP()` (PR #106014)
Alex Rønne Petersen via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 30 00:32:56 PDT 2024
https://github.com/alexrp updated https://github.com/llvm/llvm-project/pull/106014
>From c8a49e1698cf579588e294cb910b507d24af7fa2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= <alex at alexrp.com>
Date: Sun, 25 Aug 2024 23:30:31 +0200
Subject: [PATCH] [llvm] Consistently respect naked fn attribute in
TargetFrameLowering::hasFP().
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.
---
.../llvm/CodeGen/TargetFrameLowering.h | 9 +-
.../Target/AArch64/AArch64FrameLowering.cpp | 6 +-
.../lib/Target/AArch64/AArch64FrameLowering.h | 4 +-
llvm/lib/Target/AMDGPU/R600FrameLowering.h | 5 +-
llvm/lib/Target/AMDGPU/SIFrameLowering.cpp | 2 +-
llvm/lib/Target/AMDGPU/SIFrameLowering.h | 5 +-
llvm/lib/Target/ARC/ARCFrameLowering.cpp | 2 +-
llvm/lib/Target/ARC/ARCFrameLowering.h | 5 +-
llvm/lib/Target/ARM/ARMFrameLowering.cpp | 8 +-
llvm/lib/Target/ARM/ARMFrameLowering.h | 4 +-
llvm/lib/Target/AVR/AVRFrameLowering.cpp | 2 +-
llvm/lib/Target/AVR/AVRFrameLowering.h | 4 +-
llvm/lib/Target/BPF/BPFFrameLowering.cpp | 4 +-
llvm/lib/Target/BPF/BPFFrameLowering.h | 4 +-
llvm/lib/Target/CSKY/CSKYFrameLowering.cpp | 2 +-
llvm/lib/Target/CSKY/CSKYFrameLowering.h | 4 +-
.../lib/Target/DirectX/DirectXFrameLowering.h | 3 +-
.../Target/Hexagon/HexagonFrameLowering.cpp | 5 +-
.../lib/Target/Hexagon/HexagonFrameLowering.h | 4 +-
llvm/lib/Target/Lanai/LanaiFrameLowering.h | 5 +-
.../LoongArch/LoongArchFrameLowering.cpp | 2 +-
.../Target/LoongArch/LoongArchFrameLowering.h | 4 +-
llvm/lib/Target/M68k/M68kFrameLowering.cpp | 2 +-
llvm/lib/Target/M68k/M68kFrameLowering.h | 13 +--
.../lib/Target/MSP430/MSP430FrameLowering.cpp | 2 +-
llvm/lib/Target/MSP430/MSP430FrameLowering.h | 2 +-
llvm/lib/Target/Mips/MipsFrameLowering.cpp | 10 +--
llvm/lib/Target/Mips/MipsFrameLowering.h | 4 +-
llvm/lib/Target/NVPTX/NVPTXFrameLowering.cpp | 4 +-
llvm/lib/Target/NVPTX/NVPTXFrameLowering.h | 4 +-
llvm/lib/Target/PowerPC/PPCFrameLowering.cpp | 6 +-
llvm/lib/Target/PowerPC/PPCFrameLowering.h | 4 +-
llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 2 +-
llvm/lib/Target/RISCV/RISCVFrameLowering.h | 4 +-
llvm/lib/Target/SPIRV/SPIRVFrameLowering.h | 3 +-
llvm/lib/Target/Sparc/SparcFrameLowering.cpp | 8 +-
llvm/lib/Target/Sparc/SparcFrameLowering.h | 4 +-
.../Target/SystemZ/SystemZFrameLowering.cpp | 9 +-
.../lib/Target/SystemZ/SystemZFrameLowering.h | 9 +-
llvm/lib/Target/VE/VEFrameLowering.cpp | 8 +-
llvm/lib/Target/VE/VEFrameLowering.h | 3 +-
.../WebAssembly/WebAssemblyFrameLowering.cpp | 2 +-
.../WebAssembly/WebAssemblyFrameLowering.h | 4 +-
llvm/lib/Target/X86/X86FrameLowering.cpp | 8 +-
llvm/lib/Target/X86/X86FrameLowering.h | 4 +-
llvm/lib/Target/XCore/XCoreFrameLowering.cpp | 2 +-
llvm/lib/Target/XCore/XCoreFrameLowering.h | 5 +-
.../lib/Target/Xtensa/XtensaFrameLowering.cpp | 2 +-
llvm/lib/Target/Xtensa/XtensaFrameLowering.h | 5 +-
.../AArch64/naked-fn-with-frame-pointer.ll | 39 +++++++++
.../AMDGPU/naked-fn-with-frame-pointer.ll | 42 +++++++++
.../ARM/naked-fn-with-frame-pointer.ll | 55 ++++++++++++
.../AVR/naked-fn-with-frame-pointer.ll | 20 +++++
.../BPF/naked-fn-with-frame-pointer.ll | 41 +++++++++
.../CSKY/naked-fn-with-frame-pointer.ll | 41 +++++++++
.../Hexagon/naked-fn-with-frame-pointer.ll | 30 +++++++
.../Lanai/naked-fn-with-frame-pointer.ll | 35 ++++++++
.../LoongArch/naked-fn-with-frame-pointer.ll | 45 ++++++++++
.../M68k/naked-fn-with-frame-pointer.ll | 26 ++++++
.../MSP430/naked-fn-with-frame-pointer.ll | 27 ++++++
.../Mips/naked-fn-with-frame-pointer.ll | 87 +++++++++++++++++++
.../NVPTX/naked-fn-with-frame-pointer.ll | 73 ++++++++++++++++
.../PowerPC/naked-fn-with-frame-pointer.ll | 87 +++++++++++++++++++
.../RISCV/naked-fn-with-frame-pointer.ll | 45 ++++++++++
.../SPARC/naked-fn-with-frame-pointer.ll | 45 ++++++++++
.../SystemZ/naked-fn-with-frame-pointer.ll | 28 ++++++
.../CodeGen/VE/naked-fn-with-frame-pointer.ll | 41 +++++++++
.../naked-fn-with-frame-pointer.ll | 37 ++++++++
.../X86/naked-fn-with-frame-pointer.ll | 39 +++++++++
.../XCore/naked-fn-with-frame-pointer.ll | 31 +++++++
.../Xtensa/naked-fn-with-frame-pointer.ll | 31 +++++++
llvm/unittests/CodeGen/MFCommon.inc | 4 +-
72 files changed, 1085 insertions(+), 90 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/AMDGPU/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/ARM/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/AVR/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/BPF/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/CSKY/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/Hexagon/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/Lanai/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/LoongArch/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/M68k/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/MSP430/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/Mips/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/NVPTX/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/PowerPC/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/RISCV/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/SPARC/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/SystemZ/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/VE/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/WebAssembly/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/X86/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/XCore/naked-fn-with-frame-pointer.ll
create mode 100644 llvm/test/CodeGen/Xtensa/naked-fn-with-frame-pointer.ll
diff --git a/llvm/include/llvm/CodeGen/TargetFrameLowering.h b/llvm/include/llvm/CodeGen/TargetFrameLowering.h
index 3df9e56db38a43..38118b32d2f198 100644
--- a/llvm/include/llvm/CodeGen/TargetFrameLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetFrameLowering.h
@@ -286,7 +286,11 @@ class TargetFrameLowering {
/// 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
@@ -483,6 +487,9 @@ class TargetFrameLowering {
/// 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
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index ad20e76d0fe2e0..cde7fe0dc66cbf 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -475,9 +475,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();
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h
index c1973124962085..20445e63bcb13e 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.h
@@ -65,7 +65,6 @@ class AArch64FrameLowering : public TargetFrameLowering {
/// 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 @@ class AArch64FrameLowering : public TargetFrameLowering {
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
diff --git a/llvm/lib/Target/AMDGPU/R600FrameLowering.h b/llvm/lib/Target/AMDGPU/R600FrameLowering.h
index f171bc4fea781f..c4621174acaba1 100644
--- a/llvm/lib/Target/AMDGPU/R600FrameLowering.h
+++ b/llvm/lib/Target/AMDGPU/R600FrameLowering.h
@@ -27,9 +27,8 @@ class R600FrameLowering : public AMDGPUFrameLowering {
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
diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
index 8c951105101d96..eb504a2283523c 100644
--- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
@@ -1811,7 +1811,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,
diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.h b/llvm/lib/Target/AMDGPU/SIFrameLowering.h
index b3feb759ed811f..938c75099a3bc3 100644
--- a/llvm/lib/Target/AMDGPU/SIFrameLowering.h
+++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.h
@@ -66,6 +66,9 @@ class SIFrameLowering final : public AMDGPUFrameLowering {
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 @@ class SIFrameLowering final : public AMDGPUFrameLowering {
Register ScratchWaveOffsetReg) const;
public:
- bool hasFP(const MachineFunction &MF) const override;
-
bool requiresStackPointerReference(const MachineFunction &MF) const;
};
diff --git a/llvm/lib/Target/ARC/ARCFrameLowering.cpp b/llvm/lib/Target/ARC/ARCFrameLowering.cpp
index 1227fae13211a8..472f1c13f362e5 100644
--- a/llvm/lib/Target/ARC/ARCFrameLowering.cpp
+++ b/llvm/lib/Target/ARC/ARCFrameLowering.cpp
@@ -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() ||
diff --git a/llvm/lib/Target/ARC/ARCFrameLowering.h b/llvm/lib/Target/ARC/ARCFrameLowering.h
index 9951a09842c57f..089326fe32057e 100644
--- a/llvm/lib/Target/ARC/ARCFrameLowering.h
+++ b/llvm/lib/Target/ARC/ARCFrameLowering.h
@@ -54,8 +54,6 @@ class ARCFrameLowering : public TargetFrameLowering {
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 @@ class ARCFrameLowering : public TargetFrameLowering {
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,
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 40354f99559896..ad4c4d94a196a0 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -196,10 +196,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();
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
index 6a31b73957f134..f8b29501d21461 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
@@ -45,7 +45,6 @@ class ARMFrameLowering : public TargetFrameLowering {
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 @@ class ARMFrameLowering : public TargetFrameLowering {
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,
diff --git a/llvm/lib/Target/AVR/AVRFrameLowering.cpp b/llvm/lib/Target/AVR/AVRFrameLowering.cpp
index 64dd0338bf60ed..91b0f8c6b2df48 100644
--- a/llvm/lib/Target/AVR/AVRFrameLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRFrameLowering.cpp
@@ -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() ||
diff --git a/llvm/lib/Target/AVR/AVRFrameLowering.h b/llvm/lib/Target/AVR/AVRFrameLowering.h
index a550c0efbb8ef7..7baa5e9d62f60b 100644
--- a/llvm/lib/Target/AVR/AVRFrameLowering.h
+++ b/llvm/lib/Target/AVR/AVRFrameLowering.h
@@ -21,7 +21,6 @@ class AVRFrameLowering : public TargetFrameLowering {
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 @@ class AVRFrameLowering : public TargetFrameLowering {
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
+
+protected:
+ bool hasFPImpl(const MachineFunction &MF) const override;
};
} // end namespace llvm
diff --git a/llvm/lib/Target/BPF/BPFFrameLowering.cpp b/llvm/lib/Target/BPF/BPFFrameLowering.cpp
index 8812cfdd86da43..123b99f254234d 100644
--- a/llvm/lib/Target/BPF/BPFFrameLowering.cpp
+++ b/llvm/lib/Target/BPF/BPFFrameLowering.cpp
@@ -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 {}
diff --git a/llvm/lib/Target/BPF/BPFFrameLowering.h b/llvm/lib/Target/BPF/BPFFrameLowering.h
index a546351ec6cbbf..6beffcbe69dd0b 100644
--- a/llvm/lib/Target/BPF/BPFFrameLowering.h
+++ b/llvm/lib/Target/BPF/BPFFrameLowering.h
@@ -26,7 +26,6 @@ class BPFFrameLowering : public TargetFrameLowering {
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 @@ class BPFFrameLowering : public TargetFrameLowering {
MachineBasicBlock::iterator MI) const override {
return MBB.erase(MI);
}
+
+protected:
+ bool hasFPImpl(const MachineFunction &MF) const override;
};
}
#endif
diff --git a/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp b/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp
index cedcbff1db24fc..c023b5a0de5ad5 100644
--- a/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp
+++ b/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp
@@ -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();
diff --git a/llvm/lib/Target/CSKY/CSKYFrameLowering.h b/llvm/lib/Target/CSKY/CSKYFrameLowering.h
index 69bf01cf1801e5..0b3b287bb6a55b 100644
--- a/llvm/lib/Target/CSKY/CSKYFrameLowering.h
+++ b/llvm/lib/Target/CSKY/CSKYFrameLowering.h
@@ -61,7 +61,6 @@ class CSKYFrameLowering : public TargetFrameLowering {
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 @@ class CSKYFrameLowering : public TargetFrameLowering {
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
+
+protected:
+ bool hasFPImpl(const MachineFunction &MF) const override;
};
} // namespace llvm
#endif
diff --git a/llvm/lib/Target/DirectX/DirectXFrameLowering.h b/llvm/lib/Target/DirectX/DirectXFrameLowering.h
index 76a1450054be81..85823556d55504 100644
--- a/llvm/lib/Target/DirectX/DirectXFrameLowering.h
+++ b/llvm/lib/Target/DirectX/DirectXFrameLowering.h
@@ -29,7 +29,8 @@ class DirectXFrameLowering : public TargetFrameLowering {
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
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index 05357de40e3a93..afd777f1e9e79c 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -1141,10 +1141,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);
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
index 98e69dcc4b3915..926aadb01f50e5 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.h
@@ -89,7 +89,6 @@ class HexagonFrameLowering : public TargetFrameLowering {
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 @@ class HexagonFrameLowering : public TargetFrameLowering {
void insertCFIInstructions(MachineFunction &MF) const;
+protected:
+ bool hasFPImpl(const MachineFunction &MF) const override;
+
private:
using CSIVect = std::vector<CalleeSavedInfo>;
diff --git a/llvm/lib/Target/Lanai/LanaiFrameLowering.h b/llvm/lib/Target/Lanai/LanaiFrameLowering.h
index 380d63df7301ef..9bd78d008f77e3 100644
--- a/llvm/lib/Target/Lanai/LanaiFrameLowering.h
+++ b/llvm/lib/Target/Lanai/LanaiFrameLowering.h
@@ -44,10 +44,11 @@ class LanaiFrameLowering : public TargetFrameLowering {
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
diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
index 4e504729b23e2d..1a787c63c6241b 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
@@ -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();
diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h
index bc2ac02c91f814..6cbfcf665f6a93 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.h
@@ -49,13 +49,15 @@ class LoongArchFrameLowering : public TargetFrameLowering {
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,
diff --git a/llvm/lib/Target/M68k/M68kFrameLowering.cpp b/llvm/lib/Target/M68k/M68kFrameLowering.cpp
index 1445bac0b92e85..4245061f0ae749 100644
--- a/llvm/lib/Target/M68k/M68kFrameLowering.cpp
+++ b/llvm/lib/Target/M68k/M68kFrameLowering.cpp
@@ -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();
diff --git a/llvm/lib/Target/M68k/M68kFrameLowering.h b/llvm/lib/Target/M68k/M68kFrameLowering.h
index a5349377232eb6..ed2bfb605ff13a 100644
--- a/llvm/lib/Target/M68k/M68kFrameLowering.h
+++ b/llvm/lib/Target/M68k/M68kFrameLowering.h
@@ -121,12 +121,6 @@ class M68kFrameLowering : public TargetFrameLowering {
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 @@ class M68kFrameLowering : public TargetFrameLowering {
/// 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
diff --git a/llvm/lib/Target/MSP430/MSP430FrameLowering.cpp b/llvm/lib/Target/MSP430/MSP430FrameLowering.cpp
index d0dc6dd146efdb..045dedfb385385 100644
--- a/llvm/lib/Target/MSP430/MSP430FrameLowering.cpp
+++ b/llvm/lib/Target/MSP430/MSP430FrameLowering.cpp
@@ -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) ||
diff --git a/llvm/lib/Target/MSP430/MSP430FrameLowering.h b/llvm/lib/Target/MSP430/MSP430FrameLowering.h
index 5227d3e731edb3..daa4eec998ee87 100644
--- a/llvm/lib/Target/MSP430/MSP430FrameLowering.h
+++ b/llvm/lib/Target/MSP430/MSP430FrameLowering.h
@@ -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 @@ class MSP430FrameLowering : public TargetFrameLowering {
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;
diff --git a/llvm/lib/Target/Mips/MipsFrameLowering.cpp b/llvm/lib/Target/Mips/MipsFrameLowering.cpp
index 99d225f9abfe89..9b3edcd61ae1e2 100644
--- a/llvm/lib/Target/Mips/MipsFrameLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsFrameLowering.cpp
@@ -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();
diff --git a/llvm/lib/Target/Mips/MipsFrameLowering.h b/llvm/lib/Target/Mips/MipsFrameLowering.h
index 710a3d40c38efc..25adc33fbf5cab 100644
--- a/llvm/lib/Target/Mips/MipsFrameLowering.h
+++ b/llvm/lib/Target/Mips/MipsFrameLowering.h
@@ -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 @@ class MipsFrameLowering : public TargetFrameLowering {
static const MipsFrameLowering *create(const MipsSubtarget &ST);
- bool hasFP(const MachineFunction &MF) const override;
-
bool hasBP(const MachineFunction &MF) const;
bool allocateScavengingFrameIndexesNearIncomingSP(
diff --git a/llvm/lib/Target/NVPTX/NVPTXFrameLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXFrameLowering.cpp
index 9abe0e3186f200..a5f6cab421fb7e 100644
--- a/llvm/lib/Target/NVPTX/NVPTXFrameLowering.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXFrameLowering.cpp
@@ -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 {
diff --git a/llvm/lib/Target/NVPTX/NVPTXFrameLowering.h b/llvm/lib/Target/NVPTX/NVPTXFrameLowering.h
index a5d49ac3ab2930..f8d1f978327bc0 100644
--- a/llvm/lib/Target/NVPTX/NVPTXFrameLowering.h
+++ b/llvm/lib/Target/NVPTX/NVPTXFrameLowering.h
@@ -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 @@ class NVPTXFrameLowering : public TargetFrameLowering {
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
diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index a57ed33bda9c77..e8ca7cb77e05d9 100644
--- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -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
diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.h b/llvm/lib/Target/PowerPC/PPCFrameLowering.h
index d74c87428326ca..47f249862946f3 100644
--- a/llvm/lib/Target/PowerPC/PPCFrameLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.h
@@ -107,7 +107,6 @@ class PPCFrameLowering: public TargetFrameLowering {
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 @@ class PPCFrameLowering: public TargetFrameLowering {
void updateCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const;
uint64_t getStackThreshold() const override;
+
+protected:
+ bool hasFPImpl(const MachineFunction &MF) const override;
};
} // End llvm namespace
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 7abd5a49a1b5fc..845b17eec0a898 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -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();
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.h b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
index 28ab4aff3b9d51..dce7aa4f8bbd93 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h
@@ -37,8 +37,6 @@ class RISCVFrameLowering : public TargetFrameLowering {
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 @@ class RISCVFrameLowering : public TargetFrameLowering {
protected:
const RISCVSubtarget &STI;
+ bool hasFPImpl(const MachineFunction &MF) const override;
+
private:
void determineFrameLayout(MachineFunction &MF) const;
void adjustStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,
diff --git a/llvm/lib/Target/SPIRV/SPIRVFrameLowering.h b/llvm/lib/Target/SPIRV/SPIRVFrameLowering.h
index b98f8d0928e5b7..c7522554166a7e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVFrameLowering.h
+++ b/llvm/lib/Target/SPIRV/SPIRVFrameLowering.h
@@ -33,7 +33,8 @@ class SPIRVFrameLowering : public TargetFrameLowering {
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
diff --git a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
index 000418be9a9e33..fa38c6cbb6ebbf 100644
--- a/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcFrameLowering.cpp
@@ -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();
diff --git a/llvm/lib/Target/Sparc/SparcFrameLowering.h b/llvm/lib/Target/Sparc/SparcFrameLowering.h
index ab0ceb6591c63c..803856811969b2 100644
--- a/llvm/lib/Target/Sparc/SparcFrameLowering.h
+++ b/llvm/lib/Target/Sparc/SparcFrameLowering.h
@@ -35,7 +35,6 @@ class SparcFrameLowering : public TargetFrameLowering {
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 @@ class SparcFrameLowering : public TargetFrameLowering {
/// 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;
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
index 8c53b8dffc2fa6..8fbd05eab5f6ee 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
@@ -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());
}
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.h b/llvm/lib/Target/SystemZ/SystemZFrameLowering.h
index c4367b491f99ef..57fc73b78bbf7c 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.h
@@ -86,7 +86,6 @@ class SystemZELFFrameLowering : public SystemZFrameLowering {
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 @@ class SystemZELFFrameLowering : public SystemZFrameLowering {
// 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 @@ class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
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 @@ class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
// 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
diff --git a/llvm/lib/Target/VE/VEFrameLowering.cpp b/llvm/lib/Target/VE/VEFrameLowering.cpp
index 195bd4e6c3aee7..10e94c28072fda 100644
--- a/llvm/lib/Target/VE/VEFrameLowering.cpp
+++ b/llvm/lib/Target/VE/VEFrameLowering.cpp
@@ -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();
diff --git a/llvm/lib/Target/VE/VEFrameLowering.h b/llvm/lib/Target/VE/VEFrameLowering.h
index 36fc8b201b648c..be9cdc01d6f446 100644
--- a/llvm/lib/Target/VE/VEFrameLowering.h
+++ b/llvm/lib/Target/VE/VEFrameLowering.h
@@ -39,7 +39,6 @@ class VEFrameLowering : public TargetFrameLowering {
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 @@ class VEFrameLowering : public TargetFrameLowering {
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;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
index 8f3ad167ae41fc..f0334ccb3afcb5 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
@@ -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
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
index 528b33e34beeef..710d5173d64dba 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
@@ -41,7 +41,6 @@ class WebAssemblyFrameLowering final : public TargetFrameLowering {
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 @@ class WebAssemblyFrameLowering final : public TargetFrameLowering {
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;
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 43a3219f789c4a..2ee2f3f709ab0b 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -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() ||
diff --git a/llvm/lib/Target/X86/X86FrameLowering.h b/llvm/lib/Target/X86/X86FrameLowering.h
index 78217911dacadf..02fe8ee02a7e45 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.h
+++ b/llvm/lib/Target/X86/X86FrameLowering.h
@@ -105,7 +105,6 @@ class X86FrameLowering : public TargetFrameLowering {
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 @@ class X86FrameLowering : public TargetFrameLowering {
/// 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;
diff --git a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp
index b3753692ac2a05..ec18eca82b52d1 100644
--- a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp
+++ b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp
@@ -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();
}
diff --git a/llvm/lib/Target/XCore/XCoreFrameLowering.h b/llvm/lib/Target/XCore/XCoreFrameLowering.h
index a914d82e198947..b06a6f922cdde0 100644
--- a/llvm/lib/Target/XCore/XCoreFrameLowering.h
+++ b/llvm/lib/Target/XCore/XCoreFrameLowering.h
@@ -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;
};
}
diff --git a/llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp b/llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp
index e24cb7714d3646..f46d386c9186aa 100644
--- a/llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp
@@ -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();
diff --git a/llvm/lib/Target/Xtensa/XtensaFrameLowering.h b/llvm/lib/Target/Xtensa/XtensaFrameLowering.h
index 9120215af08b52..3f946e1ea730f9 100644
--- a/llvm/lib/Target/Xtensa/XtensaFrameLowering.h
+++ b/llvm/lib/Target/Xtensa/XtensaFrameLowering.h
@@ -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 @@ class XtensaFrameLowering : public TargetFrameLowering {
void processFunctionBeforeFrameFinalized(MachineFunction &MF,
RegScavenger *RS) const override;
+
+protected:
+ bool hasFPImpl(const MachineFunction &MF) const override;
};
} // namespace llvm
diff --git a/llvm/test/CodeGen/AArch64/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/AArch64/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..fb559867a2d47b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/AMDGPU/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/AMDGPU/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..5ff2d82c1464f2
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/naked-fn-with-frame-pointer.ll
@@ -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, at 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 at rel32@lo+4
+; CHECK-NEXT: s_addc_u32 s17, s17, main at 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, at 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 at rel32@lo+4
+; CHECK-NEXT: s_addc_u32 s17, s17, main at rel32@hi+12
+; CHECK-NEXT: s_swappc_b64 s[30:31], s[16:17]
+ call void @main()
+ unreachable
+}
diff --git a/llvm/test/CodeGen/ARM/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/ARM/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..2bdc7d3e29b981
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/AVR/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/AVR/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..18ea60906bd0cd
--- /dev/null
+++ b/llvm/test/CodeGen/AVR/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/BPF/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/BPF/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..4e4436296f3b56
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/naked-fn-with-frame-pointer.ll
@@ -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, at 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, at 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, at 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, at function
+; CHECK-BE-NEXT: .cfi_startproc
+; CHECK-BE-NEXT: # %bb.0:
+; CHECK-BE-NEXT: call main
+ call void @main()
+ unreachable
+}
diff --git a/llvm/test/CodeGen/CSKY/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/CSKY/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..e897127eb31cdd
--- /dev/null
+++ b/llvm/test/CodeGen/CSKY/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/Hexagon/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/Hexagon/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..c53f2d4df9b62c
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/Lanai/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/Lanai/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..4e148764e478b7
--- /dev/null
+++ b/llvm/test/CodeGen/Lanai/naked-fn-with-frame-pointer.ll
@@ -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, at 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, at 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
+}
diff --git a/llvm/test/CodeGen/LoongArch/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/LoongArch/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..9bb449101683d6
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/M68k/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/M68k/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..807c52c39b6e6a
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/MSP430/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/MSP430/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..2fdb01005bb280
--- /dev/null
+++ b/llvm/test/CodeGen/MSP430/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/Mips/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/Mips/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..a3820da8b221c9
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/NVPTX/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/NVPTX/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..a1f0577c2218bd
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/PowerPC/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/PowerPC/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..59b1044084c645
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/RISCV/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/RISCV/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..de87b10d387338
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/SPARC/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/SPARC/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..af97c573625b52
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/SystemZ/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/SystemZ/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..3eb396e4044206
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/naked-fn-with-frame-pointer.ll
@@ -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 at 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 at PLT
+ call void @main()
+ unreachable
+}
diff --git a/llvm/test/CodeGen/VE/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/VE/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..3b88bea46c4dd0
--- /dev/null
+++ b/llvm/test/CodeGen/VE/naked-fn-with-frame-pointer.ll
@@ -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 at lo
+; CHECK-NEXT: and %s0, %s0, (32)0
+; CHECK-NEXT: lea.sl %s12, main at 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 at lo
+; CHECK-NEXT: and %s0, %s0, (32)0
+; CHECK-NEXT: lea.sl %s12, main at hi(, %s0)
+; CHECK-NEXT: bsic %s10, (, %s12)
+ call void @main()
+ unreachable
+}
diff --git a/llvm/test/CodeGen/WebAssembly/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/WebAssembly/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..fcd42e8cbfb9f5
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/X86/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/X86/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..37756009fa7d86
--- /dev/null
+++ b/llvm/test/CodeGen/X86/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/XCore/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/XCore/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..429a78108a7bac
--- /dev/null
+++ b/llvm/test/CodeGen/XCore/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/test/CodeGen/Xtensa/naked-fn-with-frame-pointer.ll b/llvm/test/CodeGen/Xtensa/naked-fn-with-frame-pointer.ll
new file mode 100644
index 00000000000000..020fcc4f6dae6d
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/naked-fn-with-frame-pointer.ll
@@ -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
+}
diff --git a/llvm/unittests/CodeGen/MFCommon.inc b/llvm/unittests/CodeGen/MFCommon.inc
index d464a16f636cf5..16b7da15c1a7aa 100644
--- a/llvm/unittests/CodeGen/MFCommon.inc
+++ b/llvm/unittests/CodeGen/MFCommon.inc
@@ -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};
More information about the llvm-commits
mailing list