aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorOliver Stannard <oliver.stannard@arm.com>2024-06-07 10:58:10 +0100
committerGitHub <noreply@github.com>2024-06-07 10:58:10 +0100
commit1a5239251ead73ee57f4e2f7fc93433ac7cf18b1 (patch)
treea2c31e3c7dce81d19f390f97e9d9754b5dbeda81 /llvm/lib
parentb87a80d4ebca9e1c065f0d2762e500078c4badca (diff)
downloadllvm-1a5239251ead73ee57f4e2f7fc93433ac7cf18b1.zip
llvm-1a5239251ead73ee57f4e2f7fc93433ac7cf18b1.tar.gz
llvm-1a5239251ead73ee57f4e2f7fc93433ac7cf18b1.tar.bz2
[ARM] r11 is reserved when using -mframe-chain=aapcs (#86951)
When using the -mframe-chain=aapcs or -mframe-chain=aapcs-leaf options, we cannot use r11 as an allocatable register, even if -fomit-frame-pointer is also used. This is so that r11 will always point to a valid frame record, even if we don't create one in every function.
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/CommandFlags.cpp5
-rw-r--r--llvm/lib/CodeGen/TargetOptionsImpl.cpp21
-rw-r--r--llvm/lib/IR/Function.cpp3
-rw-r--r--llvm/lib/IR/Verifier.cpp2
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp2
-rw-r--r--llvm/lib/Target/ARM/ARMFeatures.td11
-rw-r--r--llvm/lib/Target/ARM/ARMFrameLowering.cpp8
-rw-r--r--llvm/lib/Target/ARM/ARMFrameLowering.h1
8 files changed, 39 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 677460a..8fc65d7 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -211,6 +211,9 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
"Disable frame pointer elimination"),
clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
"Disable frame pointer elimination for non-leaf frame"),
+ clEnumValN(FramePointerKind::Reserved, "reserved",
+ "Enable frame pointer elimination, but reserve the frame "
+ "pointer register"),
clEnumValN(FramePointerKind::None, "none",
"Enable frame pointer elimination")));
CGBINDOPT(FramePointerUsage);
@@ -693,6 +696,8 @@ void codegen::setFunctionAttributes(StringRef CPU, StringRef Features,
NewAttrs.addAttribute("frame-pointer", "all");
else if (getFramePointerUsage() == FramePointerKind::NonLeaf)
NewAttrs.addAttribute("frame-pointer", "non-leaf");
+ else if (getFramePointerUsage() == FramePointerKind::Reserved)
+ NewAttrs.addAttribute("frame-pointer", "reserved");
else if (getFramePointerUsage() == FramePointerKind::None)
NewAttrs.addAttribute("frame-pointer", "none");
}
diff --git a/llvm/lib/CodeGen/TargetOptionsImpl.cpp b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
index af5d101..5bf1d26 100644
--- a/llvm/lib/CodeGen/TargetOptionsImpl.cpp
+++ b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
@@ -21,7 +22,7 @@ using namespace llvm;
/// DisableFramePointerElim - This returns true if frame pointer elimination
/// optimization should be disabled for the given machine function.
bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const {
- // Check to see if the target want to forcably keep frame pointer.
+ // Check to see if the target want to forcibly keep frame pointer.
if (MF.getSubtarget().getFrameLowering()->keepFramePointer(MF))
return true;
@@ -34,11 +35,27 @@ bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const {
return true;
if (FP == "non-leaf")
return MF.getFrameInfo().hasCalls();
- if (FP == "none")
+ if (FP == "none" || FP == "reserved")
return false;
llvm_unreachable("unknown frame pointer flag");
}
+bool TargetOptions::FramePointerIsReserved(const MachineFunction &MF) const {
+ // Check to see if the target want to forcibly keep frame pointer.
+ if (MF.getSubtarget().getFrameLowering()->keepFramePointer(MF))
+ return true;
+
+ const Function &F = MF.getFunction();
+
+ if (!F.hasFnAttribute("frame-pointer"))
+ return false;
+
+ StringRef FP = F.getFnAttribute("frame-pointer").getValueAsString();
+ return StringSwitch<bool>(FP)
+ .Cases("all", "non-leaf", "reserved", true)
+ .Case("none", false);
+}
+
/// HonorSignDependentRoundingFPMath - Return true if the codegen must assume
/// that the rounding mode of the FPU can change from its default.
bool TargetOptions::HonorSignDependentRoundingFPMath() const {
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 13fa1af..3f73502 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -383,6 +383,9 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty,
case FramePointerKind::None:
// 0 ("none") is the default.
break;
+ case FramePointerKind::Reserved:
+ B.addAttribute("frame-pointer", "reserved");
+ break;
case FramePointerKind::NonLeaf:
B.addAttribute("frame-pointer", "non-leaf");
break;
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 684e544..e592720 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2322,7 +2322,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
if (Attrs.hasFnAttr("frame-pointer")) {
StringRef FP = Attrs.getFnAttr("frame-pointer").getValueAsString();
- if (FP != "all" && FP != "non-leaf" && FP != "none")
+ if (FP != "all" && FP != "non-leaf" && FP != "none" && FP != "reserved")
CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V);
}
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 9adf758..c149db31 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -207,7 +207,7 @@ getReservedRegs(const MachineFunction &MF) const {
markSuperRegs(Reserved, ARM::PC);
markSuperRegs(Reserved, ARM::FPSCR);
markSuperRegs(Reserved, ARM::APSR_NZCV);
- if (TFI->hasFP(MF))
+ if (TFI->isFPReserved(MF))
markSuperRegs(Reserved, STI.getFramePointerReg());
if (hasBasePointer(MF))
markSuperRegs(Reserved, BasePtr);
diff --git a/llvm/lib/Target/ARM/ARMFeatures.td b/llvm/lib/Target/ARM/ARMFeatures.td
index 84481af..8b0ade5 100644
--- a/llvm/lib/Target/ARM/ARMFeatures.td
+++ b/llvm/lib/Target/ARM/ARMFeatures.td
@@ -548,16 +548,15 @@ def FeatureFixCortexA57AES1742098 : SubtargetFeature<"fix-cortex-a57-aes-1742098
"FixCortexA57AES1742098", "true",
"Work around Cortex-A57 Erratum 1742098 / Cortex-A72 Erratum 1655431 (AES)">;
+// If frame pointers are in use, they must follow the AAPCS definition, which
+// always uses R11 as the frame pointer. If this is not set, we can use R7 as
+// the frame pointer for Thumb1-only code, which is more efficient, but less
+// compatible. Note that this feature does not control whether frame pointers
+// are emitted, that is controlled by the "frame-pointer" function attribute.
def FeatureAAPCSFrameChain : SubtargetFeature<"aapcs-frame-chain",
"CreateAAPCSFrameChain", "true",
"Create an AAPCS compliant frame chain">;
-def FeatureAAPCSFrameChainLeaf : SubtargetFeature<"aapcs-frame-chain-leaf",
- "CreateAAPCSFrameChainLeaf", "true",
- "Create an AAPCS compliant frame chain "
- "for leaf functions",
- [FeatureAAPCSFrameChain]>;
-
// Assume that lock-free 32-bit atomics are available, even if the target
// and operating system combination would not usually provide them. The user
// is responsible for providing any necessary __sync implementations. Code
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 11496a6..831b6b0 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -215,7 +215,7 @@ bool ARMFrameLowering::hasFP(const MachineFunction &MF) const {
/// isFPReserved - Return true if the frame pointer register should be
/// considered a reserved register on the scope of the specified function.
bool ARMFrameLowering::isFPReserved(const MachineFunction &MF) const {
- return hasFP(MF) || MF.getSubtarget<ARMSubtarget>().createAAPCSFrameChain();
+ return hasFP(MF) || MF.getTarget().Options.FramePointerIsReserved(MF);
}
/// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
@@ -2233,10 +2233,10 @@ bool ARMFrameLowering::enableShrinkWrapping(const MachineFunction &MF) const {
return true;
}
-static bool requiresAAPCSFrameRecord(const MachineFunction &MF) {
+bool ARMFrameLowering::requiresAAPCSFrameRecord(
+ const MachineFunction &MF) const {
const auto &Subtarget = MF.getSubtarget<ARMSubtarget>();
- return Subtarget.createAAPCSFrameChainLeaf() ||
- (Subtarget.createAAPCSFrameChain() && MF.getFrameInfo().hasCalls());
+ return Subtarget.createAAPCSFrameChain() && hasFP(MF);
}
// Thumb1 may require a spill when storing to a frame index through FP (or any
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
index 3c7358d..6a31b73 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
@@ -47,6 +47,7 @@ public:
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;
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,