David Miller <da...@davemloft.net> writes:
> From: David Miller <da...@davemloft.net>
> Date: Tue, 23 Oct 2012 22:06:55 -0400 (EDT)
>
>> From: David Miller <da...@davemloft.net>
>> Date: Tue, 23 Oct 2012 21:44:05 -0400 (EDT)
>> 
>>> The first issue sparc runs into is that it does not define it's
>>> extra constraints properly.  In particular 'T' and 'W' must use
>>> define_memory_constraint.
>>> 
>>> Otherwise the EXTRA_MEMORY_CONSTRAINT logic in process_alt_operands()
>>> does not trigger and we therefore cannot even load a constant into
>>> floating point registers properly.
>> 
>> Ok, the next problem we hit will be a little bit more difficult
>> to solve.
>> 
>> Sparc accepts addresses of the form:
>> 
>> (plus:DI (lo_sum:DI (reg/f:DI 282)
>>         (symbol_ref:DI ("__mf_opts") <var_decl 0xf78d74a0 __mf_opts>))
>>     (const_int 40 [0x28]))
>> 
>> These make use of Sparc's offsetable %lo() relocations.
>> 
>> But LRA is unable to cope with this expression when it is processed by
>> extract_address_regs() because when the LO_SUM is inspected
>> ad->disp_loc is already non-NULL triggering this assertion:
>
> So I added a workaround for this, and the next problem we hit involves
> PIC.  It stems from the HAVE_lo_sum code block in process_address.
>
> It unconditionally tries to perform a HIGH/LO_SUM sequence to load an
> address, and depends upon insn recognition and target backend address
> validation to reject such sequences as needed.
>
> Actually, this HAVE_lo_sum code block seems to be an ad-hoc
> replacement for a target macro, namely LEGITIMIZE_RELOAD_ADDRESS.
>
> However, on Sparc, LEGITIMIZE_RELOAD_ADDRESS would never emit the
> HIGH/LO_SUM sequence for PIC.  Instead, it would leave it to reload to
> push the reload and then emit a move of the address into a register,
> which in turn would go through all the proper PIC handling logic in
> the Sparc backend's move expander.
>
> Before LRA, the target legitimate_address_p would never have to ever
> see such strange "(LO_SUM REG SYMBOLIC)" expressions when PIC is
> enabled, but now it can and they therefore have to now be explicitly
> checked for.

I think that's a true feature rather than an ad-hoc feature or bug.
If the target supports LO_SUM then this split is an obvious thing to try.

FWIW, combine.c:find_split_point does a similar thing in a similar
situation:

#ifdef HAVE_lo_sum
      /* If we have (mem (const ..)) or (mem (symbol_ref ...)), split it
         using LO_SUM and HIGH.  */
      if (GET_CODE (XEXP (x, 0)) == CONST
          || GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
        {
          enum machine_mode address_mode = get_address_mode (x);

          SUBST (XEXP (x, 0),
                 gen_rtx_LO_SUM (address_mode,
                                 gen_rtx_HIGH (address_mode, XEXP (x, 0)),
                                 XEXP (x, 0)));
          return &XEXP (XEXP (x, 0), 0);
        }
#endif

> This case triggers every time LRA does a force_const_mem().
>
> I'll add the straightforward check to sparc's legitimate_address_p,
> but I'm really surprised you never hit this case in your testing.

Adding the check sounds like the right thing to do.  And remember
that the merge was only for the core LRA code and x86 bits.
The LRA branch has patches to e.g. rs6000's address handling;
it's just something that needs to be done when "porting" to LRA.

Richard

Reply via email to