Hi Peter, On Fri, Mar 01, 2019 at 01:33:27PM -0600, Peter Bergner wrote: > PR88845 shows a problem where LRA spilled an input operand of an inline > asm statement by calling our generic movsf pattern which ended up generating > an insn we don't have a pattern for, so we ICE. The insn was: > > (insn (set (reg:SF 125) > (subreg:SF (reg:SI 124) 0))) > > The problem is that rs6000_emit_move_si_sf_subreg() is disabled for LRA > and so wasn't able to call gen_movsf_from_si() which generates the correct > pattern for moving a 32-bit value from a GPR to a FPR. The patch below > fixes the issue by allowing rs6000_emit_move_si_sf_subreg() to be called > during LRA as well as creating an expander so that when it is called during > LRA, we can create the scratch register that is required for its associated > splitter. We have to do this, since LRA has already converted all of the > scratches into real registers before it does any spilling.
> + /* If LRA is generating a direct move from a GPR to a FPR, > + then the splitter is going to need a scratch register. */ > + rtx insn = gen_movsf_from_si_internal (operands[0], operands[1]); > + XEXP (XVECEXP (insn, 0, 1), 0) = gen_reg_rtx (DImode); > + emit_insn (insn); > + DONE; This part isn't so great, needing detailed knowledge of the RTL generated by some other pattern. Maybe there already exists some function that generates a register for every scratch in an insn, or you can make such a function? Okay for trunk with or without such an improvement. Also backports, if you want those. But note (on trunk): > +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { > "-mcpu=power8" } } */ > +/* { dg-options "-mcpu=power8 -O2" } */ These two lines should now be just /* { dg-options "-mdejagnu-cpu=power8 -O2" } */ Thanks! Segher