https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79201
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |missed-optimization Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2017-01-24 Component|c |tree-optimization Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- Confirmed. code sinking doesn't sink calls. While that's easily fixed for this case PRE running before sinking produces <bb 2> [3.03%]: <bb 3> [96.97%]: # i_10 = PHI <i_6(4), 0(2)> # prephitmp_2 = PHI <_3(4), 0(2)> i_6 = i_10 + 1; if (i_6 != 32) goto <bb 4>; [96.88%] else goto <bb 5>; [3.12%] <bb 4> [93.94%]: _3 = __builtin_ffs (i_6); goto <bb 3>; [100.00%] <bb 5> [3.03%]: return prephitmp_2; which makes this no longer a sinking opportunity code sinking handles (it can't "sink" PHIs). But we shouldn't insert loop uses for stuff w/o loop uses. Oh, and final value replacement also doesn't understand the above either. Will fix for GCC 8. Index: gcc/tree-ssa-sink.c =================================================================== --- gcc/tree-ssa-sink.c (revision 244856) +++ gcc/tree-ssa-sink.c (working copy) @@ -254,8 +254,10 @@ statement_sink_location (gimple *stmt, b ssa_op_iter iter; imm_use_iterator imm_iter; - /* We only can sink assignments. */ - if (!is_gimple_assign (stmt)) + /* We only can sink assignments or const/pure calls. */ + if (!is_gimple_assign (stmt) + && (!is_gimple_call (stmt) + || ! (gimple_call_flags (stmt) & (ECF_CONST|ECF_PURE)))) return false; /* We only can sink stmts with a single definition. */ Generally one can say the PRE data-flow gets confused by "wrongly placed" computations (aka trivial sinking opportunities). So it might make sense to swap PRE and sink passes (PRE shouldn't expose sinking opportunities but through the VN it performs).