]> granicus.if.org Git - clang/commitdiff
[X86] Add explicit alignment to __m128/__m128i/__m128d/etc. to allow matching of...
authorCraig Topper <craig.topper@intel.com>
Fri, 8 Feb 2019 19:45:08 +0000 (19:45 +0000)
committerCraig Topper <craig.topper@intel.com>
Fri, 8 Feb 2019 19:45:08 +0000 (19:45 +0000)
Summary:
With MSVC, #pragma pack is ignored when there is explicit alignment. This differs from gcc. Clang emulates this difference when compiling for Windows.

It appears that MSVC and its headers consider the __m128/__m128i/__m128d/etc. types to be explicitly aligned and ignores #pragma pack for them. Since we don't have explicit alignment on them in our headers, we don't match the MSVC behavior here.

This patch adds explicit alignment to match this behavior. I'm hoping this won't cause any problems when we're not emulating MSVC. But if someone knows of something that would be different we can swith to conditionally adding the alignment based on _MSC_VER.

I had to add explicitly unaligned types as well so we could use them in the loadu/storeu intrinsics which use __attribute__(__packed__). Using the now explicitly aligned types wouldn't produce align 1 accesses when targeting Windows.

Reviewers: rnk, erichkeane, spatel, RKSimon

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D57961

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@353555 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Headers/avx512bwintrin.h
lib/Headers/avx512fintrin.h
lib/Headers/avx512vlbwintrin.h
lib/Headers/avx512vlintrin.h
lib/Headers/avxintrin.h
lib/Headers/emmintrin.h
lib/Headers/mmintrin.h
lib/Headers/xmmintrin.h
test/CodeGen/x86-vec-struct-packing.c [new file with mode: 0644]

index a90a255376c04a25712ee4bc33169c4193357208..32fea8d79590aabaf9d0aa7132497a6119a32ab4 100644 (file)
@@ -1751,7 +1751,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
 _mm512_loadu_epi16 (void const *__P)
 {
   struct __loadu_epi16 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi16*)__P)->__v;
 }
@@ -1777,7 +1777,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
 _mm512_loadu_epi8 (void const *__P)
 {
   struct __loadu_epi8 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi8*)__P)->__v;
 }
@@ -1803,7 +1803,7 @@ static __inline void __DEFAULT_FN_ATTRS512
 _mm512_storeu_epi16 (void *__P, __m512i __A)
 {
   struct __storeu_epi16 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi16*)__P)->__v = __A;
 }
@@ -1820,7 +1820,7 @@ static __inline void __DEFAULT_FN_ATTRS512
 _mm512_storeu_epi8 (void *__P, __m512i __A)
 {
   struct __storeu_epi8 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi8*)__P)->__v = __A;
 }
index 1c19993ff1bb7241d135609f8a69d94d27237353..55f3fe96098dffd4716b0cc82fc204d877411d37 100644 (file)
@@ -40,9 +40,13 @@ typedef unsigned short __v32hu __attribute__((__vector_size__(64)));
 typedef unsigned long long __v8du __attribute__((__vector_size__(64)));
 typedef unsigned int __v16su __attribute__((__vector_size__(64)));
 
-typedef float __m512 __attribute__((__vector_size__(64)));
-typedef double __m512d __attribute__((__vector_size__(64)));
-typedef long long __m512i __attribute__((__vector_size__(64)));
+typedef float __m512 __attribute__((__vector_size__(64), __aligned__(64)));
+typedef double __m512d __attribute__((__vector_size__(64), __aligned__(64)));
+typedef long long __m512i __attribute__((__vector_size__(64), __aligned__(64)));
+
+typedef float __m512_u __attribute__((__vector_size__(64), __aligned__(1)));
+typedef double __m512d_u __attribute__((__vector_size__(64), __aligned__(1)));
+typedef long long __m512i_u __attribute__((__vector_size__(64), __aligned__(1)));
 
 typedef unsigned char __mmask8;
 typedef unsigned short __mmask16;
