re PR tree-optimization/53465 (wrong code with -O1 -ftree-vrp)
authorJakub Jelinek <jakub@gcc.gnu.org>
Thu, 24 May 2012 11:51:09 +0000 (13:51 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 24 May 2012 11:51:09 +0000 (13:51 +0200)
PR tree-optimization/53465
* tree-vrp.c (extract_range_from_cond_expr): First copy_value_range
vr0 into *vr, then vrp_meet that.
(vrp_meet): If one vr type is VR_UNDEFINED, ensure the result doesn't
have any equivalences.
(vrp_visit_phi_node): Call copy_value_range instead of vrp_meet the
first time.

* gcc.c-torture/execute/pr53465.c: New test.

From-SVN: r187827

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr53465.c [new file with mode: 0644]
gcc/tree-vrp.c

index 8246ae9a5f7319079a319cd7ccaf48ccc0c332f0..aec62a07a0e75026038f04c6220125be0f42453f 100644 (file)
@@ -1,4 +1,14 @@
-2012-05-24  Jim MacArthur<jim.macarthur@arm.com>
+2012-05-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/53465
+       * tree-vrp.c (extract_range_from_cond_expr): First copy_value_range
+       vr0 into *vr, then vrp_meet that.
+       (vrp_meet): If one vr type is VR_UNDEFINED, ensure the result doesn't
+       have any equivalences.
+       (vrp_visit_phi_node): Call copy_value_range instead of vrp_meet the
+       first time.
+
+2012-05-24  Jim MacArthur  <jim.macarthur@arm.com>
 
        * recog.c (reg_fits_class_p): Check both regno and regno + offset are
        hard registers.
        is enabled.
        (movdi_vfp_cortexa8): Likewise.
 
-2012-04-30  Ian Bolton <ian.bolton@arm.com>
+2012-04-30  Ian Bolton  <ian.bolton@arm.com>
            Sameera Deshpande  <sameera.deshpande@arm.com>
            Greta Yorsh  <greta.yorsh@arm.com>
 
index f337a296910be7a403ec57d2401c9dd2d7beb0af..3ee4008b5d88b5c301e8ba1f6735ca50b7b4d644 100644 (file)
@@ -1,3 +1,8 @@
+2012-05-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/53465
+       * gcc.c-torture/execute/pr53465.c: New test.
+
 2012-05-23  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/51055
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr53465.c b/gcc/testsuite/gcc.c-torture/execute/pr53465.c
new file mode 100644 (file)
index 0000000..6a31719
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR tree-optimization/53465 */
+
+extern void abort ();
+
+static const int a[] = { 1, 2 };
+
+void
+foo (const int *x, int y)
+{
+  int i;
+  int b = 0;
+  int c;
+  for (i = 0; i < y; i++)
+    {
+      int d = x[i];
+      if (d == 0)
+       break;
+      if (b && d <= c)
+       abort ();
+      c = d;
+      b = 1;
+    }
+}
+
+int
+main ()
+{
+  foo (a, 2);
+  return 0;
+}
index 4dc942cc388a99a9fcbc89b7c8953758dec5831c..2c1bcad95079e41e8b3b7e8e1ee0e97fa4e67c6d 100644 (file)
@@ -3282,8 +3282,8 @@ extract_range_from_cond_expr (value_range_t *vr, gimple stmt)
     set_value_range_to_varying (&vr1);
 
   /* The resulting value range is the union of the operand ranges */
-  vrp_meet (&vr0, &vr1);
   copy_value_range (vr, &vr0);
+  vrp_meet (vr, &vr1);
 }
 
 
@@ -6888,13 +6888,17 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
 {
   if (vr0->type == VR_UNDEFINED)
     {
-      copy_value_range (vr0, vr1);
+      /* Drop equivalences.  See PR53465.  */
+      set_value_range (vr0, vr1->type, vr1->min, vr1->max, NULL);
       return;
     }
 
   if (vr1->type == VR_UNDEFINED)
     {
-      /* Nothing to do.  VR0 already has the resulting range.  */
+      /* VR0 already has the resulting range, just drop equivalences.
+        See PR53465.  */
+      if (vr0->equiv)
+       bitmap_clear (vr0->equiv);
       return;
     }
 
@@ -7036,6 +7040,7 @@ vrp_visit_phi_node (gimple phi)
   tree lhs = PHI_RESULT (phi);
   value_range_t *lhs_vr = get_value_range (lhs);
   value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
+  bool first = true;
   int edges, old_edges;
   struct loop *l;
 
@@ -7092,7 +7097,11 @@ vrp_visit_phi_node (gimple phi)
              fprintf (dump_file, "\n");
            }
 
-         vrp_meet (&vr_result, &vr_arg);
+         if (first)
+           copy_value_range (&vr_result, &vr_arg);
+         else
+           vrp_meet (&vr_result, &vr_arg);
+         first = false;
 
          if (vr_result.type == VR_VARYING)
            break;