https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78411
--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> --- diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 4f17200..c50c598 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3017,6 +3017,7 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum, } /* Make the necessary insertions. */ + bool all_constant = true; FOR_EACH_EDGE (pred, ei, block->preds) { gimple_seq stmts = NULL; @@ -3041,8 +3042,15 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum, if (is_gimple_min_invariant (builtexpr)) avail[pred->dest_idx] = get_or_alloc_expr_for_constant (builtexpr); else - avail[pred->dest_idx] = get_or_alloc_expr_for_name (builtexpr); + { + avail[pred->dest_idx] = get_or_alloc_expr_for_name (builtexpr); + all_constant = false; + } } + /* If we're about to insert a PHI with all arguments constant refuse + to do that. But return whether we inserted stuff. */ + if (all_constant) + return insertions; /* If we didn't want a phi node, and we made insertions, we still have inserted new stuff, and thus return true. If we didn't want a phi node, and didn't make insertions, we haven't added anything new, so return but that still leaves us with _25 = MEM[base: products_16(D), index: i_35, step: 8, offset: 0B]; if (_25 > 0) goto <bb 7>; else goto <bb 6>; <bb 6>: _17 = -_25; <bb 7>: # iftmp.0_13 = PHI <1(5), -1(6)> # prephitmp_10 = PHI <_25(5), _17(6)> _9 = (long long unsigned int) prephitmp_10; and thus phiopt not matching the ABS. For some reason split-paths split the loop latch confusing RTL if-conversion even more (removing the possibility to emit a conditional store). I don't believe what tree-if-conv.c did was reasonable here (together with PRE) but we do not generate optimal code from the code in the testcase. Still if-conversion is generally a RTL opt task.