https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69935
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2016-02-24 Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- sinking doesn't consider it because of /* If this is a load then do not sink past any stores. ??? This is overly simple but cheap. We basically look for an existing load with the same VUSE in the path to one of the sink candidate blocks and we adjust commondom to the nearest to commondom. */ if (gimple_vuse (stmt)) { but it fails to find any VUSE in the path and the block with the actual use (in a PHI) doesn't have a virtual PHI either. The only block it finds is the block of the load itself. Now if the walk doesn't hit any VDEF then obviously we can take commondom. Mine. Index: gcc/tree-ssa-sink.c =================================================================== --- gcc/tree-ssa-sink.c (revision 233660) +++ gcc/tree-ssa-sink.c (working copy) @@ -374,6 +374,7 @@ statement_sink_location (gimple *stmt, b imm_use_iterator imm_iter; use_operand_p use_p; basic_block found = NULL; + bool seen_vdef = false; FOR_EACH_IMM_USE_FAST (use_p, imm_iter, gimple_vuse (stmt)) { gimple *use_stmt = USE_STMT (use_p); @@ -382,6 +383,8 @@ statement_sink_location (gimple *stmt, b is the incoming block with the use. */ if (gimple_code (use_stmt) == GIMPLE_PHI) bb = EDGE_PRED (bb, PHI_ARG_INDEX_FROM_USE (use_p))->src; + else if (gimple_vdef (use_stmt)) + seen_vdef = true; /* Any dominator of commondom would be ok with adjusting commondom to that block. */ bb = nearest_common_dominator (CDI_DOMINATORS, bb, commondom); @@ -393,7 +396,8 @@ statement_sink_location (gimple *stmt, b if (found == commondom) break; } - commondom = found; + if (seen_vdef) + commondom = found; if (commondom == frombb) return false; }