summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-niter.c
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2007-03-15 23:47:18 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2007-03-15 23:47:18 +0000
commit8cd53b4f5baeb58f379bbc0c3e471b18dd98d8ee (patch)
treed2935d7f2f33812081b0014f86ea1614fad91f72 /gcc/tree-ssa-loop-niter.c
parent26d3c536dd4474e86175525eb4ef9f228be67643 (diff)
downloadgcc-8cd53b4f5baeb58f379bbc0c3e471b18dd98d8ee.tar.gz
* tree-ssa-loop-niter.c (refine_bounds_using_guard, bound_difference):
Handle NE_EXPR guards. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122963 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-niter.c')
-rw-r--r--gcc/tree-ssa-loop-niter.c52
1 files changed, 42 insertions, 10 deletions
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index f105d2b636e..688bc3910f6 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -283,7 +283,7 @@ refine_bounds_using_guard (tree type, tree varx, mpz_t offx,
tree c0, enum tree_code cmp, tree c1,
bounds *bnds)
{
- tree varc0, varc1, tmp;
+ tree varc0, varc1, tmp, ctype;
mpz_t offc0, offc1, loffx, loffy, bnd;
bool lbound = false;
bool no_wrap = nowrap_type_p (type);
@@ -295,17 +295,48 @@ refine_bounds_using_guard (tree type, tree varx, mpz_t offx,
case LE_EXPR:
case GT_EXPR:
case GE_EXPR:
+ STRIP_SIGN_NOPS (c0);
+ STRIP_SIGN_NOPS (c1);
+ ctype = TREE_TYPE (c0);
+ if (!tree_ssa_useless_type_conversion_1 (ctype, type))
+ return;
+
break;
case EQ_EXPR:
/* We could derive quite precise information from EQ_EXPR, however, such
- a guard is unlikely to appear, so we do not bother with handling it.
- TODO. */
+ a guard is unlikely to appear, so we do not bother with handling
+ it. */
return;
case NE_EXPR:
- /* NE_EXPR comparisons do not contain much of useful information (except for
- special cases like comparing with the bounds of the type, TODO). */
+ /* NE_EXPR comparisons do not contain much of useful information, except for
+ special case of comparing with the bounds of the type. */
+ if (TREE_CODE (c1) != INTEGER_CST
+ || !INTEGRAL_TYPE_P (type))
+ return;
+
+ /* Ensure that the condition speaks about an expression in the same type
+ as X and Y. */
+ ctype = TREE_TYPE (c0);
+ if (TYPE_PRECISION (ctype) != TYPE_PRECISION (type))
+ return;
+ c0 = fold_convert (type, c0);
+ c1 = fold_convert (type, c1);
+
+ if (TYPE_MIN_VALUE (type)
+ && operand_equal_p (c1, TYPE_MIN_VALUE (type), 0))
+ {
+ cmp = GT_EXPR;
+ break;
+ }
+ if (TYPE_MAX_VALUE (type)
+ && operand_equal_p (c1, TYPE_MAX_VALUE (type), 0))
+ {
+ cmp = LT_EXPR;
+ break;
+ }
+
return;
default:
return;
@@ -422,9 +453,14 @@ bound_difference (struct loop *loop, tree x, tree y, bounds *bnds)
int cnt = 0;
edge e;
basic_block bb;
- tree cond, c0, c1, ctype;
+ tree cond, c0, c1;
enum tree_code cmp;
+ /* Get rid of unnecessary casts, but preserve the value of
+ the expressions. */
+ STRIP_SIGN_NOPS (x);
+ STRIP_SIGN_NOPS (y);
+
mpz_init (bnds->below);
mpz_init (bnds->up);
mpz_init (offx);
@@ -482,10 +518,6 @@ bound_difference (struct loop *loop, tree x, tree y, bounds *bnds)
c0 = TREE_OPERAND (cond, 0);
cmp = TREE_CODE (cond);
c1 = TREE_OPERAND (cond, 1);
- ctype = TREE_TYPE (c0);
-
- if (!tree_ssa_useless_type_conversion_1 (ctype, type))
- continue;
if (e->flags & EDGE_FALSE_VALUE)
cmp = invert_tree_comparison (cmp, false);