Ошибка очистителя памяти Clang с встроенными функциями SSE
Вот фрагмент кода, который генерирует внутреннюю ошибку компилятора, если я компилирую и запускаю его с clang с включенным очистителем памяти.
В основном он просто помещает некоторые данные в регистр SSE и вызывает функцию для преобразования половинных чисел с плавающей запятой в числа с плавающей запятой:
int main(int argc, char** argv) {
// Just some memory to load from.
alignas(64) std::array<uint16_t, 16> array;
array.fill(0);
__m128i ints = _mm_set1_epi64x(*reinterpret_cast<const uint64_t*>(array.data()));
// msan is happy with this version, and both versions work if we compile with anything other than -Og or -O1
// __m128i ints = _mm_set_epi64x(*reinterpret_cast<const uint64_t*>(array.data()), 0);
__m128 floats = _mm_cvtph_ps(ints);
std::array<float, 4> p;
_mm_storeu_ps(p.data(), floats);
std::cout<< p[0] << p[3] << std::endl;
return 0;
}
См. Также https://godbolt.org/z/5xva3q -
Запуск двоичного файла, созданного clang10.0.1
-Og -g -std=c++17 -march=haswell -fsanitize=memory -fsanitize-memory-track-origins
производит этот вывод:
Program returned: 77
==1==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x4a5f00 (/app/output.s+0x4a5f00)
#1 0x7f1f2b3a0b96 (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#2 0x41f369 (/app/output.s+0x41f369)
SUMMARY: MemorySanitizer: use-of-uninitialized-value (/app/output.s+0x4a5f00)
ORIGIN: invalid (0). Might be a bug in MemorySanitizer origin tracking.
This could still be a bug in your code, too!
Exiting
Я понятия не имею, почему это может вызвать ошибку, и это происходит только при определенных настройках оптимизации. Мне это кажется потенциальной ошибкой, но я хотел подтвердить это на более широкой аудитории.
Изменить: похоже, это исправлено в основной версии clang.