http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60032
Alan Modra <amodra at gmail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2014-02-04 CC| |amodra at gmail dot com Ever confirmed|0 |1 --- Comment #1 from Alan Modra <amodra at gmail dot com> --- Reduced testcase void foo (void) { register float __attribute__ ((mode(SD))) r31 __asm__ ("r31"); register float __attribute__ ((mode(SD))) fr1 __asm__ ("fr1"); __asm__ ("#" : "=d" (fr1)); r31 = fr1; __asm__ ("#" : : "r" (r31)); } This: enum machine_mode rs6000_secondary_memory_needed_mode (enum machine_mode mode) { if (mode == SDmode) return DDmode; return mode; } doesn't play well with the following code in reload1.c #ifdef SECONDARY_MEMORY_NEEDED /* If we need a memory location to do the move, do it that way. */ else if ((tem1 = replaced_subreg (in), tem2 = replaced_subreg (out), (REG_P (tem1) && REG_P (tem2))) && REGNO (tem1) < FIRST_PSEUDO_REGISTER && REGNO (tem2) < FIRST_PSEUDO_REGISTER && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (tem1)), REGNO_REG_CLASS (REGNO (tem2)), GET_MODE (out))) { /* Get the memory to use and rewrite both registers to its mode. */ rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type); if (GET_MODE (loc) != GET_MODE (out)) out = gen_rtx_REG (GET_MODE (loc), reg_or_subregno (out)); if (GET_MODE (loc) != GET_MODE (in)) in = gen_rtx_REG (GET_MODE (loc), reg_or_subregno (in)); gen_reload (loc, in, opnum, type); gen_reload (out, loc, opnum, type); } #endif get_secondary_mem() gives you a DD mem, and the reload out reg (reg/v:SD 31 31 [ r31 ]) is rewritten to (reg/v:DD 31 31 [ r31 ]) A DDmode requires two gprs when 32-bit, and of course we don't have r32..