[PATCH][no-undefined-overflow] More comparison folding
Richard Guenther
rguenther@suse.de
Tue Mar 10 16:59:00 GMT 2009
This re-enables &a + o <=> &b + o folding for NV variants. It also
adds POINTER_PLUSNV_EXPR to strip_nv (whoops) and adjusts DOM to
value-number NV and non-NV variants the same (DOM doesn't do insertions,
so this is safe).
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to the
branch.
Richard.
2009-03-10 Richard Guenther <rguenther@suse.de>
* fold-const.c (fold_comparison): Adjust address comparison
folding.
* tree.h (strip_nv): Also strip POINTER_PLUSNV_EXPR.
* tree-ssa-dom.c (initialize_hash_element): Treat *NV_EXPR the
same as non-NV_EXPR variants for value-numbering.
(simple_iv_increment_p): Handle *NV_EXPR.
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c 2009-03-10 14:48:39.000000000 +0100
--- gcc/fold-const.c 2009-03-10 16:58:33.000000000 +0100
*************** fold_comparison (enum tree_code code, tr
*** 8946,8959 ****
if (POINTER_TYPE_P (TREE_TYPE (arg0))
&& (TREE_CODE (arg0) == ADDR_EXPR
|| TREE_CODE (arg1) == ADDR_EXPR
! || TREE_CODE (arg0) == POINTER_PLUS_EXPR
! || TREE_CODE (arg1) == POINTER_PLUS_EXPR))
{
tree base0, base1, offset0 = NULL_TREE, offset1 = NULL_TREE;
HOST_WIDE_INT bitsize, bitpos0 = 0, bitpos1 = 0;
enum machine_mode mode;
int volatilep, unsignedp;
bool indirect_base0 = false, indirect_base1 = false;
/* Get base and offset for the access. Strip ADDR_EXPR for
get_inner_reference, but put it back by stripping INDIRECT_REF
--- 8946,8960 ----
if (POINTER_TYPE_P (TREE_TYPE (arg0))
&& (TREE_CODE (arg0) == ADDR_EXPR
|| TREE_CODE (arg1) == ADDR_EXPR
! || POINTER_PLUS_EXPR_P (arg0)
! || POINTER_PLUS_EXPR_P (arg1)))
{
tree base0, base1, offset0 = NULL_TREE, offset1 = NULL_TREE;
HOST_WIDE_INT bitsize, bitpos0 = 0, bitpos1 = 0;
enum machine_mode mode;
int volatilep, unsignedp;
bool indirect_base0 = false, indirect_base1 = false;
+ bool no_overflow = true;
/* Get base and offset for the access. Strip ADDR_EXPR for
get_inner_reference, but put it back by stripping INDIRECT_REF
*************** fold_comparison (enum tree_code code, tr
*** 8970,8977 ****
else
indirect_base0 = true;
}
! else if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
{
base0 = TREE_OPERAND (arg0, 0);
offset0 = TREE_OPERAND (arg0, 1);
}
--- 8971,8980 ----
else
indirect_base0 = true;
}
! else if (POINTER_PLUS_EXPR_P (arg0))
{
+ if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
+ no_overflow = false;
base0 = TREE_OPERAND (arg0, 0);
offset0 = TREE_OPERAND (arg0, 1);
}
*************** fold_comparison (enum tree_code code, tr
*** 8987,8994 ****
else
indirect_base1 = true;
}
! else if (TREE_CODE (arg1) == POINTER_PLUS_EXPR)
{
base1 = TREE_OPERAND (arg1, 0);
offset1 = TREE_OPERAND (arg1, 1);
}
--- 8990,8999 ----
else
indirect_base1 = true;
}
! else if (POINTER_PLUS_EXPR_P (arg1))
{
+ if (TREE_CODE (arg1) == POINTER_PLUS_EXPR)
+ no_overflow = false;
base1 = TREE_OPERAND (arg1, 0);
offset1 = TREE_OPERAND (arg1, 1);
}
*************** fold_comparison (enum tree_code code, tr
*** 9004,9011 ****
&& operand_equal_p (offset0, offset1, 0)))
&& (code == EQ_EXPR
|| code == NE_EXPR
! || POINTER_TYPE_OVERFLOW_UNDEFINED))
!
{
if (code != EQ_EXPR
&& code != NE_EXPR
--- 9009,9015 ----
&& operand_equal_p (offset0, offset1, 0)))
&& (code == EQ_EXPR
|| code == NE_EXPR
! || no_overflow))
{
if (code != EQ_EXPR
&& code != NE_EXPR
*************** fold_comparison (enum tree_code code, tr
*** 9043,9049 ****
6.5.6/8 and /9 with respect to the signed ptrdiff_t. */
else if (bitpos0 == bitpos1
&& ((code == EQ_EXPR || code == NE_EXPR)
! || POINTER_TYPE_OVERFLOW_UNDEFINED))
{
tree signed_size_type_node;
signed_size_type_node = signed_type_for (size_type_node);
--- 9047,9053 ----
6.5.6/8 and /9 with respect to the signed ptrdiff_t. */
else if (bitpos0 == bitpos1
&& ((code == EQ_EXPR || code == NE_EXPR)
! || no_overflow))
{
tree signed_size_type_node;
signed_size_type_node = signed_type_for (size_type_node);
Index: gcc/tree.h
===================================================================
*** gcc/tree.h (revision 144722)
--- gcc/tree.h (working copy)
*************** strip_nv (enum tree_code code)
*** 207,212 ****
--- 207,214 ----
{
case NEGATENV_EXPR:
return NEGATE_EXPR;
+ case POINTER_PLUSNV_EXPR:
+ return POINTER_PLUS_EXPR;
case PLUSNV_EXPR:
return PLUS_EXPR;
case MINUSNV_EXPR:
Index: gcc/tree-ssa-dom.c
===================================================================
*** gcc/tree-ssa-dom.c (revision 144676)
--- gcc/tree-ssa-dom.c (working copy)
*************** initialize_hash_element (gimple stmt, tr
*** 223,229 ****
if (code == GIMPLE_ASSIGN)
{
! enum tree_code subcode = gimple_assign_rhs_code (stmt);
expr->type = NULL_TREE;
--- 223,229 ----
if (code == GIMPLE_ASSIGN)
{
! enum tree_code subcode = strip_nv (gimple_assign_rhs_code (stmt));
expr->type = NULL_TREE;
*************** simple_iv_increment_p (gimple stmt)
*** 1567,1574 ****
if (TREE_CODE (lhs) != SSA_NAME)
return false;
! if (gimple_assign_rhs_code (stmt) != PLUS_EXPR
! && gimple_assign_rhs_code (stmt) != MINUS_EXPR)
return false;
preinc = gimple_assign_rhs1 (stmt);
--- 1567,1574 ----
if (TREE_CODE (lhs) != SSA_NAME)
return false;
! if (!PLUS_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
! && !MINUS_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
return false;
preinc = gimple_assign_rhs1 (stmt);
More information about the Gcc-patches
mailing list