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
This commit is contained in:
Richard Guenther 2011-03-15 12:22:12 +00:00 committed by Richard Biener
parent 7ee93d4e34
commit b2ad5e3738
4 changed files with 57 additions and 8 deletions

View File

@ -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

View File

@ -1,3 +1,8 @@
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

View File

@ -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" } } */

View File

@ -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)