【发布时间】:2019-05-13 11:57:41
【问题描述】:
考虑一下我在this question 中找到的这个函数:
void to_bytes(uint64_t const& x, uint8_t* dest) {
dest[7] = uint8_t(x >> 8*7);
dest[6] = uint8_t(x >> 8*6);
dest[5] = uint8_t(x >> 8*5);
dest[4] = uint8_t(x >> 8*4);
dest[3] = uint8_t(x >> 8*3);
dest[2] = uint8_t(x >> 8*2);
dest[1] = uint8_t(x >> 8*1);
dest[0] = uint8_t(x >> 8*0);
}
由于x 和dest 可能指向同一个内存,因此不允许编译器将其优化为单个qword 移动(每一行都可能更改x 的值)。
到目前为止一切顺利。
但如果您改为通过值传递x,则此参数不再成立。
事实上,GCC 将其优化为一个简单的 mov 指令,正如预期的那样:https://godbolt.org/z/iYj1or
但是,clang 没有:https://godbolt.org/z/Hgg5z9
我假设,因为它甚至不能保证 x 占用任何堆栈内存,所以任何尝试使 dest 指向 x 在调用函数之前会导致未定义的行为,因此编译器可以假设这永远不会发生。这意味着 clang 在这里错过了一些机会。但我不确定。有人可以澄清一下吗?
【问题讨论】:
-
对齐浮现在脑海中。不确定您是否可以使用未对齐的 qword mov。
-
@Someprogrammerdude 我不想让编译器不优化它。我只是想知道 clang 是否有正当理由不像 gcc 那样优化它
-
dest不能指向局部变量,因为它还不存在。也许报告一个错过的优化错误 -
@M.M 是的,这和我的想法一样。将尽快提交报告
-
你在问为什么clang不做gcc做的一些/所有优化?也许是因为它不是必需的。
标签: c++ optimization clang