re PR middle-end/58742 (pointer arithmetic simplification)
2014-01-29 Richard Biener <rguenther@suse.de> PR tree-optimization/58742 * tree-ssa-forwprop.c (associate_pointerplus): Rename to associate_pointerplus_align. (associate_pointerplus_diff): New function. (associate_pointerplus): Likewise. Call associate_pointerplus_align and associate_pointerplus_diff. * gcc.dg/pr58742-1.c: New testcase. * gcc.dg/pr58742-2.c: Likewise. * gcc.dg/pr58742-3.c: Likewise. From-SVN: r207239
This commit is contained in:
parent
15b25b242b
commit
77574c3534
6 changed files with 154 additions and 1 deletions
|
@ -1,3 +1,12 @@
|
|||
2014-01-29 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/58742
|
||||
* tree-ssa-forwprop.c (associate_pointerplus): Rename to
|
||||
associate_pointerplus_align.
|
||||
(associate_pointerplus_diff): New function.
|
||||
(associate_pointerplus): Likewise. Call associate_pointerplus_align
|
||||
and associate_pointerplus_diff.
|
||||
|
||||
2014-01-29 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* lto-streamer.h (LTO_major_version): Bump to 3.
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2014-01-29 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/58742
|
||||
* gcc.dg/pr58742-1.c: New testcase.
|
||||
* gcc.dg/pr58742-2.c: Likewise.
|
||||
* gcc.dg/pr58742-3.c: Likewise.
|
||||
|
||||
2014-01-29 Renlin Li <Renlin.Li@arm.com>
|
||||
|
||||
* gcc.target/arm/ftest-armv7ve-arm.c: New.
|
||||
|
|
13
gcc/testsuite/gcc.dg/pr58742-1.c
Normal file
13
gcc/testsuite/gcc.dg/pr58742-1.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -fdump-tree-cddce1" } */
|
||||
|
||||
int *
|
||||
fx (int *b, int *e)
|
||||
{
|
||||
__SIZE_TYPE__ p = e - b;
|
||||
/* The first forwprop pass should optimize this to return e; */
|
||||
return b + p;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "return e" "cddce1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "cddce1" } } */
|
13
gcc/testsuite/gcc.dg/pr58742-2.c
Normal file
13
gcc/testsuite/gcc.dg/pr58742-2.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -fdump-tree-cddce1" } */
|
||||
|
||||
__SIZE_TYPE__
|
||||
fx (char *a, __SIZE_TYPE__ sz)
|
||||
{
|
||||
char *b = a + sz;
|
||||
/* The first forwprop pass should optimize this to return sz; */
|
||||
return b - a;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "return sz" "cddce1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "cddce1" } } */
|
14
gcc/testsuite/gcc.dg/pr58742-3.c
Normal file
14
gcc/testsuite/gcc.dg/pr58742-3.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -fdump-tree-cddce1" } */
|
||||
|
||||
int *
|
||||
fx (int *a, int sz)
|
||||
{
|
||||
int *b = a + sz;
|
||||
b = b - sz;
|
||||
/* forwprop together with FRE should optimize this to return a; */
|
||||
return b;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "return a" "cddce1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "cddce1" } } */
|
|
@ -2802,7 +2802,7 @@ out:
|
|||
true if anything changed, false otherwise. */
|
||||
|
||||
static bool
|
||||
associate_pointerplus (gimple_stmt_iterator *gsi)
|
||||
associate_pointerplus_align (gimple_stmt_iterator *gsi)
|
||||
{
|
||||
gimple stmt = gsi_stmt (*gsi);
|
||||
gimple def_stmt;
|
||||
|
@ -2850,6 +2850,103 @@ associate_pointerplus (gimple_stmt_iterator *gsi)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Associate operands of a POINTER_PLUS_EXPR assignmen at *GSI. Returns
|
||||
true if anything changed, false otherwise. */
|
||||
|
||||
static bool
|
||||
associate_pointerplus_diff (gimple_stmt_iterator *gsi)
|
||||
{
|
||||
gimple stmt = gsi_stmt (*gsi);
|
||||
gimple def_stmt;
|
||||
tree ptr1, rhs;
|
||||
|
||||
/* Pattern match
|
||||
tem1 = (long) ptr1;
|
||||
tem2 = (long) ptr2;
|
||||
tem3 = tem2 - tem1;
|
||||
tem4 = (unsigned long) tem3;
|
||||
tem5 = ptr1 + tem4;
|
||||
and produce
|
||||
tem5 = ptr2; */
|
||||
ptr1 = gimple_assign_rhs1 (stmt);
|
||||
rhs = gimple_assign_rhs2 (stmt);
|
||||
if (TREE_CODE (rhs) != SSA_NAME)
|
||||
return false;
|
||||
gimple minus = SSA_NAME_DEF_STMT (rhs);
|
||||
/* Conditionally look through a sign-changing conversion. */
|
||||
if (is_gimple_assign (minus)
|
||||
&& CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (minus))
|
||||
&& (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (minus)))
|
||||
== TYPE_PRECISION (TREE_TYPE (rhs)))
|
||||
&& TREE_CODE (gimple_assign_rhs1 (minus)) == SSA_NAME)
|
||||
minus = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (minus));
|
||||
if (!is_gimple_assign (minus))
|
||||
return false;
|
||||
if (gimple_assign_rhs_code (minus) != MINUS_EXPR)
|
||||
return false;
|
||||
rhs = gimple_assign_rhs2 (minus);
|
||||
if (TREE_CODE (rhs) != SSA_NAME)
|
||||
return false;
|
||||
def_stmt = SSA_NAME_DEF_STMT (rhs);
|
||||
if (!is_gimple_assign (def_stmt)
|
||||
|| ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
|
||||
|| gimple_assign_rhs1 (def_stmt) != ptr1)
|
||||
return false;
|
||||
rhs = gimple_assign_rhs1 (minus);
|
||||
if (TREE_CODE (rhs) != SSA_NAME)
|
||||
return false;
|
||||
def_stmt = SSA_NAME_DEF_STMT (rhs);
|
||||
if (!is_gimple_assign (def_stmt)
|
||||
|| ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
|
||||
return false;
|
||||
rhs = gimple_assign_rhs1 (def_stmt);
|
||||
if (! useless_type_conversion_p (TREE_TYPE (ptr1), TREE_TYPE (rhs)))
|
||||
return false;
|
||||
|
||||
gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (rhs), rhs, NULL_TREE);
|
||||
update_stmt (stmt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Associate operands of a POINTER_PLUS_EXPR assignmen at *GSI. Returns
|
||||
true if anything changed, false otherwise. */
|
||||
|
||||
static bool
|
||||
associate_pointerplus (gimple_stmt_iterator *gsi)
|
||||
{
|
||||
gimple stmt = gsi_stmt (*gsi);
|
||||
gimple def_stmt;
|
||||
tree ptr, off1, off2;
|
||||
|
||||
if (associate_pointerplus_align (gsi)
|
||||
|| associate_pointerplus_diff (gsi))
|
||||
return true;
|
||||
|
||||
/* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). */
|
||||
ptr = gimple_assign_rhs1 (stmt);
|
||||
off1 = gimple_assign_rhs2 (stmt);
|
||||
if (TREE_CODE (ptr) != SSA_NAME)
|
||||
return false;
|
||||
def_stmt = SSA_NAME_DEF_STMT (ptr);
|
||||
if (!is_gimple_assign (def_stmt)
|
||||
|| gimple_assign_rhs_code (def_stmt) != POINTER_PLUS_EXPR)
|
||||
return false;
|
||||
ptr = gimple_assign_rhs1 (def_stmt);
|
||||
off2 = gimple_assign_rhs2 (def_stmt);
|
||||
if (!types_compatible_p (TREE_TYPE (off1), TREE_TYPE (off2)))
|
||||
return false;
|
||||
|
||||
tree off = make_ssa_name (TREE_TYPE (off1), NULL);
|
||||
gimple ostmt = gimple_build_assign_with_ops (PLUS_EXPR, off, off1, off2);
|
||||
gsi_insert_before (gsi, ostmt, GSI_SAME_STMT);
|
||||
|
||||
gimple_assign_set_rhs_with_ops (gsi, POINTER_PLUS_EXPR, ptr, off);
|
||||
update_stmt (stmt);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Combine two conversions in a row for the second conversion at *GSI.
|
||||
Returns 1 if there were any changes made, 2 if cfg-cleanup needs to
|
||||
run. Else it returns 0. */
|
||||
|
|
Loading…
Add table
Reference in a new issue