Rust originally did enable LLVM’s noalias
attribute, but this caused miscompiled code. When all supported LLVM versions no longer miscompile the code, it will be re-enabled.
If you add -Zmutable-noalias=yes
to the compiler options, you get the expected assembly:
adds:
mov eax, dword ptr [rsi]
add eax, eax
add dword ptr [rdi], eax
ret
Simply put, Rust put the equivalent of C’s restrict
keyword everywhere, far more prevalent than any usual C program. This exercised corner cases of LLVM more than it was able to handle correctly. It turns out that C and C++ programmers simply don’t use restrict
as frequently as &mut
is used in Rust.
This has happened multiple times.
- Rust 1.0 through 1.7 —
noalias
enabled - Rust 1.8 through 1.27 —
noalias
disabled - Rust 1.28 through 1.29 —
noalias
enabled - Rust 1.30 through 1.54 —
noalias
disabled - Rust 1.54 through ??? —
noalias
conditionally enabled depending on the version of LLVM the compiler uses
Related Rust issues
-
Current case
- Incorrect code generation for nalgebra’s Matrix::swap_rows() #54462
- Re-enable noalias annotations by default once LLVM no longer miscompiles them #54878
- Enable mutable noalias for LLVM >= 12 #82834
- Regression: Miscompilation due to bug in “mutable noalias” logic #84958
-
Previous case
- Workaround LLVM optimizer bug by not marking &mut pointers as noalias #31545
- Mark &mut pointers as noalias once LLVM no longer miscompiles them #31681
-
Other
- make use of LLVM’s scoped noalias metadata #16515
- Missed optimization: references from pointers aren’t treated as noalias #38941
- noalias is not enough #53105
- mutable noalias: re-enable permanently, only for panic=abort, or stabilize flag? #45029