]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/59501 (Vector Gather with GCC 4.9 2013-12-08 Snapshot)
authorJakub Jelinek <jakub@redhat.com>
Mon, 30 Dec 2013 08:53:10 +0000 (09:53 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 30 Dec 2013 08:53:10 +0000 (09:53 +0100)
PR target/59501
* config/i386/i386.c (ix86_save_reg): Don't return true for drap_reg
if !crtl->stack_realign_needed.
(ix86_finalize_stack_realign_flags): If drap_reg isn't live on entry
and stack_realign_needed will be false, clear drap_reg and need_drap.
Optimize leaf functions that don't need stack frame even if
crtl->need_drap.

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

From-SVN: r206243

13 files changed:
gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr59501-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59501-1a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59501-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59501-2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59501-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59501-3a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59501-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59501-4a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59501-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr59501-6.c [new file with mode: 0644]

index 290a978f8bdeddba8204bae185cb9961c8428340..b0870aa1f851552b32fb36b3a9cc35a107030ea5 100644 (file)
@@ -1,3 +1,13 @@
+2013-12-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/59501
+       * config/i386/i386.c (ix86_save_reg): Don't return true for drap_reg
+       if !crtl->stack_realign_needed.
+       (ix86_finalize_stack_realign_flags): If drap_reg isn't live on entry
+       and stack_realign_needed will be false, clear drap_reg and need_drap.
+       Optimize leaf functions that don't need stack frame even if
+       crtl->need_drap.
+
 2013-12-30   H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/59605
index 6e6b2617f92e6cd0e28abae5f27470b8d3c4d8fb..0a90ead8970ea15a3ac1768bd93384da3d2264cc 100644 (file)
@@ -9189,7 +9189,9 @@ ix86_save_reg (unsigned int regno, bool maybe_eh_return)
        }
     }
 
-  if (crtl->drap_reg && regno == REGNO (crtl->drap_reg))
+  if (crtl->drap_reg
+      && regno == REGNO (crtl->drap_reg)
+      && crtl->stack_realign_needed)
     return true;
 
   return (df_regs_ever_live_p (regno)
@@ -10427,12 +10429,23 @@ ix86_finalize_stack_realign_flags (void)
       return;
     }
 
+  /* If drap has been set, but it actually isn't live at the start
+     of the function and !stack_realign, there is no reason to set it up.  */
+  if (crtl->drap_reg && !stack_realign)
+    {
+      basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
+      if (! REGNO_REG_SET_P (DF_LR_IN (bb), REGNO (crtl->drap_reg)))
+       {
+         crtl->drap_reg = NULL_RTX;
+         crtl->need_drap = false;
+       }
+    }
+
   /* If the only reason for frame_pointer_needed is that we conservatively
      assumed stack realignment might be needed, but in the end nothing that
      needed the stack alignment had been spilled, clear frame_pointer_needed
      and say we don't need stack realignment.  */
   if (stack_realign
-      && !crtl->need_drap
       && frame_pointer_needed
       && crtl->is_leaf
       && flag_omit_frame_pointer
@@ -10470,6 +10483,18 @@ ix86_finalize_stack_realign_flags (void)
              }
        }
 
+      /* If drap has been set, but it actually isn't live at the start
+        of the function, there is no reason to set it up.  */
+      if (crtl->drap_reg)
+       {
+         basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
+         if (! REGNO_REG_SET_P (DF_LR_IN (bb), REGNO (crtl->drap_reg)))
+           {
+             crtl->drap_reg = NULL_RTX;
+             crtl->need_drap = false;
+           }
+       }
+
       frame_pointer_needed = false;
       stack_realign = false;
       crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
