[cfe-commits] r139874 - in /cfe/trunk: lib/Headers/emmintrin.h lib/Headers/pmmintrin.h lib/Headers/xmmintrin.h test/CodeGen/sse-builtins.c

Eli Friedman eli.friedman at gmail.com
Thu Sep 15 16:15:27 PDT 2011


Author: efriedma
Date: Thu Sep 15 18:15:27 2011
New Revision: 139874

URL: http://llvm.org/viewvc/llvm-project?rev=139874&view=rev
Log:
Tweak *mmintrin.h so that they don't make any bad assumptions about alignment (which probably has little effect in practice, but better to get it right).  Make the load in _mm_loadh_pi and _mm_loadl_pi a single LLVM IR instruction to make optimizing easier for CodeGen.

rdar://10054986


Added:
    cfe/trunk/test/CodeGen/sse-builtins.c
Modified:
    cfe/trunk/lib/Headers/emmintrin.h
    cfe/trunk/lib/Headers/pmmintrin.h
    cfe/trunk/lib/Headers/xmmintrin.h

Modified: cfe/trunk/lib/Headers/emmintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/emmintrin.h?rev=139874&r1=139873&r2=139874&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/emmintrin.h (original)
+++ cfe/trunk/lib/Headers/emmintrin.h Thu Sep 15 18:15:27 2011
@@ -458,7 +458,11 @@
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
 _mm_load1_pd(double const *dp)
 {
-  return (__m128d){ dp[0], dp[0] };
+  struct __mm_load1_pd_struct {
+    double u;
+  } __attribute__((__packed__, __may_alias__));
+  double u = ((struct __mm_load1_pd_struct*)dp)->u;
+  return (__m128d){ u, u };
 }
 
 #define        _mm_load_pd1(dp)        _mm_load1_pd(dp)
@@ -466,7 +470,8 @@
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
 _mm_loadr_pd(double const *dp)
 {
-  return (__m128d){ dp[1], dp[0] };
+  __m128d u = *(__m128d*)dp;
+  return __builtin_shufflevector(u, u, 1, 0);
 }
 
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
@@ -481,19 +486,31 @@
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
 _mm_load_sd(double const *dp)
 {
-  return (__m128d){ *dp, 0.0 };
+  struct __mm_load_sd_struct {
+    double u;
+  } __attribute__((__packed__, __may_alias__));
+  double u = ((struct __mm_load_sd_struct*)dp)->u;
+  return (__m128d){ u, 0 };
 }
 
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
 _mm_loadh_pd(__m128d a, double const *dp)
 {
-  return (__m128d){ a[0], *dp };
+  struct __mm_loadh_pd_struct {
+    double u;
+  } __attribute__((__packed__, __may_alias__));
+  double u = ((struct __mm_loadh_pd_struct*)dp)->u;
+  return (__m128d){ a[0], u };
 }
 
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
 _mm_loadl_pd(__m128d a, double const *dp)
 {
-  return (__m128d){ *dp, a[1] };
+  struct __mm_loadl_pd_struct {
+    double u;
+  } __attribute__((__packed__, __may_alias__));
+  double u = ((struct __mm_loadl_pd_struct*)dp)->u;
+  return (__m128d){ u, a[1] }; 
 }
 
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
@@ -535,14 +552,20 @@
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 _mm_store_sd(double *dp, __m128d a)
 {
-  dp[0] = a[0];
+  struct __mm_store_sd_struct {
+    double u;
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_store_sd_struct*)dp)->u = a[0];
 }
 
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 _mm_store1_pd(double *dp, __m128d a)
 {
-  dp[0] = a[0];
-  dp[1] = a[0];
+  struct __mm_store1_pd_struct {
+    double u[2];
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_store1_pd_struct*)dp)->u[0] = a[0];
+  ((struct __mm_store1_pd_struct*)dp)->u[1] = a[0];
 }
 
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
@@ -560,20 +583,26 @@
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 _mm_storer_pd(double *dp, __m128d a)
 {
-  dp[0] = a[1];
-  dp[1] = a[0];
+  a = __builtin_shufflevector(a, a, 1, 0);
+  *(__m128d *)dp = a;
 }
 
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 _mm_storeh_pd(double *dp, __m128d a)
 {
-  dp[0] = a[1];
+  struct __mm_storeh_pd_struct {
+    double u;
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_storeh_pd_struct*)dp)->u = a[1];
 }
 
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 _mm_storel_pd(double *dp, __m128d a)
 {
-  dp[0] = a[0];
+  struct __mm_storeh_pd_struct {
+    double u;
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_storeh_pd_struct*)dp)->u = a[0];
 }
 
 static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
