оптимизация компилятора: перемещение переменной из стека в регистр - PullRequest
3 голосов
/ 23 марта 2019

Вот код:

#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 ]

1 голос
/ 24 марта 2019

Не ответ.

Хотя сама по себе оптимизация действительно отсутствует в 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

1 голос
/ 23 марта 2019

Да, эта оптимизация является законной.5 байтов (не 8) считываются с правильного адреса;нет необходимости хранить их снова, просто чтобы прочитать их для return, адреса заняты или нет.Я разделяю скептицизм Майкла Кензела о том, что это определило поведение, но это может только укрепить обоснованность оптимизации.

...