That being said, there's also cases where Rust does not have LLVM semantics, and that can cause bugs. Some famous examples being the loop optimization miscompilation, and &mut T currently not being marked noalias.
That being said, there's also cases where Rust does not have LLVM semantics, and that can cause bugs. Some famous examples being the loop optimization miscompilation, and &mut T currently not being marked noalias.
I don't think that's a case where Rust "doesn't have LLVM semantics" since the miscompilation was reproduced in standard C. Rather that rust is actively and ubiquitously leveraging otherwise rarely-exercised LLVM features, revealing a bunch of bugs (either leftovers or breakages) in them.
The former though is an area of significant divergence between Rust and C++ semantics, and LLVM directly following C++ semantics.
Ah I must have missed that, I thought you were talking about only one thing (since IIRC the noalias miscompilation is due to loop unrolling?)
There is a major effort to revamp the `noalias`/`restrict` handling going on for a while now. It takes quite long because it is hard and complex and we want to get it right.
In case you are interested, here is the new design https://reviews.llvm.org/differential/changeset/?ref=2170825 here the overall code changes currently considered https://reviews.llvm.org/D69542 and here you can find information on our monthly LLVM Alias Analysis call https://docs.google.com/document/d/1ybwEKDVtIbhIhK50qYtwKsL5...
TL;DR: C++ says that an infinite loop with no side effects is UB, Rust does not. Empty loops in Rust will disappear entirely when they should really loop forever.
(I edited my comment slightly because, re-reading, "blindly" sounds too negative.)
loop {
core::sync::atomic::compiler_fence( core::sync::atomic::Ordering::SeqCst);
}
So there is a significant difference in semantics between Rust and C/C++ here.
The standard may allow the generation of insane code, but a decent-quality compiler does not do so. The standard ought to be fixed.
Which ones?
If this optimizations are so important, how come Rust was designed in such a way to make them impossible? Also, how does this fit, e.g., the benchmark game results which show that Rust is faster than C for all benchmarks considered there ?
C does not have this guarantee (at least not in all cases). Also rust is compiled with the llvm backend, so my understanding is that in practice rust assumes that loops terminate. See:
https://github.com/rust-lang/rust/issues/28728
There are llvm directives that can be added to prevent the optimization, but they are rejected by the rust maintainers exactly because they would cause performance regressions.
Letting the compiler assume that a "switch" without a default will never go there is a great optimization too. Why not put that in the standard?
Actually, this is worse. Letting the loop be UB is like letting a true "if" be UB. Just never mind the code actually written; surely it doesn't mean what it says.
that's actually the case already. A missing default is UB if the switch condition does not match any of the cases. And C compilers already optimize accordingly.
If your loop infinitely writes the number 70 to an atomic int, it's fine.