https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88998
Bug ID: 88998 Summary: bad codegen with mmx instructions for unordered_map Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: barry.revzin at gmail dot com Target Milestone: --- This program should be valid: #include <cassert> #include <unordered_map> #include <x86intrin.h> [[gnu::noinline]] double prepare(int a, int b) { __m128i is = _mm_setr_epi32(a, b, 0, 0); __m128d ds =_mm_cvtepi32_pd(is); return ds[0] + ds[1]; } int main(int, char**) { double d = prepare(1, 2); std::unordered_map<int, int> m; m.insert({0, 0}); m.insert({1, 1}); assert(m.load_factor() <= m.max_load_factor()); return d; } But if I use MMX instructions, the assertion triggers: $ g++ -std=c++11 -march=haswell -mtune=haswell -mavx -O3 foo.cxx && ./a.out a.out: foo.cxx:19: int main(int, char**): Assertion `m.load_factor() <= m.max_load_factor()' failed. Aborted (core dumped) Whereas it does not if I explicitly remove them: $ g++ -std=c++11 -march=haswell -mtune=haswell -mavx -mno-mmx -O3 foo.cxx && ./a.out $ Additionally, adding a call to _mm_empty() right before the return statement in prepare() fixes the issue. If you look at the load_factor(), it returns 2 (and then 3 on the next insert, etc.)