mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 01:50:34 +08:00
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
This commit is contained in:
parent
4ba9f2a1e4
commit
75b9aa9f27
@ -1,3 +1,13 @@
|
||||
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>
|
||||
|
||||
* config/mips/rtems.h (MIPS_DEFAULT_GVALUE): Set to 0.
|
||||
|
@ -8439,28 +8439,57 @@ fold (tree expr)
|
||||
|
||||
if (TREE_CODE (arg1) == INTEGER_CST
|
||||
&& ! TREE_CONSTANT_OVERFLOW (arg1)
|
||||
&& width <= HOST_BITS_PER_WIDE_INT
|
||||
&& width <= 2 * HOST_BITS_PER_WIDE_INT
|
||||
&& (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
|
||||
|| POINTER_TYPE_P (TREE_TYPE (arg1))))
|
||||
{
|
||||
unsigned HOST_WIDE_INT signed_max;
|
||||
unsigned HOST_WIDE_INT max, min;
|
||||
HOST_WIDE_INT signed_max_hi;
|
||||
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 (TYPE_UNSIGNED (TREE_TYPE (arg1)))
|
||||
if (width <= HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
max = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
|
||||
min = 0;
|
||||
signed_max_lo = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
|
||||
- 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
|
||||
{
|
||||
max = signed_max;
|
||||
min = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
|
||||
width -= HOST_BITS_PER_WIDE_INT;
|
||||
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
|
||||
&& TREE_INT_CST_LOW (arg1) == max)
|
||||
if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) == max_hi
|
||||
&& TREE_INT_CST_LOW (arg1) == max_lo)
|
||||
switch (code)
|
||||
{
|
||||
case GT_EXPR:
|
||||
@ -8481,8 +8510,9 @@ fold (tree expr)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else if (TREE_INT_CST_HIGH (arg1) == 0
|
||||
&& TREE_INT_CST_LOW (arg1) == max - 1)
|
||||
else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
|
||||
== max_hi
|
||||
&& TREE_INT_CST_LOW (arg1) == max_lo - 1)
|
||||
switch (code)
|
||||
{
|
||||
case GT_EXPR:
|
||||
@ -8494,8 +8524,9 @@ fold (tree expr)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else if (TREE_INT_CST_HIGH (arg1) == (min ? -1 : 0)
|
||||
&& TREE_INT_CST_LOW (arg1) == min)
|
||||
else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
|
||||
== min_hi
|
||||
&& TREE_INT_CST_LOW (arg1) == min_lo)
|
||||
switch (code)
|
||||
{
|
||||
case LT_EXPR:
|
||||
@ -8513,8 +8544,9 @@ fold (tree expr)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else if (TREE_INT_CST_HIGH (arg1) == (min ? -1 : 0)
|
||||
&& TREE_INT_CST_LOW (arg1) == min + 1)
|
||||
else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
|
||||
== min_hi
|
||||
&& TREE_INT_CST_LOW (arg1) == min_lo + 1)
|
||||
switch (code)
|
||||
{
|
||||
case GE_EXPR:
|
||||
@ -8528,8 +8560,8 @@ fold (tree expr)
|
||||
}
|
||||
|
||||
else if (!in_gimple_form
|
||||
&& TREE_INT_CST_HIGH (arg1) == 0
|
||||
&& TREE_INT_CST_LOW (arg1) == signed_max
|
||||
&& TREE_INT_CST_HIGH (arg1) == signed_max_hi
|
||||
&& TREE_INT_CST_LOW (arg1) == signed_max_lo
|
||||
&& TYPE_UNSIGNED (TREE_TYPE (arg1))
|
||||
/* signed_type does not work on pointer types. */
|
||||
&& INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
|
||||
|
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
PR fortran/18983
|
||||
|
23
gcc/testsuite/gcc.c-torture/execute/20050104-1.c
Normal file
23
gcc/testsuite/gcc.c-torture/execute/20050104-1.c
Normal file
@ -0,0 +1,23 @@
|
||||
/* 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;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/* 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>
|
||||
|
||||
This file is part of GCC.
|
||||
@ -2088,10 +2088,18 @@ simplify_cond_and_lookup_avail_expr (tree stmt,
|
||||
tree tmp_high, tmp_low;
|
||||
int dummy;
|
||||
|
||||
/* The last element has not been processed. Process it now. */
|
||||
extract_range_from_cond (element->cond, &tmp_high,
|
||||
&tmp_low, &dummy);
|
||||
|
||||
/* The last element has not been processed. Process it now.
|
||||
record_range should ensure for cond inverted is not set.
|
||||
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,
|
||||
the high/low values from extract_range_from_cond are all
|
||||
we need. */
|
||||
@ -3204,8 +3212,10 @@ extract_range_from_cond (tree cond, tree *hi_p, tree *lo_p, int *inverted_p)
|
||||
break;
|
||||
|
||||
case GT_EXPR:
|
||||
low = int_const_binop (PLUS_EXPR, op1, integer_one_node, 1);
|
||||
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;
|
||||
break;
|
||||
|
||||
@ -3216,8 +3226,10 @@ extract_range_from_cond (tree cond, tree *hi_p, tree *lo_p, int *inverted_p)
|
||||
break;
|
||||
|
||||
case LT_EXPR:
|
||||
high = int_const_binop (MINUS_EXPR, op1, integer_one_node, 1);
|
||||
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;
|
||||
break;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user