re PR middle-end/26899 (Fold does not fold (i0 > i1 + 1) || (i1 < i0 - 1))
2006-10-28 Richard Guenther <rguenther@suse.de> PR middle-end/26899 * fold-const.c (maybe_canonicalize_comparison_1): Helper for maybe_canonicalize_comparison. (maybe_canonicalize_comparison): New function for canonicalizing comparison trees. (fold_comparison): Call it to canonicalize comparisons with constants involved. * gcc.dg/tree-ssa/pr26899.c: New testcase. From-SVN: r118106
This commit is contained in:
parent
4d81bf8435
commit
e73dbcaefc
@ -1,3 +1,13 @@
|
||||
2006-10-28 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/26899
|
||||
* fold-const.c (maybe_canonicalize_comparison_1): Helper
|
||||
for maybe_canonicalize_comparison.
|
||||
(maybe_canonicalize_comparison): New function for canonicalizing
|
||||
comparison trees.
|
||||
(fold_comparison): Call it to canonicalize comparisons with
|
||||
constants involved.
|
||||
|
||||
2006-10-28 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR target/28806
|
||||
|
124
gcc/fold-const.c
124
gcc/fold-const.c
@ -7749,6 +7749,126 @@ fold_minmax (enum tree_code code, tree type, tree op0, tree op1)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Helper that tries to canonicalize the comparison ARG0 CODE ARG1
|
||||
by changing CODE to reduce the magnitude of constants involved in
|
||||
ARG0 of the comparison.
|
||||
Returns a canonicalized comparison tree if a simplification was
|
||||
possible, otherwise returns NULL_TREE. */
|
||||
|
||||
static tree
|
||||
maybe_canonicalize_comparison_1 (enum tree_code code, tree type,
|
||||
tree arg0, tree arg1)
|
||||
{
|
||||
enum tree_code code0 = TREE_CODE (arg0);
|
||||
tree t, cst0 = NULL_TREE;
|
||||
int sgn0;
|
||||
bool swap = false;
|
||||
|
||||
/* Match A +- CST code arg1 and CST code arg1. */
|
||||
if (!(((code0 == MINUS_EXPR
|
||||
|| code0 == PLUS_EXPR)
|
||||
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
|
||||
|| code0 == INTEGER_CST))
|
||||
return NULL_TREE;
|
||||
|
||||
/* Identify the constant in arg0 and its sign. */
|
||||
if (code0 == INTEGER_CST)
|
||||
cst0 = arg0;
|
||||
else
|
||||
cst0 = TREE_OPERAND (arg0, 1);
|
||||
sgn0 = tree_int_cst_sgn (cst0);
|
||||
|
||||
/* Overflowed constants and zero will cause problems. */
|
||||
if (integer_zerop (cst0)
|
||||
|| TREE_OVERFLOW (cst0))
|
||||
return NULL_TREE;
|
||||
|
||||
/* See if we can reduce the mangitude of the constant in
|
||||
arg0 by changing the comparison code. */
|
||||
if (code0 == INTEGER_CST)
|
||||
{
|
||||
/* CST <= arg1 -> CST-1 < arg1. */
|
||||
if (code == LE_EXPR && sgn0 == 1)
|
||||
code = LT_EXPR;
|
||||
/* -CST < arg1 -> -CST-1 <= arg1. */
|
||||
else if (code == LT_EXPR && sgn0 == -1)
|
||||
code = LE_EXPR;
|
||||
/* CST > arg1 -> CST-1 >= arg1. */
|
||||
else if (code == GT_EXPR && sgn0 == 1)
|
||||
code = GE_EXPR;
|
||||
/* -CST >= arg1 -> -CST-1 > arg1. */
|
||||
else if (code == GE_EXPR && sgn0 == -1)
|
||||
code = GT_EXPR;
|
||||
else
|
||||
return NULL_TREE;
|
||||
/* arg1 code' CST' might be more canonical. */
|
||||
swap = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A - CST < arg1 -> A - CST-1 <= arg1. */
|
||||
if (code == LT_EXPR
|
||||
&& code0 == ((sgn0 == -1) ? PLUS_EXPR : MINUS_EXPR))
|
||||
code = LE_EXPR;
|
||||
/* A + CST > arg1 -> A + CST-1 >= arg1. */
|
||||
else if (code == GT_EXPR
|
||||
&& code0 == ((sgn0 == -1) ? MINUS_EXPR : PLUS_EXPR))
|
||||
code = GE_EXPR;
|
||||
/* A + CST <= arg1 -> A + CST-1 < arg1. */
|
||||
else if (code == LE_EXPR
|
||||
&& code0 == ((sgn0 == -1) ? MINUS_EXPR : PLUS_EXPR))
|
||||
code = LT_EXPR;
|
||||
/* A - CST >= arg1 -> A - CST-1 > arg1. */
|
||||
else if (code == GE_EXPR
|
||||
&& code0 == ((sgn0 == -1) ? PLUS_EXPR : MINUS_EXPR))
|
||||
code = GT_EXPR;
|
||||
else
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Now build the constant reduced in magnitude. */
|
||||
t = int_const_binop (sgn0 == -1 ? PLUS_EXPR : MINUS_EXPR,
|
||||
cst0, build_int_cst (TREE_TYPE (cst0), 1), 0);
|
||||
if (code0 != INTEGER_CST)
|
||||
t = fold_build2 (code0, TREE_TYPE (arg0), TREE_OPERAND (arg0, 0), t);
|
||||
|
||||
/* If swapping might yield to a more canonical form, do so. */
|
||||
if (swap)
|
||||
return fold_build2 (swap_tree_comparison (code), type, arg1, t);
|
||||
else
|
||||
return fold_build2 (code, type, t, arg1);
|
||||
}
|
||||
|
||||
/* Canonicalize the comparison ARG0 CODE ARG1 with type TYPE with undefined
|
||||
overflow further. Try to decrease the magnitude of constants involved
|
||||
by changing LE_EXPR and GE_EXPR to LT_EXPR and GT_EXPR or vice versa
|
||||
and put sole constants at the second argument position.
|
||||
Returns the canonicalized tree if changed, otherwise NULL_TREE. */
|
||||
|
||||
static tree
|
||||
maybe_canonicalize_comparison (enum tree_code code, tree type,
|
||||
tree arg0, tree arg1)
|
||||
{
|
||||
tree t;
|
||||
|
||||
/* In principle pointers also have undefined overflow behavior,
|
||||
but that causes problems elsewhere. */
|
||||
if ((flag_wrapv || flag_trapv)
|
||||
|| (TYPE_UNSIGNED (TREE_TYPE (arg0))
|
||||
&& !POINTER_TYPE_P (TREE_TYPE (arg0))))
|
||||
return NULL_TREE;
|
||||
|
||||
/* Try canonicalization by simplifying arg0. */
|
||||
t = maybe_canonicalize_comparison_1 (code, type, arg0, arg1);
|
||||
if (t)
|
||||
return t;
|
||||
|
||||
/* Try canonicalization by simplifying arg1 using the swapped
|
||||
comparsion. */
|
||||
code = swap_tree_comparison (code);
|
||||
return maybe_canonicalize_comparison_1 (code, type, arg1, arg0);
|
||||
}
|
||||
|
||||
/* Subroutine of fold_binary. This routine performs all of the
|
||||
transformations that are common to the equality/inequality
|
||||
operators (EQ_EXPR and NE_EXPR) and the ordering operators
|
||||
@ -7877,6 +7997,10 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
|
||||
variable2);
|
||||
}
|
||||
|
||||
tem = maybe_canonicalize_comparison (code, type, arg0, arg1);
|
||||
if (tem)
|
||||
return tem;
|
||||
|
||||
if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
|
||||
{
|
||||
tree targ0 = strip_float_extensions (arg0);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2006-10-28 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/26899
|
||||
* gcc.dg/tree-ssa/pr26899.c: New testcase.
|
||||
|
||||
2006-10-28 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR target/28806
|
||||
|
10
gcc/testsuite/gcc.dg/tree-ssa/pr26899.c
Normal file
10
gcc/testsuite/gcc.dg/tree-ssa/pr26899.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
int foo (int i, int j)
|
||||
{
|
||||
return (i < j + 1) || (j > i - 1);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "j >= i" "gimple" } } */
|
||||
/* { dg-final { cleanup-tree-dump "gimple" } } */
|
||||
|
Loading…
Reference in New Issue
Block a user