re PR middle-end/66945 (ICE in generic_simplify (generic-match.c:24790))
authorRichard Biener <rguenther@suse.de>
Thu, 23 Jul 2015 07:23:23 +0000 (07:23 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 23 Jul 2015 07:23:23 +0000 (07:23 +0000)
2015-07-23  Richard Biener  <rguenther@suse.de>

PR tree-optimization/66945
* tree-ssa-propagate.c (substitute_and_fold_dom_walker
::before_dom_children): Force the propagators idea of
non-executable edges to materialize, not what the folder
chooses.

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

From-SVN: r226088

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr66945.c [new file with mode: 0644]
gcc/tree-ssa-propagate.c

index 7cd07f9d7d692d4fe537261b9ac5656dedadfb7d..e89f685cb8cb5e06077df90bd75036874f8c2425 100644 (file)
@@ -1,3 +1,11 @@
+2015-07-23  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/66945
+       * tree-ssa-propagate.c (substitute_and_fold_dom_walker
+       ::before_dom_children): Force the propagators idea of
+       non-executable edges to materialize, not what the folder
+       chooses.
+
 2015-07-23  Richard Biener  <rguenther@suse.de>
 
        * gimple.h (gimple_cond_make_false): Use 0 != 0.
index f457b27fe6ad272f6830a73f98006046030b0fd8..20fad268d2dfdca34b48e2e6b7726a55d51888ce 100644 (file)
@@ -1,3 +1,8 @@
+2015-07-23  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/66945
+       * gcc.dg/torture/pr66945.c: New testcase.
+
 2015-07-22  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/66954
diff --git a/gcc/testsuite/gcc.dg/torture/pr66945.c b/gcc/testsuite/gcc.dg/torture/pr66945.c
new file mode 100644 (file)
index 0000000..53ac230
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+unsigned b;
+void f()
+{
+  for(;;)
+    if(!b?:(b=0))
+      ;
+    else if(b%0<b?:b) /* { dg-warning "division by zero" } */
+      for(;;)
+       ;
+}
index 3f3a694702e6b63fa2bce498ff2db41a88cf4729..b7684e07905ce24f6bd21ff3817a6ed16b63053a 100644 (file)
@@ -1236,13 +1236,33 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb)
 
       /* If we made a replacement, fold the statement.  */
       if (did_replace)
-       fold_stmt (&i, follow_single_use_edges);
+       {
+         fold_stmt (&i, follow_single_use_edges);
+         stmt = gsi_stmt (i);
+       }
+
+      /* If this is a control statement the propagator left edges
+         unexecuted on force the condition in a way consistent with
+        that.  See PR66945 for cases where the propagator can end
+        up with a different idea of a taken edge than folding
+        (once undefined behavior is involved).  */
+      if (gimple_code (stmt) == GIMPLE_COND)
+       {
+         if ((EDGE_SUCC (bb, 0)->flags & EDGE_EXECUTABLE)
+             ^ (EDGE_SUCC (bb, 1)->flags & EDGE_EXECUTABLE))
+           {
+             if (((EDGE_SUCC (bb, 0)->flags & EDGE_TRUE_VALUE) != 0)
+                 == ((EDGE_SUCC (bb, 0)->flags & EDGE_EXECUTABLE) != 0))
+               gimple_cond_make_true (as_a <gcond *> (stmt));
+             else
+               gimple_cond_make_false (as_a <gcond *> (stmt));
+             did_replace = true;
+           }
+       }
 
       /* Now cleanup.  */
       if (did_replace)
        {
-         stmt = gsi_stmt (i);
-
          /* If we cleaned up EH information from the statement,
             remove EH edges.  */
          if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))