From: Jakub Jelinek Date: Mon, 30 Dec 2013 08:53:10 +0000 (+0100) Subject: re PR tree-optimization/59501 (Vector Gather with GCC 4.9 2013-12-08 Snapshot) X-Git-Tag: misc/gupc_5_2_0_release~111^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e72847528aa99b09cfc9b4072dbcf17b6d700bf;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 290a978f8bde..b0870aa1f851 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2013-12-30 Jakub Jelinek + + 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 PR target/59605 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 6e6b2617f92e..0a90ead8970e 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 b7f12f5b9b57..e5f1a82c8879 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2013-12-30 Jakub Jelinek + + 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 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 000000000000..6a104eef1adc --- /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 000000000000..5b468e55635b --- /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 000000000000..8ce177deb8e4 --- /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 000000000000..c0fe36269611 --- /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 000000000000..0bf5ef6139a3 --- /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 000000000000..ded4336fc88e --- /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 000000000000..43a5ad2428aa --- /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 000000000000..5c3cb683a2eb --- /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 000000000000..f2feca8ec4f0 --- /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 000000000000..d0ac2425b902 --- /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"