@@ -4324,7 +4328,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
 _mm512_loadu_si512 (void const *__P)
 {
   struct __loadu_si512 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_si512*)__P)->__v;
 }
@@ -4333,7 +4337,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
 _mm512_loadu_epi32 (void const *__P)
 {
   struct __loadu_epi32 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi32*)__P)->__v;
 }
@@ -4360,7 +4364,7 @@ static __inline __m512i __DEFAULT_FN_ATTRS512
 _mm512_loadu_epi64 (void const *__P)
 {
   struct __loadu_epi64 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi64*)__P)->__v;
 }
@@ -4420,7 +4424,7 @@ static __inline __m512d __DEFAULT_FN_ATTRS512
 _mm512_loadu_pd(void const *__p)
 {
   struct __loadu_pd {
-    __m512d __v;
+    __m512d_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_pd*)__p)->__v;
 }
@@ -4429,7 +4433,7 @@ static __inline __m512 __DEFAULT_FN_ATTRS512
 _mm512_loadu_ps(void const *__p)
 {
   struct __loadu_ps {
-    __m512 __v;
+    __m512_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_ps*)__p)->__v;
 }
@@ -4504,7 +4508,7 @@ static __inline void __DEFAULT_FN_ATTRS512
 _mm512_storeu_epi64 (void *__P, __m512i __A)
 {
   struct __storeu_epi64 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi64*)__P)->__v = __A;
 }
@@ -4520,7 +4524,7 @@ static __inline void __DEFAULT_FN_ATTRS512
 _mm512_storeu_si512 (void *__P, __m512i __A)
 {
   struct __storeu_si512 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_si512*)__P)->__v = __A;
 }
@@ -4529,7 +4533,7 @@ static __inline void __DEFAULT_FN_ATTRS512
 _mm512_storeu_epi32 (void *__P, __m512i __A)
 {
   struct __storeu_epi32 {
-    __m512i __v;
+    __m512i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi32*)__P)->__v = __A;
 }
@@ -4551,7 +4555,7 @@ static __inline void __DEFAULT_FN_ATTRS512
 _mm512_storeu_pd(void *__P, __m512d __A)
 {
   struct __storeu_pd {
-    __m512d __v;
+    __m512d_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_pd*)__P)->__v = __A;
 }
@@ -4567,7 +4571,7 @@ static __inline void __DEFAULT_FN_ATTRS512
 _mm512_storeu_ps(void *__P, __m512 __A)
 {
   struct __storeu_ps {
-    __m512 __v;
+    __m512_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_ps*)__P)->__v = __A;
 }
index 87e0023e8b74eea920bf72ff9b72efb34c41a95e..9e85ffd528b18b7c070b989b50afdb5b4516df91 100644 (file)
@@ -2301,7 +2301,7 @@ static __inline __m128i __DEFAULT_FN_ATTRS128
 _mm_loadu_epi16 (void const *__P)
 {
   struct __loadu_epi16 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi16*)__P)->__v;
 }
@@ -2327,7 +2327,7 @@ static __inline __m256i __DEFAULT_FN_ATTRS256
 _mm256_loadu_epi16 (void const *__P)
 {
   struct __loadu_epi16 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi16*)__P)->__v;
 }
@@ -2353,7 +2353,7 @@ static __inline __m128i __DEFAULT_FN_ATTRS128
 _mm_loadu_epi8 (void const *__P)
 {
   struct __loadu_epi8 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi8*)__P)->__v;
 }
@@ -2379,7 +2379,7 @@ static __inline __m256i __DEFAULT_FN_ATTRS256
 _mm256_loadu_epi8 (void const *__P)
 {
   struct __loadu_epi8 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi8*)__P)->__v;
 }
