Force compiler to compile a function rather than optimize it out in release mode

I have a function that is complicated but has no side effects and is removed as an optimisation in release mode! In debug mode it exists and is called (with a segfault, I may add).

Is there any way to force the function to compile - I want to hand-examine the assembly dump in release mode because the function is performance critical.

Steve

What this sounds like is that your function causes Undefined Behavior. The correct solution is thus to fix the code.


There's no way to control optimization at a function level with rustc. You can, however, choose to optimize different crates at different levels. ref

2 Likes

If the optimizer went so far as to remove your function, then I'd bet efforts to force keeping it would just give you a trap-unreachable result, like x86 UD2.

3 Likes

maybe #[no_mangle] helps

#[no_mangle]
fn segfault()->!{
    unreachable!()
}
fn main(){
    segfault()
}

which compiles to

segfault:
.Lfunc_begin0:
        .file   1 "/app" "example.rs"
        .loc    1 2 0
        .cfi_startproc
        pushq   %rax
        .cfi_def_cfa_offset 16
.Ltmp0:
        .loc    1 3 5 prologue_end
        leaq    .L__unnamed_1(%rip), %rdi
        leaq    .L__unnamed_2(%rip), %rdx
        movl    $40, %esi
        callq   *core::panicking::panic@GOTPCREL(%rip)
        ud2

you could see, segfault does not removed.

std::hint::black_box() may be useful here as an optimization barrier. (It is currently nightly-only but will be stable soon.)

That said, I agree with @CAD97 that if your code currently segfaults then you should not assume that anything about it is representative of what a corrected version would compile to.

3 Likes

Alright, I solved the problem... examining the assembly dump, the compiler removed the whole function. This was because it detected a pointer in it was null and following it would cause a crash. It replaced the code with a UD2 operation. I fixed the bug in the function and used #[inline(never)] and now the compiler includes the function.

It would be good if such a smart compiler could issue a warning or error if it detects following the null pointer, rather than deliberately making the program crash.

Btw. Rust compiler generated brilliant assembly code for my function, I am convinced that inline assembler is hardly ever needed.

Steve

2 Likes

On one hand, I imagine the Rust team would agree with this, and you can file a request at https://github.com/rust-lang/rust/issues/new?labels=A-diagnostics%2C+T-compiler&template=diagnostics.md, with example code that triggers this behavior. On the other hand, I suspect that it was LLVM rather than the Rust part of rustc that detected the problem and resolved it simply by making the program fail faster, and making rustc able to detect the problem may be too difficult to be prioritized much.

2 Likes