https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103006
--- Comment #14 from Richard Biener <rguenth at gcc dot gnu.org> --- There's an interesting case, a = BIRTH loop: b = DEATH a = DEATH b = BIRTH goto loop; where we end up having both a and b in the live-in set at the loop label but a is removed before we see the BIRTH of b which is where we add conflicts based on the current set of active vars. In the case I'm running into this I have tail-recursion do a = BIRTH b = BIRTH ... a = DEATH b = DEATH into loop: a = BIRTH b = BIRTH goto loop; a = DEATH b = DEATH leading to a similar issue. The issue above can for example arise from loop rotation. In all cases live from backedges confuse the "optimization" done to only record conflicts when we add a var to the live set (and it is not already set). The previous code had /* If this is the first real instruction in this BB we need to add conflicts for everything live at this point now. Unlike classical liveness for named objects we can't rely on seeing a def/use of the names we're interested in. There might merely be indirect loads/stores. We'd not add any conflicts for such partitions. */ and the easiest is to do the same here (we don't see the backedge "use"), but we could possibly improve by noting which vars are only live from a backedge here.