This makes sure that we do not record a signed GIV that we do not
know whether it overflows or not.  For the testcase IVOPTs else
can end up replacing an unsigned computation with a signed one.

Note that alternatively we may decide that it is not desirable
for SCEV to return signed { 2147483643, +, 1 } for this case
(ISTR adding that as feature ...).  But I think that the
result, (int) { 2147483643, +, 1 } would not be a simple-iv
anymore.

Bootstrap and regtest pending on x86_64-unknown-linux-gnu.

Any opinions?

Thanks,
Richard.

2013-10-15  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/58736
        * tree-ssa-loop-ivopts.c (find_givs_in_stmt_scev): If this
        is a GIV with undefined behavior on overflow make sure it
        does not overflow before recording it.

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

Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c  (revision 203590)
+++ gcc/tree-ssa-loop-ivopts.c  (working copy)
@@ -1084,6 +1084,13 @@ find_givs_in_stmt_scev (struct ivopts_da
 
   if (!simple_iv (loop, loop_containing_stmt (stmt), lhs, iv, true))
     return false;
+
+  /* If the induction variable invokes undefined behavior when it wraps
+     make sure it does not overflow.  */
+  if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (lhs))
+      && !iv->no_overflow)
+    return false;
+
   iv->base = expand_simple_operations (iv->base);
 
   if (contains_abnormal_ssa_name_p (iv->base)
Index: gcc/testsuite/gcc.dg/torture/pr58736.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr58736.c      (revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr58736.c      (working copy)
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fstrict-overflow" } */
+
+int a, b, c, d, e;
+
+int
+main ()
+{
+  for (b = 4; b > -30; b--)
+    {
+      e = a > (int)((unsigned int) __INT_MAX__ - (unsigned int) b);
+      for (; c;)
+       for (;;)
+         {
+           if (d)
+             break;
+         }
+    }
+  return 0;
+}

Reply via email to