https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91841

            Bug ID: 91841
           Summary: vector_size(8) passes MMX register without emms
                    cleanup
           Product: gcc
           Version: 9.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: kretz at kde dot org
  Target Milestone: ---
            Target: i?86-*-*

Test case `g++ -O2 -m32` (cf. https://godbolt.org/z/RDUZo9):

#include <iostream>

using T = unsigned short;
using V [[gnu::vector_size(8)]] = T;

[[gnu::noinline]] V f(V x) { return x; }

int main() {
    volatile float a = 1.f;
    auto x = f(~V{});
    asm("" :: "X"(x));
    std::cout << a + 2.f;
}

The V parameter is passed via mm0 which leads to 1.f+2.f becoming -nan.

If GCC cannot reliably insert emms, it should not (never!) transparently emit
MMX code. Nowhere in this code did I ask for MMX... I understand that this
would be an ABI break. But at least clang does not implement this ABI either.

Why is this relevant?

namespace std {
template <class T, int N>
class simd {
  using V [[gnu::vector_size(sizeof(T) * N)]] = T;
  V d;
public:
  ...
};
}

Subsequently interleaving `std::simd<char, 8>` and any FPU code (forced e.g.
with long double) would lead to disaster.

Reply via email to