index b7f12f5b9b57deb6feeed12bb89cf7acce697dc8..e5f1a82c8879d8aeedd760640737b780190db971 100644 (file)
@@ -1,3 +1,17 @@
+2013-12-30  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/59501
+       * gcc.target/i386/pr59501-1.c: New test.
+       * gcc.target/i386/pr59501-1a.c: New test.
+       * gcc.target/i386/pr59501-2.c: New test.
+       * gcc.target/i386/pr59501-2a.c: New test.
+       * gcc.target/i386/pr59501-3.c: New test.
+       * gcc.target/i386/pr59501-3a.c: New test.
+       * gcc.target/i386/pr59501-4.c: New test.
+       * gcc.target/i386/pr59501-4a.c: New test.
+       * gcc.target/i386/pr59501-5.c: New test.
+       * gcc.target/i386/pr59501-6.c: New test.
+
 2013-12-30   H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/59605
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-1.c b/gcc/testsuite/gcc.target/i386/pr59501-1.c
new file mode 100644 (file)
index 0000000..6a104ee
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR target/59501 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx -mno-accumulate-outgoing-args" } */
+
+#define CHECK_H "avx-check.h"
+#define TEST avx_test
+
+#include CHECK_H
+
+typedef double V __attribute__ ((vector_size (32)));
+
+__attribute__((noinline, noclone)) V
+foo (double *x, unsigned *y)
+{
+  V r = { x[y[0]], x[y[1]], x[y[2]], x[y[3]] };
+  return r;
+}
+
+static void
+TEST (void)
+{
+  double a[16];
+  unsigned b[4] = { 5, 0, 15, 7 };
+  int i;
+  for (i = 0; i < 16; i++)
+    a[i] = 0.5 + i;
+  V v = foo (a, b);
+  if (v[0] != 5.5 || v[1] != 0.5 || v[2] != 15.5 || v[3] != 7.5)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-1a.c b/gcc/testsuite/gcc.target/i386/pr59501-1a.c
new file mode 100644 (file)
index 0000000..5b468e5
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR target/59501 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx -mno-accumulate-outgoing-args" } */
+
+typedef double V __attribute__ ((vector_size (32)));
+
+V
+foo (double *x, unsigned *y)
+{
+  V r = { x[y[0]], x[y[1]], x[y[2]], x[y[3]] };
+  return r;
+}
+
+/* Verify no dynamic realignment is performed.  */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*sp" } } */
+/* And DRAP isn't needed either.  */
+/* { dg-final { scan-assembler-not "r10" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-2.c b/gcc/testsuite/gcc.target/i386/pr59501-2.c
new file mode 100644 (file)
index 0000000..8ce177d
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR target/59501 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx -maccumulate-outgoing-args" } */
+
+#include "pr59501-1.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-2a.c b/gcc/testsuite/gcc.target/i386/pr59501-2a.c
new file mode 100644 (file)
index 0000000..c0fe362
--- /dev/null
@@ -0,0 +1,10 @@
+/* PR target/59501 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx -maccumulate-outgoing-args" } */
+
+#include "pr59501-1a.c"
+
+/* Verify no dynamic realignment is performed.  */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*sp" } } */
+/* And DRAP isn't needed either.  */
+/* { dg-final { scan-assembler-not "r10" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-3.c b/gcc/testsuite/gcc.target/i386/pr59501-3.c
new file mode 100644 (file)
index 0000000..0bf5ef6
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR target/59501 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx -mno-accumulate-outgoing-args" } */
+
+#define CHECK_H "avx-check.h"
+#define TEST avx_test
+
+#include CHECK_H
+
+typedef double V __attribute__ ((vector_size (32)));
+
+__attribute__((noinline, noclone)) V
+foo (double *x, int a, int b, int c, int d, int e, int f, unsigned *y)
+{
+  V r = { x[y[0]], x[y[1]], x[y[2]], x[y[3]] };
+  return r;
+}
+
+static void
+TEST (void)
+{
+  double a[16];
+  unsigned b[4] = { 5, 0, 15, 7 };
+  int i;
+  for (i = 0; i < 16; i++)
+    a[i] = 0.5 + i;
+  V v = foo (a, 0, 0, 0, 0, 0, 0, b);
+  if (v[0] != 5.5 || v[1] != 0.5 || v[2] != 15.5 || v[3] != 7.5)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-3a.c b/gcc/testsuite/gcc.target/i386/pr59501-3a.c
new file mode 100644 (file)
index 0000000..ded4336
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR target/59501 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx -mno-accumulate-outgoing-args" } */
+
+typedef double V __attribute__ ((vector_size (32)));
+
+V
+foo (double *x, int a, int b, int c, int d, int e, int f, unsigned *y)
+{
+  V r = { x[y[0]], x[y[1]], x[y[2]], x[y[3]] };
+  return r;
+}
+
+/* Verify no dynamic realignment is performed.  */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*sp" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-4.c b/gcc/testsuite/gcc.target/i386/pr59501-4.c
new file mode 100644 (file)
index 0000000..43a5ad2
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR target/59501 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx -maccumulate-outgoing-args" } */
+
+#include "pr59501-3.c"
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-4a.c b/gcc/testsuite/gcc.target/i386/pr59501-4a.c
new file mode 100644 (file)
index 0000000..5c3cb68
--- /dev/null
@@ -0,0 +1,8 @@
+/* PR target/59501 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx -maccumulate-outgoing-args" } */
+
+#include "pr59501-3a.c"
+
+/* Verify no dynamic realignment is performed.  */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*sp" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-5.c b/gcc/testsuite/gcc.target/i386/pr59501-5.c
new file mode 100644 (file)
index 0000000..f2feca8
--- /dev/null
@@ -0,0 +1,39 @@
+/* PR target/59501 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx -mno-accumulate-outgoing-args" } */
+
+#define CHECK_H "avx-check.h"
+#define TEST avx_test
+
+#include CHECK_H
+
+typedef double V __attribute__ ((vector_size (32)));
+
+__attribute__((noinline, noclone)) void
+bar (char *p)
+{
+  p[0] = 1;
+  p[37] = 2;
+  asm volatile ("" : : "r" (p) : "memory");
+}
+
+__attribute__((noinline, noclone)) V
+foo (double *x, int a, int b, int c, int d, int e, int f, unsigned *y)
+{
+  bar (__builtin_alloca (a + b + c + d + e + f));
+  V r = { x[y[0]], x[y[1]], x[y[2]], x[y[3]] };
+  return r;
+}
+
+static void
+TEST (void)
+{
+  double a[16];
+  unsigned b[4] = { 5, 0, 15, 7 };
+  int i;
+  for (i = 0; i < 16; i++)
+    a[i] = 0.5 + i;
+  V v = foo (a, 0, 30, 0, 0, 8, 0, b);
+  if (v[0] != 5.5 || v[1] != 0.5 || v[2] != 15.5 || v[3] != 7.5)  
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-6.c b/gcc/testsuite/gcc.target/i386/pr59501-6.c
new file mode 100644 (file)
index 0000000..d0ac242
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR target/59501 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx -maccumulate-outgoing-args" } */
+
+#include "pr59501-5.c"