re PR rtl-optimization/65078 (4.9 and 5.0 generate more spill-fill in comparison...
authorJakub Jelinek <jakub@redhat.com>
Wed, 18 Mar 2015 10:58:32 +0000 (11:58 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 18 Mar 2015 10:58:32 +0000 (11:58 +0100)
PR target/65078
* config/i386/sse.md (movsi/movdi -> vec_extract_*_0 splitter): New.

* gcc.target/i386/pr65078-1.c: New test.
* gcc.target/i386/pr65078-2.c: New test.
* gcc.target/i386/pr65078-3.c: New test.
* gcc.target/i386/pr65078-4.c: New test.
* gcc.target/i386/pr65078-5.c: New test.
* gcc.target/i386/pr65078-6.c: New test.

From-SVN: r221485

gcc/ChangeLog
gcc/config/i386/sse.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr65078-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr65078-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr65078-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr65078-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr65078-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr65078-6.c [new file with mode: 0644]

index 7120cc363e47b54dffb9cb2d75a00ffcb3fdb66d..77abe6739f9656dd7a484117b54b00a8340300ea 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/65078
+       * config/i386/sse.md (movsi/movdi -> vec_extract_*_0 splitter): New.
+
 2015-03-16  Georg-Johann Lay  <avr@gjlay.de>
 
        PR target/65296
index af74b35d5caeb0a7953fb9cee9604a3050e01e2e..5800a3eebf21f5b24866a228a10bc26e8cfa98d0 100644 (file)
   operands[1] = adjust_address (operands[1], <ssescalarmode>mode, offs);
 })
 
