https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79725
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2017-02-27 Component|c |tree-optimization Summary|Sinking opportunity missed |Sinking opportunity missed |if complex type is changed |if blocked by dead stmt Ever confirmed|0 |1 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- We seem to be quite unlucky with initial IL: p = __complex__ (1.0e+0, 0.0); { int i; i = 0; goto <D.2520>; <D.2519>: _1 = (long unsigned int) i; _2 = _1 * 16; _3 = x + _2; D.2523 = *_3; _4 = REALPART_EXPR <D.2523>; _5 = (float) _4; _6 = IMAGPART_EXPR <D.2523>; _7 = (float) _6; p = COMPLEX_EXPR <_5, _7>; i = i + 1; <D.2520>: if (i <= 999999) goto <D.2519>; else goto <D.2521>; <D.2521>: } p.0 = p; _8 = REALPART_EXPR <p.0>; _9 = (double) _8; _10 = IMAGPART_EXPR <p.0>; _11 = (double) _10; D.2524 = COMPLEX_EXPR <_9, _11>; return D.2524; this causes a PHI node for p inside the loop and the uses partly vanish after threading. But before sinking we still have a dead expression that blocks the sinking because we do static bool statement_sink_location (gimple *stmt, basic_block frombb, gimple_stmt_iterator *togsi) { ... /* Return if there are no immediate uses of this stmt. */ if (has_zero_uses (DEF_FROM_PTR (def_p))) return false; it's understandable we don't want to deal with dead code but in this case it's "premature compile-time optimization" ;) (OTOH we just crash if we remove that check). PRE figured out the redundancy in _5 = (float) _4; _7 = (float) _6; p_18 = COMPLEX_EXPR <_5, _7>; i_19 = i_24 + 1; if (i_19 != 1000000) goto <bb 5>; [98.99%] else goto <bb 4>; [1.01%] <bb 5> [98.00%]: goto <bb 3>; [100.00%] <bb 4> [1.00%]: _9 = (double) _5; _11 = (double) _7; _14 = COMPLEX_EXPR <_9, _11>; and made p_18 unused but left the dead p_18 around (it's not its job to do the DCE). If you change complex float to complex double the initial IL doesn't contain the decomposition and the situation is much easier. I'll have a look to mitigate this in sinking for GCC 8.