https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94254
--- Comment #4 from rsandifo at gcc dot gnu.org <rsandifo at gcc dot gnu.org> --- The cycling comes from reloading: (insn 7 6 8 2 (set (reg:SD 122 [ a32 ]) (mem/c:SD (reg/f:DI 120) [1 a32+0 S4 A32])) "gcc/testsuite/gcc.target/powerpc/pr39902-2.c":15:13 516 {movsd_hardfloat} (expr_list:REG_DEAD (reg/f:DI 120) (nil))) r122 is assigned an FPR, and the power6 pattern doesn't provide any alternatives that load from memory into FPRs, so we convert this into a secondary memory reload. Doing that for SDmode memory would cycle, but the rs6000 port has: /* Implement TARGET_SECONDARY_RELOAD_NEEDED_MODE. For SDmode values we need to use DDmode, in all other cases we can use the same mode. */ static machine_mode rs6000_secondary_memory_needed_mode (machine_mode mode) { if (lra_in_progress && mode == SDmode) return DDmode; return mode; } which says that the move should happen in DDmode instead. This means that the eventual FPR reload will happen in DDmode rather than SDmode. The problem is that rs6000_can_change_mode_class doesn't allow FPRs to change from SDmode to DDmode: if (from_size < 8 || to_size < 8) return false; So there seems to be a contradiction here: secondary memory reloads for FPRs have to happen in DDmode rather than SDmode, but FPRs aren't allowed to change to DDmode from SDmode. Previously this worked because LRA ignored rs6000_can_change_mode_class and changed the mode of the FPR regardless. I guess that must have been the right thing to do in context, but it would be good to pin down exactly why the SD->DD mode change is OK for rs6000 in the specific context of secondary memory reloads but not otherwise.