Open CrazyboyQCD opened 1 month ago
@rustbot label +A-codegen +C-optimization +T-compiler +I-slow -needs-triage
In C and C++, integer overflow is considered UB, so rather than j = j + 1;
you might also consider j = j.unchecked_add(1);
. Funny enough, this makes the Rust codegen worse.
Also note that if you switch from Clang to GCC, the optimizer manages to eliminate the loop in C. So this is (probably?) unrelated to the fact that C++ considers infinite loops without side effects to be UB.
unrelated to the fact that C++ considers infinite loops without side effects to be UB.
May be this is the reason, and rust doesn't think so, though it can be optimized if put it in a const
block to force a constant evalutation or put j = j + 1
after the modulo
like while
and for
.
I did some extra test and found it can be optimized away on certain condition and I don't known why it works.
The optimization difference in C++ is indeed due to the forward progress guarantee. SCEV just doesn't know how to compute the exit count for such a loop, and thus can't prove it finite, see https://llvm.godbolt.org/z/vMMT9b7GT.
It should be easy to support this. What is the real-world context where you encountered this issue?
The optimization difference in C++ is indeed due to the forward progress guarantee.
What then is the explanation for the optimization difference in C with GCC? (godbolt link)
From what I understand, C89 and C99 have no forward progress guarantee, and C11/C17/C23 only makes some infinite loops without side effects UB (e.g. while (1)
can not be assumed to terminate)
The optimization difference in C++ is indeed due to the forward progress guarantee. SCEV just doesn't know how to compute the exit count for such a loop, and thus can't prove it finite, see https://llvm.godbolt.org/z/vMMT9b7GT.
@nikic, thanks for explaining.
What is the real-world context where you encountered this issue?
I accidentally found out when I was coding with primality test.
rust
andc
can't optimize code like this whenmodulo
is larger than100
and is notpower of 2
butcpp
can:rust
: godbolt linkc
: godbolt linkcpp
: godbolt link