@@ -2405,7 +2405,7 @@ static __inline void __DEFAULT_FN_ATTRS128
 _mm_storeu_epi16 (void *__P, __m128i __A)
 {
   struct __storeu_epi16 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi16*)__P)->__v = __A;
 }
@@ -2422,7 +2422,7 @@ static __inline void __DEFAULT_FN_ATTRS256
 _mm256_storeu_epi16 (void *__P, __m256i __A)
 {
   struct __storeu_epi16 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi16*)__P)->__v = __A;
 }
@@ -2439,7 +2439,7 @@ static __inline void __DEFAULT_FN_ATTRS128
 _mm_storeu_epi8 (void *__P, __m128i __A)
 {
   struct __storeu_epi8 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi8*)__P)->__v = __A;
 }
@@ -2456,7 +2456,7 @@ static __inline void __DEFAULT_FN_ATTRS256
 _mm256_storeu_epi8 (void *__P, __m256i __A)
 {
   struct __storeu_epi8 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi8*)__P)->__v = __A;
 }
index a2cdc0a96e59a29c5e6a8937e28370e6c11c86af..a3758e7d333e30f7003375df671bb540bc319ba8 100644 (file)
@@ -5513,7 +5513,7 @@ static __inline __m128i __DEFAULT_FN_ATTRS128
 _mm_loadu_epi64 (void const *__P)
 {
   struct __loadu_epi64 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi64*)__P)->__v;
 }
@@ -5539,7 +5539,7 @@ static __inline __m256i __DEFAULT_FN_ATTRS256
 _mm256_loadu_epi64 (void const *__P)
 {
   struct __loadu_epi64 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi64*)__P)->__v;
 }
@@ -5565,7 +5565,7 @@ static __inline __m128i __DEFAULT_FN_ATTRS128
 _mm_loadu_epi32 (void const *__P)
 {
   struct __loadu_epi32 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi32*)__P)->__v;
 }
@@ -5591,7 +5591,7 @@ static __inline __m256i __DEFAULT_FN_ATTRS256
 _mm256_loadu_epi32 (void const *__P)
 {
   struct __loadu_epi32 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_epi32*)__P)->__v;
 }
@@ -5717,7 +5717,7 @@ static __inline void __DEFAULT_FN_ATTRS128
 _mm_storeu_epi64 (void *__P, __m128i __A)
 {
   struct __storeu_epi64 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi64*)__P)->__v = __A;
 }
@@ -5734,7 +5734,7 @@ static __inline void __DEFAULT_FN_ATTRS256
 _mm256_storeu_epi64 (void *__P, __m256i __A)
 {
   struct __storeu_epi64 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi64*)__P)->__v = __A;
 }
@@ -5751,7 +5751,7 @@ static __inline void __DEFAULT_FN_ATTRS128
 _mm_storeu_epi32 (void *__P, __m128i __A)
 {
   struct __storeu_epi32 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi32*)__P)->__v = __A;
 }
@@ -5768,7 +5768,7 @@ static __inline void __DEFAULT_FN_ATTRS256
 _mm256_storeu_epi32 (void *__P, __m256i __A)
 {
   struct __storeu_epi32 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_epi32*)__P)->__v = __A;
 }
index cb15396b3faf329cd8396d662a9f6b41d3a45f21..f68ae6715d7221670c4fd7cbb9b6f011a647e991 100644 (file)
@@ -45,9 +45,13 @@ typedef unsigned char __v32qu __attribute__ ((__vector_size__ (32)));
  * appear in the interface though. */
 typedef signed char __v32qs __attribute__((__vector_size__(32)));
 