+;; Turn SImode or DImode extraction from arbitrary SSE/AVX/AVX512F
+;; vector modes into vec_extract*.
+(define_split
+  [(set (match_operand:SWI48x 0 "nonimmediate_operand")
+       (match_operand:SWI48x 1 "register_operand"))]
+  "can_create_pseudo_p ()
+   && GET_CODE (operands[1]) == SUBREG
+   && REG_P (SUBREG_REG (operands[1]))
+   && (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[1]))) == MODE_VECTOR_INT
+       || (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[1])))
+          == MODE_VECTOR_FLOAT))
+   && SUBREG_BYTE (operands[1]) == 0
+   && TARGET_SSE
+   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[1]))) == 16
+       || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[1]))) == 32
+          && TARGET_AVX)
+       || (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[1]))) == 64
+          && TARGET_AVX512F))
+   && (<MODE>mode == SImode || TARGET_64BIT || MEM_P (operands[0]))"
+  [(set (match_dup 0) (vec_select:SWI48x (match_dup 1)
+                                        (parallel [(const_int 0)])))]
+{
+  rtx tmp;
+  operands[1] = SUBREG_REG (operands[1]);
+  switch (GET_MODE_SIZE (GET_MODE (operands[1])))
+    {
+    case 64:
+      if (<MODE>mode == SImode)
+       {
+         tmp = gen_reg_rtx (V8SImode);
+         emit_insn (gen_vec_extract_lo_v16si (tmp,
+                                              gen_lowpart (V16SImode,
+                                                           operands[1])));
+       }
+      else
+       {
+         tmp = gen_reg_rtx (V4DImode);
+         emit_insn (gen_vec_extract_lo_v8di (tmp,
+                                             gen_lowpart (V8DImode,
+                                                          operands[1])));
+       }
+      operands[1] = tmp;
+      /* FALLTHRU */
+    case 32:
+      tmp = gen_reg_rtx (<ssevecmode>mode);
+      if (<MODE>mode == SImode)
+       emit_insn (gen_vec_extract_lo_v8si (tmp, gen_lowpart (V8SImode,
+                                                             operands[1])));
+      else
+       emit_insn (gen_vec_extract_lo_v4di (tmp, gen_lowpart (V4DImode,
+                                                             operands[1])));
+      operands[1] = tmp;
+      break;
+    case 16:
+      operands[1] = gen_lowpart (<ssevecmode>mode, operands[1]);
+      break;
+    }
+})
+
 (define_insn "*vec_concatv2si_sse4_1"
   [(set (match_operand:V2SI 0 "register_operand"     "=Yr,*x,x, Yr,*x,x, x, *y,*y")
        (vec_concat:V2SI
index 16605f35f2a428d669862f486e10751d3c738740..406fec06f0ef7ed08d3dad11875ea74eceed121b 100644 (file)
@@ -1,3 +1,13 @@
+2015-03-18  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/65078
+       * gcc.target/i386/pr65078-1.c: New test.
+       * gcc.target/i386/pr65078-2.c: New test.
+       * gcc.target/i386/pr65078-3.c: New test.
+       * gcc.target/i386/pr65078-4.c: New test.
+       * gcc.target/i386/pr65078-5.c: New test.
+       * gcc.target/i386/pr65078-6.c: New test.
+
 2015-03-18  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/65340
diff --git a/gcc/testsuite/gcc.target/i386/pr65078-1.c b/gcc/testsuite/gcc.target/i386/pr65078-1.c
new file mode 100644 (file)
index 0000000..d8d0d85
--- /dev/null
@@ -0,0 +1,61 @@
+/* PR target/65078 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2" } */
+/* { dg-additional-options "-mregparm=2" { target ia32 } } */
+/* { dg-final { scan-assembler-not "\\(%\[er\]sp\\)" } } */
+
+typedef unsigned char V __attribute__((vector_size (16)));
+typedef unsigned long long W __attribute__((vector_size (16)));
+typedef unsigned int T __attribute__((vector_size (16)));
+
+void
+f1 (unsigned long long *x, V y)
+{
+  *x = ((W)y)[0];
+}
+
+#if defined(__x86_64__) || defined(ALL)
+unsigned long long
+f2 (V y)
+{
+  return ((W)y)[0];
+}
+#endif
+
+void
+f3 (unsigned int *x, V y)
+{
+  *x = ((T)y)[0];
+}
+
+unsigned int
+f4 (V y)
+{
+  return ((T)y)[0];
+}
+
+void
+f5 (unsigned long long *x, W y)
+{
+  *x = ((W)y)[0];
+}
+
+#if defined(__x86_64__) || defined(ALL)
+unsigned long long
+f6 (W y)
+{
+  return ((W)y)[0];
+}
+#endif
+
+void
+f7 (unsigned int *x, T y)
+{
+  *x = ((T)y)[0];
+}
+
+unsigned int
+f8 (T y)
+{
+  return ((T)y)[0];
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr65078-2.c b/gcc/testsuite/gcc.target/i386/pr65078-2.c
new file mode 100644 (file)
index 0000000..bf220cd
--- /dev/null
@@ -0,0 +1,61 @@
+/* PR target/65078 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-additional-options "-mregparm=2" { target ia32 } } */
+/* { dg-final { scan-assembler-not "\\(%\[er\]sp\\)" } } */
+
+typedef unsigned char V __attribute__((vector_size (32)));
+typedef unsigned long long W __attribute__((vector_size (32)));
+typedef unsigned int T __attribute__((vector_size (32)));
+
+void
+f1 (unsigned long long *x, V y)
+{
+  *x = ((W)y)[0];
+}
+
+#if defined(__x86_64__) || defined(ALL)
+unsigned long long
+f2 (V y)
+{
+  return ((W)y)[0];
+}
+#endif
+
+void
+f3 (unsigned int *x, V y)
+{
+  *x = ((T)y)[0];
+}
+
+unsigned int
+f4 (V y)
+{
+  return ((T)y)[0];
+}
+
+void
+f5 (unsigned long long *x, W y)
+{
+  *x = ((W)y)[0];
+}
+
+#if defined(__x86_64__) || defined(ALL)
+unsigned long long
+f6 (W y)
+{
+  return ((W)y)[0];
+}
+#endif
+
+void
+f7 (unsigned int *x, T y)
+{
+  *x = ((T)y)[0];
+}
+
+unsigned int
+f8 (T y)
+{
+  return ((T)y)[0];
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr65078-3.c b/gcc/testsuite/gcc.target/i386/pr65078-3.c
new file mode 100644 (file)
index 0000000..d1b679f
--- /dev/null
@@ -0,0 +1,61 @@
+/* PR target/65078 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512f" } */
+/* { dg-additional-options "-mregparm=2" { target ia32 } } */
+/* { dg-final { scan-assembler-not "\\(%\[er\]sp\\)" } } */
+
+typedef unsigned char V __attribute__((vector_size (64)));
+typedef unsigned long long W __attribute__((vector_size (64)));
+typedef unsigned int T __attribute__((vector_size (64)));
+
+void
+f1 (unsigned long long *x, V y)
+{
+  *x = ((W)y)[0];
+}
+
+#if defined(__x86_64__) || defined(ALL)
+unsigned long long
+f2 (V y)
+{
+  return ((W)y)[0];
+}
+#endif
+
+void
+f3 (unsigned int *x, V y)
+{
+  *x = ((T)y)[0];
+}
+
+unsigned int
+f4 (V y)
+{
+  return ((T)y)[0];
+}
+
+void
+f5 (unsigned long long *x, W y)
+{
+  *x = ((W)y)[0];
+}
+
+#if defined(__x86_64__) || defined(ALL)
+unsigned long long
+f6 (W y)
+{
+  return ((W)y)[0];
+}
+#endif
+
+void
+f7 (unsigned int *x, T y)
+{
+  *x = ((T)y)[0];
+}
+
+unsigned int
+f8 (T y)
+{
+  return ((T)y)[0];
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr65078-4.c b/gcc/testsuite/gcc.target/i386/pr65078-4.c
new file mode 100644 (file)
index 0000000..d6c5224
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR target/65078 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse -DALL" } */
+
+#include "pr65078-1.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr65078-5.c b/gcc/testsuite/gcc.target/i386/pr65078-5.c
new file mode 100644 (file)
index 0000000..9e787fe
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR target/65078 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -DALL" } */
+
+#include "pr65078-2.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr65078-6.c b/gcc/testsuite/gcc.target/i386/pr65078-6.c
new file mode 100644 (file)
index 0000000..3fdc905
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR target/65078 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512f -DALL" } */
+
+#include "pr65078-3.c"