[rs6000] Fix x86-compat vector intrinsics testcases for BE, 32bit
authorPaul A. Clarke <pc@us.ibm.com>
Thu, 6 Dec 2018 22:11:01 +0000 (22:11 +0000)
committerPaul Clarke <pc@gcc.gnu.org>
Thu, 6 Dec 2018 22:11:01 +0000 (22:11 +0000)
Fix general endian issues found in the test cases for thecompatibility
implementations of the x86 vector intrinsics.  (The tests had been
inadvertently made to PASS without actually running the test code.
A later patch fixes this issue.)

Additionally, a new <smmintrin.h> is added, as some of the APIs therein are
now used by the test cases.  It is _not_ a complete implementation of the
SSE4 interfaces, only the few "extract" interfaces uses by the tests.

2018-12-06  Paul A. Clarke  <pc@us.ibm.com>

[gcc]

PR target/88316
* config/rs6000/smmintrin.h: New file.
* config.gcc: Add smmintrin.h to extra_headers for powerpc*-*-*.

[gcc/testsuite]

PR target/88316
* gcc.target/powerpc/mmx-packssdw-1.c: Fixes for big-endian.
* gcc.target/powerpc/mmx-packsswb-1.c: Likewise.
* gcc.target/powerpc/mmx-packuswb-1.c: Likewise.
* gcc.target/powerpc/mmx-pmulhw-1.c: Likewise.
* gcc.target/powerpc/sse-cvtpi32x2ps-1.c: Likewise.
* gcc.target/powerpc/sse-cvtpu16ps-1.c: Likewise.
* gcc.target/powerpc/sse-cvtss2si-1.c: Likewise.
* gcc.target/powerpc/sse-cvtss2si-2.c: Likewise.
* gcc.target/powerpc/sse2-pshufhw-1.c: Likewise.
* gcc.target/powerpc/sse2-pshuflw-1.c: Likewise.

From-SVN: r266869

14 files changed:
gcc/ChangeLog
gcc/config.gcc
gcc/config/rs6000/smmintrin.h [new file with mode: 0644]
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/mmx-packssdw-1.c
gcc/testsuite/gcc.target/powerpc/mmx-packsswb-1.c
gcc/testsuite/gcc.target/powerpc/mmx-packuswb-1.c
gcc/testsuite/gcc.target/powerpc/mmx-pmulhw-1.c
gcc/testsuite/gcc.target/powerpc/sse-cvtpi32x2ps-1.c
gcc/testsuite/gcc.target/powerpc/sse-cvtpu16ps-1.c
gcc/testsuite/gcc.target/powerpc/sse-cvtss2si-1.c
gcc/testsuite/gcc.target/powerpc/sse-cvtss2si-2.c
gcc/testsuite/gcc.target/powerpc/sse2-pshufhw-1.c
gcc/testsuite/gcc.target/powerpc/sse2-pshuflw-1.c

index 653ded92bc3dad72951dfe3ef8f668c41b3de6c6..dc596889e34d327702a97aeebb0482b5bc8b9518 100644 (file)
@@ -1,3 +1,9 @@
+2018-12-06  Paul A. Clarke  <pc@us.ibm.com>
+
+       PR target/88316
+       * config/rs6000/smmintrin.h: New file.
+       * config.gcc: Add smmintrin.h to extra_headers for powerpc*-*-*.
+
 2018-12-06  Paul A. Clarke  <pc@us.ibm.com>
 
        PR target/88316
index 3b2a6595080f624503ba5670fb75c8afb8d3d361..71f083555a44e7c9d803734525c7fb551235f842 100644 (file)
@@ -505,7 +505,7 @@ powerpc*-*-*)
        extra_headers="${extra_headers} bmi2intrin.h bmiintrin.h"
        extra_headers="${extra_headers} xmmintrin.h mm_malloc.h emmintrin.h"
        extra_headers="${extra_headers} mmintrin.h x86intrin.h"
-       extra_headers="${extra_headers} pmmintrin.h tmmintrin.h"
+       extra_headers="${extra_headers} pmmintrin.h tmmintrin.h smmintrin.h"
        extra_headers="${extra_headers} ppu_intrinsics.h spu2vmx.h vec_types.h si2vmx.h"
        extra_headers="${extra_headers} amo.h"
        case x$with_cpu in
