On Wed, Apr 14, 2021 at 09:20:35PM +0200, Jakub Jelinek wrote:
> The question is what to write in the splitter pattern so that
> they would match.
>   [(set (match_operand:GPI 0 "register_operand")
>         (LOGICAL:GPI
>           (and:GPI (ashift:GPI (match_operator:GPI 4 "subreg_lowpart_operator"
>                                  [(match_operand 1 "register_operand")])
>                                (match_operand:QI 2 
> "aarch64_shift_imm_<mode>"))
>                    (match_operand:GPI 3 "const_int_operand"))
>           (zero_extend:GPI (match_dup 1))))]
> provably doesn't (that is from the splitter I wrote for the non-hard regs),
> nor
>   [(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 3 "const_int_operand"))
>           (zero_extend:GPI (subreg (match_dup 1) 0))))]
> works (and it is unclear how I'd find out the mode of the subreg even if it
> worked).

What seems to work and handles both the pseudos (in which case there
is a (subreg:GPI (reg:whatever xyz) 0) and (reg:whatever xyz)
in the operands) and the hard registers (in which case there is
(reg:GPI xyz) and (reg:whatever xyz) in the operands) is:

(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 3 "const_int_operand"))
          (zero_extend:GPI (match_operand 4 "register_operand"))))]
  "can_create_pseudo_p ()
   && ((paradoxical_subreg_p (operands[1])
        && rtx_equal_p (SUBREG_REG (operands[1]), operands[4]))
       || (REG_P (operands[1])
           && REG_P (operands[4])
           && REGNO (operands[1]) == REGNO (operands[4])))
   && (trunc_int_for_mode (GET_MODE_MASK (GET_MODE (operands[4]))
                           << INTVAL (operands[2]), <MODE>mode)
       == INTVAL (operands[3]))"
  [(set (match_dup 5) (zero_extend:GPI (match_dup 4)))
   (set (match_dup 0) (LOGICAL:GPI (ashift:GPI (match_dup 5) (match_dup 2))
                                   (match_dup 5)))]
  "operands[5] = gen_reg_rtx (<MODE>mode);"
)

While it is one pattern, it needs different handling for the two cases.
Is that acceptable?

        Jakub

Reply via email to