Commit 20fb52af by Zdenek Dvorak Committed by Zdenek Dvorak

tree-ssa-loop-niter.c (implies_ge_p): New function.

	* tree-ssa-loop-niter.c (implies_ge_p): New function.
	(derive_constant_upper_bound): Handle OP0 - CST in unsigned types
	correctly.

From-SVN: r114782
parent dfa52cf9
2006-06-19 Zdenek Dvorak <dvorakz@suse.cz>
* tree-ssa-loop-niter.c (implies_ge_p): New function.
(derive_constant_upper_bound): Handle OP0 - CST in unsigned types
correctly.
2006-06-19 Denis Chertykov <denisc@overta.ru> 2006-06-19 Denis Chertykov <denisc@overta.ru>
* config/avr/libgcc.S : Correct my wrong previous commit. * config/avr/libgcc.S : Correct my wrong previous commit.
......
...@@ -1491,6 +1491,24 @@ implies_nonnegative_p (tree cond, tree val) ...@@ -1491,6 +1491,24 @@ implies_nonnegative_p (tree cond, tree val)
return nonzero_p (compare); return nonzero_p (compare);
} }
/* Returns true if we can prove that COND ==> A >= B. */
static bool
implies_ge_p (tree cond, tree a, tree b)
{
tree compare = fold_build2 (GE_EXPR, boolean_type_node, a, b);
if (nonzero_p (compare))
return true;
if (nonzero_p (cond))
return false;
compare = tree_simplify_using_condition_1 (cond, compare);
return nonzero_p (compare);
}
/* Returns a constant upper bound on the value of expression VAL. VAL /* Returns a constant upper bound on the value of expression VAL. VAL
is considered to be unsigned. If its type is signed, its value must is considered to be unsigned. If its type is signed, its value must
be nonnegative. be nonnegative.
...@@ -1554,8 +1572,11 @@ derive_constant_upper_bound (tree val, tree additional) ...@@ -1554,8 +1572,11 @@ derive_constant_upper_bound (tree val, tree additional)
|| !implies_nonnegative_p (additional, op0)) || !implies_nonnegative_p (additional, op0))
return max; return max;
/* Canonicalize to OP0 - CST. */ /* Canonicalize to OP0 - CST. Consider CST to be signed, in order to
choose the most logical way how to treat this constant regardless
of the signedness of the type. */
cst = tree_to_double_int (op1); cst = tree_to_double_int (op1);
cst = double_int_sext (cst, TYPE_PRECISION (type));
if (TREE_CODE (val) == PLUS_EXPR) if (TREE_CODE (val) == PLUS_EXPR)
cst = double_int_neg (cst); cst = double_int_neg (cst);
...@@ -1568,7 +1589,7 @@ derive_constant_upper_bound (tree val, tree additional) ...@@ -1568,7 +1589,7 @@ derive_constant_upper_bound (tree val, tree additional)
if (double_int_negative_p (cst)) if (double_int_negative_p (cst))
return max;; return max;;
/* Case OP0 + CST. We need to check that /* OP0 + CST. We need to check that
BND <= MAX (type) - CST. */ BND <= MAX (type) - CST. */
mmax = double_int_add (max, double_int_neg (cst)); mmax = double_int_add (max, double_int_neg (cst));
...@@ -1579,9 +1600,27 @@ derive_constant_upper_bound (tree val, tree additional) ...@@ -1579,9 +1600,27 @@ derive_constant_upper_bound (tree val, tree additional)
} }
else else
{ {
/* OP0 - CST, where CST >= 0.
If TYPE is signed, we have already verified that OP0 >= 0, and we
know that the result is nonnegative. This implies that
VAL <= BND - CST.
If TYPE is unsigned, we must additionally know that OP0 >= CST,
otherwise the operation underflows.
*/
/* This should only happen if the type is unsigned; however, for
programs that use overflowing signed arithmetics even with
-fno-wrapv, this condition may also be true for signed values. */
if (double_int_ucmp (bnd, cst) < 0) if (double_int_ucmp (bnd, cst) < 0)
return max; return max;
if (TYPE_UNSIGNED (type)
&& !implies_ge_p (additional,
op0, double_int_to_tree (type, cst)))
return max;
bnd = double_int_add (bnd, double_int_neg (cst)); bnd = double_int_add (bnd, double_int_neg (cst));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment