为什么LLVM不通过优化浮点指令?
这个问题在这里已经有了答案:
说不优化是不可能的。 我将通过前几行来显示转换和不允许的转换:
%addtmp = fadd double %x, %x
这第一行可以安全地转换为fmul double %x 2.0e+0
,但实际上这并不是大多数体系结构上的优化( fadd
通常比fmul
快或者更快,并且不需要生成常量2.0
)。 请注意,禁止溢出,这个操作是准确的(就像所有按2的幂进行缩放)。
%addtmp1 = fadd double %addtmp, %x
该行可以转换为fmul double %x 3.0e+0
。 为什么这是一个合法的转变? 因为生成%addtmp
的计算是精确的,所以只有一次四舍五入,无论这是计算为x * 3
还是x + x + x
。 由于这些是IEEE-754基本操作,因此正确舍入,结果是相同的。 什么溢出? 除非另一方也如此,否则都不会溢出。
%addtmp2 = fadd double %addtmp1, %x
这是无法合法转换为常数* x的第一行。 4 * x
会精确计算,没有任何舍入,而x + x + x + x
会产生两次舍入: x + x + x
会舍入一次,然后再次将x
加上一次。
%addtmp3 = fadd double %addtmp2, %x
同上这里; 5 * x
会产生一次舍入; x + x + x + x + x
引发三次。
唯一可能有益的改变是用3 * x
代替x + x + x
3 * x
。 然而,子表达式x + x
已经存在于其他地方,所以优化器很容易选择不使用这种转换(因为如果不存在,它可以利用现有的部分结果)。
上一篇: Why don't LLVM passes optimize floating point instructions?