The following reportedly fixes a LLVM miscompile.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2017-03-22  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/80032
        * gimplify.c (gimple_push_cleanup): Forced unconditional
        cleanups still have to go to the conditional_cleanups
        sequence.

Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c      (revision 246364)
+++ gcc/gimplify.c      (working copy)
@@ -6304,7 +6304,7 @@ gimple_push_cleanup (tree var, tree clea
   if (seen_error ())
     return;
 
-  if (gimple_conditional_context () && ! force_uncond)
+  if (gimple_conditional_context ())
     {
       /* If we're in a conditional context, this is more complex.  We only
         want to run the cleanup if we actually ran the initialization that
@@ -6326,22 +6326,31 @@ gimple_push_cleanup (tree var, tree clea
           }
           val
       */
-      tree flag = create_tmp_var (boolean_type_node, "cleanup");
-      gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
-      gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
-
-      cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
-      gimplify_stmt (&cleanup, &cleanup_stmts);
-      wce = gimple_build_wce (cleanup_stmts);
-
-      gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
-      gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
-      gimplify_seq_add_stmt (pre_p, ftrue);
-
-      /* Because of this manipulation, and the EH edges that jump
-        threading cannot redirect, the temporary (VAR) will appear
-        to be used uninitialized.  Don't warn.  */
-      TREE_NO_WARNING (var) = 1;
+      if (force_uncond)
+       {
+         gimplify_stmt (&cleanup, &cleanup_stmts);
+         wce = gimple_build_wce (cleanup_stmts);
+         gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
+       }
+      else
+       {
+         tree flag = create_tmp_var (boolean_type_node, "cleanup");
+         gassign *ffalse = gimple_build_assign (flag, boolean_false_node);
+         gassign *ftrue = gimple_build_assign (flag, boolean_true_node);
+
+         cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
+         gimplify_stmt (&cleanup, &cleanup_stmts);
+         wce = gimple_build_wce (cleanup_stmts);
+
+         gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, ffalse);
+         gimplify_seq_add_stmt (&gimplify_ctxp->conditional_cleanups, wce);
+         gimplify_seq_add_stmt (pre_p, ftrue);
+
+         /* Because of this manipulation, and the EH edges that jump
+            threading cannot redirect, the temporary (VAR) will appear
+            to be used uninitialized.  Don't warn.  */
+         TREE_NO_WARNING (var) = 1;
+       }
     }
   else
     {

Reply via email to