Skip to content

#[inline(never)] is not respected for trivial functions #91452

@linkmauve

Description

@linkmauve

I’m working on a pure Rust Wii/GameCube bare metal runtime, and in order to get the Dolphin emulator to output debug information to stdout I need to have a function named a certain way which gets replaced at runtime with code from outside the sandbox.

In order to do so, #[inline(never)] seemed the perfect match, but I couldn’t get it to actually force the function to never be inlined, which kind of defeats its purpose.

I found a workaround in having an empty asm!() call, which also needs to receive the registers, otherwise rustc won’t even emit the code putting the correct values for the arguments before the call. This has the downside of allocating and deallocating 16 bytes on the stack, I’m really not sure why as the assembly doesn’t actually do anything.

I tried this code:

#![feature(asm)]

#[no_mangle]
#[inline(never)]
unsafe extern "C" fn do_foo(arg: u32) {
    // Comment out this line and this function becomes a noop, and never gets
    // called.
    asm!("/* {0} */", in(reg) arg);
}

fn main() {
    unsafe { do_foo(4) };
    unsafe { do_foo(12) };
}

I expected to see this happen: codegen should be exactly the same with and without the asm!() call on line 8, due to the #[inline(never)] which requests do_foo() calls to stay as calls and not be inlined.

Instead, this happened: when line 8 is commented out, rustc detects do_foo is a noop and inlines it in main as such, which then contains a single blr instruction (equivalent of ret on x86). This renders #[inline(never)] useless.

Meta

rustc --version --verbose:

rustc 1.58.0-nightly (65f3f8b22 2021-11-21)
binary: rustc
commit-hash: 65f3f8b220f020e562c5dd848ff7319257a7ba45
commit-date: 2021-11-21
host: x86_64-unknown-linux-gnu
release: 1.58.0-nightly
LLVM version: 13.0.0

I’m building for PowerPC, but this bug also reproduces on x86.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions