c++ - Clang 不优化这段代码有什么原因吗?

标签 c++ optimization clang

考虑我在 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);
}

由于 xdest 可能指向相同的内存,编译器不允许将其优化为单个 qword 移动(每行可能会更改 x).

到目前为止一切顺利。

但如果您改为按值传递 x,则此论点不再成立。 事实上,GCC 将其优化为一个简单的 mov 指令,正如预期的那样:https://godbolt.org/z/iYj1or

但是,clang 不会:https://godbolt.org/z/Hgg5z9

我假设,因为甚至不能保证 x 完全占用任何堆栈内存,任何使 dest 指向 x< 的尝试 before 函数被调用将导致未定义的行为,因此编译器可以假设这永远不会发生。这意味着 clang 在这里错过了一些机会。但我不确定。有人可以澄清一下吗?

最佳答案

您提供的代码过于复杂。您可以将其替换为:

void to_bytes(uint64_t x, uint8_t* dest) {
    x = htole64(x);
    std::memcpy(dest, &x, sizeof(x));
}

是的,这使用了 Linux-ism htole64(),但如果您在另一个平台上,您可以轻松地重新实现它。

Clang 和 GCC 在小端和大端平台上都对此进行了完美优化。

关于c++ - Clang 不优化这段代码有什么原因吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56111844/

相关文章:

delphi - 用Delphi快速搜索大文件中是否存在字符串

c++ - 删除析构函数的类被认为是可简单复制的?

c++ - GCC如何优化这个 `switch`

c++ - 使用 GoogleTest 对构造函数进行死亡测试

微 Controller 类型转换改进

c++ - memset 和 std::complex<double> 的动态数组

python - 在 Python 中使用 Pyomo 库的强对偶约束

arduino - Clang + AVR 编译错误 : '=w' in asm

c++ - 覆盖标准库使用的内存分配方法?

c++ - 这个元素在 c++ Qt 中被称为什么?