-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
opt-level=0 does not do constant folding #136366
Comments
Additional info: A google search of the term "constant folding" results in several articles that describe the process that calculates the literal expression and replaces the expression with a single value, the behavour I am advocating here. Some of these articles even state that this is a "compiler optimization". However, gcc, by default, applies this process even when the optimization level is set to none; therefore, it seems to me that the gcc developers considered this to be a desirable feature that doesn't need an option to invoke. gcc does have a means to inhibit constant folding for floating point numbers, in particular, with the option |
The semantics of these values is that they are indeed potentially evaluated at runtime. Consider instead https://rust.godbolt.org/z/637djG7cd which uses the following code: #[inline(never)]
pub fn whatever() -> i32 {
let _blah = const { 1 << (5 + 2) };
_blah
} The use of the I am not entirely sure why |
The expression is correctly folded with overflow checks disabled; Looks like overflow checks require Seems like a regression from stable to stable; @rustbot label +A-codegen +C-optimization +I-heavy +T-compiler |
Oh, thank you for identifying this is a regression! I was wondering. |
This was probably due to the following PR which changed const prop to happen at higher MIR opt levels: #109900 |
If this sort of regression is a problem for you, you should definitely be using |
Consider this code:
When inspecting the assembly (from gdb), I expected to see this happen:
Instead, this happened:
This is the compiler actually generating code that computes the value of 1 << (5 + 2) at run time, along with a whole bunch of stuff that appears to relate to the safety of performing such an operation on variable data at run time.
This is unexpected. The entire expression on the right side of the assignment statement, 1 << (5 + 2), involves no variables. This can be safely resolved at compile time.
Strangely, the following code,
actually produces the expected result. This isn't consistent behaviour. Why is this expression, 1 << 7, resolved at compile time while 1 << (5 + 2) is not?
If I set the optimization level to 1 in the Cargo.toml as follows:
The expected code is produced with either expression (as long as the variable is used later, of course). However, I do not see how this is thought of as an optimization; optimization is supposed to be applied to executed code that involves actual data in variables or references. Since both 1 << (5 + 2) and 1 << 7 are literal expressions that resolve to the same identical value, and they do not involve data, they do not need to be "optimized". Each expression ought to be treated as a single entity and treated the same.
Rationale:
I suppose that this will be viewed as trivial in the context of a PC or server environment. However, in an embedded environment, the additional unnecessary code may result in consumption of valuable resources, if optimization must be disabled in order to perform debugging activites on an embedded system. This might even cause the unoptimized code to not compile at all on a sytem with tight memory constraints. Therefore, it is desirable, and in my opinion, a show stopper, that evaluation of literal expressions ought to be resolved at compile time regardless of optimization level.
Meta
rustc --version --verbose
:Backtrace
The text was updated successfully, but these errors were encountered: