[llvm] ad4a582 - [llvm] Consistently respect `naked` fn attribute in `TargetFrameLowering::hasFP()` (#106014)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 17 22:35:46 PDT 2024
Author: Alex Rønne Petersen
Date: 2024-10-18T09:35:42+04:00
New Revision: ad4a582fd938c933e784f0052bd773676b37b690
URL: https://github.com/llvm/llvm-project/commit/ad4a582fd938c933e784f0052bd773676b37b690
DIFF: https://github.com/llvm/llvm-project/commit/ad4a582fd938c933e784f0052bd773676b37b690.diff
LOG: [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.
Added:
llvm/test/CodeGen/AArch64/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/AMDGPU/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/ARM/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/AVR/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/BPF/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/CSKY/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/Hexagon/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/Lanai/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/LoongArch/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/M68k/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/MSP430/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/Mips/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/NVPTX/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/PowerPC/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/RISCV/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/SPARC/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/SystemZ/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/VE/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/WebAssembly/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/X86/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/XCore/naked-fn-with-frame-pointer.ll
llvm/test/CodeGen/Xtensa/naked-fn-with-frame-pointer.ll
Modified:
llvm/include/llvm/CodeGen/TargetFrameLowering.h
llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
llvm/lib/Target/AArch64/AArch64FrameLowering.h
llvm/lib/Target/AMDGPU/R600FrameLowering.h
llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
llvm/lib/Target/AMDGPU/SIFrameLowering.h
llvm/lib/Target/ARC/ARCFrameLowering.cpp
llvm/lib/Target/ARC/ARCFrameLowering.h
llvm/lib/Target/ARM/ARMFrameLowering.cpp
llvm/lib/Target/ARM/ARMFrameLowering.h
llvm/lib/Target/AVR/AVRFrameLowering.cpp
llvm/lib/Target/AVR/AVRFrameLowering.h
llvm/lib/Target/BPF/BPFFrameLowering.cpp
llvm/lib/Target/BPF/BPFFrameLowering.h
llvm/lib/Target/CSKY/CSKYFrameLowering.cpp
llvm/lib/Target/CSKY/CSKYFrameLowering.h
llvm/lib/Target/DirectX/DirectXFrameLowering.h
llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
llvm/lib/Target/Hexagon/HexagonFrameLowering.h
llvm/lib/Target/Lanai/LanaiFrameLowering.h
llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
llvm/lib/Target/LoongArch/LoongArchFrameLowering.h
llvm/lib/Target/M68k/M68kFrameLowering.cpp
llvm/lib/Target/M68k/M68kFrameLowering.h
llvm/lib/Target/MSP430/MSP430FrameLowering.cpp
llvm/lib/Target/MSP430/MSP430FrameLowering.h
llvm/lib/Target/Mips/MipsFrameLowering.cpp
llvm/lib/Target/Mips/MipsFrameLowering.h
llvm/lib/Target/NVPTX/NVPTXFrameLowering.cpp
llvm/lib/Target/NVPTX/NVPTXFrameLowering.h
llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
llvm/lib/Target/PowerPC/PPCFrameLowering.h
llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
llvm/lib/Target/RISCV/RISCVFrameLowering.h
llvm/lib/Target/SPIRV/SPIRVFrameLowering.h
llvm/lib/Target/Sparc/SparcFrameLowering.cpp
llvm/lib/Target/Sparc/SparcFrameLowering.h
llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
llvm/lib/Target/SystemZ/SystemZFrameLowering.h
llvm/lib/Target/VE/VEFrameLowering.cpp
llvm/lib/Target/VE/VEFrameLowering.h
llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
llvm/lib/Target/X86/X86FrameLowering.cpp
llvm/lib/Target/X86/X86FrameLowering.h
llvm/lib/Target/XCore/XCoreFrameLowering.cpp
llvm/lib/Target/XCore/XCoreFrameLowering.h
llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp
llvm/lib/Target/Xtensa/XtensaFrameLowering.h
llvm/unittests/CodeGen/MFCommon.inc
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/TargetFrameLowering.h b/llvm/include/llvm/CodeGen/TargetFrameLowering.h
index 9882d851187578..97de0197da9b40 100644
--- a/llvm/include/llvm/CodeGen/TargetFrameLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetFrameLowering.h
@@ -280,7 +280,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
@@ -477,6 +481,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 1b8eac7fac21f7..bbf2f267795457 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -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();
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 bc162b0953a7be..13a2db7a87b437 100644
--- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
@@ -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,
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 2706efa83fc3f1..82b6f808688eb0 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -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();
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
index 3c5bc00cb449f1..ff51f1a7af0229 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 7c82f5e9f9a604..48acd9da9587fe 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -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);
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 f7188b856461b7..1083febc5f8520 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 f388376c12c943..b49cbab1876d79 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 d660f3ad67c968..f45fcdb0acd6bc 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 4f83267c999e4a..a35b04606e595d 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 5d5720c3162da9..749c5780fbac3d 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