re PR tree-optimization/25148 (compare_values assumes that CST in a + CST (and a - CST) is always postive)
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. From-SVN: r113298
This commit is contained in:
parent
869170df10
commit
67ac6e637c
@ -1,3 +1,13 @@
|
||||
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.
|
||||
|
||||
2006-04-27 Dirk Mueller <dmueller@suse.de>
|
||||
|
||||
* config/i386/xmmintrin.h (_mm_shuffle_pi16): Declare
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user