]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/68963 (O3 vs. O2 discards part of loop and terminates early)
authorRichard Biener <rguenther@suse.de>
Wed, 24 Feb 2016 12:03:27 +0000 (12:03 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 24 Feb 2016 12:03:27 +0000 (12:03 +0000)
2016-02-24  Richard Biener  <rguenther@suse.de>

PR middle-end/68963
* tree-ssa-loop-niter.c (derive_constant_upper_bound_ops): Fix
bogus check.
(record_nonwrapping_iv): Do not fall back to the low/high bound
for non-constant IV bases if the stmt is not always executed.

* gcc.dg/torture/pr68963.c: New testcase.

From-SVN: r233660

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr68963.c [new file with mode: 0644]
gcc/tree-ssa-loop-niter.c

index 05b04b911da16af93452af99e322548f3b03a7fa..9dab27af9aa8c7a8ed8762f02109ddf11d686d0d 100644 (file)
@@ -1,3 +1,11 @@
+2016-02-24  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/68963
+       * tree-ssa-loop-niter.c (derive_constant_upper_bound_ops): Fix
+       bogus check.
+       (record_nonwrapping_iv): Do not fall back to the low/high bound
+       for non-constant IV bases if the stmt is not always executed.
+
 2016-02-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/arm/arm-cores.def (cortex-a32): New entry.
index f678fbaeb398390d5b676e5afa622184302f5210..ad48962d72317e20abc5abc428ad9d8f488590e9 100644 (file)
@@ -1,3 +1,8 @@
+2016-02-24  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/68963
+       * gcc.dg/torture/pr68963.c: New testcase.
+
 2016-02-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR target/69875
diff --git a/gcc/testsuite/gcc.dg/torture/pr68963.c b/gcc/testsuite/gcc.dg/torture/pr68963.c
new file mode 100644 (file)
index 0000000..c83b543
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run } */
+
+static const float a[3] = { 1, 2, 3 };
+int b = 3;
+
+__attribute__((noinline, noclone)) void
+bar (int x)
+{
+  if (x != b++)
+    __builtin_abort ();
+}
+
+void
+foo (float *x, int y)
+{
+  int i;
+  for (i = 0; i < 2 * y; ++i)
+    {
+      if (i < y)
+       x[i] = a[i];
+      else
+       {
+         bar (i);
+         x[i] = a[i - y];
+       }
+    }
+}
+
+int
+main ()
+{
+  float x[10];
+  unsigned int i;
+  for (i = 0; i < 10; ++i)
+    x[i] = 1337;
+  foo (x, 3);
+  for (i = 0; i < 10; ++i)
+    if (x[i] != (i < 6 ? (i % 3) + 1 : 1337))
+      __builtin_abort ();
+  return 0;
+}
index fbeeb9d6b731fb5378e61a7329028cb658a3064d..43632edfe5d7ab20b77e344d208165096b1e109c 100644 (file)
@@ -2757,7 +2757,7 @@ derive_constant_upper_bound_ops (tree type, tree op0,
                                 enum tree_code code, tree op1)
 {
   tree subtype, maxt;
-  widest_int bnd, max, mmax, cst;
+  widest_int bnd, max, cst;
   gimple *stmt;
 
   if (INTEGRAL_TYPE_P (type))
@@ -2823,8 +2823,8 @@ derive_constant_upper_bound_ops (tree type, tree op0,
          /* OP0 + CST.  We need to check that
             BND <= MAX (type) - CST.  */
 
-         mmax -= cst;
-         if (wi::ltu_p (bnd, max))
+         widest_int mmax = max - cst;
+         if (wi::leu_p (bnd, mmax))
            return max;
 
          return bnd + cst;
@@ -3065,7 +3065,9 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple *stmt,
          && get_range_info (orig_base, &min, &max) == VR_RANGE
          && wi::gts_p (high, max))
        base = wide_int_to_tree (unsigned_type, max);
-      else if (TREE_CODE (base) != INTEGER_CST)
+      else if (TREE_CODE (base) != INTEGER_CST
+              && dominated_by_p (CDI_DOMINATORS,
+                                 loop->latch, gimple_bb (stmt)))
        base = fold_convert (unsigned_type, high);
       delta = fold_build2 (MINUS_EXPR, unsigned_type, base, extreme);
       step = fold_build1 (NEGATE_EXPR, unsigned_type, step);
@@ -3080,7 +3082,9 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple *stmt,
          && get_range_info (orig_base, &min, &max) == VR_RANGE
          && wi::gts_p (min, low))
        base = wide_int_to_tree (unsigned_type, min);
-      else if (TREE_CODE (base) != INTEGER_CST)
+      else if (TREE_CODE (base) != INTEGER_CST
+              && dominated_by_p (CDI_DOMINATORS,
+                                 loop->latch, gimple_bb (stmt)))
        base = fold_convert (unsigned_type, low);
       delta = fold_build2 (MINUS_EXPR, unsigned_type, extreme, base);
     }