diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-12-30 09:53:10 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-12-30 09:53:10 +0100 |
commit | 8e72847528aa99b09cfc9b4072dbcf17b6d700bf (patch) | |
tree | 0649e97443c7d9592033f4f7069d09922c90a60c /gcc | |
parent | 5cf5a0e59b7ad7736d36b0042881f0c0788ccd82 (diff) | |
download | gcc-8e72847528aa99b09cfc9b4072dbcf17b6d700bf.zip gcc-8e72847528aa99b09cfc9b4072dbcf17b6d700bf.tar.gz gcc-8e72847528aa99b09cfc9b4072dbcf17b6d700bf.tar.bz2 |
re PR tree-optimization/59501 (Vector Gather with GCC 4.9 2013-12-08 Snapshot)
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-1.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-1a.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-2.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-2a.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-3.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-3a.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-4.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-4a.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-5.c | 39 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-6.c | 5 |
13 files changed, 215 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 290a978..b0870aa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 6e6b261..0a90ead 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b7f12f5..e5f1a82 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..6a104ee --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-1.c @@ -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 index 0000000..5b468e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-1a.c @@ -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 index 0000000..8ce177d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-2.c @@ -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 index 0000000..c0fe362 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-2a.c @@ -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 index 0000000..0bf5ef6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-3.c @@ -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 index 0000000..ded4336 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-3a.c @@ -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 index 0000000..43a5ad2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-4.c @@ -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 index 0000000..5c3cb68 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-4a.c @@ -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 index 0000000..f2feca8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-5.c @@ -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 index 0000000..d0ac242 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr59501-6.c @@ -0,0 +1,5 @@ +/* PR target/59501 */ +/* { dg-do run } */ +/* { dg-options "-O2 -mavx -maccumulate-outgoing-args" } */ + +#include "pr59501-5.c" |