------- Comment #5 from vmakarov at redhat dot com 2008-12-19 23:30 ------- Eric, thanks for analysis. It saved a lot of my time.
The problem was in wrong final live ranges of a379r452 therefore the conflicts was not recognized and the pseudos were coalesced. One pseudo is a temporary pseudo used for breaking register shuffle cycle (it is actually a rare case) on a CFG edge (loop exit). And another pseudo is destination of removed store insn on the loop exit. In normal case it should not conflict with the temporary pseudo because the temporary lives only on the edge and another pseudo lives only after the edge destination. But it should conflict with the temporary in this case because we removed the store and another pseudo lives through all loop. The suspicious code looks like EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi) { a = node->regno_allocno_map[regno]; if (ALLOCNO_MEM_OPTIMIZED_DEST (a) == NULL) { ALLOCNO_LIVE_RANGES (a) = ira_create_allocno_live_range (a, start, ira_max_point - 1, ALLOCNO_LIVE_RANGES (a)); if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) fprintf (ira_dump_file, " Adding range [%d..%d] to live through allocno a%dr%d\n", start, ira_max_point - 1, ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a))); } I'll send a patch solving the problem after its testing. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38495