Skip to content

opt-level=0 does not do constant folding #136366

Closed as not planned
Closed as not planned
@allanwmacdonald

Description

@allanwmacdonald

Consider this code:

  let _blah = 1 << (5 + 2);

When inspecting the assembly (from gdb), I expected to see this happen:

   0x000055555555b740 <+0>:	movl   $0x80,-0x4(%rsp)

4	}
=> 0x000055555555b748 <+8>:	ret    

Instead, this happened:

3	  let _blah = 1 << (5 + 2);
=> 0x000055555555b7c1 <+1>:	mov    $0x5,%eax
   0x000055555555b7c6 <+6>:	add    $0x2,%eax
   0x000055555555b7c9 <+9>:	mov    %eax,(%rsp)
   0x000055555555b7cc <+12>:	seto   %al
   0x000055555555b7cf <+15>:	jo     0x55555555b7db <_ZN9debugrust4main17h1db24d82a646b36bE+27>
   0x000055555555b7d1 <+17>:	mov    (%rsp),%eax
   0x000055555555b7d4 <+20>:	cmp    $0x20,%eax
   0x000055555555b7d7 <+23>:	jb     0x55555555b7eb <_ZN9debugrust4main17h1db24d82a646b36bE+43>
   0x000055555555b7d9 <+25>:	jmp    0x55555555b7fe <_ZN9debugrust4main17h1db24d82a646b36bE+62>
   0x000055555555b7db <+27>:	lea    0x4c87e(%rip),%rdi        # 0x5555555a8060
   0x000055555555b7e2 <+34>:	lea    -0x2b9(%rip),%rax        # 0x55555555b530 <_ZN4core9panicking11panic_const24panic_const_add_overflow17h5a5f82b06563d133E>
   0x000055555555b7e9 <+41>:	call   *%rax
   0x000055555555b7eb <+43>:	mov    (%rsp),%ecx
--Type <RET> for more, q to quit, c to continue without paging--c
   0x000055555555b7ee <+46>:	and    $0x1f,%ecx
   0x000055555555b7f1 <+49>:	mov    $0x1,%eax
   0x000055555555b7f6 <+54>:	shl    %cl,%eax
   0x000055555555b7f8 <+56>:	mov    %eax,0x4(%rsp)
   0x000055555555b7fe <+62>:	lea    0x4c873(%rip),%rdi        # 0x5555555a8078
   0x000055555555b805 <+69>:	lea    -0x29c(%rip),%rax        # 0x55555555b570 <_ZN4core9panicking11panic_const24panic_const_shl_overflow17hfdbee9592709de18E>
   0x000055555555b80c <+76>:	call   *%rax

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,

  let _blah = 1 << 7;

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:

[profile.dev]
opt-level = 1

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:

rustc 1.84.0 (9fc6b4312 2025-01-07)
binary: rustc
commit-hash: 9fc6b43126469e3858e2fe86cafb4f0fd5068869
commit-date: 2025-01-07
host: x86_64-unknown-linux-gnu
release: 1.84.0
LLVM version: 19.1.5

Backtrace

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationC-optimizationCategory: An issue highlighting optimization opportunities or PRs implementing suchI-heavyIssue: Problems and improvements with respect to binary size of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions