On Thu, Apr 15, 2021 at 07:11:11PM +0100, Richard Sandiford wrote: > Jakub Jelinek <ja...@redhat.com> writes: > > --- gcc/config/aarch64/aarch64.md.jj 2021-04-15 10:45:02.798853095 > > +0200 > > +++ gcc/config/aarch64/aarch64.md 2021-04-15 13:28:04.734754364 +0200 > > @@ -3572,6 +3572,18 @@ (define_insn "*neg_<shift>_si2_uxtw" > > [(set_attr "autodetect_type" "alu_shift_<shift>_op2")] > > ) > > > > +(define_insn "*neg_asr_si2_extr" > > + [(set (match_operand:SI 0 "register_operand" "r") > > + (neg:SI (match_operator 4 "subreg_lowpart_operator" > > Very minor, but it might be better to have the :SI on the match_operator > too, like in the pattern below.
Fixed, thanks for catching that (and the "r" -> "=r"; I've actually tested a patch that didn't have any constraints on the first define_insn because I started with a define_split that didn't work, and it happened to work during testing, only noticed I've missed them afterwards. > > @@ -5382,6 +5394,22 @@ (define_insn "*extrsi5_insn_uxtw_alt" > > "extr\\t%w0, %w1, %w2, %4" > > [(set_attr "type" "rotate_imm")] > > ) > > + > > +(define_insn "*extrsi5_insn_di" > > + [(set (match_operand:SI 0 "register_operand" "=r") > > + (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") > > + (match_operand 3 "const_int_operand" "n")) > > + (match_operator:SI 6 "subreg_lowpart_operator" > > + [(zero_extract:DI > > + (match_operand:DI 2 "register_operand" "r") > > + (match_operand 5 "const_int_operand" "n") > > + (match_operand 4 "const_int_operand" "n"))])))] > > + "UINTVAL (operands[3]) < 32 > > + && UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32 > > + && UINTVAL (operands[4]) + UINTVAL (operands[5]) - 32 <= 64" > > Could you explain this condition? With operand 5 being the size > and operand 4 being the position, I was expecting something like: The first two conditions are like those on *extr<mode>5_insn except that GET_MODE_BITSIZE (<MODE>mode) is hardcoded as 32. Like in *extr<mode>5_insn, we have two shift counts, because aarch64 is !BITS_BIG_ENDIAN the last operand of zero_extract is a shift count too. The UINTVAL (operands[4]) + UINTVAL (operands[5]) - 32 <= 64 (should have been <= 32 actually) meant to test IN_RANGE (UINTVAL (operands[4]) + UINTVAL (operands[5]), 32, 64) because I mistakenly thought or maybe just UINTVAL (operands[4]) + UINTVAL (operands[5]) >= 32 was meant to test that the zero_extract extracts at least as many bits that it doesn't mask any bits above that. But the subreg:SI actually applies to the zero_extract result and therefore operands[2] >> operands[4] rather than before that, so you're right it needs to be == 32 rather than >= 32. So, either it can be "UINTVAL (operands[3]) < 32 && UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32 && UINTVAL (operands[4]) + UINTVAL (operands[5]) == 32" or what you wrote: > "UINTVAL (operands[3]) < 32 > && UINTVAL (operands[3]) == UINTVAL (operands[5]) > && UINTVAL (operands[4]) + UINTVAL (operands[5]) == 32" or it could be: "UINTVAL (operands[3]) < 32 && UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32 && INTVAL (operands[3]) == INTVAL (operands[5])" Jakub