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 {