Does rustc always ignore inline(never) when optimization is used?

Viewed 161

I have the following Rust code:

#[inline(never)]
fn x() -> i32 {
    21
}

pub fn main() -> i32 {
    x()
}

With no optimization (-C opt-level=0), the function call is not inlined, even if #[inline(never)] is removed.

example::x:
        mov     eax, 21
        ret

example::main:
        push    rax
        call    example::x
        mov     dword ptr [rsp + 4], eax
        mov     eax, dword ptr [rsp + 4]
        pop     rcx
        ret

However, any other optimization level will cause the function to be inlined no matter what.

example::main:
        mov     eax, 21
        ret

I know that the inline attribute is only a suggestion to the compiler, but I can't seem to find any examples where using #[inline(never)] would actually stop a function from being inlined when it otherwise would be.

Here is the Compiler Explorer result: https://godbolt.org/z/WKfevdW37

1 Answers

If I had to guess, a function without side effects (e.g. you can mark it const fn without any errors) is treated as a special optimization separate from inlining. If you give x a side effect (e.g. printing something), then inline(never) will have an effect:

#[inline(never)]
fn x() -> i32 {
    println!("foo");
    21
}

pub fn main() -> i32 {
    x()
}

This doesn't inline in opt-level=0 or opt-level=2, but if you remove the inline(never), then it will inline in opt-level=2.

Related