OSDN Git Service

* config/i386/i386.c (ix86_expand_sse_movcc): Use
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Sep 2011 18:24:18 +0000 (18:24 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Sep 2011 18:24:18 +0000 (18:24 +0000)
blendvps, blendvpd and pblendvb if possible.

* gcc.dg/vect/vect-cond-7.c: New test.
* gcc.target/i386/sse4_1-cond-1.c: New test.
* gcc.target/i386/avx-cond-1.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179055 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/vect-cond-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-cond-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-cond-1.c [new file with mode: 0644]

index 9b9d698..ed4c4fc 100644 (file)
@@ -1,3 +1,8 @@
+2011-09-21  Jakub Jelinek  <jakub@redhat.com>
+
+       * config/i386/i386.c (ix86_expand_sse_movcc): Use
+       blendvps, blendvpd and pblendvb if possible.
+
 2011-09-21  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/50464
index eae3ff2..f952d2e 100644 (file)
@@ -18909,24 +18909,80 @@ ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
     }
   else
     {
-      op_true = force_reg (mode, op_true);
+      rtx (*gen) (rtx, rtx, rtx, rtx) = NULL;
+
       op_false = force_reg (mode, op_false);
 
-      t2 = gen_reg_rtx (mode);
-      if (optimize)
-       t3 = gen_reg_rtx (mode);
+      switch (mode)
+       {
+       case V4SFmode:
+         if (TARGET_SSE4_1)
+           gen = gen_sse4_1_blendvps;
+         break;
+       case V2DFmode:
+         if (TARGET_SSE4_1)
+           gen = gen_sse4_1_blendvpd;
+         break;
+       case V16QImode:
+       case V8HImode:
+       case V4SImode:
+       case V2DImode:
+         if (TARGET_SSE4_1)
+           {
+             gen = gen_sse4_1_pblendvb;
+             dest = gen_lowpart (V16QImode, dest);
+             op_false = gen_lowpart (V16QImode, op_false);
+             op_true = gen_lowpart (V16QImode, op_true);
+             cmp = gen_lowpart (V16QImode, cmp);
+           }
+         break;
+       case V8SFmode:
+         if (TARGET_AVX)
+           gen = gen_avx_blendvps256;
+         break;
+       case V4DFmode:
+         if (TARGET_AVX)
+           gen = gen_avx_blendvpd256;
+         break;
+       case V32QImode:
+       case V16HImode:
+       case V8SImode:
+       case V4DImode:
+         if (TARGET_AVX2)
+           {
+             gen = gen_avx2_pblendvb;
+             dest = gen_lowpart (V32QImode, dest);
+             op_false = gen_lowpart (V32QImode, op_false);
+             op_true = gen_lowpart (V32QImode, op_true);
+             cmp = gen_lowpart (V32QImode, cmp);
+           }
+         break;
+       default:
+         break;
+       }
+
+      if (gen != NULL)
+       emit_insn (gen (dest, op_false, op_true, cmp));
       else
-       t3 = dest;
+       {
+         op_true = force_reg (mode, op_true);
 
-      x = gen_rtx_AND (mode, op_true, cmp);
-      emit_insn (gen_rtx_SET (VOIDmode, t2, x));
+         t2 = gen_reg_rtx (mode);
+         if (optimize)
+           t3 = gen_reg_rtx (mode);
+         else
+           t3 = dest;
 
-      x = gen_rtx_NOT (mode, cmp);
-      x = gen_rtx_AND (mode, x, op_false);
-      emit_insn (gen_rtx_SET (VOIDmode, t3, x));
+         x = gen_rtx_AND (mode, op_true, cmp);
+         emit_insn (gen_rtx_SET (VOIDmode, t2, x));
 
-      x = gen_rtx_IOR (mode, t3, t2);
-      emit_insn (gen_rtx_SET (VOIDmode, dest, x));
+         x = gen_rtx_NOT (mode, cmp);
+         x = gen_rtx_AND (mode, x, op_false);
+         emit_insn (gen_rtx_SET (VOIDmode, t3, x));
+
+         x = gen_rtx_IOR (mode, t3, t2);
+         emit_insn (gen_rtx_SET (VOIDmode, dest, x));
+       }
     }
 }
 
