> On Jan 12, 2023, at 9:40 AM, Segher Boessenkool <seg...@kernel.crashing.org>
> wrote:
>
> On Thu, Jan 12, 2023 at 09:17:31AM -0500, Paul Koning wrote:
>>> On Jan 12, 2023, at 4:50 AM, Segher Boessenkool
>>> <seg...@kernel.crashing.org> wrote:
>>> I mean general_operand accepts that sp thing you saw. But your
>>> constraints do not? (I don't know your target well, maybe this isn't
>>> true). Things like this should be sorted out by reload, but you get
>>> better code (and fewer problems ;-) ) if you make code that fits
>>> earlier. The L in LRA means "local": it "just" makes things fit, it
>>> does not emphasise optimising your code.
>>
>> The destination is "nonimmediate_operand" which matches what the machine
>> actually does. It's like VAX and M68k, instruction operands in general can
>> be registers, memory references, register indirect or memory indirect,
>> memory at register with offset, or autoinc/autodec off any register.
>>
>> As far as operand type is concerned, SP is certainly a valid operand for an
>> add operation, that isn't the problem. The problem is that it's a two
>> operand machine: the first operand of the add instruction is both source and
>> destination. And LRA assigned the source register to be the destination
>> register as required, but then after doing so it replaced the destination
>> (an FP reference) by a different register (SP reference), violating the
>> constraint after having satisfied it earlier.
>
> Ah okay. Yes, something does not verify if the instructions are valid
> before doing some replacement. Something around ELIMINABLE_REGS it
> looks like? Maybe the dump file says more, or maybe the dump file can
> be improved.
The Reload dump file mentions in a couple of places that it sees r5 (FP) as
eliminable, replaced by r6 (SP). The IRA dump file says nothing.
Yes, the ELIMINABLE_REGS macro says FP can be eliminated, which is correct. In
fact, if it weren't for that, it would be wrong for the register allocator to
pick it (R5) as a general register to hold the result of that addhi3. So the
trouble is that the replacement is made after that register allocation, and
given the constraint the allocator actually needs to generate an additional
instruction, a move from SP to R5 so it can then do the two-operand add the
constraint requires.
This feels like a bug; should I file a bug report? Or is there something the
target code can do to make this work? I looked through the internals manual a
bit, it doesn't show anything helpful. The register elimination hooks are
rather generic and don't give me any handle to recognize cases like this one.
paul