------- Comment #4 from hubicka at gcc dot gnu dot org 2009-07-11 22:34 ------- OK, this is interesting case. We have:
# BLOCK 6 # PRED: 2 [61.0%] (true,exec) 3 [61.0%] (true,exec) 4 [39.0%] (true,exec) 5 [100.0%] (fallthru,exec) # D.2735_12 = PHI <0(2), 0(3), 0(4), 1(5)> # .MEM_21 = PHI <.MEM_22(2), .MEM_25(3), .MEM_27(4), .MEM_27(5)> goto <bb 8>; # SUCC: 8 [100.0%] (fallthru,exec) This block exists only because of D.2735_12 def that gets removed. Now we also eliminate conditional of BB 4: # BLOCK 4 # PRED: 3 [39.0%] (false,exec) # .MEM_26 = VDEF <.MEM_25> xmsih.2_10 = f1 (); # .MEM_27 = VDEF <.MEM_26> xmsih = xmsih.2_10; # VUSE <.MEM_27> xmsih.3_11 = xmsih; if (xmsih.3_11 == 0) goto <bb 6>; else goto <bb 5>; # SUCC: 6 [39.0%] (true,exec) 5 [61.0%] (false,exec) and redirect it to the first live post dominator, that is BB 8 skipping BB 6 that is on the way but dead since it contains dead PHI and virtual PHI ignored for liveness. Now everythign would go well, since BB 6 would get removed and result of its virtual PHI would be eliminated and symbol sent for renaming by previously discussed if (cfg_altered) code, if we didn't had the other two live predecestors BB 2 and 3. Those don't contain dead control flow statement and thus does not get updated. The BB becomes dead later during cleanup_cfg done before update_ssa and update_ssa fails. I see two ways to fix this: 1) Make SSA DCE to forward every control flow edge in program to first live post dominator (this is in original formulation of program) so we can rely on fact that code removing unreachable BB in tree-ssa-dce will handle the PHIs. I am bit affraid that it will be difficult to handle well all the corner cases where edges gets identified and such, but I can give it a try. 2) Move the if (cfg_altered) code into unreachable blocks removal. Unreachable blocks removal is run on SSA prepared for updating in other cases too, so it would make sense. Honza -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40676