https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64895
--- Comment #6 from vries at gcc dot gnu.org --- >From PR64342 comment 7: Register allocation seems to progress similarly, up until this message in reload, which seems to be directly related to the r216154 patch: ... Spill r86 after risky transformations Reassigning non-reload pseudos Assign 3 to r86 (freq=3000) ... I've looked a bit in more detail at this message. fipa-ra manages to allocate hardreg 1 (dx) to the call-crossing liverange as before. But setup_live_pseudos_and_spill_after_risky_transforms looks at the conflict regs, and finds that lra_reg_info[regno].conflict_hard_regs contains dx. Hence, it spills the liverange into an available reg, which happens to be hardreg 3 (bx). So, the risky transformations and fipa-ra have in common that they allocate registers from the conflict_hard_regs set. In the case of -fipa-ra, we don't want setup_live_pseudos_and_spill_after_risky_transforms to undo the -fipa-ra allocation, but currently there's no way to distinguish between the two. Using this patch, we make sure the conflict registers don't include dx for this testcase, and the test-cases passes again: ... diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index 9dfffb6..0231057 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -636,8 +636,11 @@ check_pseudos_live_through_calls (int regno) if (! sparseset_bit_p (pseudos_live_through_calls, regno)) return; sparseset_clear_bit (pseudos_live_through_calls, regno); + IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, - call_used_reg_set); + !hard_reg_set_empty_p (lra_reg_info[regno].actual_call_used_reg_set) + ? lra_reg_info[regno].actual_call_used_reg_set + : call_used_reg_set); for (hr = 0; hr < FIRST_PSEUDO_REGISTER; hr++) if (HARD_REGNO_CALL_PART_CLOBBERED (hr, PSEUDO_REGNO_MODE (regno))) ...