Code change:
The godbolt link: I think this snippet should just return : The generated asm with :
I think there are 2 issues: is not const fn is not const fn See this modified example:
I may misunderstand but in the C version, does clang require similar conditions to optimize code? modify labels: A-codegen A-const-eval
Those are preprocessor directives and are handled at compile time so their Rust equivalent would be:
states that macro:
Good point, those two are equal: I don't know enough about const and I could be totally wrong but I think in the first case expands to something like: It cannot make constant because is not yet complete.
Interesting, If I look at MIR output, I think rustc already have enough information: <details<summaryMIR</summary</details
Whether a function is marked at the source level has no effect on whether or not it can be optimized by LLVM. Even if was not , inlining and const propagation could conceivably reduce this to a constant.
Rust now generates the for the OP's code: I would guess that recent improvements to const propagation in the MIR are responsible for this (thanks but it might also have been a change in LLVM. This seems like a decent candidate for a codegen regression test, although an equivalent one might already exist.
It is better now. But are and instructions necessary?
I assume it is due to a difference in calling convention, but it does seem kind of silly. You'll need to ask someone more knowledgeable unfortunately.
A quick google leads me to believe that the is used to align the stack to a 16-byte boundary.
So does it: Looks like only regression tests are needed.
This version doesn't need any stack alignment:
I tried to leave this alone since I'm not very knowledgeable in this area, but curiosity got the better of me. The following might be incorrect, but it's my best guess. In the optimized LLVM IR for rust, a call to remains which has been optimized out in the C++ version. I believe stack alignment on x64 is required only prior to a instruction, so LLVM sees that a non-trivial call instruction exists in the IR from rust and that only has an 8-byte return pointer on the stack, meaning the stack would be misaligned for that . That's why it inserts the stack alignment code in the rust version only. At some point during translation to x86 assembly, the gets removed entirely (I have no idea how), resulting in a function that has a / to align the stack for a call but that doesn't actually call anything. Perhaps someone more familiar with the various LLVM passes could say more. BTW, a fairer C++ comparison is the following, but this gives the same results:
There's some discussion of this in . I was indeed wrong BTW :smile:.
This issue appears to be fixed on beta. Maybe we need a codegen test for it. Edit: It seems that the llvm-ir generated by rustc are the same between beta and stable. Only the optimized asm for x86 is different. Should I just write assembly codegen or just close this issue.
The issue seems to have re-appeared in master :(
Both & generates the following asm (with )

Related discussion:
text: <ins> // Ensure the asm for array comparisons is properly optimized. //@ compile-flags: -C opt-level=2 #![crate_type = "lib"] // CHECK-LABEL: @compare // CHECK: start: // CHECK-NEXT: ret i1 true #[no_mangle] pub fn compare() -> bool { let bytes = 12.5f32.to_ne_bytes(); bytes == if cfg!(target_endian = "big") { [0x41, 0x48, 0x00, 0x00] } else { [0x00, 0x00, 0x48, 0x41] } } </ins>