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 "*extr5_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) && (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (mode))" "extr\\t%0, %1, %2, %4" @@ -6208,10 +6209,11 @@ ;; so we have to match both orderings. (define_insn "*extr5_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) && (UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (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