由于有符号整数溢出是未定义行为,我预计下面的三个函数将编译为相同或类似的汇编代码。然而事实并非如此。test2
与test1
稍有不同,test3
使用了两个不必要的imul
指令。
int test1(int x)
{
return x * 5 / 2;
}
int test2(int x)
{
return x * 10 / 4;
}
int test3(int x)
{
return x * 50 / 20;
}
为什么编译器不执行这种优化呢?
由于有符号整数溢出是未定义行为,我预计下面的三个函数将编译为相同或类似的汇编代码。然而事实并非如此。test2
与test1
稍有不同,test3
使用了两个不必要的imul
指令。
int test1(int x)
{
return x * 5 / 2;
}
int test2(int x)
{
return x * 10 / 4;
}
int test3(int x)
{
return x * 50 / 20;
}
为什么编译器不执行这种优化呢?
这样的优化是否正确取决于实现对整数溢出效果的任何保证:
x*(m*a)/(m*b)
替换为 x*a/b
将违反此类保证。fwrapv
标志构建,该标志强制使用选项#1。
x * 5 / 2
、x * 10 / 4
和x * 50 / 20
会产生不同的结果,因此它们不能被优化为相同的代码。 - Eric Postpischil