Validity of SUBREG+AND-imm transformations
Kyrill Tkachov
kyrylo.tkachov@foss.arm.com
Fri Mar 4 15:30:00 GMT 2016
On 04/03/16 15:12, Kyrill Tkachov wrote:
>
> On 04/03/16 15:07, Segher Boessenkool wrote:
>> On Fri, Mar 04, 2016 at 02:48:21PM +0000, Kyrill Tkachov wrote:
>>> Although there are case where we hit the same problem:
>>> unsigned long
>>> f3 (unsigned long bit_addr)
>>> {
>>> unsigned long bitnumb = bit_addr & 63;
>>> return (1L << bitnumb);
>>> }
>>>
>>> combine will try to match:
>>> (set (reg:DI 78)
>>> (ashift:DI (reg:DI 80)
>>> (subreg:SI (and:DI (reg:DI 0 x0 [ bit_addr ])
>>> (const_int 63 [0x3f])) 0)))
>>>
>>> does that mean that the shift amount should be DImode?
>> Heh. Maybe? Try it out, see which works best.
>>
>> My point was that you do not have QI anywhere else. Registers are
>> always SI or DI (I think? Not totally familiar with the aarch64 code).
>
> Yeah, registers can be accessed either in SImode (w-form) or DImode (x-form)
> and if an instruction writes the SImode form the top 32 bits are implicitly
> zeroed out.
>
Making DImode performs worst of all...
For code:
unsigned long
foo (unsigned long a, unsigned int b)
{
return a << b;
}
If we represent the shift amount as DImode then the SImode register for 'b' is wrapped
into a zero-extend to DImode during expand, so we'd need all of the arith+shift patterns
to match a zero_extend form. When the shift amount is QImode we don't have any of that
because we just take the QImode subreg in the ashift RTX. I suspect that's the original
reason why it was not made DImode.
>>> Seems like a more flexible approach would be for the midend to be able to
>>> handle these things...
>> Of course. OTOH, there is no reason to make it harder than necessary
>> for the compiler to do a reasonable job ;-)
>
> I'll do some more investigations. Last time I looked at changing the mode I recall
> having various zero_extends being introduced that hurt matching...
>
> Kyrill
>
>
>>
>> Segher
>
More information about the Gcc
mailing list