clang vs gcc:易失性访问的不同代码

clang vs gcc: different code for volatile access

考虑这个例子:

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), while gcc-7.3 produces this (See https://godbolt.org/g/vMcKVV)f():

 mov 0x200b67(%rip),%eax # 601034 <x>
 shr %eax
 mov %eax,0x200b5f(%rip) # 601034 <x>

这只是错过了优化,还是 gcc 有理由拒绝 shrl <offset>(%rip) 以防访问不稳定?谁错了?

这只是 gcc 遗漏的优化。两种实现都精确地保留了对 x 的读取和写入,因此都是正确的。

"Under the hood" 对内存操作数的操作执行与较长实现相同的加载和存储。