This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: splitting const_int's
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: "Omar Torres" <gcc dot omar at gmail dot com>
- Cc: rdsandiford at googlemail dot com, gcc at gcc dot gnu dot org
- Date: Thu, 22 May 2008 20:32:23 +0100
- Subject: Re: splitting const_int's
- References: <178adb870805201430x60742020r3c8df56a89b14739@mail.gmail.com>
"Omar Torres" <gcc.omar@gmail.com> writes:
> Richard Sandiford wrote:
>> Also, you need to beware of cases in which operands[1] overlaps
>> operands[0]. The splitter says:
>>
>> [(set (match_dup 2) (match_dup 4))
>> (set (match_dup 3) (match_dup 5))]
>>
>> and operands[2] is always the highpart:
>>
>> operands[2] = gen_highpart(QImode, operands[0]);
>>
>> but consider the case in which operands[1] (and thus operands[4])
>> is a memory reference that uses the high part of operands[0] as
>> a base register. In that case, the base register will be modified
>> by the first split instruction and have the wrong value in the
>> second split instruction. See other ports for the canonical way
>> of handling this.
>>
>> Richard
>
> By looking at other ports, I learned that I can detect when this happens
> by using the reg_overlap_mentioned_p(). Here is one case:
> (insn 43 115 74 (set (reg:HI 7 %i0h)
> (mem/s/j:HI (plus:HI (reg/f:HI 7 %i0h [orig:39 source ] [39])
> (const_int 2 [0x2])) [0 <variable>.r+0 S2 A8])) 3
> {*movhi} (nil)
> (nil))
>
> I need to tell the compiler not to use as destination the same base
> register when doing index operations. Any suggestions on how do I that?
Hmm. If one destination register is the base and the other is the
index, you're probably best off adding them together and freeing up
a register that way. Hopefully it'll be a rare case.
Because you're doing this in a splitter, some of the later
rtl optimisers _might_ be able to get rid of the addition,
but I wouldn't bet on it.
Richard