考虑以下示例:
volatile unsigned int x;
unsigned int y;
void f() {
x /= 2;
}
void g() {
y /= 2;
}
用-Os编译时,clang-6.0在x64上为f和g生成相同的
shrl <offset>(%rip)
指令模式(请参见https://godbolt.org/g/hUPprL),而gcc-7.3则为f()生成此模式(请参见https://godbolt.org/g/vMcKVV): mov 0x200b67(%rip),%eax # 601034 <x>
shr %eax
mov %eax,0x200b5f(%rip) # 601034 <x>
这仅仅是错过的优化,还是gcc有理由在访问不稳定的情况下拒绝
shrl <offset>(%rip)
?谁错了? 最佳答案
这只是gcc错过的优化。两种实现都精确地保留了对x
的读取和写入,因此是正确的。
在内存操作数上执行的“高级操作”执行与更长的实现相同的加载和存储。