https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113933
--- Comment #26 from John David Anglin <danglin at gcc dot gnu.org> ---
(In reply to Segher Boessenkool from comment #25)
> (In reply to John David Anglin from comment #24)
> > There are a couple of issues. The pa backend only supports memory
> > accesses that load to a register or store from a register. LRA was
> > creating insns like the following:
> >
> > (insn 387 386 35 2 (set (subreg:SI (reg/v:OI 132 [ e ]) 28)
> > (subreg:SI (reg/v:OI 452 [orig:132 e ] [132]) 28))
> > "/home/dave/gnu/gcc/gcc/gcc/testsuite/gcc.c-torture/compile/pr92618.c":18:15
> > 42 {*pa.md:2195}
> > (nil))
>
> That is a simple 32-bit register-to-register move, which is quite expected
> here? It should work fine if your OImode datums are stored in 8 consecutive
> GPR regs.
Yes. Problem arises if reg/v:OI 452 is spilled to memory. Without
reg_equiv_mem, I don't see how pa backend can handle spill. What happens
is pa_emit_move_sequence is called repeatedly with same arguments.
While there are 31 general registers, they are split between caller saves and
callee saves. Some registers have fixed functionality. We have three 8
register block in non pic code and two in pic code.
> > There doesn't seem to be any good reason to allow register modes that
> > aren't supported in pa.md.
>
> Obviously. And LRA tries to use such modes? That can never work, no? So
> we should do something about that?
Yes, LRA used OI and TI modes with gcc.c-torture/compile/pr92618.c. It
defines the following types:
typedef long long __m128i __attribute__((__may_alias__, __vector_size__(2 *
sizeof (long long))));
typedef long long __m256i __attribute__((__may_alias__, __vector_size__(4 *
sizeof (long long))));
typedef long long __m512i __attribute__((__may_alias__, __vector_size__(8 *
sizeof (long long))));
Maybe PA has enough registers but I don't know how to handle subreg spills in
backend with LRA.
I did wonder about doing the following:
@@ -2011,6 +2027,17 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode,
rtx scratch_reg)
!= XEXP (operand1, 0)))
operand1 = replace_equiv_address (operand1, tem);
+ if (scratch_reg
+ && !(REG_P (operand0)
+ || REG_P (operand1)
+ || operand1 == CONST0_RTX (GET_MODE (operands[0]))))
+ {
+ scratch_reg = force_mode (GET_MODE (operand0), scratch_reg);
+ emit_move_insn (scratch_reg, operand1);
+ emit_move_insn (operand0, scratch_reg);
+ return 1;
+ }
+
/* Handle secondary reloads for loads/stores of FP registers from
REG+D addresses where D does not fit in 5 or 14 bits, including
(subreg (mem (addr))) cases, and reloads for other unsupported
Maybe LRA could handle spills then?
> > I debated whether to allow complex 16-byte
> > modes in the general registers. There's one test that fails if I disallow
> > 16-byte modes in the general registers. It uses an asm to load a complex
> > long long value to a register. It is xfailed on a number of targets
> > because they don't have enough registers.
>
> But it's just four hardware registers for you, and you have plenty?
I tried allowing all 16-byte types in the general registers but pr92618.c still
failed with LRA.
> If your ABI doesn't require this (for parameter passing), I don't think
> there is much benefit though (and if it does require it, of course you
> have to, no choice then :-) )
Types larger than 64-bits are passed by reference in 32-bit ABI. This is not
the case in the 64-bit ABI where all types and aggregates are passed by value.
Test doesn't fail on 64-bit.