考虑以下示例:

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的读取和写入,因此是正确的。

在内存操作数上执行的“高级操作”执行与更长的实现相同的加载和存储。

10-06 06:46