3

Does rustc optimize such expressions?

  • 2*x -> x<<1
  • x/2 -> x>>1
  • x % 8 -> x&7
  • and such
ArekBulski
  • 4,520
  • 4
  • 39
  • 61
  • 3
    Yes, that's the kind of optimization that LLVM performs routinely without the assistance of the rustc frontend. – user4815162342 Apr 17 '21 at 07:10
  • 2
    They are even able to optimize more complex cases like `x*13` and `x%13`. Note that optimizations need to be enabled for that. – Jérôme Richard Apr 17 '21 at 07:28
  • 2
    Even more complex example: `pub fn sum(i: u32) -> u32 { (0..i).sum() }` (the sum of all the numbers between 0 and the given number) is optimized to it's closed-form solution. While the code says "iterate over all the numbers and sum them up", LLVM figures that there is an equivalent solution that runs in constant time and removes the loop. – user2722968 Apr 17 '21 at 11:06

1 Answers1

3

Such trivial optimizations are in the domain of LLVM optimization passes, in fact generated assembly is even better and more correct.

2*x is compiled to single instruction lea rax, [rdi + rdi], which on all modern x86 processors is single uop (relevant question)

x/2 for signed numbers is compiled to fastest and the correct way, which gives right answer in case of -1 (relevant question

mov     rax, rdi
shr     rax, 63
add     rax, rdi 
sar     rax 

but compiles to right shift for unsigned numbers

mov     rax, rdi
shr     rax

same story goes for x % 8 it compiles to long assembly for signed numbers (for negative cases)

mov     rax, rdi
lea     rcx, [rdi + 7]
test    rdi, rdi
cmovns  rcx, rdi
and     rcx, -8
sub     rax, rcx
ret

and to and instruction for unsigned numbers (relevant question)

 mov     rax, rdi
 and     eax, 7
 ret

Godbolt link

Inline
  • 2,566
  • 1
  • 16
  • 32