From 17b236ed68b931cb5100c4ebc4574565ac9bca3e Mon Sep 17 00:00:00 2001 From: Zdenek Dvorak Date: Fri, 16 Mar 2007 00:47:18 +0100 Subject: [PATCH] tree-ssa-loop-niter.c (refine_bounds_using_guard, [...]): Handle NE_EXPR guards. * tree-ssa-loop-niter.c (refine_bounds_using_guard, bound_difference): Handle NE_EXPR guards. From-SVN: r122963 --- gcc/ChangeLog | 5 ++++ gcc/tree-ssa-loop-niter.c | 52 +++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9dfece9fa61..0825b1b8439 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2007-03-15 Zdenek Dvorak + + * tree-ssa-loop-niter.c (refine_bounds_using_guard, bound_difference): + Handle NE_EXPR guards. + 2007-03-15 Manuel Lopez-Ibanez PR c++/24924 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);