re PR tree-optimization/81913 (wrong code at -O1)
authorBin Cheng <bin.cheng@arm.com>
Thu, 24 Aug 2017 15:38:39 +0000 (15:38 +0000)
committerBin Cheng <amker@gcc.gnu.org>
Thu, 24 Aug 2017 15:38:39 +0000 (15:38 +0000)
PR tree-optimization/81913
* tree-ssa-loop-niter.c (number_of_iterations_cond): Skip niter
analysis when either IVs in condition can wrap.

gcc/testsuite
* gcc.c-torture/execute/pr81913.c: New test.
* gcc.dg/tree-ssa/loop-niter-1.c: New test.
* gcc.dg/tree-ssa/loop-niter-2.c: New test.

From-SVN: r251337

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

index 50ebb2b71ee9d994660744b00fc2d21f13a5dbe9..ac7cf9243c7688736b0edb38e86b945eed8dc0b5 100644 (file)
@@ -1,3 +1,9 @@
+2017-08-24  Bin Cheng  <bin.cheng@arm.com>
+
+       PR tree-optimization/81913
+       * tree-ssa-loop-niter.c (number_of_iterations_cond): Skip niter
+       analysis when either IVs in condition can wrap.
+
 2017-08-24  Uros Bizjak  <ubizjak@gmail.com>
 
        * dwarf2out.c (MAX_ARTIFICIAL_LABEL_BYTES): Increase to 40.
index 115d44550ad024a81a23d359b2dca69e9fb0858a..1720a89b2e3e9a6ba7adb15ca1d7095f2ffad0f8 100644 (file)
@@ -1,3 +1,10 @@
+2017-08-24  Bin Cheng  <bin.cheng@arm.com>
+
+       PR tree-optimization/81913
+       * gcc.c-torture/execute/pr81913.c: New test.
+       * gcc.dg/tree-ssa/loop-niter-1.c: New test.
+       * gcc.dg/tree-ssa/loop-niter-2.c: New test.
+
 2017-08-23  Richard Biener  <rguenther@suse.de>
 
         PR target/81921
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr81913.c b/gcc/testsuite/gcc.c-torture/execute/pr81913.c
new file mode 100644 (file)
index 0000000..11eec4e
--- /dev/null
@@ -0,0 +1,27 @@
+/* PR tree-optimization/81913 */
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
+static u32
+b (u8 d, u32 e, u32 g)
+{
+  do
+    {
+      e += g + 1;
+      d--;
+    }
+  while (d >= (u8) e);
+
+  return e;
+}
+
+int
+main (void)
+{
+  u32 x = b (1, -0x378704, ~0xba64fc);
+  if (x != 0xd93190d0)
+    __builtin_abort ();
+  return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-niter-1.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-niter-1.c
new file mode 100644 (file)
index 0000000..16c76fe
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-sccp-details" } */
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
+static u32
+b (u8 d, u32 e, u32 g)
+{
+  do
+    {
+      e += g + 1;
+      d--;
+    }
+  while (d >= (u8) e);
+
+  return e;
+}
+
+int
+main (void)
+{
+  u32 x = b (200, -0x378704, ~0xba64fc);
+  if (x != 0xe1ee4ca0)
+    __builtin_abort ();
+
+  return 0;
+}
+
+/* Niter analyzer should be able to compute niters for the loop.  */
+/* { dg-final { scan-tree-dump "Replacing uses of: .* with: 3790490784" "sccp" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-niter-2.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-niter-2.c
new file mode 100644 (file)
index 0000000..2377e6c
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-sccp-details" } */
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
+static u32
+b (u8 d, u32 e, u32 g)
+{
+  do
+    {
+      e += g + 1;
+      d--;
+    }
+  while (d >= (u8) e);
+
+  return e;
+}
+
+int
+main (void)
+{
+  u32 x = b (1, -0x378704, ~0xba64fc);
+  if (x != 0xd93190d0)
+    __builtin_abort ();
+  return 0;
+}
+
+/* Niter analyzer should be able to compute niters for the loop even though
+   IV:d wraps.  */
+/* { dg-final { scan-tree-dump "Replacing uses of: .* with: 3643904208" "sccp" { xfail *-*-* } } } */
index 0d6d1019ac63961f5c3f509e0eeec8cbae464c7e..27244eb27c1a75dfb5686ac88cdb2bf263afdabe 100644 (file)
@@ -1728,7 +1728,7 @@ number_of_iterations_cond (struct loop *loop,
      provided that either below condition is satisfied:
 
        a) the test is NE_EXPR;
-       b) iv0.step - iv1.step is positive integer.
+       b) iv0.step - iv1.step is integer and iv0/iv1 don't overflow.
 
      This rarely occurs in practice, but it is simple enough to manage.  */
   if (!integer_zerop (iv0->step) && !integer_zerop (iv1->step))
@@ -1739,7 +1739,9 @@ number_of_iterations_cond (struct loop *loop,
 
       /* No need to check sign of the new step since below code takes care
         of this well.  */
-      if (code != NE_EXPR && TREE_CODE (step) != INTEGER_CST)
+      if (code != NE_EXPR
+         && (TREE_CODE (step) != INTEGER_CST
+             || !iv0->no_overflow || !iv1->no_overflow))
        return false;
 
       iv0->step = step;