diff --git a/gcc/config/rs6000/smmintrin.h b/gcc/config/rs6000/smmintrin.h
new file mode 100644 (file)
index 0000000..151bb8d
--- /dev/null
@@ -0,0 +1,69 @@
+/* Copyright (C) 2018 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Implemented from the specification included in the Intel C++ Compiler
+   User Guide and Reference, version 9.0.
+
+   NOTE: This is NOT a complete implementation of the SSE4 intrinsics!  */
+
+#ifndef NO_WARN_X86_INTRINSICS
+/* This header is distributed to simplify porting x86_64 code that
+   makes explicit use of Intel intrinsics to powerpc64le.
+   It is the user's responsibility to determine if the results are
+   acceptable and make additional changes as necessary.
+   Note that much code that uses Intel intrinsics can be rewritten in
+   standard C or GNU C extensions, which are more portable and better
+   optimized across multiple targets.  */
+#endif
+
+#ifndef SMMINTRIN_H_
+#define SMMINTRIN_H_
+
+#include <altivec.h>
+#include <tmmintrin.h>
+
+extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_extract_epi8 (__m128i __X, const int __N)
+{
+  return (unsigned char) ((__v16qi)__X)[__N & 15];
+}
+
+extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_extract_epi32 (__m128i __X, const int __N)
+{
+  return ((__v4si)__X)[__N & 3];
+}
+
+extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_extract_epi64 (__m128i __X, const int __N)
+{
+  return ((__v2di)__X)[__N & 1];
+}
+
+extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_extract_ps (__m128 __X, const int __N)
+{
+  return ((__v4si)__X)[__N & 3];
+}
+
+#endif
index 047b4b3bf01fbad42ec8ecbe2c1024f82596b18c..de36ed45ebf610d2cf65ac6a64bffb157867c8b1 100644 (file)
@@ -1,3 +1,17 @@
+2018-12-06  Paul A. Clarke  <pc@us.ibm.com>
+
+       PR target/88316
+       * gcc.target/powerpc/mmx-packssdw-1.c: Fixes for big-endian.
+       * gcc.target/powerpc/mmx-packsswb-1.c: Likewise.
+       * gcc.target/powerpc/mmx-packuswb-1.c: Likewise.
+       * gcc.target/powerpc/mmx-pmulhw-1.c: Likewise.
+       * gcc.target/powerpc/sse-cvtpi32x2ps-1.c: Likewise.
+       * gcc.target/powerpc/sse-cvtpu16ps-1.c: Likewise.
+       * gcc.target/powerpc/sse-cvtss2si-1.c: Likewise.
+       * gcc.target/powerpc/sse-cvtss2si-2.c: Likewise.
+       * gcc.target/powerpc/sse2-pshufhw-1.c: Likewise.
+       * gcc.target/powerpc/sse2-pshuflw-1.c: Likewise.
+
 2018-12-06  Marek Polacek  <polacek@redhat.com>
 
        PR c++/88373 - wrong parse error with ~.
index 84ee3cd237e00942c33381254d4b1ab6fb649a5d..ecfe2d694cd7eed90e5b1f045be9cc049111c9aa 100644 (file)
@@ -22,37 +22,50 @@ test (__m64 s1, __m64 s2)
   return _mm_packs_pi32 (s1, s2);
 }
 