@@ -1029,7 +1058,10 @@
 static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
 _mm_loadl_epi64(__m128i const *p)
 {
-  return (__m128i) { *(long long*)p, 0};
+  struct __mm_loadl_epi64_struct {
+    long long u;
+  } __attribute__((__packed__, __may_alias__));
+  return (__m128i) { ((struct __mm_loadl_epi64_struct*)p)->u, 0};
 }
 
 static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))

Modified: cfe/trunk/lib/Headers/pmmintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/pmmintrin.h?rev=139874&r1=139873&r2=139874&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/pmmintrin.h (original)
+++ cfe/trunk/lib/Headers/pmmintrin.h Thu Sep 15 18:15:27 2011
@@ -84,11 +84,7 @@
   return __builtin_ia32_hsubpd(a, b);
 }
 
-static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
-_mm_loaddup_pd(double const *dp)
-{
-  return (__m128d){ *dp, *dp };
-}
+#define        _mm_loaddup_pd(dp)        _mm_load1_pd(dp)
 
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
 _mm_movedup_pd(__m128d a)

Modified: cfe/trunk/lib/Headers/xmmintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/xmmintrin.h?rev=139874&r1=139873&r2=139874&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/xmmintrin.h (original)
+++ cfe/trunk/lib/Headers/xmmintrin.h Thu Sep 15 18:15:27 2011
@@ -501,31 +501,45 @@
 static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_loadh_pi(__m128 a, const __m64 *p)
 {
-  __m128 b;
-  b[0] = *(float*)p;
-  b[1] = *((float*)p+1);
-  return __builtin_shufflevector(a, b, 0, 1, 4, 5);
+  typedef float __mm_loadh_pi_v2f32 __attribute__((__vector_size__(8)));
+  struct __mm_loadh_pi_struct {
+    __mm_loadh_pi_v2f32 u;
+  } __attribute__((__packed__, __may_alias__));
+  __mm_loadh_pi_v2f32 b = ((struct __mm_loadh_pi_struct*)p)->u;
+  __m128 bb = __builtin_shufflevector(b, b, 0, 1, 0, 1);
+  return __builtin_shufflevector(a, bb, 0, 1, 4, 5);
 }
 
 static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_loadl_pi(__m128 a, const __m64 *p)
 {
-  __m128 b;
-  b[0] = *(float*)p;
-  b[1] = *((float*)p+1);
-  return __builtin_shufflevector(a, b, 4, 5, 2, 3);
+  typedef float __mm_loadl_pi_v2f32 __attribute__((__vector_size__(8)));
+  struct __mm_loadl_pi_struct {
+    __mm_loadl_pi_v2f32 u;
+  } __attribute__((__packed__, __may_alias__));
+  __mm_loadl_pi_v2f32 b = ((struct __mm_loadl_pi_struct*)p)->u;
+  __m128 bb = __builtin_shufflevector(b, b, 0, 1, 0, 1);
+  return __builtin_shufflevector(a, bb, 4, 5, 2, 3);
 }
 
 static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_load_ss(const float *p)
 {
-  return (__m128){ *p, 0, 0, 0 };
+  struct __mm_load_ss_struct {
+    float u;
+  } __attribute__((__packed__, __may_alias__));
+  float u = ((struct __mm_load_ss_struct*)p)->u;
+  return (__m128){ u, 0, 0, 0 };
 }
 
 static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_load1_ps(const float *p)
 {
-  return (__m128){ *p, *p, *p, *p };
+  struct __mm_load1_ps_struct {
+    float u;
+  } __attribute__((__packed__, __may_alias__));
+  float u = ((struct __mm_load1_ps_struct*)p)->u;
+  return (__m128){ u, u, u, u };
 }
 
 #define        _mm_load_ps1(p) _mm_load1_ps(p)
@@ -541,7 +555,7 @@
 {
   struct __loadu_ps {
     __m128 v;
-  } __attribute__((packed, may_alias));
+  } __attribute__((__packed__, __may_alias__));
   return ((struct __loadu_ps*)p)->v;
 }
 
@@ -604,7 +618,10 @@
 static __inline__ void __attribute__((__always_inline__))
 _mm_store_ss(float *p, __m128 a)
 {
-  *p = a[0];
+  struct __mm_store_ss_struct {
+    float u;
+  } __attribute__((__packed__, __may_alias__));
+  ((struct __mm_store_ss_struct*)p)->u = a[0];
 }
 
 static __inline__ void __attribute__((__always_inline__, __nodebug__))

