On 01/28/2011 09:45 PM, Ian Lance Taylor wrote:
> Jean-Marc Saffroy <jean-marc.saff...@joguin.com> writes:
> 
>> On 01/28/2011 06:44 PM, Ian Lance Taylor wrote:
>>> Jean-Marc Saffroy <jean-marc.saff...@joguin.com> writes:
>>>
>>>> error: insn does not satisfy its constraints:
>>>> (insn 1424 1423 141 (set (reg:DI 2 r2)
>>>>         (plus:DI (reg:DI 2 r2)
>>>>             (const_int 40 [0x28])))
>>>> /home/jmsaffroy/cygnus/src/newlib/libc/time/strptime.c:165 24 {adddi3}
>>>>      (expr_list:REG_EQUIV (plus:DI (reg/f:DI 70 a6)
>>>>             (const_int 40 [0x28]))
>>>>         (nil)))
>>>
>>> You should find out what is creating this insn.  Is it being created by
>>> reload, or is it being created by some pass that runs after reload?
>>
>> With gcc -da, I see that it appears in dump .195r.ira, so that's reload,
>> right?
> 
> Right.
> 
> 
>>> It is likely that you need to make adddi3 a define_expand which tests
>>> reload_in_progress and reload_completed.  If those are the case, you
>>> will need to explicitly convert
>>>     (set (reg:DI DREG1) (plus:DI (reg:DI DREG2) (const_int N)))
>>> into
>>>     (set (reg:DI DREG1) (const_int N))
>>>     (set (reg:DI DREG1) (plus:DI (reg:DI DREG1) (REG:DI DREG2)))
>>>
>>
>> Ah, but here it happens that DREG1 and DREG2 (r2 and a6 above) are
>> different types of registers, and I can't add them directly.
> 
> The insn you showed is adding a constant to a DREG.  There is no
> addition of a DREG and an AREG, and I would not expect reload to
> generate any such addition either.  Are you looking at a different insn?
> Don't get confused by the REG_EQUIV note, it's irrelevant here.

Actually, looking at the full dumps, I see that this incorrect insn
shown in the ICE above is emitted when eliminating the arg pointer: a6
is the frame pointer (a6+40 probably points to the args on stack).

Running cc1 under gdb, I see that gen_reload is tasked with reloading
(plus AREG N) into (DREG): the first attempts fail (the generated insns
are rejected by emit_insn_if_valid_for_reload), and so gen_reload
recurses (reload.c:8550), generates a 2-insn sequence that does:
  (set DREG AREG)
  (set DREG (plus DREG N))

But this N is not a valid immediate for an add to a DREG, according to
the predicates I defined for adddi3, which are not checked at this
point, but only later on in final_scan_insn.

So it seems I will have to have adddi3 be a define_expand that splits
the increment by N into smaller increments when called with
(reload_in_progress||reload_completed). Does that sound reasonable?

It's worth noting that I'm developing with an old svn checkout of the
gcc trunk from last October, I will update ASAP just in case.


Jean-Marc

Reply via email to