diff options
author | Richard Guenther <rguenther@suse.de> | 2011-03-15 12:22:12 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2011-03-15 12:22:12 +0000 |
commit | b2ad5e3738bdf0c957dea0973400320995f185c5 (patch) | |
tree | 5a72cd150668d074636e998470b168a9e760eae5 /gcc | |
parent | 7ee93d4e3473e678dcabef2e09b3cc1c820968e4 (diff) | |
download | gcc-b2ad5e3738bdf0c957dea0973400320995f185c5.zip gcc-b2ad5e3738bdf0c957dea0973400320995f185c5.tar.gz gcc-b2ad5e3738bdf0c957dea0973400320995f185c5.tar.bz2 |
re PR rtl-optimization/48037 (Missed optimization: unnecessary register moves)
2011-03-15 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48037
* tree-ssa.c (maybe_rewrite_mem_ref_base): Rewrite vector
selects into BIT_FIELD_REFs.
(non_rewritable_mem_ref_base): Check if a MEM_REF is a
vector select.
* gcc.target/i386/pr48037-1.c: New testcase.
From-SVN: r170986
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr48037-1.c | 15 | ||||
-rw-r--r-- | gcc/tree-ssa.c | 37 |
4 files changed, 57 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec59459..198b1b7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-03-15 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/48037 + * tree-ssa.c (maybe_rewrite_mem_ref_base): Rewrite vector + selects into BIT_FIELD_REFs. + (non_rewritable_mem_ref_base): Check if a MEM_REF is a + vector select. + 2011-03-15 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/48129 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2db72ee..6c209b0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2011-03-15 Richard Guenther <rguenther@suse.de> + PR tree-optimization/48037 + * gcc.target/i386/pr48037-1.c: New testcase. + +2011-03-15 Richard Guenther <rguenther@suse.de> + PR tree-optimization/41490 * gcc.dg/tree-ssa/ssa-sink-6.c: New testcase. * gcc.dg/tree-ssa/ssa-sink-7.c: Likewise. diff --git a/gcc/testsuite/gcc.target/i386/pr48037-1.c b/gcc/testsuite/gcc.target/i386/pr48037-1.c new file mode 100644 index 0000000..30c81e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr48037-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O -fno-math-errno" } */ + +typedef double __m128d __attribute__((vector_size(16))); +__m128d vsqrt1 (__m128d const x) +{ + double const* __restrict__ const y = (double const*)&x; + double const a = __builtin_sqrt(y[0]); + double const b = __builtin_sqrt(y[1]); + return (__m128d) { a, b }; +} + +/* Verify we do not spill x to the stack. */ +/* { dg-final { scan-assembler-not "%rsp" } } */ diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 5c9e0d8..f28e5d1 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1838,18 +1838,32 @@ maybe_rewrite_mem_ref_base (tree *tp) tp = &TREE_OPERAND (*tp, 0); if (TREE_CODE (*tp) == MEM_REF && TREE_CODE (TREE_OPERAND (*tp, 0)) == ADDR_EXPR - && integer_zerop (TREE_OPERAND (*tp, 1)) && (sym = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0)) && DECL_P (sym) && !TREE_ADDRESSABLE (sym) && symbol_marked_for_renaming (sym)) { - if (!useless_type_conversion_p (TREE_TYPE (*tp), - TREE_TYPE (sym))) - *tp = build1 (VIEW_CONVERT_EXPR, - TREE_TYPE (*tp), sym); - else - *tp = sym; + if (TREE_CODE (TREE_TYPE (sym)) == VECTOR_TYPE + && useless_type_conversion_p (TREE_TYPE (*tp), + TREE_TYPE (TREE_TYPE (sym))) + && multiple_of_p (sizetype, TREE_OPERAND (*tp, 1), + TYPE_SIZE_UNIT (TREE_TYPE (*tp)))) + { + *tp = build3 (BIT_FIELD_REF, TREE_TYPE (*tp), sym, + TYPE_SIZE (TREE_TYPE (*tp)), + int_const_binop (MULT_EXPR, + bitsize_int (BITS_PER_UNIT), + TREE_OPERAND (*tp, 1), 0)); + } + else if (integer_zerop (TREE_OPERAND (*tp, 1))) + { + if (!useless_type_conversion_p (TREE_TYPE (*tp), + TREE_TYPE (sym))) + *tp = build1 (VIEW_CONVERT_EXPR, + TREE_TYPE (*tp), sym); + else + *tp = sym; + } } } @@ -1869,11 +1883,18 @@ non_rewritable_mem_ref_base (tree ref) base = TREE_OPERAND (base, 0); /* But watch out for MEM_REFs we cannot lower to a - VIEW_CONVERT_EXPR. */ + VIEW_CONVERT_EXPR or a BIT_FIELD_REF. */ if (TREE_CODE (base) == MEM_REF && TREE_CODE (TREE_OPERAND (base, 0)) == ADDR_EXPR) { tree decl = TREE_OPERAND (TREE_OPERAND (base, 0), 0); + if (TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE + && useless_type_conversion_p (TREE_TYPE (base), + TREE_TYPE (TREE_TYPE (decl))) + && double_int_fits_in_uhwi_p (mem_ref_offset (base)) + && multiple_of_p (sizetype, TREE_OPERAND (base, 1), + TYPE_SIZE_UNIT (TREE_TYPE (base)))) + return NULL_TREE; if (DECL_P (decl) && (!integer_zerop (TREE_OPERAND (base, 1)) || (DECL_SIZE (decl) |