index 0e68b06..b575881 100644 (file)
@@ -1,3 +1,9 @@
+2011-09-21  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.dg/vect/vect-cond-7.c: New test.
+       * gcc.target/i386/sse4_1-cond-1.c: New test.
+       * gcc.target/i386/avx-cond-1.c: New test.
+
 2011-09-21  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/50464
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-7.c b/gcc/testsuite/gcc.dg/vect/vect-cond-7.c
new file mode 100644 (file)
index 0000000..227192c
--- /dev/null
@@ -0,0 +1,68 @@
+#include "tree-vect.h"
+
+extern void abort (void);
+double ad[64], bd[64], cd[64], dd[64], ed[64];
+float af[64], bf[64], cf[64], df[64], ef[64];
+signed char ac[64], bc[64], cc[64], dc[64], ec[64];
+short as[64], bs[64], cs[64], ds[64], es[64];
+int ai[64], bi[64], ci[64], di[64], ei[64];
+long long all[64], bll[64], cll[64], dll[64], ell[64];
+unsigned char auc[64], buc[64], cuc[64], duc[64], euc[64];
+unsigned short aus[64], bus[64], cus[64], dus[64], eus[64];
+unsigned int au[64], bu[64], cu[64], du[64], eu[64];
+unsigned long long aull[64], bull[64], cull[64], dull[64], eull[64];
+
+#define F(var) \
+__attribute__((noinline, noclone)) void \
+f##var (void) \
+{ \
+  int i; \
+  for (i = 0; i < 64; i++) \
+    { \
+      __typeof (a##var[0]) d = d##var[i], e = e##var[i]; \
+      a##var[i] = b##var[i] > c##var[i] ? d : e; \
+    } \
+}
+
+#define TESTS \
+F (d) F (f) F (c) F (s) F (i) F (ll) F (uc) F (us) F (u) F (ull)
+
+TESTS
+
+int
+main ()
+{
+  int i;
+
+  check_vect ();
+  for (i = 0; i < 64; i++)
+    {
+#undef F
+#define F(var) \
+      b##var[i] = i + 64; \
+      switch (i % 3) \
+       { \
+       case 0: c##var[i] = i + 64; break; \
+       case 1: c##var[i] = 127 - i; break; \
+       case 2: c##var[i] = i; break; \
+       } \
+      d##var[i] = i / 2; \
+      e##var[i] = i * 2;
+      TESTS
+    }
+#undef F
+#define F(var) f##var ();
+  TESTS
+  for (i = 0; i < 64; i++)
+    {
+      asm volatile ("" : : : "memory");
+#undef F
+#define F(var) \
+      if (a##var[i] != (b##var[i] > c##var[i] ? d##var[i] : e##var[i])) \
+       abort ();
+      TESTS
+    }
+  return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx-cond-1.c b/gcc/testsuite/gcc.target/i386/avx-cond-1.c
new file mode 100644 (file)
index 0000000..e233ec9
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mavx" } */
+/* { dg-require-effective-target avx_runtime } */
+
+#ifndef CHECK_H
+#define CHECK_H "avx-check.h"
+#endif
+
+#ifndef TEST
+#define TEST avx_test
+#endif
+
+#include "sse4_1-cond-1.c"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-cond-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-cond-1.c
new file mode 100644 (file)
index 0000000..41e69e5
--- /dev/null
@@ -0,0 +1,75 @@
+/* { dg-do run } */
+/* { dg-require-effective-target sse4 } */
+/* { dg-options "-O3 -msse4.1" } */
+
+#ifndef CHECK_H
+#define CHECK_H "sse4_1-check.h"
+#endif
+
+#ifndef TEST
+#define TEST sse4_1_test
+#endif
+
+#include CHECK_H
+
+extern void abort (void);
+double ad[64], bd[64], cd[64], dd[64], ed[64];
+float af[64], bf[64], cf[64], df[64], ef[64];
+signed char ac[64], bc[64], cc[64], dc[64], ec[64];
+short as[64], bs[64], cs[64], ds[64], es[64];
+int ai[64], bi[64], ci[64], di[64], ei[64];
+long long all[64], bll[64], cll[64], dll[64], ell[64];
+unsigned char auc[64], buc[64], cuc[64], duc[64], euc[64];
+unsigned short aus[64], bus[64], cus[64], dus[64], eus[64];
+unsigned int au[64], bu[64], cu[64], du[64], eu[64];
+unsigned long long aull[64], bull[64], cull[64], dull[64], eull[64];
+
+#define F(var) \
+__attribute__((noinline, noclone)) void \
+f##var (void) \
+{ \
+  int i; \
+  for (i = 0; i < 64; i++) \
+    { \
+      __typeof (a##var[0]) d = d##var[i], e = e##var[i]; \
+      a##var[i] = b##var[i] > c##var[i] ? d : e; \
+    } \
+}
+
+#define TESTS \
+F (d) F (f) F (c) F (s) F (i) F (ll) F (uc) F (us) F (u) F (ull)
+
+TESTS
+
+void
+TEST ()
+{
+  int i;
+  for (i = 0; i < 64; i++)
+    {
+#undef F
+#define F(var) \
+      b##var[i] = i + 64; \
+      switch (i % 3) \
+       { \
+       case 0: c##var[i] = i + 64; break; \
+       case 1: c##var[i] = 127 - i; break; \
+       case 2: c##var[i] = i; break; \
+       } \
+      d##var[i] = i / 2; \
+      e##var[i] = i * 2;
+      TESTS
+    }
+#undef F
+#define F(var) f##var ();
+  TESTS
+  for (i = 0; i < 64; i++)
+    {
+      asm volatile ("" : : : "memory");
+#undef F
+#define F(var) \
+      if (a##var[i] != (b##var[i] > c##var[i] ? d##var[i] : e##var[i])) \
+       abort ();
+      TESTS
+    }
+}