Jeff Law <jeffreya...@gmail.com> writes: > So the change to prefer ADD over IOR for combining two objects with no > bits in common is (IMHO) generally good. It has some minor fallout. > > In particular the aarch64 port (and I suspect others) have patterns that > recognize IOR, but not PLUS or XOR for these cases and thus tests which > expected to optimize with IOR are no longer optimizing. > > Roger suggested using a code iterator for this purpose. Richard S. > suggested a new match operator to cover those cases. > > I really like the match operator idea, but as Richard S. notes in the PR > it would require either not validating the "no bits in common", which > dramatically reduces the utility IMHO or we'd need some work to allow > consistent results without polluting the nonzero bits cache. > > So this patch goes back to Roger's idea of just using a match iterator > in the aarch64 backend (and presumably anywhere else we see this popping > up). > > Bootstrapped and regression tested on aarch64-linux-gnu where it fixes > bitint-args.c (as expected). > > OK for the trunk? > > Jeff > > PR target/115478 > gcc/ > * config/aarch64/iterators.md (any_or_plus): New code iterator. > * config/aarch64/aarch64.md (extr<mode>5_insn): Use any_or_plus. > (extr<mode>5_insn_alt, extrsi5_insn_uxtw): Likewise. > (extrsi5_insn_uxtw_alt, extrsi5_insn_di): Likewise. > > gcc/testsuite/ > * gcc.target/aarch64/bitint-args.c: Update expected output.
OK, thanks! (For the record, I agree that the match_operator thing requires too many changes for stage 4.) Richard > diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md > index 071058dbeb3..cfe730f3732 100644 > --- a/gcc/config/aarch64/aarch64.md > +++ b/gcc/config/aarch64/aarch64.md > @@ -6194,10 +6194,11 @@ > > (define_insn "*extr<mode>5_insn" > [(set (match_operand:GPI 0 "register_operand" "=r") > - (ior:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r") > - (match_operand 3 "const_int_operand" "n")) > - (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r") > - (match_operand 4 "const_int_operand" "n"))))] > + (any_or_plus:GPI > + (ashift:GPI (match_operand:GPI 1 "register_operand" "r") > + (match_operand 3 "const_int_operand" "n")) > + (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r") > + (match_operand 4 "const_int_operand" "n"))))] > "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) && > (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE > (<MODE>mode))" > "extr\\t%<w>0, %<w>1, %<w>2, %4" > @@ -6208,10 +6209,11 @@ > ;; so we have to match both orderings. > (define_insn "*extr<mode>5_insn_alt" > [(set (match_operand:GPI 0 "register_operand" "=r") > - (ior:GPI (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r") > - (match_operand 4 "const_int_operand" "n")) > - (ashift:GPI (match_operand:GPI 1 "register_operand" "r") > - (match_operand 3 "const_int_operand" "n"))))] > + (any_or_plus:GPI > + (lshiftrt:GPI (match_operand:GPI 2 "register_operand" "r") > + (match_operand 4 "const_int_operand" "n")) > + (ashift:GPI (match_operand:GPI 1 "register_operand" "r") > + (match_operand 3 "const_int_operand" "n"))))] > "UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) > && (UINTVAL (operands[3]) + UINTVAL (operands[4]) > == GET_MODE_BITSIZE (<MODE>mode))" > @@ -6223,10 +6225,11 @@ > (define_insn "*extrsi5_insn_uxtw" > [(set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI > - (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") > - (match_operand 3 "const_int_operand" "n")) > - (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") > - (match_operand 4 "const_int_operand" "n")))))] > + (any_or_plus:SI > + (ashift:SI (match_operand:SI 1 "register_operand" "r") > + (match_operand 3 "const_int_operand" "n")) > + (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") > + (match_operand 4 "const_int_operand" "n")))))] > "UINTVAL (operands[3]) < 32 && > (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)" > "extr\\t%w0, %w1, %w2, %4" > @@ -6236,10 +6239,11 @@ > (define_insn "*extrsi5_insn_uxtw_alt" > [(set (match_operand:DI 0 "register_operand" "=r") > (zero_extend:DI > - (ior:SI (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") > - (match_operand 4 "const_int_operand" "n")) > - (ashift:SI (match_operand:SI 1 "register_operand" "r") > - (match_operand 3 "const_int_operand" "n")))))] > + (any_or_plus:SI > + (lshiftrt:SI (match_operand:SI 2 "register_operand" "r") > + (match_operand 4 "const_int_operand" "n")) > + (ashift:SI (match_operand:SI 1 "register_operand" "r") > + (match_operand 3 "const_int_operand" "n")))))] > "UINTVAL (operands[3]) < 32 && > (UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)" > "extr\\t%w0, %w1, %w2, %4" > @@ -6248,13 +6252,13 @@ > > (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"))])))] > + (any_or_plus: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 > && INTVAL (operands[3]) == INTVAL (operands[5])" > diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md > index 9fbd7493988..5bfd6e7d362 100644 > --- a/gcc/config/aarch64/iterators.md > +++ b/gcc/config/aarch64/iterators.md > @@ -2657,6 +2657,10 @@ > ;; Code iterator for logical operations > (define_code_iterator LOGICAL [and ior xor]) > > +;; Code iterator for operations that are equivalent when the > +;; two input operands are known have disjoint bits set. > +(define_code_iterator any_or_plus [plus ior xor]) > + > ;; LOGICAL with plus, for when | gets converted to +. > (define_code_iterator LOGICAL_OR_PLUS [and ior xor plus]) > > diff --git a/gcc/testsuite/gcc.target/aarch64/bitint-args.c > b/gcc/testsuite/gcc.target/aarch64/bitint-args.c > index e7e1099c303..06b47246fa5 100644 > --- a/gcc/testsuite/gcc.target/aarch64/bitint-args.c > +++ b/gcc/testsuite/gcc.target/aarch64/bitint-args.c > @@ -69,7 +69,7 @@ CHECK_ARG(65) > ** f65: > ** extr (x[0-9]+), x3, x2, 1 > ** and (x[0-9]+), x2, 1 > -** orr (x[0-9]+), \2, \1, lsl 1 > +** add (x[0-9]+), \2, \1, lsl 1 > ** asr (x[0-9]+), \1, 63 > ** stp \3, \4, \[x0\] > ** ret > @@ -80,7 +80,7 @@ CHECK_ARG(127) > ** f127: > ** extr (x[0-9]+), x3, x2, 63 > ** and (x[0-9]+), x2, 9223372036854775807 > -** orr (x[0-9]+), \2, \1, lsl 63 > +** add (x[0-9]+), \2, \1, lsl 63 > ** asr (x[0-9]+), \1, 1 > ** stp \3, \4, \[x0\] > ** ret