From 3574cf47facc3fdc37a02411eb879b1bdcfe4067 Mon Sep 17 00:00:00 2001 From: Bill Schmidt Date: Tue, 12 Jan 2016 04:49:55 +0000 Subject: [PATCH] rs6000.c (v2df_reduction_p): New function. [gcc] 2016-01-11 Bill Schmidt * config/rs6000/rs6000.c (v2df_reduction_p): New function. (rtx_is_swappable_p): Reductions are swappable. (insn_is_swappable_p): V2DF reductions are swappable. [gcc/testsuite] 2016-01-11 Bill Schmidt * gcc.target/powerpc/swaps-p8-23.c: New test. * gcc.target/powerpc/swaps-p8-24.c: Likewise. From-SVN: r232257 --- gcc/ChangeLog | 6 +++ gcc/config/rs6000/rs6000.c | 52 +++++++++++++++++++ gcc/testsuite/ChangeLog | 5 ++ .../gcc.target/powerpc/swaps-p8-23.c | 26 ++++++++++ .../gcc.target/powerpc/swaps-p8-24.c | 26 ++++++++++ 5 files changed, 115 insertions(+) create mode 100644 gcc/testsuite/gcc.target/powerpc/swaps-p8-23.c create mode 100644 gcc/testsuite/gcc.target/powerpc/swaps-p8-24.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd84e1f36d63..4a8a005138f9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-01-11 Bill Schmidt + + * config/rs6000/rs6000.c (v2df_reduction_p): New function. + (rtx_is_swappable_p): Reductions are swappable. + (insn_is_swappable_p): V2DF reductions are swappable. + 2016-01-11 John David Anglin * config/pa/pa.c (pa_emit_move_sequence): Handle floating point diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index cd5243adb0fe..4cd6a1b58cd8 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -36648,6 +36648,44 @@ const_load_sequence_p (swap_web_entry *insn_entry, rtx insn) return true; } +/* Return TRUE iff OP matches a V2DF reduction pattern. See the + definition of vsx_reduc__v2df in vsx.md. */ +static bool +v2df_reduction_p (rtx op) +{ + if (GET_MODE (op) != V2DFmode) + return false; + + enum rtx_code code = GET_CODE (op); + if (code != PLUS && code != SMIN && code != SMAX) + return false; + + rtx concat = XEXP (op, 0); + if (GET_CODE (concat) != VEC_CONCAT) + return false; + + rtx select0 = XEXP (concat, 0); + rtx select1 = XEXP (concat, 1); + if (GET_CODE (select0) != VEC_SELECT || GET_CODE (select1) != VEC_SELECT) + return false; + + rtx reg0 = XEXP (select0, 0); + rtx reg1 = XEXP (select1, 0); + if (!rtx_equal_p (reg0, reg1) || !REG_P (reg0)) + return false; + + rtx parallel0 = XEXP (select0, 1); + rtx parallel1 = XEXP (select1, 1); + if (GET_CODE (parallel0) != PARALLEL || GET_CODE (parallel1) != PARALLEL) + return false; + + if (!rtx_equal_p (XVECEXP (parallel0, 0, 0), const1_rtx) + || !rtx_equal_p (XVECEXP (parallel1, 0, 0), const0_rtx)) + return false; + + return true; +} + /* Return 1 iff OP is an operand that will not be affected by having vector doublewords swapped in memory. */ static unsigned int @@ -36719,6 +36757,8 @@ rtx_is_swappable_p (rtx op, unsigned int *special) *special = SH_XXPERMDI; return 1; } + else if (v2df_reduction_p (op)) + return 1; else return 0; @@ -36783,6 +36823,9 @@ rtx_is_swappable_p (rtx op, unsigned int *special) case UNSPEC_VSPLT_DIRECT: *special = SH_SPLAT; return 1; + case UNSPEC_REDUC_PLUS: + case UNSPEC_REDUC: + return 1; } } @@ -36907,6 +36950,15 @@ insn_is_swappable_p (swap_web_entry *insn_entry, rtx insn, return 1; } + /* V2DF reductions are always swappable. */ + if (GET_CODE (body) == PARALLEL) + { + rtx expr = XVECEXP (body, 0, 0); + if (GET_CODE (expr) == SET + && v2df_reduction_p (SET_SRC (expr))) + return 1; + } + /* An UNSPEC_VPERM is ok if the mask operand is loaded from the constant pool. */ if (GET_CODE (body) == SET diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7e9fc7f2d601..97562b918172 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-11 Bill Schmidt + + * gcc.target/powerpc/swaps-p8-23.c: New test. + * gcc.target/powerpc/swaps-p8-24.c: Likewise. + 2016-01-11 John David Anglin PR tree-optimization/68356 diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-23.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-23.c new file mode 100644 index 000000000000..a3f83ae26b9f --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-23.c @@ -0,0 +1,26 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3 -ffast-math" } */ +/* { dg-final { scan-assembler "lxvd2x" } } */ +/* { dg-final { scan-assembler-not "xxpermdi" } } */ + +/* Verify that swap optimization works correctly in the presence of + a V2DFmode reduction. */ + +extern double optvalue; +extern void obfuscate (double, unsigned int); + +void +foo (double *x, double *y, unsigned int n, unsigned int m) +{ + unsigned int i, j; + double sacc; + for (j = 0; j < m; ++j) + { + sacc = 0.0; + for (i = 0; i < n; ++i) + sacc += x[i] * y[i]; + obfuscate (sacc, n); + } + optvalue = n * 2.0 * m; +} diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-24.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-24.c new file mode 100644 index 000000000000..528d6e6a68cf --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-24.c @@ -0,0 +1,26 @@ +/* { dg-do compile { target { powerpc64le-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-mcpu=power8 -O3 -ffast-math" } */ +/* { dg-final { scan-assembler "lxvd2x" } } */ +/* { dg-final { scan-assembler-not "xxpermdi" } } */ + +/* Verify that swap optimization works correctly in the presence of + a V4SFmode reduction. */ + +extern double optvalue; +extern void obfuscate (float, unsigned int); + +void +foo (float *x, float *y, unsigned int n, unsigned int m) +{ + unsigned int i, j; + float sacc; + for (j = 0; j < m; ++j) + { + sacc = 0.0f; + for (i = 0; i < n; ++i) + sacc += x[i] * y[i]; + obfuscate (sacc, n); + } + optvalue = n * 2.0f * m; +} -- 2.47.2