Added: cfe/trunk/test/CodeGen/sse-builtins.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/sse-builtins.c?rev=139874&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/sse-builtins.c (added)
+++ cfe/trunk/test/CodeGen/sse-builtins.c Thu Sep 15 18:15:27 2011
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -target-cpu pentium4 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s
+
+#include <emmintrin.h>
+
+__m128 test_loadl_pi(__m128 x, void* y) {
+  // CHECK: define {{.*}} @test_loadl_pi
+  // CHECK: load <2 x float>* {{.*}}, align 1{{$}}
+  // CHECK: shufflevector {{.*}} <4 x i32> <i32 0, i32 1
+  // CHECK: shufflevector {{.*}} <4 x i32> <i32 4, i32 5, i32 2, i32 3>
+  return _mm_loadl_pi(x,y);
+}
+
+__m128 test_loadh_pi(__m128 x, void* y) {
+  // CHECK: define {{.*}} @test_loadh_pi
+  // CHECK: load <2 x float>* {{.*}}, align 1{{$}}
+  // CHECK: shufflevector {{.*}} <4 x i32> <i32 0, i32 1
+  // CHECK: shufflevector {{.*}} <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+  return _mm_loadh_pi(x,y);
+}
+
+__m128 test_load_ss(void* y) {
+  // CHECK: define {{.*}} @test_load_ss
+  // CHECK: load float* {{.*}}, align 1{{$}}
+  return _mm_load_ss(y);
+}
+
+__m128 test_load1_ps(void* y) {
+  // CHECK: define {{.*}} @test_load1_ps
+  // CHECK: load float* {{.*}}, align 1{{$}}
+  return _mm_load1_ps(y);
+}
+
+void test_store_ss(__m128 x, void* y) {
+  // CHECK: define void @test_store_ss
+  // CHECK: store {{.*}} float* {{.*}}, align 1,
+  _mm_store_ss(y, x);
+}
+
+__m128d test_load1_pd(__m128 x, void* y) {
+  // CHECK: define {{.*}} @test_load1_pd
+  // CHECK: load double* {{.*}}, align 1{{$}}
+  return _mm_load1_pd(y);
+}
+
+__m128d test_loadr_pd(__m128 x, void* y) {
+  // CHECK: define {{.*}} @test_loadr_pd
+  // CHECK: load <2 x double>* {{.*}}, align 16{{$}}
+  return _mm_loadr_pd(y);
+}
+
+__m128d test_load_sd(void* y) {
+  // CHECK: define {{.*}} @test_load_sd
+  // CHECK: load double* {{.*}}, align 1{{$}}
+  return _mm_load_sd(y);
+}
+
+__m128d test_loadh_pd(__m128d x, void* y) {
+  // CHECK: define {{.*}} @test_loadh_pd
+  // CHECK: load double* {{.*}}, align 1{{$}}
+  return _mm_loadh_pd(x, y);
+}
+
+__m128d test_loadl_pd(__m128d x, void* y) {
+  // CHECK: define {{.*}} @test_loadl_pd
+  // CHECK: load double* {{.*}}, align 1{{$}}
+  return _mm_loadl_pd(x, y);
+}
+
+void test_store_sd(__m128d x, void* y) {
+  // CHECK: define void @test_store_sd
+  // CHECK: store {{.*}} double* {{.*}}, align 1{{$}}
+  _mm_store_sd(y, x);
+}
+
+void test_store1_pd(__m128d x, void* y) {
+  // CHECK: define void @test_store1_pd
+  // CHECK: store {{.*}} double* {{.*}}, align 1{{$}}
+  // CHECK: store {{.*}} double* {{.*}}, align 1{{$}}
+  _mm_store1_pd(y, x);
+}
+
+void test_storer_pd(__m128d x, void* y) {
+  // CHECK: define void @test_storer_pd
+  // CHECK: store {{.*}} <2 x double>* {{.*}}, align 16{{$}}
+  _mm_storer_pd(y, x);
+}
+
+void test_storeh_pd(__m128d x, void* y) {
+  // CHECK: define void @test_storeh_pd
+  // CHECK: store {{.*}} double* {{.*}}, align 1{{$}}
+  _mm_storeh_pd(y, x);
+}
+
+void test_storel_pd(__m128d x, void* y) {
+  // CHECK: define void @test_storel_pd
+  // CHECK: store {{.*}} double* {{.*}}, align 1{{$}}
+  _mm_storel_pd(y, x);
+}
+
+__m128i test_loadl_epi64(void* y) {
+  // CHECK: define {{.*}} @test_loadl_epi64
+  // CHECK: load i64* {{.*}}, align 1{{$}}
+  return _mm_loadl_epi64(y);
+}





More information about the cfe-commits mailing list