编译器优化:将变量从堆栈移至寄存器

时间:2019-03-23 14:42:53

标签: c++ gcc clang language-lawyer compiler-optimization

代码如下:

#include <cstring>
#include <cstdint>
#include <cstddef>

uint64_t uint5korr(const std::byte *p)
{
  uint64_t result= 0;
  std::memcpy(&result, p, 5);
  return result;
}

https://godbolt.org/z/vULPAZ

这里的clang将result优化为寄存器,而gcc则没有。 我怀疑这可能与我使用变量的地址有关,因为我不能使用寄存器的地址。

这仅仅是gcc缺少优化还是clang某种程度上违反了标准?

2 个答案:

答案 0 :(得分:1)

是的,此优化是合法的。从正确的地址读取5个字节(不是8个字节);无需再次存储它们,只需阅读return,已收地址或否的地址即可。我与迈克尔·肯泽尔(Michael Kenzel)对此表示怀疑,认为它已经定义了行为,但这只能巩固优化的有效性。

答案 1 :(得分:1)

不是答案。

虽然在GCC中似乎确实缺少优化本身,但是使用部分memcpy ed值IIUC却是不确定的行为。我会向GCC提交错误,以就此问题获得明确的答复。

通过GCC / Clang / MSVC完美优化的方式来加载40位宽度的整数:

std::uint64_t load_u40(const std::byte *p)
{
  std::uint8_t lo = 0;
  std::memcpy(&lo, p, 1);
  std::uint32_t hi = 0;
  std::memcpy(&hi, p + 1, 4);
  return (static_cast<std::uint64_t>(hi) << 8) | lo;
}

https://godbolt.org/z/4Kk9IM