+static short
+saturate (int val)
+{
+  if (val > 32767)
+    return 32767;
+  else if (val < -32768)
+    return -32768;
+  else
+    return val;
+}
+
+static inline int
+l_mm_extract_pi32 (__m64 b, int imm8)
+{
+  unsigned int shift = imm8 & 0x1;
+#ifdef __BIG_ENDIAN__
+  shift = 1 - shift;
+#endif
+  return ((long long)b >> (shift * 32)) & 0xffffffff;
+}
+
 static void
 TEST (void)
 {
   __m64_union s1, s2;
   __m64_union u;
   __m64_union e;
-  int i;
+  int start, end, inc;
 
   s1.as_m64 = _mm_set_pi32 (2134, -128);
   s2.as_m64 = _mm_set_pi32 (41124, 234);
   u.as_m64 = test (s1.as_m64, s2.as_m64);
 
-  for (i = 0; i < 2; i++)
-    {
-      if (s1.as_int[i] > 32767)
-        e.as_short[i] = 32767;
-      else if (s1.as_int[i] < -32768)
-        e.as_short[i] = -32768;
-      else
-        e.as_short[i] = s1.as_int[i];
-    }
-  
-  for (i = 0; i < 2; i++)
-   {
-      if (s2.as_int[i] > 32767)
-        e.as_short[i+2] = 32767;
-      else if (s2.as_int[i] < -32768)
-        e.as_short[i+2] = -32768;
-      else
-        e.as_short[i+2] = s2.as_int[i];
-    }
+#ifdef __LITTLE_ENDIAN__
+  e.as_m64 = _mm_set_pi16 (saturate (l_mm_extract_pi32 (s2.as_m64, 1)),
+                           saturate (l_mm_extract_pi32 (s2.as_m64, 0)),
+                           saturate (l_mm_extract_pi32 (s1.as_m64, 1)),
+                           saturate (l_mm_extract_pi32 (s1.as_m64, 0)));
+#else
+  e.as_m64 = _mm_set_pi16 (saturate (l_mm_extract_pi32 (s1.as_m64, 1)),
+                           saturate (l_mm_extract_pi32 (s1.as_m64, 0)),
+                           saturate (l_mm_extract_pi32 (s2.as_m64, 1)),
+                           saturate (l_mm_extract_pi32 (s2.as_m64, 0)));
+#endif
 
   if (u.as_m64 != e.as_m64)
     abort ();
index d244bd87e5f6450b59f2de452b943227dbdff23d..4ca69b126a97aec8e51dccf4dae430f11f63a207 100644 (file)
@@ -14,6 +14,7 @@
 #include CHECK_H
 
 #include <mmintrin.h>
+#include <xmmintrin.h>
 
 static __m64
 __attribute__((noinline, unused))
@@ -22,6 +23,17 @@ test (__m64 s1, __m64 s2)
   return _mm_packs_pi16 (s1, s2);
 }
 
+static signed char
+saturate (signed short val)
+{
+  if (val > 127)
+    return 127;
+  else if (val < -128)
+    return -128;
+  else
+    return val;
+}
+
 static void
 TEST (void)
 {
@@ -34,25 +46,25 @@ TEST (void)
   s2.as_m64 = _mm_set_pi16 (41124, 234, 2344, 2354);
   u.as_m64 = test (s1.as_m64, s2.as_m64);
 
-  for (i = 0; i < 4; i++)
-    {
-      if (s1.as_short[i] > 127)
-        e.as_char[i] = 127;
-      else if (s1.as_short[i] < -128)
-        e.as_char[i] = -128;
-      else
-        e.as_char[i] = s1.as_short[i];
-    }
-  
-  for (i = 0; i < 4; i++)
-   {
-      if (s2.as_short[i] > 127)
-        e.as_char[i+4] = 127;
-      else if (s2.as_short[i] < -128)
-        e.as_char[i+4] = -128;
-      else
-        e.as_char[i+4] = s2.as_short[i];
-    }
+#ifdef __LITTLE_ENDIAN__
+  e.as_m64 = _mm_set_pi8 (saturate (_mm_extract_pi16 (s2.as_m64, 3)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 2)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 1)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 0)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 3)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 2)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 1)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 0)));
+#else
+  e.as_m64 = _mm_set_pi8 (saturate (_mm_extract_pi16 (s1.as_m64, 3)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 2)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 1)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 0)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 3)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 2)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 1)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 0)));
+#endif
 
   if (u.as_m64 != e.as_m64)
     abort ();
index be9f754f05f69802b9c8e7d772da660e2891a97a..2f74e130823711d6539dd2841a4e6fca6e4f99e8 100644 (file)
@@ -15,6 +15,7 @@
 #include CHECK_H
 
 #include <mmintrin.h>
+#include <xmmintrin.h>
 
 static __m64
 __attribute__((noinline, unused))
@@ -23,6 +24,17 @@ test (__m64 s1, __m64 s2)
   return _mm_packs_pu16 (s1, s2);
 }
 