-typedef float __m256 __attribute__ ((__vector_size__ (32)));
-typedef double __m256d __attribute__((__vector_size__(32)));
-typedef long long __m256i __attribute__((__vector_size__(32)));
+typedef float __m256 __attribute__ ((__vector_size__ (32), __aligned__(32)));
+typedef double __m256d __attribute__((__vector_size__(32), __aligned__(32)));
+typedef long long __m256i __attribute__((__vector_size__(32), __aligned__(32)));
+
+typedef float __m256_u __attribute__ ((__vector_size__ (32), __aligned__(1)));
+typedef double __m256d_u __attribute__((__vector_size__(32), __aligned__(1)));
+typedef long long __m256i_u __attribute__((__vector_size__(32), __aligned__(1)));
 
 /* Define the default attributes for the functions in this file. */
 #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("avx"), __min_vector_width__(256)))
@@ -3113,7 +3117,7 @@ static __inline __m256d __DEFAULT_FN_ATTRS
 _mm256_loadu_pd(double const *__p)
 {
   struct __loadu_pd {
-    __m256d __v;
+    __m256d_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_pd*)__p)->__v;
 }
@@ -3133,7 +3137,7 @@ static __inline __m256 __DEFAULT_FN_ATTRS
 _mm256_loadu_ps(float const *__p)
 {
   struct __loadu_ps {
-    __m256 __v;
+    __m256_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_ps*)__p)->__v;
 }
@@ -3169,7 +3173,7 @@ static __inline __m256i __DEFAULT_FN_ATTRS
 _mm256_loadu_si256(__m256i const *__p)
 {
   struct __loadu_si256 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_si256*)__p)->__v;
 }
@@ -3246,7 +3250,7 @@ static __inline void __DEFAULT_FN_ATTRS
 _mm256_storeu_pd(double *__p, __m256d __a)
 {
   struct __storeu_pd {
-    __m256d __v;
+    __m256d_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_pd*)__p)->__v = __a;
 }
@@ -3266,7 +3270,7 @@ static __inline void __DEFAULT_FN_ATTRS
 _mm256_storeu_ps(float *__p, __m256 __a)
 {
   struct __storeu_ps {
-    __m256 __v;
+    __m256_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_ps*)__p)->__v = __a;
 }
@@ -3304,7 +3308,7 @@ static __inline void __DEFAULT_FN_ATTRS
 _mm256_storeu_si256(__m256i *__p, __m256i __a)
 {
   struct __storeu_si256 {
-    __m256i __v;
+    __m256i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_si256*)__p)->__v = __a;
 }
index 6d61f971994448df9f20c74e0d930cb904f7a2bf..7b2735bdf5e4b8cbe7d371e6defa3b259e2fd67f 100644 (file)
 
 #include <xmmintrin.h>
 
-typedef double __m128d __attribute__((__vector_size__(16)));
-typedef long long __m128i __attribute__((__vector_size__(16)));
+typedef double __m128d __attribute__((__vector_size__(16), __aligned__(16)));
+typedef long long __m128i __attribute__((__vector_size__(16), __aligned__(16)));
+
+typedef double __m128d_u __attribute__((__vector_size__(16), __aligned__(1)));
+typedef long long __m128i_u __attribute__((__vector_size__(16), __aligned__(1)));
 
 /* Type defines.  */
 typedef double __v2df __attribute__ ((__vector_size__ (16)));
@@ -1652,7 +1655,7 @@ static __inline__ __m128d __DEFAULT_FN_ATTRS
 _mm_loadu_pd(double const *__dp)
 {
   struct __loadu_pd {
-    __m128d __v;
+    __m128d_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_pd*)__dp)->__v;
 }
@@ -2042,7 +2045,7 @@ static __inline__ void __DEFAULT_FN_ATTRS
 _mm_storeu_pd(double *__dp, __m128d __a)
 {
   struct __storeu_pd {
-    __m128d __v;
+    __m128d_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_pd*)__dp)->__v = __a;
 }
@@ -3567,7 +3570,7 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS
 _mm_loadu_si128(__m128i const *__p)
 {
   struct __loadu_si128 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_si128*)__p)->__v;
 }
