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.