+static unsigned char
+saturate (signed short val)
+{
+  if (val > 255)
+    return 255;
+  else if (val < 0)
+    return 0;
+  else
+    return val;
+}
+
 static void
 TEST (void)
 {
@@ -35,16 +47,25 @@ TEST (void)
   s2.as_m64 = _mm_set_pi16 (-9, -10, -11, -12);
   u.as_m64 = test (s1.as_m64, s2.as_m64);
 
-  for (i=0; i<4; i++)
-    {
-      tmp = s1.as_short[i]<0 ? 0 : s1.as_short[i];
-      tmp = tmp>255 ? 255 : tmp;
-      e.as_char[i] = tmp;
-
-      tmp = s2.as_short[i]<0 ? 0 : s2.as_short[i];
-      tmp = tmp>255 ? 255 : tmp;
-      e.as_char[i+4] = tmp;
-    }
+#ifdef __LITTLE_ENDIAN__
+  e.as_m64 = _mm_set_pi8 (saturate (_mm_extract_pi16 (s2.as_m64, 3)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 2)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 1)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 0)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 3)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 2)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 1)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 0)));
+#else
+  e.as_m64 = _mm_set_pi8 (saturate (_mm_extract_pi16 (s1.as_m64, 3)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 2)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 1)),
+                          saturate (_mm_extract_pi16 (s1.as_m64, 0)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 3)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 2)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 1)),
+                          saturate (_mm_extract_pi16 (s2.as_m64, 0)));
+#endif
 
   if (u.as_m64 != e.as_m64)
     abort ();
index 4cfb0c3ae9664930f8a014a7d7739dbab1ed93a5..631324c4cd96af00b5ac300cf6aacb54e4902f97 100644 (file)
@@ -33,12 +33,11 @@ TEST (void)
   s2.as_m64 = _mm_set_pi16 (11, 9834, 7444, -10222);
   u.as_m64 = test (s1.as_m64, s2.as_m64);
 
-  for (i = 0; i < 4; i++)
-    {
-      tmp = s1.as_short[i] * s2.as_short[i];
-
-      e.as_short[i] = (tmp & 0xffff0000)>>16;
-    }
+  e.as_m64 = _mm_set_pi16 (
+    ((s1.as_short[3] * s2.as_short[3]) & 0xffff0000) >> 16,
+    ((s1.as_short[2] * s2.as_short[2]) & 0xffff0000) >> 16,
+    ((s1.as_short[1] * s2.as_short[1]) & 0xffff0000) >> 16,
+    ((s1.as_short[0] * s2.as_short[0]) & 0xffff0000) >> 16);
 
   if (u.as_m64 != e.as_m64)
     abort ();
index 296fa3989acf2928ab403d669842b1fa7cbf3fca..a2539af1c77b9893dc69a8b82d5ffe509011944e 100644 (file)
@@ -27,8 +27,8 @@ static void
 TEST (void)
 {
   __m64_union s1, s2;
-  union128 u;
-  float e[4] = {1000.0, -20000.0, 43.0, 546.0};
+  union128 u, e;
+  e.x = _mm_set_ps (546.0, 43.0, -20000.0, 1000.0);
 
   /* input signed in {1000, -20000, 43, 546}.  */
   s1.as_m64 = _mm_setr_pi32 (1000, -20000);
@@ -37,6 +37,6 @@ TEST (void)
   u.x = test (s1.as_m64, s2.as_m64);
 
 
-  if (check_union128 (u, e))
+  if (check_union128 (u, e.a))
     abort ();
 }
index 4cfa468e976ac36ef260dded94c0999794c6ddfd..0cf187be1901ae9e5ed12d7103f639ef25efcb20 100644 (file)
@@ -27,14 +27,14 @@ static void
 TEST (void)
 {
   __m64_union s1;
-  union128 u;
-  float e[4] = {1000.0, 45536.0, 45.0, 65535.0};
+  union128 u, e;
+  e.x = _mm_set_ps (65535.0, 45.0, 45536.0, 1000.0);
 
   /* input unsigned short {1000, 45536, 45, 65535}.  */
   s1.as_m64 = _mm_setr_pi16 (1000, -20000, 45, -1);
    
   u.x = test (s1.as_m64);
 
-  if (check_union128 (u, e))
+  if (check_union128 (u, e.a))
     abort ();
 }
index 216ef771f8d9b680bed7e4da8be3ac67e3962efd..c12a98102e6ee79cd525996cfd76dbe52ae3248b 100644 (file)
@@ -15,6 +15,7 @@
 #endif
 
 #include <xmmintrin.h>
+#include <smmintrin.h>
 
 static int
 __attribute__((noinline, unused))
