http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57411
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- It's already DOM that breaks virtual SSA form by making life-ranges overlap (something we do not verify ...) <bb 5>: # .MEM_14 = PHI <.MEM_9(3)> if (equal_4(D) != 0) goto <bb 6>; else goto <bb 7>; <bb 6>: # .MEM_5 = VDEF <.MEM_14> assert_fail (); <bb 7>: # .MEM_1 = PHI <.MEM_9(5), .MEM_5(6)> # VUSE <.MEM_1> return; here .MEM_14 and .MEM_9 have overlapping life-ranges. @@ -33,7 +50,7 @@ assert_fail (); <bb 7>: - # .MEM_1 = PHI <.MEM_14(5), .MEM_5(6)> + # .MEM_1 = PHI <.MEM_9(5), .MEM_5(6)> # VUSE <.MEM_1> return; It fails to update the # .MEM_5 = VDEF <.MEM_14> assert_fail (); statement because it only walks over real operands when optimizing stmts in cprop_into_stmt and because it refrains from /* Do not propagate copies if the propagated value is at a deeper loop depth than the propagatee. Otherwise, this may move loop variant variables outside of their loops and prevent coalescing opportunities. If the value was loop invariant, it will be hoisted by LICM and exposed for copy propagation. */ if (loop_depth_of_name (val) > loop_depth_of_name (op)) return; thus it won't copyprop out the loop-closed PHI. A simple solution is to never copy-propagate virtual operands if doing so does not propagate into all uses.