Segher Boessenkool <seg...@kernel.crashing.org> writes:
> On Wed, Apr 14, 2021 at 05:31:23PM +0100, Richard Sandiford wrote:
>> Jakub Jelinek <ja...@redhat.com> writes:
>> > +(define_split
>> > +  [(set (match_operand:GPI 0 "register_operand")
>> > +  (LOGICAL:GPI
>> > +    (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand")
>> > +                         (match_operand:QI 2 "aarch64_shift_imm_<mode>"))
>> > +             (match_operand:GPI 4 "const_int_operand"))
>> > +    (zero_extend:GPI (match_operand 3 "register_operand"))))]
>> > +  "can_create_pseudo_p ()
>> > +   && REG_P (operands[1])
>> > +   && REG_P (operands[3])
>> > +   && REGNO (operands[1]) == REGNO (operands[3])
>> > +   && ((unsigned HOST_WIDE_INT)
>> > +       trunc_int_for_mode (GET_MODE_MASK (GET_MODE (operands[3]))
>> > +                     << INTVAL (operands[2]), <MODE>mode)
>> > +       == UINTVAL (operands[4]))"
>> 
>> IMO this would be easier to understand as:
>> 
>>    && (trunc_int_for_mode (GET_MODE_MASK (GET_MODE (operands[3]))
>>                         << INTVAL (operands[2]), <MODE>mode)
>>        == INTVAL (operands[4]))
>> 
>> (At first I thought the cast and UINTVAL were trying to escape the
>> sign-extension canonicalisation.)
>
> Yeah.  Or just that with UINTVAL, the implicit conversion is fine (but
> maybe that warns?)  But INTVAL is simpler for sure.
>
>> I'm not sure about this one though.  The REGNO checks mean that this is
>> effectively for hard registers only.  I thought one of the reasons for
>> make_more_copies was to avoid combining hard registers like this, so I'm
>> not sure we should have a pattern that specifically targets them.
>> 
>> Segher, have I misunderstood?
>
> The REGNO checks work fine for pseudos as well.  But, why does it do
> this at all, instead of using match_dup?  That should be clearer.

The register is appearing in two different modes: GPI for operand 1
and something smaller than GPI for operand 3 (otherwise the extension
would be ill-formed).  That's what makes it specific to hard registers.

> The point of make_more_copies is that the hard registers from function
> arguments are not pushed down by combine into actual instructions.  This
> can be done by RA if it thinks that is a good idea, and not done if it
> thinks it is a bad idea.  Having combine usurp part of the register
> allocators role is not a good idea.
>
> There are other reasons hard regs can still end up in RTL insns in
> earlier RTL passes of course, but the other changes that went together
> with make_more_copies stop combine from doing that a lot (the function
> itself makes sure every hard reg is copied to a new pseudo, because
> combining that trivial move (from that new pseudo to the pseudo it was
> copying it to already!) can still be beneficial for other reasons, all
> strange and pretty unhappy, but important on many targets).

What would your recommendation be for this pattern?  Is matching
hard registers a bad idea, or should we go with it?

Thanks,
Richard

Reply via email to