This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Preserve more pointer arithmetic in IVOPTs
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 2 Sep 2013 13:25:32 +0200 (CEST)
- Subject: [PATCH] Preserve more pointer arithmetic in IVOPTs
- Authentication-results: sourceware.org; auth=none
tree-affine is a bit overzealous when converting elements of
pointer-typed combinations to sizetype. From IVOPTs we often
get a combination that doesn't start with a pointer element in
which case the result was a pure sizetype compute. This shows
when fixing PR57511 in gcc.dg/tree-ssa/reassoc-19.c where
we after the fix detect induction variables but manage to
break the pattern we expect.
So the following re-arranges add_elt_to_tree to preserve
pointerness when possible.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
Richard.
2013-09-02 Richard Biener <rguenther@suse.de>
* tree-affine.c (add_elt_to_tree): Avoid converting all pointer
arithmetic to sizetype.
* gcc.dg/tree-ssa/loop-4.c: Adjust scan looking for one memory
reference.
Index: gcc/tree-affine.c
===================================================================
*** gcc/tree-affine.c (revision 202097)
--- gcc/tree-affine.c (working copy)
*************** add_elt_to_tree (tree expr, tree type, t
*** 377,411 ****
type1 = sizetype;
scale = double_int_ext_for_comb (scale, comb);
! elt = fold_convert (type1, elt);
if (scale.is_one ())
{
if (!expr)
! return fold_convert (type, elt);
! if (POINTER_TYPE_P (type))
! return fold_build_pointer_plus (expr, elt);
! return fold_build2 (PLUS_EXPR, type, expr, elt);
}
if (scale.is_minus_one ())
{
if (!expr)
! return fold_convert (type, fold_build1 (NEGATE_EXPR, type1, elt));
! if (POINTER_TYPE_P (type))
! {
! elt = fold_build1 (NEGATE_EXPR, type1, elt);
! return fold_build_pointer_plus (expr, elt);
! }
! return fold_build2 (MINUS_EXPR, type, expr, elt);
}
if (!expr)
! return fold_convert (type,
! fold_build2 (MULT_EXPR, type1, elt,
! double_int_to_tree (type1, scale)));
if (scale.is_negative ())
{
--- 377,422 ----
type1 = sizetype;
scale = double_int_ext_for_comb (scale, comb);
!
! if (scale.is_minus_one ()
! && POINTER_TYPE_P (TREE_TYPE (elt)))
! {
! elt = fold_build1 (NEGATE_EXPR, sizetype, convert_to_ptrofftype (elt));
! scale = double_int_one;
! }
if (scale.is_one ())
{
if (!expr)
! return elt;
! if (POINTER_TYPE_P (TREE_TYPE (expr)))
! return fold_build_pointer_plus (expr, convert_to_ptrofftype (elt));
! if (POINTER_TYPE_P (TREE_TYPE (elt)))
! return fold_build_pointer_plus (elt, convert_to_ptrofftype (expr));
! return fold_build2 (PLUS_EXPR, type1,
! fold_convert (type1, expr),
! fold_convert (type1, elt));
}
if (scale.is_minus_one ())
{
if (!expr)
! return fold_build1 (NEGATE_EXPR, TREE_TYPE (elt), elt);
! if (POINTER_TYPE_P (TREE_TYPE (expr)))
! return fold_build_pointer_plus
! (expr, convert_to_ptrofftype
! (fold_build1 (NEGATE_EXPR, TREE_TYPE (elt), elt)));
! return fold_build2 (MINUS_EXPR, type1,
! fold_convert (type1, expr),
! fold_convert (type1, elt));
}
+ elt = fold_convert (type1, elt);
if (!expr)
! return fold_build2 (MULT_EXPR, type1, elt,
! double_int_to_tree (type1, scale));
if (scale.is_negative ())
{
*************** add_elt_to_tree (tree expr, tree type, t
*** 417,429 ****
elt = fold_build2 (MULT_EXPR, type1, elt,
double_int_to_tree (type1, scale));
! if (POINTER_TYPE_P (type))
{
if (code == MINUS_EXPR)
elt = fold_build1 (NEGATE_EXPR, type1, elt);
return fold_build_pointer_plus (expr, elt);
}
! return fold_build2 (code, type, expr, elt);
}
/* Makes tree from the affine combination COMB. */
--- 428,441 ----
elt = fold_build2 (MULT_EXPR, type1, elt,
double_int_to_tree (type1, scale));
! if (POINTER_TYPE_P (TREE_TYPE (expr)))
{
if (code == MINUS_EXPR)
elt = fold_build1 (NEGATE_EXPR, type1, elt);
return fold_build_pointer_plus (expr, elt);
}
! return fold_build2 (code, type1,
! fold_convert (type1, expr), elt);
}
/* Makes tree from the affine combination COMB. */
Index: gcc/testsuite/gcc.dg/tree-ssa/loop-4.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/loop-4.c (revision 202097)
--- gcc/testsuite/gcc.dg/tree-ssa/loop-4.c (working copy)
*************** void xxx(void)
*** 37,43 ****
/* { dg-final { scan-tree-dump-times " \\* \[^\\n\\r\]*=" 0 "optimized" } } */
/* { dg-final { scan-tree-dump-times "\[^\\n\\r\]*= \\* " 0 "optimized" } } */
! /* { dg-final { scan-tree-dump-times "MEM" 1 "optimized" } } */
/* And the original induction variable should be eliminated. */
--- 37,43 ----
/* { dg-final { scan-tree-dump-times " \\* \[^\\n\\r\]*=" 0 "optimized" } } */
/* { dg-final { scan-tree-dump-times "\[^\\n\\r\]*= \\* " 0 "optimized" } } */
! /* { dg-final { scan-tree-dump-times " MEM" 1 "optimized" } } */
/* And the original induction variable should be eliminated. */