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