OSDN Git Service

PR tree-optimization/19060
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 Jan 2005 09:46:10 +0000 (09:46 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 Jan 2005 09:46:10 +0000 (09:46 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@93692 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20050104-1.c [new file with mode: 0644]
gcc/tree-ssa-dom.c

index 3d6aba1..8aec528 100644 (file)
@@ -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.
index 7ccd3a8..24bd28b 100644 (file)
@@ -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)))
index ba010eb..0e05c9e 100644 (file)
@@ -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
diff --git a/gcc/testsuite/gcc.c-torture/execute/20050104-1.c b/gcc/testsuite/gcc.c-torture/execute/20050104-1.c
new file mode 100644 (file)
index 0000000..6083e9c
--- /dev/null
@@ -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;
+}
index 67446b1..36cac29 100644 (file)
@@ -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;