Commit 75b9aa9f by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/19060 (Miscompiling of if and "long long")

	PR tree-optimization/19060
	* tree-ssa-dom.c (extract_range_from_cond) <case LT_EXPR, GT_EXPR>:
	Return 0 if op1 <= TYPE_MIN_VALUE () resp. op1 >= TYPE_MAX_VALUE ().
	(simplify_cond_and_lookup_avail_expr): Add assert for dummy == 0
	and handle extract_range_from_cond returning false.
	* fold-const.c (fold): Optimize comparisons with min/max even for
	width > HOST_BITS_PER_WIDE_INT.

	* gcc.c-torture/execute/20050104-1.c: New test.

From-SVN: r93692
parent 4ba9f2a1
2005-01-15 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/19060
* tree-ssa-dom.c (extract_range_from_cond) <case LT_EXPR, GT_EXPR>:
Return 0 if op1 <= TYPE_MIN_VALUE () resp. op1 >= TYPE_MAX_VALUE ().
(simplify_cond_and_lookup_avail_expr): Add assert for dummy == 0
and handle extract_range_from_cond returning false.
* fold-const.c (fold): Optimize comparisons with min/max even for
width > HOST_BITS_PER_WIDE_INT.
2005-01-15 Ralf Corsepius <ralf.corsepius@rtems.org> 2005-01-15 Ralf Corsepius <ralf.corsepius@rtems.org>
* config/mips/rtems.h (MIPS_DEFAULT_GVALUE): Set to 0. * config/mips/rtems.h (MIPS_DEFAULT_GVALUE): Set to 0.
......
...@@ -8439,28 +8439,57 @@ fold (tree expr) ...@@ -8439,28 +8439,57 @@ fold (tree expr)
if (TREE_CODE (arg1) == INTEGER_CST if (TREE_CODE (arg1) == INTEGER_CST
&& ! TREE_CONSTANT_OVERFLOW (arg1) && ! TREE_CONSTANT_OVERFLOW (arg1)
&& width <= HOST_BITS_PER_WIDE_INT && width <= 2 * HOST_BITS_PER_WIDE_INT
&& (INTEGRAL_TYPE_P (TREE_TYPE (arg1)) && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
|| POINTER_TYPE_P (TREE_TYPE (arg1)))) || POINTER_TYPE_P (TREE_TYPE (arg1))))
{ {
unsigned HOST_WIDE_INT signed_max; HOST_WIDE_INT signed_max_hi;
unsigned HOST_WIDE_INT max, min; unsigned HOST_WIDE_INT signed_max_lo;
unsigned HOST_WIDE_INT max_hi, max_lo, min_hi, min_lo;
signed_max = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1; if (width <= HOST_BITS_PER_WIDE_INT)
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
{ {
max = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1; signed_max_lo = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
min = 0; - 1;
signed_max_hi = 0;
max_hi = 0;
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
{
max_lo = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
min_lo = 0;
min_hi = 0;
}
else
{
max_lo = signed_max_lo;
min_lo = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
min_hi = -1;
}
} }
else else
{ {
max = signed_max; width -= HOST_BITS_PER_WIDE_INT;
min = ((unsigned HOST_WIDE_INT) -1 << (width - 1)); signed_max_lo = -1;
signed_max_hi = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
- 1;
max_lo = -1;
min_lo = 0;
if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
{
max_hi = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
min_hi = 0;
}
else
{
max_hi = signed_max_hi;
min_hi = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
}
} }
if (TREE_INT_CST_HIGH (arg1) == 0 if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) == max_hi
&& TREE_INT_CST_LOW (arg1) == max) && TREE_INT_CST_LOW (arg1) == max_lo)
switch (code) switch (code)
{ {
case GT_EXPR: case GT_EXPR:
...@@ -8481,8 +8510,9 @@ fold (tree expr) ...@@ -8481,8 +8510,9 @@ fold (tree expr)
default: default:
break; break;
} }
else if (TREE_INT_CST_HIGH (arg1) == 0 else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
&& TREE_INT_CST_LOW (arg1) == max - 1) == max_hi
&& TREE_INT_CST_LOW (arg1) == max_lo - 1)
switch (code) switch (code)
{ {
case GT_EXPR: case GT_EXPR:
...@@ -8494,8 +8524,9 @@ fold (tree expr) ...@@ -8494,8 +8524,9 @@ fold (tree expr)
default: default:
break; break;
} }
else if (TREE_INT_CST_HIGH (arg1) == (min ? -1 : 0) else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
&& TREE_INT_CST_LOW (arg1) == min) == min_hi
&& TREE_INT_CST_LOW (arg1) == min_lo)
switch (code) switch (code)
{ {
case LT_EXPR: case LT_EXPR:
...@@ -8513,8 +8544,9 @@ fold (tree expr) ...@@ -8513,8 +8544,9 @@ fold (tree expr)
default: default:
break; break;
} }
else if (TREE_INT_CST_HIGH (arg1) == (min ? -1 : 0) else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
&& TREE_INT_CST_LOW (arg1) == min + 1) == min_hi
&& TREE_INT_CST_LOW (arg1) == min_lo + 1)
switch (code) switch (code)
{ {
case GE_EXPR: case GE_EXPR:
...@@ -8528,8 +8560,8 @@ fold (tree expr) ...@@ -8528,8 +8560,8 @@ fold (tree expr)
} }
else if (!in_gimple_form else if (!in_gimple_form
&& TREE_INT_CST_HIGH (arg1) == 0 && TREE_INT_CST_HIGH (arg1) == signed_max_hi
&& TREE_INT_CST_LOW (arg1) == signed_max && TREE_INT_CST_LOW (arg1) == signed_max_lo
&& TYPE_UNSIGNED (TREE_TYPE (arg1)) && TYPE_UNSIGNED (TREE_TYPE (arg1))
/* signed_type does not work on pointer types. */ /* signed_type does not work on pointer types. */
&& INTEGRAL_TYPE_P (TREE_TYPE (arg1))) && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
......
2005-01-15 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/19060
* gcc.c-torture/execute/20050104-1.c: New test.
2005-01-15 Bud Davis <bdavis9659@comcast.net> 2005-01-15 Bud Davis <bdavis9659@comcast.net>
PR fortran/18983 PR fortran/18983
......
/* PR tree-optimization/19060 */
void abort (void);
static
long long min ()
{
return -__LONG_LONG_MAX__ - 1;
}
void
foo (long long j)
{
if (j > 10 || j < min ())
abort ();
}
int
main (void)
{
foo (10);
return 0;
}
/* SSA Dominator optimizations for trees /* SSA Dominator optimizations for trees
Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Diego Novillo <dnovillo@redhat.com> Contributed by Diego Novillo <dnovillo@redhat.com>
This file is part of GCC. This file is part of GCC.
...@@ -2088,10 +2088,18 @@ simplify_cond_and_lookup_avail_expr (tree stmt, ...@@ -2088,10 +2088,18 @@ simplify_cond_and_lookup_avail_expr (tree stmt,
tree tmp_high, tmp_low; tree tmp_high, tmp_low;
int dummy; int dummy;
/* The last element has not been processed. Process it now. */ /* The last element has not been processed. Process it now.
extract_range_from_cond (element->cond, &tmp_high, record_range should ensure for cond inverted is not set.
&tmp_low, &dummy); This call can only fail if cond is x < min or x > max,
which fold should have optimized into false.
If that doesn't happen, just pretend all values are
in the range. */
if (! extract_range_from_cond (element->cond, &tmp_high,
&tmp_low, &dummy))
gcc_unreachable ();
else
gcc_assert (dummy == 0);
/* If this is the only element, then no merging is necessary, /* If this is the only element, then no merging is necessary,
the high/low values from extract_range_from_cond are all the high/low values from extract_range_from_cond are all
we need. */ we need. */
...@@ -3204,8 +3212,10 @@ extract_range_from_cond (tree cond, tree *hi_p, tree *lo_p, int *inverted_p) ...@@ -3204,8 +3212,10 @@ extract_range_from_cond (tree cond, tree *hi_p, tree *lo_p, int *inverted_p)
break; break;
case GT_EXPR: case GT_EXPR:
low = int_const_binop (PLUS_EXPR, op1, integer_one_node, 1);
high = TYPE_MAX_VALUE (type); high = TYPE_MAX_VALUE (type);
if (!tree_int_cst_lt (op1, high))
return 0;
low = int_const_binop (PLUS_EXPR, op1, integer_one_node, 1);
inverted = 0; inverted = 0;
break; break;
...@@ -3216,8 +3226,10 @@ extract_range_from_cond (tree cond, tree *hi_p, tree *lo_p, int *inverted_p) ...@@ -3216,8 +3226,10 @@ extract_range_from_cond (tree cond, tree *hi_p, tree *lo_p, int *inverted_p)
break; break;
case LT_EXPR: case LT_EXPR:
high = int_const_binop (MINUS_EXPR, op1, integer_one_node, 1);
low = TYPE_MIN_VALUE (type); low = TYPE_MIN_VALUE (type);
if (!tree_int_cst_equal (low, op1))
return 0;
high = int_const_binop (MINUS_EXPR, op1, integer_one_node, 1);
inverted = 0; inverted = 0;
break; break;
......
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