编译器会优化数学表达式吗?

3

rustc是否对这些表达式进行优化?

  • 2*x -> x<<1(将x左移1位)
  • x/2 -> x>>1(将x右移1位)
  • x % 8 -> x&7(取x与7的按位与结果)
  • 以及类似的操作

3
没问题,LLVM经常在没有rustc前端的帮助下执行这种优化。 - user4815162342
2
它们甚至能够优化更复杂的情况,如 x*13x%13。请注意,需要启用优化。 - Jérôme Richard
2
更复杂的例子:pub fn sum(i: u32) -> u32 { (0..i).sum() }(计算0到给定数字之间所有数字的总和)被优化为其闭式解。虽然代码中说“遍历所有数字并将它们相加”,但LLVM发现有一个等效的解决方案可以在常数时间内运行并删除循环。 - user2722968
1个回答

3

这些微小的优化属于LLVM 优化 Pass的领域,实际上生成的汇编代码更好、更正确。

2*x 编译成单指令 lea rax, [rdi + rdi],在所有现代 x86 处理器上都是单 uop(相关问题

x/2 对于有符号数被编译为最快和正确的方式,这在 -1 的情况下可以得到正确的答案(相关问题

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

但对于无符号数,它会编译成右移操作。

mov     rax, rdi
shr     rax

x % 8同样适用这个情况,对于有符号数(负数),它会编译成较长的汇编代码。

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

针对无符号数的and指令(相关问题

 mov     rax, rdi
 and     eax, 7
 ret

Godbolt link


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接