diff options
author | Tejas Belagod <tejas.belagod@arm.com> | 2013-12-05 17:24:52 +0000 |
---|---|---|
committer | Tejas Belagod <belagod@gcc.gnu.org> | 2013-12-05 17:24:52 +0000 |
commit | 8c8952918b75f4fa6adbbe44cd641d5fd0bb55e3 (patch) | |
tree | 9724f5ffff7a15227f05b12519028d421225dfaf | |
parent | 601a5921eb0b56c647b3fa7136d11172495c0cb0 (diff) | |
download | gcc-8c8952918b75f4fa6adbbe44cd641d5fd0bb55e3.zip gcc-8c8952918b75f4fa6adbbe44cd641d5fd0bb55e3.tar.gz gcc-8c8952918b75f4fa6adbbe44cd641d5fd0bb55e3.tar.bz2 |
Eliminate redundant vec_select moves.
gcc/
* rtlanal.c (set_noop_p): Return nonzero in case of redundant vec_select for
overlapping register lanes.
testsuite/
* config/gcc.dg/vect/vect-nop-move.c: New.
From-SVN: r205712
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/rtlanal.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/vect-nop-move.c | 64 |
4 files changed, 94 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7488e92..49c0844 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2013-12-05 Tejas Belagod <tejas.belagod@arm.com> + + * rtlanal.c (set_noop_p): Return nonzero in case of redundant vec_select + for overlapping register lanes. + 2013-12-05 Kirill Yukhin <kirill.yukhin@intel.com> * config/i386/i386.c (ix86_expand_builtin): Generate diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 0cd0c7e..38f9e36 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1180,6 +1180,27 @@ set_noop_p (const_rtx set) dst = SUBREG_REG (dst); } + /* It is a NOOP if destination overlaps with selected src vector + elements. */ + if (GET_CODE (src) == VEC_SELECT + && REG_P (XEXP (src, 0)) && REG_P (dst) + && HARD_REGISTER_P (XEXP (src, 0)) + && HARD_REGISTER_P (dst)) + { + int i; + rtx par = XEXP (src, 1); + rtx src0 = XEXP (src, 0); + int c0 = INTVAL (XVECEXP (par, 0, 0)); + HOST_WIDE_INT offset = GET_MODE_UNIT_SIZE (GET_MODE (src0)) * c0; + + for (i = 1; i < XVECLEN (par, 0); i++) + if (INTVAL (XVECEXP (par, 0, i)) != c0 + i) + return 0; + return + simplify_subreg_regno (REGNO (src0), GET_MODE (src0), + offset, GET_MODE (dst)) == (int) REGNO (dst); + } + return (REG_P (src) && REG_P (dst) && REGNO (src) == REGNO (dst)); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2ede528..d9f7de3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-12-05 Tejas Belagod <tejas.belagod@arm.com> + + * gcc.dg/vect/vect-nop-move.c: New test. + 2013-12-05 Max Ostapenko <m.ostapenko@partner.samsung.com> * c-c++-common/tsan/atomic_stack.c: New test. diff --git a/gcc/testsuite/gcc.dg/vect/vect-nop-move.c b/gcc/testsuite/gcc.dg/vect/vect-nop-move.c new file mode 100644 index 0000000..19419335 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/vect-nop-move.c @@ -0,0 +1,64 @@ +/* { dg-do run } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-options "-O3 -fdump-rtl-combine-details" } */ + +extern void abort (void); + +#define NOINLINE __attribute__((noinline)) + +typedef float float32x4_t __attribute__ ((__vector_size__ (16))); +typedef float float32x2_t __attribute__ ((__vector_size__ (8))); + +NOINLINE float +foo32x4_be (float32x4_t x) +{ + return x[3]; +} + +NOINLINE float +foo32x4_le (float32x4_t x) +{ + return x[0]; +} + +NOINLINE float +bar (float a) +{ + return a; +} + +NOINLINE float +foo32x2_be (float32x2_t x) +{ + return bar (x[1]); +} + +NOINLINE float +foo32x2_le (float32x2_t x) +{ + return bar (x[0]); +} + +int +main() +{ + float32x4_t a = { 0.0f, 1.0f, 2.0f, 3.0f }; + float32x2_t b = { 0.0f, 1.0f }; + + if (foo32x4_be (a) != 3.0f) + abort (); + + if (foo32x4_le (a) != 0.0f) + abort (); + + if (foo32x2_be (b) != 1.0f) + abort (); + + if (foo32x2_le (b) != 0.0f) + abort (); + + return 0; +} + +/* { dg-final { scan-rtl-dump "deleting noop move" "combine" { target aarch64*-*-* } } } */ +/* { dg-final { cleanup-rtl-dump "combine" } } */ |