summaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2006-04-27 13:52:44 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2006-04-27 13:52:44 +0000
commit820860910545844dfef72ad380727e3f3b38e196 (patch)
tree2be2839b78c9aa92f56204a43ca3cf7bed9461c9 /gcc/tree-vrp.c
parentaaaa94f934093c08abcbeffcbfd1d5ff4cfc3324 (diff)
downloadgcc-820860910545844dfef72ad380727e3f3b38e196.tar.gz
2006-04-27 Richard Guenther <rguenther@suse.de>
PR tree-optimization/25148 * tree-vrp.c (compare_values): Remove code dealing with comparisons against type min/max value. Honour overflow and negative constants in code dealing with comparisons of plus and minus expressions. (value_inside_range): Use fold_binary with LE_EXPR and GE_EXPR rather than compare_values. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113298 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c97
1 files changed, 46 insertions, 51 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 872a466a55d..9733a3669fb 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -432,37 +432,6 @@ compare_values (tree val1, tree val2)
gcc_assert (POINTER_TYPE_P (TREE_TYPE (val1))
== POINTER_TYPE_P (TREE_TYPE (val2)));
- /* Do some limited symbolic comparisons. */
- if (!POINTER_TYPE_P (TREE_TYPE (val1)))
- {
- /* We can determine some comparisons against +INF and -INF even
- if the other value is an expression. */
- if (val1 == TYPE_MAX_VALUE (TREE_TYPE (val1))
- && TREE_CODE (val2) == MINUS_EXPR)
- {
- /* +INF > NAME - CST. */
- return 1;
- }
- else if (val1 == TYPE_MIN_VALUE (TREE_TYPE (val1))
- && TREE_CODE (val2) == PLUS_EXPR)
- {
- /* -INF < NAME + CST. */
- return -1;
- }
- else if (TREE_CODE (val1) == MINUS_EXPR
- && val2 == TYPE_MAX_VALUE (TREE_TYPE (val2)))
- {
- /* NAME - CST < +INF. */
- return -1;
- }
- else if (TREE_CODE (val1) == PLUS_EXPR
- && val2 == TYPE_MIN_VALUE (TREE_TYPE (val2)))
- {
- /* NAME + CST > -INF. */
- return 1;
- }
- }
-
if ((TREE_CODE (val1) == SSA_NAME
|| TREE_CODE (val1) == PLUS_EXPR
|| TREE_CODE (val1) == MINUS_EXPR)
@@ -471,69 +440,95 @@ compare_values (tree val1, tree val2)
|| TREE_CODE (val2) == MINUS_EXPR))
{
tree n1, c1, n2, c2;
+ enum tree_code code1, code2;
/* If VAL1 and VAL2 are of the form 'NAME [+-] CST' or 'NAME',
return -1 or +1 accordingly. If VAL1 and VAL2 don't use the
same name, return -2. */
if (TREE_CODE (val1) == SSA_NAME)
{
+ code1 = SSA_NAME;
n1 = val1;
c1 = NULL_TREE;
}
else
{
+ code1 = TREE_CODE (val1);
n1 = TREE_OPERAND (val1, 0);
c1 = TREE_OPERAND (val1, 1);
+ if (tree_int_cst_sgn (c1) == -1)
+ {
+ c1 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c1), c1);
+ if (!c1)
+ return -2;
+ code1 = code1 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
+ }
}
if (TREE_CODE (val2) == SSA_NAME)
{
+ code2 = SSA_NAME;
n2 = val2;
c2 = NULL_TREE;
}
else
{
+ code2 = TREE_CODE (val2);
n2 = TREE_OPERAND (val2, 0);
c2 = TREE_OPERAND (val2, 1);
+ if (tree_int_cst_sgn (c2) == -1)
+ {
+ c2 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c2), c2);
+ if (!c2)
+ return -2;
+ code2 = code2 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
+ }
}
/* Both values must use the same name. */
if (n1 != n2)
return -2;
- if (TREE_CODE (val1) == SSA_NAME)
+ if (code1 == SSA_NAME
+ && code2 == SSA_NAME)
+ /* NAME == NAME */
+ return 0;
+
+ /* If overflow is defined we cannot simplify more. */
+ if (TYPE_UNSIGNED (TREE_TYPE (val1))
+ || flag_wrapv)
+ return -2;
+
+ if (code1 == SSA_NAME)
{
- if (TREE_CODE (val2) == SSA_NAME)
- /* NAME == NAME */
- return 0;
- else if (TREE_CODE (val2) == PLUS_EXPR)
+ if (code2 == PLUS_EXPR)
/* NAME < NAME + CST */
return -1;
- else if (TREE_CODE (val2) == MINUS_EXPR)
+ else if (code2 == MINUS_EXPR)
/* NAME > NAME - CST */
return 1;
}
- else if (TREE_CODE (val1) == PLUS_EXPR)
+ else if (code1 == PLUS_EXPR)
{
- if (TREE_CODE (val2) == SSA_NAME)
+ if (code2 == SSA_NAME)
/* NAME + CST > NAME */
return 1;
- else if (TREE_CODE (val2) == PLUS_EXPR)
+ else if (code2 == PLUS_EXPR)
/* NAME + CST1 > NAME + CST2, if CST1 > CST2 */
return compare_values (c1, c2);
- else if (TREE_CODE (val2) == MINUS_EXPR)
+ else if (code2 == MINUS_EXPR)
/* NAME + CST1 > NAME - CST2 */
return 1;
}
- else if (TREE_CODE (val1) == MINUS_EXPR)
+ else if (code1 == MINUS_EXPR)
{
- if (TREE_CODE (val2) == SSA_NAME)
+ if (code2 == SSA_NAME)
/* NAME - CST < NAME */
return -1;
- else if (TREE_CODE (val2) == PLUS_EXPR)
+ else if (code2 == PLUS_EXPR)
/* NAME - CST1 < NAME + CST2 */
return -1;
- else if (TREE_CODE (val2) == MINUS_EXPR)
+ else if (code2 == MINUS_EXPR)
/* NAME - CST1 > NAME - CST2, if CST1 < CST2. Notice that
C1 and C2 are swapped in the call to compare_values. */
return compare_values (c2, c1);
@@ -605,17 +600,17 @@ compare_values (tree val1, tree val2)
static inline int
value_inside_range (tree val, value_range_t *vr)
{
- int cmp1, cmp2;
+ tree cmp1, cmp2;
- cmp1 = compare_values (val, vr->min);
- if (cmp1 == -2 || cmp1 == 2)
+ cmp1 = fold_binary_to_constant (GE_EXPR, boolean_type_node, val, vr->min);
+ if (!cmp1)
return -2;
- cmp2 = compare_values (val, vr->max);
- if (cmp2 == -2 || cmp2 == 2)
+ cmp2 = fold_binary_to_constant (LE_EXPR, boolean_type_node, val, vr->max);
+ if (!cmp2)
return -2;
- return (cmp1 == 0 || cmp1 == 1) && (cmp2 == -1 || cmp2 == 0);
+ return cmp1 == boolean_true_node && cmp2 == boolean_true_node;
}