Non-aliasing guarantees of &mut T and rustc optimization

Dear Rustaceans,
I did a small experiment in Compiler Explorer to test whether non-aliasing guarantees of mutable references let rustc do additional optimizations in some situations.

I wrote a very short function in C and Rust to compare how they are compiled down to assembly. My expectation was that rustc would take advantage of the fact that a and b are non-aliasing pointers, and generate assembly that would simply return 10 (without even dereferencing the pointers). However, it turns out the generated assembly from gcc and rustc are identical, indicating that Rustc didn't work as I expected. Optimization levels were O3 in both gcc and rustc.

It seems to me that rustc is missing an optimization opportunity, but I'd like to know what other Rustaceans would think about this. Thanks! :slight_smile:

4 Likes

This is due to aliasing bugs in LLVM, see

7 Likes

Wow, that was pretty fast! Thanks!

1 Like

Just happened to be on when I saw your question. :slight_smile:

1 Like

I'm not able to give references and what was stated may well be out of date but...

I have been tenaciously watching every Rust related video I can find on YouTube, a couple of times presenters have mentioned that there were opportunities for optimization offered by the non-aliasing guarantees that were not yet passed on to LLVM. The expectation being that they would be in the future.

I guess that includes whatever is covered by the github issue mentioned above.

1 Like

Oddly, when I punch your example code into godbolt I get one more instruction than you do. For all versions of Rust, at op-level 2 and 3:

        mov     dword ptr [rdi], 4
        mov     dword ptr [rsi], 6
        mov     eax, dword ptr [rdi]
        add     eax, eax
        lea     eax, [rax + 2*rax]
        ret

Long story short, C has been so bad at providing good non-aliasing guarantees that LLVM related code generation was never truly tested in "real production". It's only with Rust that it has been the case, and this has revealed LLVM bugs. So until these are fixed (it's something that is being worked on), this kind of optimizations cannot be exploited yet.

4 Likes

That is interesting.. would you mind sharing the link to your godbolt experiment? Link to mine is in the post.
I wonder if it could be a bug from Godbolt's side..

No, never mind, I had a "*" where you have a "+"

Your gogbolt refused to load in my browser earlier and I had a hard time reading your code from the image above.

It all comes out the same now.

1 Like

Just a small note about "what Rust could do", adding a couple of restrict in the C version gives us what we will expect (hopefully) in Rust.

Compiler Explorer

2 Likes

Wow, been using C since forever, never heard of "restrict", never seen it used. From wikipedia:

if the declaration of intent is not followed and the object is accessed by an independent pointer, this will result in undefined behavior. The use of the restrict keyword in C, in principle, allows non-obtuse C to achieve the same performance as the same program written in Fortran.

I think I see why I have never seen it used.

BTW, Is this post more relevant to the "Rust Internals Forum"??
If so, from now on I'll try to post such questions to that forum instead of the Rust language forum..

This is a bit fuzzy, I could see this on either forum, but I think that users is a better fit for questions.

3 Likes

I concur with @KrishnaSannasi – Rust Internals is focused on language and tooling enhancements / changes, whereas Rust Users (this forum) is more appropriate for answering questions about the existing language and tooling, as well as for providing help in how to express programming intent in Rust, Cargo, etc.

I'd imagine that issues like the OP here are well known to the developers so no point to bother them about it.

It's an interesting tidbit for us users to be aware of though.