Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
13 changes: 9 additions & 4 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,13 @@ class CodeGenOptions : public CodeGenOptionsBase {
std::string BinutilsVersion;

enum class FramePointerKind {
Copy link
Collaborator

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?

Copy link
Member Author

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.

Copy link
Collaborator

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

None, // Omit all frame pointers.
Reserved, // Maintain valid frame pointer chain.
NonLeaf, // Keep non-leaf frame pointers.
All, // Keep all frame pointers.
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, don't allow the FP to be used as a
// GPR in leaf functions.
All, // Keep all frame pointers.
};

static StringRef getFramePointerKindName(FramePointerKind Kind) {
Expand All @@ -167,6 +170,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:
Expand Down
7 changes: 5 additions & 2 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -5657,6 +5657,9 @@ def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings
def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>;
def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>,
HelpText<"Omit frame pointer setup for leaf functions">;
def mno_reserve_frame_pointer_reg : Flag<["-"], "mno-reserve-frame-pointer-reg">, Group<m_Group>;
def mreserve_frame_pointer_reg : Flag<["-"], "mreserve-frame-pointer-reg">, Group<m_Group>,
HelpText<"Reserve the frame pointer register even if the function doesn't have a frame">;
def moslib_EQ : Joined<["-"], "moslib=">, Group<m_Group>;
def mpascal_strings : Flag<["-"], "mpascal-strings">, Alias<fpascal_strings>;
def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>;
Expand Down Expand Up @@ -8481,8 +8484,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">;


Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
49 changes: 35 additions & 14 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,26 +222,39 @@ 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
// | Frame Setup | Reg Reserved |
// |-----------------|-----------------|
// | Non-leaf | Leaf | Non-Leaf | 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
Expand All @@ -261,12 +274,20 @@ 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 = Args.hasFlag(
clang::driver::options::OPT_mreserve_frame_pointer_reg,
clang::driver::options::OPT_mno_reserve_frame_pointer_reg, false);

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;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
76 changes: 45 additions & 31 deletions clang/test/Driver/frame-pointer-elim.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// KEEP-ALL: "-mframe-pointer=all"
// KEEP-NON-LEAF-NOT: warning: argument unused
// KEEP-NON-LEAF: "-mframe-pointer=non-leaf"
// KEEP-NON-LEAF-NO-RESERVE-NOT: warning: argument unused
// KEEP-NON-LEAF-NO-RESERVE: "-mframe-pointer=non-leaf-no-reserve"
// KEEP-NONE-NOT: warning: argument unused
// KEEP-NONE: "-mframe-pointer=none"
// KEEP-RESERVED-NOT: warning: argument unused
Expand All @@ -24,19 +26,27 @@
// -momit-leaf-frame-pointer omits leaf frame pointer.
// -fno-omit-frame-pointer loses out to -momit-leaf-frame-pointer.
// RUN: %clang -### --target=i386 -S -momit-leaf-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=i386-linux -S -O1 -momit-leaf-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s

// -momit-leaf-frame-pointer -mreserve-frame-pointer-reg results in the frame pointer reg being reserved
// RUN: %clang -### --target=i386 -S -momit-leaf-frame-pointer -mreserve-frame-pointer-reg %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s

// -fomit-frame-pointer -mreserve-frame-pointer-reg results in the frame pointer reg being reserved
// RUN: %clang -### --target=i386 -S -fomit-frame-pointer -mreserve-frame-pointer-reg %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-RESERVED %s

// fno-omit-frame-pointer -momit-leaf-frame-pointer can be overwritten by
// fomit-frame-pointer later on the command without warning
// RUN: %clang -### --target=i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s

// RUN: %clang -### --target=i386-linux -S -O1 -fno-omit-frame-pointer -momit-leaf-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// Explicit or default -fomit-frame-pointer wins over -mno-omit-leaf-frame-pointer.
// RUN: %clang -### --target=i386 -S %s -fomit-frame-pointer -mno-omit-leaf-frame-pointer 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NONE %s
Expand Down Expand Up @@ -68,45 +78,45 @@
// RUN: FileCheck --check-prefix=KEEP-NONE %s

// RUN: %clang -### --target=i386-darwin -S -momit-leaf-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s

// 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
// RUN: %clang -### --target=aarch64 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=x86_64-scei-ps4 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=x86_64-scei-ps4 -S -O2 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=x86_64-sie-ps5 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=x86_64-sie-ps5 -S -O2 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### -target aarch64-apple-darwin -arch arm64_32 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=ve-unknown-linux-gnu -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=aarch64-linux-android -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=aarch64-linux-android -S -O2 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=aarch64-linux-android -S -Os %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s

// RUN: %clang -### --target=powerpc64 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
Expand Down Expand Up @@ -161,9 +171,9 @@
// RUN: %clang -### --target=armv7a-linux-androideabi- -mthumb -mbig-endian -O1 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-ALL %s
// RUN: %clang -### --target=riscv64-linux-android -O1 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s

// On ARM backend bare metal targets, frame pointer is omitted
// RUN: %clang -### --target=arm-arm-none-eabi -S %s 2>&1 | \
Expand Down Expand Up @@ -191,21 +201,21 @@

// Check that for Apple bare metal targets, we're keeping frame pointers by default
// RUN: %clang -### --target=armv6m-apple-none-macho -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=armv6m-apple-none-macho -S -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=arm-apple-none-macho -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=arm-apple-none-macho -S -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=armv6m-apple-none-macho -S -O1 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=armv6m-apple-none-macho -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=arm-apple-none-macho -S -O1 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=arm-apple-none-macho -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s

// RUN: %clang --target=armv7-apple-macho -### -S %s 2>&1 \
// RUN: -fomit-frame-pointer \
Expand All @@ -221,17 +231,21 @@

// AArch64 bare metal targets behave like hosted targets
// RUN: %clang -### --target=aarch64-none-elf -S %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=aarch64-none-elf -S -O1 %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=aarch64-none-elf -S -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s
// RUN: %clang -### --target=aarch64-none-elf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s
// RUN: FileCheck --check-prefix=KEEP-NON-LEAF-NO-RESERVE %s

// AArch64 Windows requires that the frame pointer be reserved
// RUN: %clang -### --target=aarch64-pc-windows-msvc -S -fomit-frame-pointer %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-RESERVED %s

// AArch64 Windows requires that the frame pointer be reserved
// RUN: %clang -### --target=aarch64-pc-windows-msvc -S -fomit-frame-pointer -mno-reserve-frame-pointer-reg %s 2>&1 | \
// RUN: FileCheck --check-prefix=KEEP-RESERVED %s

void f0() {}
void f1() { f0(); }
2 changes: 1 addition & 1 deletion clang/test/Driver/fuchsia.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
8 changes: 7 additions & 1 deletion llvm/include/llvm/Support/CodeGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ 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 {
Expand Down
Loading
Loading