@@ -4030,7 +4033,7 @@ static __inline__ void __DEFAULT_FN_ATTRS
 _mm_storeu_si128(__m128i *__p, __m128i __b)
 {
   struct __storeu_si128 {
-    __m128i __v;
+    __m128i_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_si128*)__p)->__v = __b;
 }
index a73539942a92ed3a9e32865b6d4b9aa2df2e2aa9..5dc304e451dc50e82126ce39d3c7d7e3fcb8e07e 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef __MMINTRIN_H
 #define __MMINTRIN_H
 
-typedef long long __m64 __attribute__((__vector_size__(8)));
+typedef long long __m64 __attribute__((__vector_size__(8), __aligned__(8)));
 
 typedef long long __v1di __attribute__((__vector_size__(8)));
 typedef int __v2si __attribute__((__vector_size__(8)));
index 17af17267c83784fe8195f9a87cd75ed6ade6e64..f57264727c7cc4f68a6f2a0588ba2cf540f7aff8 100644 (file)
@@ -28,7 +28,9 @@
 
 typedef int __v4si __attribute__((__vector_size__(16)));
 typedef float __v4sf __attribute__((__vector_size__(16)));
-typedef float __m128 __attribute__((__vector_size__(16)));
+typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));
+
+typedef float __m128_u __attribute__((__vector_size__(16), __aligned__(1)));
 
 /* Unsigned types */
 typedef unsigned int __v4su __attribute__((__vector_size__(16)));
@@ -1987,7 +1989,7 @@ static __inline__ void __DEFAULT_FN_ATTRS
 _mm_storeu_ps(float *__p, __m128 __a)
 {
   struct __storeu_ps {
-    __m128 __v;
+    __m128_u __v;
   } __attribute__((__packed__, __may_alias__));
   ((struct __storeu_ps*)__p)->__v = __a;
 }