@@ -29,12 +30,17 @@ TEST (void)
 {
   union128 s1;
   int d;
-  int e;
+  union {
+       float f;
+       int i;
+  } e;
    
   s1.x = _mm_set_ps (24.43, 68.346, 43.35, 546.46);
   d = test (s1.x); 
-  e = (int)s1.a[0];  
 
-  if (e != d)
+  e.i = _mm_extract_ps (s1.x, 0);
+  e.i = e.f;
+
+  if (e.i != d)
     abort ();
 }
index c1597bf43eb01603c53c15bb6d01523b410d4518..023446eb7fb25edff183fda3f9cd8ba18d01aed6 100644 (file)
@@ -15,6 +15,7 @@
 #endif
 
 #include <xmmintrin.h>
+#include <smmintrin.h>
 
 static long long
 __attribute__((noinline, unused))
@@ -29,10 +30,16 @@ TEST (void)
   union128 s1;
   long long d;
   long long e;
+  union {
+       float f;
+       int i;
+  } u;
    
   s1.x = _mm_set_ps (344.4, 68.346, 43.35, 429496729501.4);
   d = test (s1.x); 
-  e = (long long)s1.a[0];  
+
+  u.i = _mm_extract_ps (s1.x, 0);
+  e = u.f;
 
   if (e != d)
     abort ();
index cee0d9f8f6d421d0ae2310930df8709b33591988..7830fd432886e92696633ac4ad5364b9d26bc5a5 100644 (file)
@@ -26,24 +26,28 @@ test (__m128i s1)
 static void
 TEST (void)
 {
-  union128i_q s1;
-  union128i_w u;
+  union128i_w s1, u;
   short  e[8] = { 0 };
   int i;
   int m1[4] = { 0x3, 0x3<<2, 0x3<<4, 0x3<<6 };
   int m2[4];
   
-  s1.x = _mm_set_epi64x (0xabcde,0xef58a234);
+  s1.x = _mm_set_epi16 (0, 0, 0xa, 0xbcde, 0, 0, 0xef58, 0xa234);
   u.x = test (s1.x);
 
   for (i = 0; i < 4; i++)
-    e[i] = (s1.a[0]>>(16 * i)) & 0xffff;
+    e[i] = s1.a[i];
 
-  for (i = 0; i < 4; i++)
-    m2[i] = (N & m1[i])>>(2*i);
+  for (i = 0; i < 4; i++) {
+    int i2 = i;
+#ifdef __LITTLE_ENDIAN__
+    i2 = 3 - i;
+#endif
+    m2[i2] = (N & m1[i2]) >> (2 * i2);
+  }
 
   for (i = 0; i < 4; i++)
-    e[i+4] = (s1.a[1] >> (16 * m2[i])) & 0xffff;
+    e[i + 4] = s1.a[m2[i] + 4];
 
   if (check_union128i_w(u, e))
     {
index c7c357b9f0512ca05d3db7f599177bf8dbe5df0c..5a014751afc98ec4d4f9ecf979abd00c3e37af4e 100644 (file)
@@ -26,24 +26,28 @@ test (__m128i s1)
 static void
 TEST (void)
 {
-  union128i_q s1;
-  union128i_w u;
+  union128i_w s1, u;
   short  e[8] = { 0 };
   int i;
   int m1[4] = { 0x3, 0x3<<2, 0x3<<4, 0x3<<6 };
   int m2[4];
   
-  s1.x = _mm_set_epi64x (0xabcde,0xef58a234);
+  s1.x = _mm_set_epi16 (0, 0, 0xa, 0xbcde, 0, 0, 0xef58, 0xa234);
   u.x = test (s1.x);
 
   for (i = 0; i < 4; i++)
-    e[i+4] = (s1.a[1]>>(16 * i)) & 0xffff;
+    e[i + 4] = s1.a[i + 4];
 
-  for (i = 0; i < 4; i++)
-    m2[i] = (N & m1[i])>>(2*i);
+  for (i = 0; i < 4; i++) {
+    int i2 = i;
+#ifdef __LITTLE_ENDIAN__
+    i2 = 3 - i;
+#endif
+    m2[i2] = (N & m1[i2]) >> (2 * i2);
+  }
 
   for (i = 0; i < 4; i++)
-    e[i] = (s1.a[0] >> (16 * m2[i])) & 0xffff;
+    e[i] = s1.a[m2[i]];
 
   if (check_union128i_w(u, e))
     {