re PR tree-optimization/43627 (slow compilation (tree canonical iv takes 75%))
authorRichard Guenther <rguenther@suse.de>
Tue, 6 Apr 2010 12:32:25 +0000 (12:32 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 6 Apr 2010 12:32:25 +0000 (12:32 +0000)
2010-04-06  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/43627
* tree-vrp.c (extract_range_from_unary_expr): Widenings
of [1, +INF(OVF)] go to [1, +INF(OVF)] of the wider type,
not varying.

* gcc.dg/tree-ssa/vrp49.c: New testcase.

From-SVN: r157992

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/vrp49.c [new file with mode: 0644]
gcc/tree-vrp.c

index 64aa244..7c66f3e 100644 (file)
@@ -1,3 +1,10 @@
+2010-04-06  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43627
+       * tree-vrp.c (extract_range_from_unary_expr): Widenings
+       of [1, +INF(OVF)] go to [1, +INF(OVF)] of the wider type,
+       not varying.
+
 2010-04-06  Jakub Jelinek  <jakub@redhat.com>
 
        * BASE-VER: Change to 4.6.0.
index 7ea5901..31e53ed 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-06  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43627
+       * gcc.dg/tree-ssa/vrp49.c: New testcase.
+
 2010-04-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/43638
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp49.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp49.c
new file mode 100644 (file)
index 0000000..664ad93
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+
+extern void link_error (void) __attribute__((noreturn));
+int n;
+float *x;
+int main()
+{
+  if (n > 0)
+    {
+      int i = 0;
+      do
+       {
+         long long index;
+         i = i + 1;
+         index = i;
+         if (index <= 0)
+           link_error ();
+         x[index] = 0;
+         i = i + 1;
+         index = i;
+         if (index <= 0)
+           link_error ();
+         x[index] = 0;
+       }
+      while (i < n);
+    }
+}
index bab0aab..c84004e 100644 (file)
@@ -2715,8 +2715,16 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
           || vr0.type == VR_ANTI_RANGE)
          && TREE_CODE (vr0.min) == INTEGER_CST
          && TREE_CODE (vr0.max) == INTEGER_CST
-         && !is_overflow_infinity (vr0.min)
-         && !is_overflow_infinity (vr0.max)
+         && (!is_overflow_infinity (vr0.min)
+             || (vr0.type == VR_RANGE
+                 && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)
+                 && needs_overflow_infinity (outer_type)
+                 && supports_overflow_infinity (outer_type)))
+         && (!is_overflow_infinity (vr0.max)
+             || (vr0.type == VR_RANGE
+                 && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)
+                 && needs_overflow_infinity (outer_type)
+                 && supports_overflow_infinity (outer_type)))
          && (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
              || (vr0.type == VR_RANGE
                  && integer_zerop (int_const_binop (RSHIFT_EXPR,
@@ -2730,6 +2738,10 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
          new_max = force_fit_type_double (outer_type,
                                           TREE_INT_CST_LOW (vr0.max),
                                           TREE_INT_CST_HIGH (vr0.max), 0, 0);
+         if (is_overflow_infinity (vr0.min))
+           new_min = negative_overflow_infinity (outer_type);
+         if (is_overflow_infinity (vr0.max))
+           new_max = positive_overflow_infinity (outer_type);
          set_and_canonicalize_value_range (vr, vr0.type,
                                            new_min, new_max, NULL);
          return;