Why does the Rust compiler not optimize code assuming that two mutable references cannot alias?

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

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)