-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Add FramePointerKind::NonLeafNoReserve #163775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This patch adds a new FramePointerKind::NonLeafNoReserve and makes it the default for -momit-frame-pointer=leaf. This should fix llvm#154379, the main impact of this patch can be found in clang/lib/Driver/ToolChains/CommonArgs.cpp.
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang-driver Author: Nabeel Omer (omern1) ChangesThis patch adds a new FramePointerKind::NonLeafNoReserve and makes it the default for -momit-leaf-frame-pointer. This should fix #154379, the main impact of this patch can be found in clang/lib/Driver/ToolChains/CommonArgs.cpp. Patch is 53.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/163775.diff 16 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 90e1f8d1eb5e9..52360b67b306c 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -54,7 +54,7 @@ CODEGENOPT(SeparateNamedSections, 1, 0, Benign) ///< Set for -fseparate-named-se
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0, Benign) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
CODEGENOPT(XCOFFReadOnlyPointers, 1, 0, Benign) ///< Set for -mxcoff-roptr.
CODEGENOPT(AllTocData, 1, 0, Benign) ///< AIX -mtocdata
-ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,reserved,none
+ENUM_CODEGENOPT(FramePointer, FramePointerKind, 3, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,non-leaf-no-reserve,reserved,none
ENUM_CODEGENOPT(ExceptionHandling, ExceptionHandlingKind, 3, ExceptionHandlingKind::None, NotCompatible)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index cae06c3c9495a..3dd0140ea0d9f 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -155,9 +155,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::string BinutilsVersion;
enum class FramePointerKind {
+ NonLeafNoReserve, // Keep non-leaf frame pointers, allow the FP to be used as a GPR in leaf functions.
None, // Omit all frame pointers.
Reserved, // Maintain valid frame pointer chain.
- NonLeaf, // Keep non-leaf frame pointers.
+ NonLeaf, // Keep non-leaf frame pointers, don't allow the FP to be used as a GPR in leaf functions.
All, // Keep all frame pointers.
};
@@ -167,6 +168,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
return "none";
case FramePointerKind::Reserved:
return "reserved";
+ case FramePointerKind::NonLeafNoReserve:
+ return "non-leaf-no-reserve";
case FramePointerKind::NonLeaf:
return "non-leaf";
case FramePointerKind::All:
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 7ae153deb9a55..5f7ef34a36be6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -8481,8 +8481,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">,
MarshallingInfoFlag<LangOpts<"PIE">>;
def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
- HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,reserved,none">,
- NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "Reserved", "None"]>,
+ HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,non-leaf-no-reserve,reserved,none">,
+ NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "NonLeafNoReserve", "Reserved", "None"]>,
MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 741fa44713ac8..60a7779786ee0 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1990,6 +1990,7 @@ static void getTrivialDefaultFunctionAttributes(
// This is the default behavior.
break;
case CodeGenOptions::FramePointerKind::Reserved:
+ case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
case CodeGenOptions::FramePointerKind::NonLeaf:
case CodeGenOptions::FramePointerKind::All:
FuncAttrs.addAttribute("frame-pointer",
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c5eb14e329315..2488b2b1ded70 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1506,6 +1506,9 @@ void CodeGenModule::Release() {
case CodeGenOptions::FramePointerKind::Reserved:
getModule().setFramePointer(llvm::FramePointerKind::Reserved);
break;
+ case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
+ getModule().setFramePointer(llvm::FramePointerKind::NonLeafNoReserve);
+ break;
case CodeGenOptions::FramePointerKind::NonLeaf:
getModule().setFramePointer(llvm::FramePointerKind::NonLeaf);
break;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index a7310ba2da061..7072a41d2507a 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5748,6 +5748,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
case CodeGenOptions::FramePointerKind::Reserved:
FPKeepKindStr = "-mframe-pointer=reserved";
break;
+ case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
+ FPKeepKindStr = "-mframe-pointer=non-leaf-no-reserve";
+ break;
case CodeGenOptions::FramePointerKind::NonLeaf:
FPKeepKindStr = "-mframe-pointer=non-leaf";
break;
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 99400ac701fbe..55a57acebfd9a 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -222,26 +222,36 @@ static bool framePointerImpliesLeafFramePointer(const llvm::opt::ArgList &Args,
clang::CodeGenOptions::FramePointerKind
getFramePointerKind(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple) {
- // There are three things to consider here:
+ // There are four things to consider here:
// * Should a frame record be created for non-leaf functions?
// * Should a frame record be created for leaf functions?
- // * Is the frame pointer register reserved, i.e. must it always point to
- // either a new, valid frame record or be un-modified?
+ // * Is the frame pointer register reserved in non-leaf functions?
+ // i.e. must it always point to either a new, valid frame record or be un-modified?
+ // * Is the frame pointer register reserved in leaf functions?
//
// Not all combinations of these are valid:
// * It's not useful to have leaf frame records without non-leaf ones.
// * It's not useful to have frame records without reserving the frame
// pointer.
//
- // | Non-leaf | Leaf | Reserved |
- // | N | N | N | FramePointerKind::None
- // | N | N | Y | FramePointerKind::Reserved
- // | N | Y | N | Invalid
- // | N | Y | Y | Invalid
- // | Y | N | N | Invalid
- // | Y | N | Y | FramePointerKind::NonLeaf
- // | Y | Y | N | Invalid
- // | Y | Y | Y | FramePointerKind::All
+ // | Non-leaf | Leaf | Reserved In Non-Leaf | Reserved In Leaf |
+ // |----------|------|-----------------------|------------------|
+ // | N | N | N | N | FramePointerKind::None
+ // | N | N | N | Y | Invalid
+ // | N | N | Y | N | Invalid
+ // | N | N | Y | Y | FramePointerKind::Reserved
+ // | N | Y | N | N | Invalid
+ // | N | Y | N | Y | Invalid
+ // | N | Y | Y | N | Invalid
+ // | N | Y | Y | Y | Invalid
+ // | Y | N | N | N | Invalid
+ // | Y | N | N | Y | Invalid
+ // | Y | N | Y | N | FramePointerKind::NonLeafNoReserve
+ // | Y | N | Y | Y | FramePointerKind::NonLeaf
+ // | Y | Y | N | N | Invalid
+ // | Y | Y | N | Y | Invalid
+ // | Y | Y | Y | N | Invalid
+ // | Y | Y | Y | Y | FramePointerKind::All
//
// The FramePointerKind::Reserved case is currently only reachable for Arm,
// which has the -mframe-chain= option which can (in combination with
@@ -261,12 +271,16 @@ getFramePointerKind(const llvm::opt::ArgList &Args,
clang::driver::options::OPT_mno_omit_leaf_frame_pointer,
clang::driver::options::OPT_momit_leaf_frame_pointer, DefaultLeafFP);
- bool FPRegReserved = EnableFP || mustMaintainValidFrameChain(Args, Triple);
+ bool FPRegReserved = mustMaintainValidFrameChain(Args, Triple);
if (EnableFP) {
if (EnableLeafFP)
return clang::CodeGenOptions::FramePointerKind::All;
- return clang::CodeGenOptions::FramePointerKind::NonLeaf;
+
+ if (FPRegReserved)
+ return clang::CodeGenOptions::FramePointerKind::NonLeaf;
+
+ return clang::CodeGenOptions::FramePointerKind::NonLeafNoReserve;
}
if (FPRegReserved)
return clang::CodeGenOptions::FramePointerKind::Reserved;
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index a56fa41c49d34..9eba3914b1e1e 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -1064,6 +1064,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
case CodeGenOptions::FramePointerKind::Reserved:
FPKeepKindStr = "-mframe-pointer=reserved";
break;
+ case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
+ FPKeepKindStr = "-mframe-pointer=non-leaf-no-reserve";
+ break;
case CodeGenOptions::FramePointerKind::NonLeaf:
FPKeepKindStr = "-mframe-pointer=non-leaf";
break;
diff --git a/clang/test/Driver/frame-pointer-elim.c b/clang/test/Driver/frame-pointer-elim.c
index 6d719828c6a06..9b0e6fa15b0d4 100644
--- a/clang/test/Driver/frame-pointer-elim.c
+++ b/clang/test/Driver/frame-pointer-elim.c
@@ -1,7 +1,7 @@
// KEEP-ALL-NOT: warning: argument unused
// KEEP-ALL: "-mframe-pointer=all"
// KEEP-NON-LEAF-NOT: warning: argument unused
-// KEEP-NON-LEAF: "-mframe-pointer=non-leaf"
+// KEEP-NON-LEAF: "-mframe-pointer=non-leaf-no-reserve"
// KEEP-NONE-NOT: warning: argument unused
// KEEP-NONE: "-mframe-pointer=none"
// KEEP-RESERVED-NOT: warning: argument unused
@@ -73,17 +73,17 @@
// RUN: %clang -### -target armv7s-apple-ios -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-7S %s
// WARN-OMIT-7S: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7s'
-// WARN-OMIT-7S: "-mframe-pointer=non-leaf"
+// WARN-OMIT-7S: "-mframe-pointer=non-leaf-no-reserve"
// RUN: %clang -### -target armv7k-apple-watchos -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-7K %s
// WARN-OMIT-7K: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7k'
-// WARN-OMIT-7K: "-mframe-pointer=non-leaf"
+// WARN-OMIT-7K: "-mframe-pointer=non-leaf-no-reserve"
// RUN: %clang -### -target armv7s-apple-ios8.0 -momit-leaf-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-LEAF-7S %s
// WARN-OMIT-LEAF-7S-NOT: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
-// WARN-OMIT-LEAF-7S: "-mframe-pointer=non-leaf"
+// WARN-OMIT-LEAF-7S: "-mframe-pointer=non-leaf-no-reserve"
// On AArch64, PS4, PS5, and VE, default to omitting the frame pointer on leaf
// functions
diff --git a/clang/test/Driver/fuchsia.c b/clang/test/Driver/fuchsia.c
index cf92f85040901..71aabcc9f7fc1 100644
--- a/clang/test/Driver/fuchsia.c
+++ b/clang/test/Driver/fuchsia.c
@@ -68,7 +68,7 @@
// RUN: %clang -### %s --target=aarch64-unknown-fuchsia -O3 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK-FP-NONE
// CHECK-FP-ALL: "-mframe-pointer=all"
-// CHECK-FP-NONLEAF: "-mframe-pointer=non-leaf"
+// CHECK-FP-NONLEAF: "-mframe-pointer=non-leaf-no-reserve"
// CHECK-FP-NONE: "-mframe-pointer=none"
// RUN: not %clang -### %s --target=x86_64-unknown-fuchsia -rtlib=libgcc 2>&1 \
diff --git a/llvm/include/llvm/Support/CodeGen.h b/llvm/include/llvm/Support/CodeGen.h
index cd1f9167b996d..6675f131bc406 100644
--- a/llvm/include/llvm/Support/CodeGen.h
+++ b/llvm/include/llvm/Support/CodeGen.h
@@ -115,7 +115,7 @@ namespace llvm {
};
// Specify what functions should keep the frame pointer.
- enum class FramePointerKind { None, NonLeaf, All, Reserved };
+ enum class FramePointerKind { None, NonLeaf, All, Reserved, NonLeafNoReserve };
// Specify what type of zeroing callee-used registers.
namespace ZeroCallUsedRegs {
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 0522698adf183..e3089dd1eb07b 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -211,6 +211,8 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
clEnumValN(FramePointerKind::All, "all",
"Disable frame pointer elimination"),
clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
+ "Disable frame pointer elimination for non-leaf frame but reserve the register in leaf functions"),
+ clEnumValN(FramePointerKind::NonLeafNoReserve, "non-leaf-no-reserve",
"Disable frame pointer elimination for non-leaf frame"),
clEnumValN(FramePointerKind::Reserved, "reserved",
"Enable frame pointer elimination, but reserve the frame "
@@ -695,6 +697,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::NonLeafNoReserve)
+ NewAttrs.addAttribute("frame-pointer", "non-leaf-no-reserve");
else if (getFramePointerUsage() == FramePointerKind::Reserved)
NewAttrs.addAttribute("frame-pointer", "reserved");
else if (getFramePointerUsage() == FramePointerKind::None)
diff --git a/llvm/lib/CodeGen/TargetOptionsImpl.cpp b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
index 5eb86e740ff7c..90d61f7b359e5 100644
--- a/llvm/lib/CodeGen/TargetOptionsImpl.cpp
+++ b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
@@ -30,7 +30,7 @@ bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const {
StringRef FP = FPAttr.getValueAsString();
if (FP == "all")
return true;
- if (FP == "non-leaf")
+ if (FP == "non-leaf" || FP == "non-leaf-no-reserve")
return MF.getFrameInfo().hasCalls();
if (FP == "none" || FP == "reserved")
return false;
@@ -45,6 +45,7 @@ bool TargetOptions::FramePointerIsReserved(const MachineFunction &MF) const {
return StringSwitch<bool>(FPAttr.getValueAsString())
.Cases("all", "non-leaf", "reserved", true)
+ .Case(("non-leaf-no-reserve"), MF.getFrameInfo().hasCalls())
.Case("none", false);
}
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index fc067459dcba3..31a294447152e 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -396,6 +396,9 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty,
case FramePointerKind::NonLeaf:
B.addAttribute("frame-pointer", "non-leaf");
break;
+ case FramePointerKind::NonLeafNoReserve:
+ B.addAttribute("frame-pointer", "non-leaf-no-reserve");
+ break;
case FramePointerKind::All:
B.addAttribute("frame-pointer", "all");
break;
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index c79a95087dbdd..4a5e0b6bdae97 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2484,7 +2484,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
if (Attribute FPAttr = Attrs.getFnAttr("frame-pointer"); FPAttr.isValid()) {
StringRef FP = FPAttr.getValueAsString();
- if (FP != "all" && FP != "non-leaf" && FP != "none" && FP != "reserved")
+ if (FP != "all" && FP != "non-leaf" && FP != "none" && FP != "reserved" && FP != "non-leaf-no-reserve")
CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V);
}
diff --git a/llvm/test/CodeGen/X86/regalloc-fp.ll b/llvm/test/CodeGen/X86/regalloc-fp.ll
new file mode 100644
index 0000000000000..e89e5ab1d6b59
--- /dev/null
+++ b/llvm/test/CodeGen/X86/regalloc-fp.ll
@@ -0,0 +1,775 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Context:
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
+define i32 @check_none() "frame-pointer"="none" {
+; CHECK-LABEL: check_none:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: pushq %rbp
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: pushq %r15
+; CHECK-NEXT: .cfi_def_cfa_offset 24
+; CHECK-NEXT: pushq %r14
+; CHECK-NEXT: .cfi_def_cfa_offset 32
+; CHECK-NEXT: pushq %r13
+; CHECK-NEXT: .cfi_def_cfa_offset 40
+; CHECK-NEXT: pushq %r12
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: pushq %rbx
+; CHECK-NEXT: .cfi_def_cfa_offset 56
+; CHECK-NEXT: .cfi_offset %rbx, -56
+; CHECK-NEXT: .cfi_offset %r12, -48
+; CHECK-NEXT: .cfi_offset %r13, -40
+; CHECK-NEXT: .cfi_offset %r14, -32
+; CHECK-NEXT: .cfi_offset %r15, -24
+; CHECK-NEXT: .cfi_offset %rbp, -16
+; CHECK-NEXT: movl $0, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $1, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $2, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $3, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $4, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $5, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $6, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $7, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $8, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $9, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $16, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $17, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $18, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $19, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $20, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %edx
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r8d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r9d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r10d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r11d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %ebx
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %ebp
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r14d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r15d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r12d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r13d
+; CHECK-NEXT: #APP
+; CHECK-NEXT: nop
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %edx, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %esi, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %edi, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r8d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r9d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r10d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r11d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %ebx, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %ebp, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r14d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r15d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r12d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r13d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: popq %rbx
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: popq %r12
+; CHECK-NEXT: .cfi_def_cfa_offset 40
+; CHECK-NEXT: popq %r13
+; CHECK-NEXT: .cfi_def_cfa_offset 32
+; CHECK-NEXT: popq %r14
+; CHECK-NEXT: .cfi_def_cfa_offset 24
+; CHECK-NEXT: popq %r15
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: popq %rbp
+; CHECK-NEXT: .cfi_def_cfa_offset 8
+; CHECK-NEXT: retq
+entry:
+ %reg0 = alloca i32, align 4
+ %reg1 = alloca i32, align 4
+ %reg2 = alloca i32, align 4
+ %reg3 = alloca i32, align 4
+ %reg4 = alloca i32, align 4
+ %reg5 = alloca i32, align 4
+ %reg6 = alloca i32, align 4
+ %reg7 = alloca i32, align 4
+ %reg8 = alloca i32, align 4
+ %reg9 = alloca i32, align 4
+ %reg10 = alloca i32, ali...
[truncated]
|
@llvm/pr-subscribers-backend-x86 Author: Nabeel Omer (omern1) ChangesThis patch adds a new FramePointerKind::NonLeafNoReserve and makes it the default for -momit-leaf-frame-pointer. This should fix #154379, the main impact of this patch can be found in clang/lib/Driver/ToolChains/CommonArgs.cpp. Patch is 53.75 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/163775.diff 16 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 90e1f8d1eb5e9..52360b67b306c 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -54,7 +54,7 @@ CODEGENOPT(SeparateNamedSections, 1, 0, Benign) ///< Set for -fseparate-named-se
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0, Benign) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
CODEGENOPT(XCOFFReadOnlyPointers, 1, 0, Benign) ///< Set for -mxcoff-roptr.
CODEGENOPT(AllTocData, 1, 0, Benign) ///< AIX -mtocdata
-ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,reserved,none
+ENUM_CODEGENOPT(FramePointer, FramePointerKind, 3, FramePointerKind::None, Benign) /// frame-pointer: all,non-leaf,non-leaf-no-reserve,reserved,none
ENUM_CODEGENOPT(ExceptionHandling, ExceptionHandlingKind, 3, ExceptionHandlingKind::None, NotCompatible)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index cae06c3c9495a..3dd0140ea0d9f 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -155,9 +155,10 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::string BinutilsVersion;
enum class FramePointerKind {
+ NonLeafNoReserve, // Keep non-leaf frame pointers, allow the FP to be used as a GPR in leaf functions.
None, // Omit all frame pointers.
Reserved, // Maintain valid frame pointer chain.
- NonLeaf, // Keep non-leaf frame pointers.
+ NonLeaf, // Keep non-leaf frame pointers, don't allow the FP to be used as a GPR in leaf functions.
All, // Keep all frame pointers.
};
@@ -167,6 +168,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
return "none";
case FramePointerKind::Reserved:
return "reserved";
+ case FramePointerKind::NonLeafNoReserve:
+ return "non-leaf-no-reserve";
case FramePointerKind::NonLeaf:
return "non-leaf";
case FramePointerKind::All:
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 7ae153deb9a55..5f7ef34a36be6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -8481,8 +8481,8 @@ def pic_is_pie : Flag<["-"], "pic-is-pie">,
MarshallingInfoFlag<LangOpts<"PIE">>;
def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
- HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,reserved,none">,
- NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "Reserved", "None"]>,
+ HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,non-leaf-no-reserve,reserved,none">,
+ NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "NonLeafNoReserve", "Reserved", "None"]>,
MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 741fa44713ac8..60a7779786ee0 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1990,6 +1990,7 @@ static void getTrivialDefaultFunctionAttributes(
// This is the default behavior.
break;
case CodeGenOptions::FramePointerKind::Reserved:
+ case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
case CodeGenOptions::FramePointerKind::NonLeaf:
case CodeGenOptions::FramePointerKind::All:
FuncAttrs.addAttribute("frame-pointer",
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c5eb14e329315..2488b2b1ded70 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1506,6 +1506,9 @@ void CodeGenModule::Release() {
case CodeGenOptions::FramePointerKind::Reserved:
getModule().setFramePointer(llvm::FramePointerKind::Reserved);
break;
+ case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
+ getModule().setFramePointer(llvm::FramePointerKind::NonLeafNoReserve);
+ break;
case CodeGenOptions::FramePointerKind::NonLeaf:
getModule().setFramePointer(llvm::FramePointerKind::NonLeaf);
break;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index a7310ba2da061..7072a41d2507a 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5748,6 +5748,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
case CodeGenOptions::FramePointerKind::Reserved:
FPKeepKindStr = "-mframe-pointer=reserved";
break;
+ case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
+ FPKeepKindStr = "-mframe-pointer=non-leaf-no-reserve";
+ break;
case CodeGenOptions::FramePointerKind::NonLeaf:
FPKeepKindStr = "-mframe-pointer=non-leaf";
break;
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 99400ac701fbe..55a57acebfd9a 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -222,26 +222,36 @@ static bool framePointerImpliesLeafFramePointer(const llvm::opt::ArgList &Args,
clang::CodeGenOptions::FramePointerKind
getFramePointerKind(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple) {
- // There are three things to consider here:
+ // There are four things to consider here:
// * Should a frame record be created for non-leaf functions?
// * Should a frame record be created for leaf functions?
- // * Is the frame pointer register reserved, i.e. must it always point to
- // either a new, valid frame record or be un-modified?
+ // * Is the frame pointer register reserved in non-leaf functions?
+ // i.e. must it always point to either a new, valid frame record or be un-modified?
+ // * Is the frame pointer register reserved in leaf functions?
//
// Not all combinations of these are valid:
// * It's not useful to have leaf frame records without non-leaf ones.
// * It's not useful to have frame records without reserving the frame
// pointer.
//
- // | Non-leaf | Leaf | Reserved |
- // | N | N | N | FramePointerKind::None
- // | N | N | Y | FramePointerKind::Reserved
- // | N | Y | N | Invalid
- // | N | Y | Y | Invalid
- // | Y | N | N | Invalid
- // | Y | N | Y | FramePointerKind::NonLeaf
- // | Y | Y | N | Invalid
- // | Y | Y | Y | FramePointerKind::All
+ // | Non-leaf | Leaf | Reserved In Non-Leaf | Reserved In Leaf |
+ // |----------|------|-----------------------|------------------|
+ // | N | N | N | N | FramePointerKind::None
+ // | N | N | N | Y | Invalid
+ // | N | N | Y | N | Invalid
+ // | N | N | Y | Y | FramePointerKind::Reserved
+ // | N | Y | N | N | Invalid
+ // | N | Y | N | Y | Invalid
+ // | N | Y | Y | N | Invalid
+ // | N | Y | Y | Y | Invalid
+ // | Y | N | N | N | Invalid
+ // | Y | N | N | Y | Invalid
+ // | Y | N | Y | N | FramePointerKind::NonLeafNoReserve
+ // | Y | N | Y | Y | FramePointerKind::NonLeaf
+ // | Y | Y | N | N | Invalid
+ // | Y | Y | N | Y | Invalid
+ // | Y | Y | Y | N | Invalid
+ // | Y | Y | Y | Y | FramePointerKind::All
//
// The FramePointerKind::Reserved case is currently only reachable for Arm,
// which has the -mframe-chain= option which can (in combination with
@@ -261,12 +271,16 @@ getFramePointerKind(const llvm::opt::ArgList &Args,
clang::driver::options::OPT_mno_omit_leaf_frame_pointer,
clang::driver::options::OPT_momit_leaf_frame_pointer, DefaultLeafFP);
- bool FPRegReserved = EnableFP || mustMaintainValidFrameChain(Args, Triple);
+ bool FPRegReserved = mustMaintainValidFrameChain(Args, Triple);
if (EnableFP) {
if (EnableLeafFP)
return clang::CodeGenOptions::FramePointerKind::All;
- return clang::CodeGenOptions::FramePointerKind::NonLeaf;
+
+ if (FPRegReserved)
+ return clang::CodeGenOptions::FramePointerKind::NonLeaf;
+
+ return clang::CodeGenOptions::FramePointerKind::NonLeafNoReserve;
}
if (FPRegReserved)
return clang::CodeGenOptions::FramePointerKind::Reserved;
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index a56fa41c49d34..9eba3914b1e1e 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -1064,6 +1064,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
case CodeGenOptions::FramePointerKind::Reserved:
FPKeepKindStr = "-mframe-pointer=reserved";
break;
+ case CodeGenOptions::FramePointerKind::NonLeafNoReserve:
+ FPKeepKindStr = "-mframe-pointer=non-leaf-no-reserve";
+ break;
case CodeGenOptions::FramePointerKind::NonLeaf:
FPKeepKindStr = "-mframe-pointer=non-leaf";
break;
diff --git a/clang/test/Driver/frame-pointer-elim.c b/clang/test/Driver/frame-pointer-elim.c
index 6d719828c6a06..9b0e6fa15b0d4 100644
--- a/clang/test/Driver/frame-pointer-elim.c
+++ b/clang/test/Driver/frame-pointer-elim.c
@@ -1,7 +1,7 @@
// KEEP-ALL-NOT: warning: argument unused
// KEEP-ALL: "-mframe-pointer=all"
// KEEP-NON-LEAF-NOT: warning: argument unused
-// KEEP-NON-LEAF: "-mframe-pointer=non-leaf"
+// KEEP-NON-LEAF: "-mframe-pointer=non-leaf-no-reserve"
// KEEP-NONE-NOT: warning: argument unused
// KEEP-NONE: "-mframe-pointer=none"
// KEEP-RESERVED-NOT: warning: argument unused
@@ -73,17 +73,17 @@
// RUN: %clang -### -target armv7s-apple-ios -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-7S %s
// WARN-OMIT-7S: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7s'
-// WARN-OMIT-7S: "-mframe-pointer=non-leaf"
+// WARN-OMIT-7S: "-mframe-pointer=non-leaf-no-reserve"
// RUN: %clang -### -target armv7k-apple-watchos -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-7K %s
// WARN-OMIT-7K: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7k'
-// WARN-OMIT-7K: "-mframe-pointer=non-leaf"
+// WARN-OMIT-7K: "-mframe-pointer=non-leaf-no-reserve"
// RUN: %clang -### -target armv7s-apple-ios8.0 -momit-leaf-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=WARN-OMIT-LEAF-7S %s
// WARN-OMIT-LEAF-7S-NOT: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
-// WARN-OMIT-LEAF-7S: "-mframe-pointer=non-leaf"
+// WARN-OMIT-LEAF-7S: "-mframe-pointer=non-leaf-no-reserve"
// On AArch64, PS4, PS5, and VE, default to omitting the frame pointer on leaf
// functions
diff --git a/clang/test/Driver/fuchsia.c b/clang/test/Driver/fuchsia.c
index cf92f85040901..71aabcc9f7fc1 100644
--- a/clang/test/Driver/fuchsia.c
+++ b/clang/test/Driver/fuchsia.c
@@ -68,7 +68,7 @@
// RUN: %clang -### %s --target=aarch64-unknown-fuchsia -O3 2>&1 \
// RUN: | FileCheck %s -check-prefix=CHECK-FP-NONE
// CHECK-FP-ALL: "-mframe-pointer=all"
-// CHECK-FP-NONLEAF: "-mframe-pointer=non-leaf"
+// CHECK-FP-NONLEAF: "-mframe-pointer=non-leaf-no-reserve"
// CHECK-FP-NONE: "-mframe-pointer=none"
// RUN: not %clang -### %s --target=x86_64-unknown-fuchsia -rtlib=libgcc 2>&1 \
diff --git a/llvm/include/llvm/Support/CodeGen.h b/llvm/include/llvm/Support/CodeGen.h
index cd1f9167b996d..6675f131bc406 100644
--- a/llvm/include/llvm/Support/CodeGen.h
+++ b/llvm/include/llvm/Support/CodeGen.h
@@ -115,7 +115,7 @@ namespace llvm {
};
// Specify what functions should keep the frame pointer.
- enum class FramePointerKind { None, NonLeaf, All, Reserved };
+ enum class FramePointerKind { None, NonLeaf, All, Reserved, NonLeafNoReserve };
// Specify what type of zeroing callee-used registers.
namespace ZeroCallUsedRegs {
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 0522698adf183..e3089dd1eb07b 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -211,6 +211,8 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
clEnumValN(FramePointerKind::All, "all",
"Disable frame pointer elimination"),
clEnumValN(FramePointerKind::NonLeaf, "non-leaf",
+ "Disable frame pointer elimination for non-leaf frame but reserve the register in leaf functions"),
+ clEnumValN(FramePointerKind::NonLeafNoReserve, "non-leaf-no-reserve",
"Disable frame pointer elimination for non-leaf frame"),
clEnumValN(FramePointerKind::Reserved, "reserved",
"Enable frame pointer elimination, but reserve the frame "
@@ -695,6 +697,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::NonLeafNoReserve)
+ NewAttrs.addAttribute("frame-pointer", "non-leaf-no-reserve");
else if (getFramePointerUsage() == FramePointerKind::Reserved)
NewAttrs.addAttribute("frame-pointer", "reserved");
else if (getFramePointerUsage() == FramePointerKind::None)
diff --git a/llvm/lib/CodeGen/TargetOptionsImpl.cpp b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
index 5eb86e740ff7c..90d61f7b359e5 100644
--- a/llvm/lib/CodeGen/TargetOptionsImpl.cpp
+++ b/llvm/lib/CodeGen/TargetOptionsImpl.cpp
@@ -30,7 +30,7 @@ bool TargetOptions::DisableFramePointerElim(const MachineFunction &MF) const {
StringRef FP = FPAttr.getValueAsString();
if (FP == "all")
return true;
- if (FP == "non-leaf")
+ if (FP == "non-leaf" || FP == "non-leaf-no-reserve")
return MF.getFrameInfo().hasCalls();
if (FP == "none" || FP == "reserved")
return false;
@@ -45,6 +45,7 @@ bool TargetOptions::FramePointerIsReserved(const MachineFunction &MF) const {
return StringSwitch<bool>(FPAttr.getValueAsString())
.Cases("all", "non-leaf", "reserved", true)
+ .Case(("non-leaf-no-reserve"), MF.getFrameInfo().hasCalls())
.Case("none", false);
}
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index fc067459dcba3..31a294447152e 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -396,6 +396,9 @@ Function *Function::createWithDefaultAttr(FunctionType *Ty,
case FramePointerKind::NonLeaf:
B.addAttribute("frame-pointer", "non-leaf");
break;
+ case FramePointerKind::NonLeafNoReserve:
+ B.addAttribute("frame-pointer", "non-leaf-no-reserve");
+ break;
case FramePointerKind::All:
B.addAttribute("frame-pointer", "all");
break;
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index c79a95087dbdd..4a5e0b6bdae97 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2484,7 +2484,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeList Attrs,
if (Attribute FPAttr = Attrs.getFnAttr("frame-pointer"); FPAttr.isValid()) {
StringRef FP = FPAttr.getValueAsString();
- if (FP != "all" && FP != "non-leaf" && FP != "none" && FP != "reserved")
+ if (FP != "all" && FP != "non-leaf" && FP != "none" && FP != "reserved" && FP != "non-leaf-no-reserve")
CheckFailed("invalid value for 'frame-pointer' attribute: " + FP, V);
}
diff --git a/llvm/test/CodeGen/X86/regalloc-fp.ll b/llvm/test/CodeGen/X86/regalloc-fp.ll
new file mode 100644
index 0000000000000..e89e5ab1d6b59
--- /dev/null
+++ b/llvm/test/CodeGen/X86/regalloc-fp.ll
@@ -0,0 +1,775 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; Context:
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
+define i32 @check_none() "frame-pointer"="none" {
+; CHECK-LABEL: check_none:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: pushq %rbp
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: pushq %r15
+; CHECK-NEXT: .cfi_def_cfa_offset 24
+; CHECK-NEXT: pushq %r14
+; CHECK-NEXT: .cfi_def_cfa_offset 32
+; CHECK-NEXT: pushq %r13
+; CHECK-NEXT: .cfi_def_cfa_offset 40
+; CHECK-NEXT: pushq %r12
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: pushq %rbx
+; CHECK-NEXT: .cfi_def_cfa_offset 56
+; CHECK-NEXT: .cfi_offset %rbx, -56
+; CHECK-NEXT: .cfi_offset %r12, -48
+; CHECK-NEXT: .cfi_offset %r13, -40
+; CHECK-NEXT: .cfi_offset %r14, -32
+; CHECK-NEXT: .cfi_offset %r15, -24
+; CHECK-NEXT: .cfi_offset %rbp, -16
+; CHECK-NEXT: movl $0, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $1, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $2, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $3, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $4, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $5, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $6, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $7, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $8, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $9, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $16, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $17, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $18, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $19, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl $20, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %eax
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %ecx
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %edx
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %esi
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %edi
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r8d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r9d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r10d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r11d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %ebx
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %ebp
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r14d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r15d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r12d
+; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %r13d
+; CHECK-NEXT: #APP
+; CHECK-NEXT: nop
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %edx, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %esi, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %edi, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r8d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r9d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r10d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r11d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %ebx, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %ebp, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r14d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r15d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r12d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: movl %r13d, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: xorl %eax, %eax
+; CHECK-NEXT: popq %rbx
+; CHECK-NEXT: .cfi_def_cfa_offset 48
+; CHECK-NEXT: popq %r12
+; CHECK-NEXT: .cfi_def_cfa_offset 40
+; CHECK-NEXT: popq %r13
+; CHECK-NEXT: .cfi_def_cfa_offset 32
+; CHECK-NEXT: popq %r14
+; CHECK-NEXT: .cfi_def_cfa_offset 24
+; CHECK-NEXT: popq %r15
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: popq %rbp
+; CHECK-NEXT: .cfi_def_cfa_offset 8
+; CHECK-NEXT: retq
+entry:
+ %reg0 = alloca i32, align 4
+ %reg1 = alloca i32, align 4
+ %reg2 = alloca i32, align 4
+ %reg3 = alloca i32, align 4
+ %reg4 = alloca i32, align 4
+ %reg5 = alloca i32, align 4
+ %reg6 = alloca i32, align 4
+ %reg7 = alloca i32, align 4
+ %reg8 = alloca i32, align 4
+ %reg9 = alloca i32, align 4
+ %reg10 = alloca i32, ali...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
// binutils support. | ||
std::string BinutilsVersion; | ||
|
||
enum class FramePointerKind { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Silly question - why is this enum ordered so differently to llvm/include/llvm/Support/CodeGen.h?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked and the order doesn't appear to matter apart from some sanitizer tests which have the frame pointer metadata written like: !1 = !{i32 7, !"frame-pointer", i32 2}
. I can make it consistent if you'd like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've no strong objection to keeping it as it is but it would make sense to match the llvm implementation (assuming that's the one hardwired by metadata) - but I assume that can be done as a followup PR. Thanks for checking
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd want a clang flag that's equivalent to mustMaintainValidFrameChain, to allow requesting non-leaf
behavior on targets where it isn't the default. At least some fraction of users will want that. -mreserve-frame-pointer-reg or something like that.
I guess my remaining question is if -fno-omit-frame-pointer should imply -mreserve-frame-pointer-reg by default. I can see why you'd want it off by default for gcc compatibility. But I suspect most users enabling frame pointers would be happier if it was on. The primary reason people enable frame pointers is to use frame chains to compute a stack trace, and clobbering the frame pointer breaks that. CC @pinskia |
So what happens on GCC side is all target dependent. So GCC compability is a bit odd here since it is dependent on the target and even different between 2 major targets. For x86_64, the ABI recommends (or is it requires) that there is unwind tables. Which is why it is allocatable still. |
Thanks for the prompt review @efriedma-quic! If you look at the following line:
I'm guessing you meant Thanks for the explanation of what happens on GCC @pinskia. I have no concerns with or opinions on I think we should go back to the behaviour that we had on X86 before #146638, i.e. |
This patch adds a new FramePointerKind::NonLeafNoReserve and makes it the default for -momit-leaf-frame-pointer.
This should fix #154379, the main impact of this patch can be found in clang/lib/Driver/ToolChains/CommonArgs.cpp.