On Mon, Jun 27, 2011 at 7:47 AM, Ulrich Weigand <uweig...@de.ibm.com> wrote:
> H.J. Lu wrote:
>
>> When reload gets:
>>
>> (insn 588 587 589 28 (set (mem:DF (zero_extend:DI (plus:SI (subreg:SI
>> (reg/v/f:DI 182 [ b ]) 0)
>>                     (const_int 8 [0x8]))) [4 MEM[base: b_96(D), index:
>> D.15020_278, step: 8, offset: 0B]+0 S8 A64])
>>         (reg:DF 340 [ D.14980 ])) spooles.c:291 106
>> {*movdf_internal_rex64}
>>      (expr_list:REG_DEAD (reg:DF 340 [ D.14980 ])
>>         (nil)))
>
> Reloading of PLUS expressions is a long-standing problem.  gen_reload
> supports those only for PLUSes that look more or less like address
> computations, and then only the "usual" cases.
>
> Is the address above (once the pseudo reg:DI 182 is replaced by
> a hard reg) really a legitimate address on your platform?  If not,
> this would need to be fixed at some earlier place.
>
> If this *is* a valid address (and just not valid for this particular
> insn pattern), the back-end needs to provide some means to reload to
> allow reloading of such expressions.  This can be done either by
> providing an insn (plus post-reload splitter if necessary), or else
> defining a secondary reload to handle the case where additional
> registers are required.  Assuming the generic gen_reload code is
> powerful enough to handle complex expressions like this is probably
> not wise ...
>
> In any case, however, gen_reload should not generate *wrong*
> code, so there's indeed a bug here.
>
> However, this:
>
>> -      if (CONSTANT_P (op1) || MEM_P (op1) || GET_CODE (op1) == SUBREG
>> +      if ((GET_CODE (op0) != SUBREG
>> +        && (CONSTANT_P (op1) || MEM_P (op1)))
>> +       || GET_CODE (op1) == SUBREG
>>         || (REG_P (op1)
>>             && REGNO (op1) >= FIRST_PSEUDO_REGISTER)
>>         || (code != CODE_FOR_nothing
>
> doesn't look like the proper fix for all cases.  The actual problem
> here is that this part of gen_reload takes the approach to transform
>
>     out <- op0 + op1
>
> into
>
>     out <- op0
>     out <- out + op1
>
> which is invalid if writing to out clobbers op1.
>
> This means that:
>
> - The "if" testing whether to swap op0 and op1 should verify
>    !reg_overlap_mentioned_p (out, op0)
>
> - Regardless of whether we swapped or not, there needs to be a
>    gcc_assert (!reg_overlap_mentioned_p (out, op1));
>  before the gen_reload (out, op0, opnum, type) line.
>
> There may still be cases where the algorithm of gen_reload doesn't
> work, but at least we'll get an ICE instead of wrong code now.
> Those cases will have to be fixed by the back-end as described
> above ...
>

The problem is reload 0 puts OP1 in OUT. Adding

gcc_assert (!reg_overlap_mentioned_p (out, op1));

doesn't help in reload 2.  How can I check if OP1 overlaps with
OUT in previous reload?


-- 
H.J.

Reply via email to