Skip to content

Commit 638be20

Browse files
committed
llvm: Always omit the frame pointer for naked functions.
1 parent 2e8be2f commit 638be20

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

src/codegen/llvm.zig

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2909,7 +2909,17 @@ pub const Object = struct {
29092909
function_index.setAlignment(resolved.alignment.toLlvm(), &o.builder);
29102910

29112911
// Function attributes that are independent of analysis results of the function body.
2912-
try o.addCommonFnAttributes(&attributes, owner_mod);
2912+
try o.addCommonFnAttributes(
2913+
&attributes,
2914+
owner_mod,
2915+
// Some backends don't respect the `naked` attribute in `TargetFrameLowering::hasFP()`,
2916+
// so for these backends, LLVM will happily emit code that accesses the stack through
2917+
// the frame pointer. This is nonsensical since what the `naked` attribute does is
2918+
// suppress generation of the prologue and epilogue, and the prologue is where the
2919+
// frame pointer normally gets set up. At time of writing, this is the case for at
2920+
// least x86 and RISC-V.
2921+
fn_info.cc == .Naked,
2922+
);
29132923

29142924
if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder);
29152925

@@ -2956,13 +2966,14 @@ pub const Object = struct {
29562966
o: *Object,
29572967
attributes: *Builder.FunctionAttributes.Wip,
29582968
owner_mod: *Package.Module,
2969+
prohibit_frame_pointer: bool,
29592970
) Allocator.Error!void {
29602971
const comp = o.pt.zcu.comp;
29612972

29622973
if (!owner_mod.red_zone) {
29632974
try attributes.addFnAttr(.noredzone, &o.builder);
29642975
}
2965-
if (owner_mod.omit_frame_pointer) {
2976+
if (prohibit_frame_pointer or owner_mod.omit_frame_pointer) {
29662977
try attributes.addFnAttr(.{ .string = .{
29672978
.kind = try o.builder.string("frame-pointer"),
29682979
.value = try o.builder.string("none"),
@@ -4528,7 +4539,7 @@ pub const Object = struct {
45284539

45294540
var attributes: Builder.FunctionAttributes.Wip = .{};
45304541
defer attributes.deinit(&o.builder);
4531-
try o.addCommonFnAttributes(&attributes, zcu.root_mod);
4542+
try o.addCommonFnAttributes(&attributes, zcu.root_mod, false);
45324543

45334544
function_index.setLinkage(.internal, &o.builder);
45344545
function_index.setCallConv(.fastcc, &o.builder);
@@ -4557,7 +4568,7 @@ pub const Object = struct {
45574568

45584569
var attributes: Builder.FunctionAttributes.Wip = .{};
45594570
defer attributes.deinit(&o.builder);
4560-
try o.addCommonFnAttributes(&attributes, zcu.root_mod);
4571+
try o.addCommonFnAttributes(&attributes, zcu.root_mod, false);
45614572

45624573
function_index.setLinkage(.internal, &o.builder);
45634574
function_index.setCallConv(.fastcc, &o.builder);
@@ -9676,7 +9687,7 @@ pub const FuncGen = struct {
96769687

96779688
var attributes: Builder.FunctionAttributes.Wip = .{};
96789689
defer attributes.deinit(&o.builder);
9679-
try o.addCommonFnAttributes(&attributes, zcu.root_mod);
9690+
try o.addCommonFnAttributes(&attributes, zcu.root_mod, false);
96809691

96819692
function_index.setLinkage(.internal, &o.builder);
96829693
function_index.setCallConv(.fastcc, &o.builder);

0 commit comments

Comments
 (0)