diff --git a/test/CodeGen/x86-vec-struct-packing.c b/test/CodeGen/x86-vec-struct-packing.c
new file mode 100644 (file)
index 0000000..01458d1
--- /dev/null
@@ -0,0 +1,227 @@
+// RUN: %clang_cc1 -ffreestanding -emit-llvm-only  -triple x86_64-windows-coff -fdump-record-layouts %s | FileCheck %s --check-prefix=CHECK-MS
+// RUN: %clang_cc1 -ffreestanding -emit-llvm-only  -triple x86_64-apple-darwin -fdump-record-layouts %s | FileCheck %s --check-prefix=CHECK-NOTMS
+#include <x86intrin.h>
+
+#pragma pack(1)
+
+struct s_m64 {
+  int a;
+  __m64 b;
+};
+typedef struct s_m64 m64;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m64) == 16) - 1];
+#else
+static int a1[(sizeof(m64) == 12) - 1];
+#endif
+
+struct s_m128 {
+  int a;
+  __m128 b;
+};
+typedef struct s_m128 m128;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m128) == 32) - 1];
+#else
+static int a1[(sizeof(m128) == 20) - 1];
+#endif
+
+struct s_m128i {
+  int a;
+  __m128i b;
+};
+typedef struct s_m128i m128i;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m128i) == 32) - 1];
+#else
+static int a1[(sizeof(m128i) == 20) - 1];
+#endif
+
+struct s_m128d {
+  int a;
+  __m128d b;
+};
+typedef struct s_m128d m128d;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m128d) == 32) - 1];
+#else
+static int a1[(sizeof(m128d) == 20) - 1];
+#endif
+
+struct s_m256 {
+  int a;
+  __m256 b;
+};
+typedef struct s_m256 m256;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m256) == 64) - 1];
+#else
+static int a1[(sizeof(m256) == 36) - 1];
+#endif
+
+struct s_m256i {
+  int a;
+  __m256i b;
+};
+typedef struct s_m256i m256i;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m256i) == 64) - 1];
+#else
+static int a1[(sizeof(m256i) == 36) - 1];
+#endif
+
+struct s_m256d {
+  int a;
+  __m256d b;
+};
+typedef struct s_m256d m256d;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m256d) == 64) - 1];
+#else
+static int a1[(sizeof(m256d) == 36) - 1];
+#endif
+
+struct s_m512 {
+  int a;
+  __m512 b;
+};
+typedef struct s_m512 m512;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m512) == 128) - 1];
+#else
+static int a1[(sizeof(m512) == 68) - 1];
+#endif
+
+struct s_m512i {
+  int a;
+  __m512i b;
+};
+typedef struct s_m512i m512i;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m512i) == 128) - 1];
+#else
+static int a1[(sizeof(m512i) == 68) - 1];
+#endif
+
+struct s_m512d {
+  int a;
+  __m512d b;
+};
+typedef struct s_m512d m512d;
+
+#if defined(_WIN32)
+static int a1[(sizeof(m512d) == 128) - 1];
+#else
+static int a1[(sizeof(m512d) == 68) - 1];
+#endif
+
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m64
+// CHECK-MS:          0 |   int a
+// CHECK-MS:          8 |   __m64 b
+// CHECK-MS:            | [sizeof=16, align=8]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m128
+// CHECK-MS:          0 |   int a
+// CHECK-MS:         16 |   __m128 b
+// CHECK-MS:            | [sizeof=32, align=16]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m128i
+// CHECK-MS:          0 |   int a
+// CHECK-MS:         16 |   __m128i b
+// CHECK-MS:            | [sizeof=32, align=16]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m128d
+// CHECK-MS:          0 |   int a
+// CHECK-MS:         16 |   __m128d b
+// CHECK-MS:            | [sizeof=32, align=16]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m256
+// CHECK-MS:          0 |   int a
+// CHECK-MS:         32 |   __m256 b
+// CHECK-MS:            | [sizeof=64, align=32]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m256i
+// CHECK-MS:          0 |   int a
+// CHECK-MS:         32 |   __m256i b
+// CHECK-MS:            | [sizeof=64, align=32]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m256d
+// CHECK-MS:          0 |   int a
+// CHECK-MS:         32 |   __m256d b
+// CHECK-MS:            | [sizeof=64, align=32]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m512
+// CHECK-MS:          0 |   int a
+// CHECK-MS:         64 |   __m512 b
+// CHECK-MS:            | [sizeof=128, align=64]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m512i
+// CHECK-MS:          0 |   int a
+// CHECK-MS:         64 |   __m512i b
+// CHECK-MS:            | [sizeof=128, align=64]
+// CHECK-MS: *** Dumping AST Record Layout
+// CHECK-MS:          0 | struct s_m512d
+// CHECK-MS:          0 |   int a
+// CHECK-MS:         64 |   __m512d b
+// CHECK-MS:            | [sizeof=128, align=64]
+
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m64
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m64 b
+// CHECK-NOTMS:            | [sizeof=12, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m128
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m128 b
+// CHECK-NOTMS:            | [sizeof=20, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m128i
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m128i b
+// CHECK-NOTMS:            | [sizeof=20, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m128d
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m128d b
+// CHECK-NOTMS:            | [sizeof=20, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m256
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m256 b
+// CHECK-NOTMS:            | [sizeof=36, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m256i
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m256i b
+// CHECK-NOTMS:            | [sizeof=36, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m256d
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m256d b
+// CHECK-NOTMS:            | [sizeof=36, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m512
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m512 b
+// CHECK-NOTMS:            | [sizeof=68, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m512i
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m512i b
+// CHECK-NOTMS:            | [sizeof=68, align=1]
+// CHECK-NOTMS: *** Dumping AST Record Layout
+// CHECK-NOTMS:          0 | struct s_m512d
+// CHECK-NOTMS:          0 |   int a
+// CHECK-NOTMS:          4 |   __m512d b
+// CHECK-NOTMS:            | [sizeof=68, align=1]