[Visual C++] Initializer List für __m128 erlaubt?

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

[Visual C++] Initializer List für __m128 erlaubt?

Beitrag von Krishty »

Huhu,

auf der Arbeit stecken wir seit einem Jahr bei Visual C++ 2015 fest, weil das Produkt kaputtgeht, wenn wir auf 2017 aktualisieren.

Ich habe das Problem auf folgende Situation eingegrenzt:

  struct Matrix {
    __m128 a;
    __m128 b;
    __m128 c;
    __m128 d;
  };

  …

  return { // Matrix
    { fa, fb, fc, fd }, // alles floats
    { fe, ff, fg, fh },
    { fi, fj, fk, fl },
    { fm, fn, fo, fp }
  };


Diese Initialisierungsliste funktionierte mit Visual C++ 2015 richtig, aber mit Visual C++ 2017 wird der zweite Vektor falsch initialisiert. Wenn ich statt einer Initialisierungsliste vier Mal _mm_set_ps() nutze, funktioniert der Code wieder.

Bevor ich einen Bug melde: Ist das undefined behavior? __m128 ist definiert als

  union __m128 {
    float m128_f32[4];
    unsigned __int64 m128_u64[2];
    …
  };


Meines Wissens nach müsste die Initializer List für das erste Member gelten, also die vier floats. Oder gibt es da einen Fallstrick, dass meine zweite Initializer List auf die 64-Bit-Integer bezogen werden kann? (Dann kann ich mir aber nicht erklären, warum der dritte und vierte Vektor wieder richtig initialisiert werden.)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Visual C++] Initializer List für __m128 erlaubt?

Beitrag von xq »

Also ein Blick in die Doku sagt:
Sie sollten auf die __m128-Felder nicht direkt zugreifen. Sie können diese Typen jedoch im Debugger finden. Eine Variable vom Typ __m128 wird den XMM[0-7]-Registern zugeordnet.
Das klingt für mich so, als solltest du das auch nicht initializerlist initialisierien
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] Initializer List für __m128 erlaubt?

Beitrag von Krishty »

Mit dem Zitat hast du recht. Ich möchte das nicht einfach so beiseite wischen, aber meinem Eindruck nach ist es veraltet:
  • damit gäbe es keine Möglichkeit, constexpr __m128 zu initialisieren
  • der Compiler erzeugt seit 2015 bei direktem Zugriff auf die Member oft besseren Code als mit Intrinsics (in vorherigen Compiler-Versionen war es umgekehrt), was darauf schließen lässt, dass sie diese Richtung langfristig anstreben
  • dann hätte es mit VS 2015 auch nicht funktionieren sollen
  • die Umstände (extrem abhängig vom Registerdruck; verschwindet bei deaktivierter Optimierung oder bei Inlining; zerstört nur zwei Werte statt alle vier) lassen es immer mehr wie einen Optimizer-Bug aussehen
Ich habe es nun einfach trotzdem gemeldet und warte auf die Reaktion der Schöpfer.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten