https://gcc.gnu.org/g:415316f432cd03755735f13f226d5193785ea8a9
commit r17-5043-g415316f432cd03755735f13f226d5193785ea8a9 Author: Roger Sayle <[email protected]> Date: Fri Oct 9 22:07:34 2026 +0100 AArch64: Change the bitfield patterns to be any-or-plus (AOP) safe. This patch tweaks aarch64.md's buitfield patterns to be more AOP-safe, i.e. can recognize bfi, bfxil and rev16 instructions when expressed in RTL using either PLUS, IOR or XOR. The recent PR tree-optimization/108477 patch caused 8 testsuite regressions on aarch64, and this patch addresses the machine description issues and resolves 2 of those 8 FAILs. Firstly, many thanks to Kyrill Tkachov for reviewing/approving the previous aarch64 fix for AOP issues (around movk). https://gcc.gnu.org/pipermail/gcc-patches/2026-September/729755.html For PR 108477, the middle-end is now even more aggressively select between PLUS and IOR, by making use of get_nonzero_bits during expand. Alas on aarch64 this causes the following code quality (not correctness) regressions in the testsuite: FAIL: gcc.target/aarch64/combine_bfi_1.c scan-assembler-times \\tbfi\\t 5 FAIL: gcc.target/aarch64/combine_bfi_2.c scan-assembler-times \\tbfi\\t 2 FAIL: gcc.target/aarch64/combine_bfxil.c scan-assembler-times bfxil\\t 3 FAIL: gcc.target/aarch64/combine_bfxil.c scan-assembler-times bfi\\t 15 FAIL: gcc.target/aarch64/fcvt_int_float_double3.c scan-assembler \\tscvtf\\td0, w[0-9]* FAIL: gcc.target/aarch64/movk_2.c check-function-bodies f2 FAIL: gcc.target/aarch64/pr100028.c scan-assembler-times \\tbfxil\\t 2 FAIL: gcc.target/aarch64/rev16_2.c scan-assembler-times rev16\\tx[0-9]+ 2 I'd initially hoped this patch would be sufficient to avoid these regressions, but alas providing AOP-safe patterns only allows combine to "recognize" these instructions, but (for the first six above) aarch64_rtx_costs also needs to provide accurate estimates for them to be used. It turns out the cost infrastructure is (partially) shared with the arm backend (via aarch-common), and my patch to the upstream config/arm/aarch-common.cc is still awaiting review. https://gcc.gnu.org/pipermail/gcc-patches/2026-September/732926.html 2026-10-09 Roger Sayle <[email protected]> gcc/ChangeLog * config/aarch64/aarch64.cc (aarch64_extr_rtx_p): Allow extr pattern to be represented as either IOR, XOR or PLUS. * config/aarch64/aarch64.md (*aarch64_bfxil<mode>_extr): Use any_or_plus iterator. (*aarch64_bfxilsi_extrdi): Likewise. (*aarch64_bfxil<mode>): Likewise. (*aarch64_bfxilsi_uxtw): Likewise. (aarch64_rev16<mode>2_alt1): Use any_or_plus iterator and new aop_pref_ior attribute so that the gen function uses IOR. (*aarch64_rev16<mode>2_alt2): Use any_or_plus iterator. (*aarch64_rev16si2_alt3): Add "*" prefix to skip gen function. * config/aarch64/iterators.md (aop_pref_ior): New code attribute to produce "*" for XOR/PLUS. Diff: --- gcc/config/aarch64/aarch64.cc | 4 ++- gcc/config/aarch64/aarch64.md | 71 ++++++++++++++++++++++------------------- gcc/config/aarch64/iterators.md | 3 ++ 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 6693cec98bdb..e8e903d82a12 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -15068,7 +15068,9 @@ aarch64_extr_rtx_p (rtx x, rtx *res_op0, rtx *res_op1) *res_op0 = NULL_RTX; *res_op1 = NULL_RTX; - if (GET_CODE (x) != IOR) + if (GET_CODE (x) != IOR + && GET_CODE (x) != XOR + && GET_CODE (x) != PLUS) return false; op0 = XEXP (x, 0); diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 7c8915ec3890..988b00e55df8 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -6889,12 +6889,13 @@ (define_insn "*aarch64_bfxil<mode>_extr" [(set (match_operand:GPI 0 "register_operand" "=r") - (ior:GPI (and:GPI (match_operand:GPI 1 "register_operand" "0") - (match_operand:GPI 2 "const_int_operand" "n")) - (zero_extract:GPI - (match_operand:GPI 3 "register_operand" "r") - (match_operand:GPI 4 "aarch64_simd_shift_imm_<mode>" "n") - (match_operand:GPI 5 "aarch64_simd_shift_imm_<mode>" "n"))))] + (any_or_plus:GPI + (and:GPI (match_operand:GPI 1 "register_operand" "0") + (match_operand:GPI 2 "const_int_operand" "n")) + (zero_extract:GPI + (match_operand:GPI 3 "register_operand" "r") + (match_operand:GPI 4 "aarch64_simd_shift_imm_<mode>" "n") + (match_operand:GPI 5 "aarch64_simd_shift_imm_<mode>" "n"))))] "UINTVAL (operands[2]) == HOST_WIDE_INT_M1U << INTVAL (operands[4]) && INTVAL (operands[4]) && (UINTVAL (operands[4]) + UINTVAL (operands[5]) @@ -6905,13 +6906,14 @@ (define_insn "*aarch64_bfxilsi_extrdi" [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (and:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "const_int_operand" "n")) - (match_operator:SI 6 "subreg_lowpart_operator" - [(zero_extract:DI - (match_operand:DI 3 "register_operand" "r") - (match_operand:SI 4 "aarch64_simd_shift_imm_si" "n") - (match_operand:SI 5 "aarch64_simd_shift_imm_si" "n"))])))] + (any_or_plus:SI + (and:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operator:SI 6 "subreg_lowpart_operator" + [(zero_extract:DI + (match_operand:DI 3 "register_operand" "r") + (match_operand:SI 4 "aarch64_simd_shift_imm_si" "n") + (match_operand:SI 5 "aarch64_simd_shift_imm_si" "n"))])))] "UINTVAL (operands[2]) == HOST_WIDE_INT_M1U << INTVAL (operands[4]) && INTVAL (operands[4]) && UINTVAL (operands[4]) + UINTVAL (operands[5]) <= 32" @@ -7025,10 +7027,11 @@ (define_insn "*aarch64_bfxil<mode>" [(set (match_operand:GPI 0 "register_operand" "=r,r") - (ior:GPI (and:GPI (match_operand:GPI 1 "register_operand" "r,0") - (match_operand:GPI 3 "const_int_operand" "n, Ulc")) - (and:GPI (match_operand:GPI 2 "register_operand" "0,r") - (match_operand:GPI 4 "const_int_operand" "Ulc, n"))))] + (any_or_plus:GPI + (and:GPI (match_operand:GPI 1 "register_operand" "r,0") + (match_operand:GPI 3 "const_int_operand" "n, Ulc")) + (and:GPI (match_operand:GPI 2 "register_operand" "0,r") + (match_operand:GPI 4 "const_int_operand" "Ulc, n"))))] "(INTVAL (operands[3]) == ~INTVAL (operands[4])) && (aarch64_high_bits_all_ones_p (INTVAL (operands[3])) || aarch64_high_bits_all_ones_p (INTVAL (operands[4])))" @@ -7051,8 +7054,8 @@ ; Zero-extended version of above (aarch64_bfxil) (define_insn "*aarch64_bfxilsi_uxtw" [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI (ior:SI (and:SI (match_operand:SI 1 "register_operand" - "r,0") + (zero_extend:DI (any_or_plus:SI + (and:SI (match_operand:SI 1 "register_operand" "r,0") (match_operand:SI 3 "const_int_operand" "n, Ulc")) (and:SI (match_operand:SI 2 "register_operand" "0,r") (match_operand:SI 4 "const_int_operand" "Ulc, n")))))] @@ -7079,14 +7082,15 @@ ;; operations within an IOR/AND RTX, therefore we have two patterns matching ;; each valid permutation. -(define_insn "aarch64_rev16<mode>2_alt1" +(define_insn "<aop_pref_ior>aarch64_rev16<mode>2_alt1" [(set (match_operand:GPI 0 "register_operand" "=r") - (ior:GPI (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r") - (const_int 8)) - (match_operand:GPI 3 "const_int_operand" "n")) - (and:GPI (lshiftrt:GPI (match_dup 1) - (const_int 8)) - (match_operand:GPI 2 "const_int_operand" "n"))))] + (any_or_plus:GPI + (and:GPI (ashift:GPI (match_operand:GPI 1 "register_operand" "r") + (const_int 8)) + (match_operand:GPI 3 "const_int_operand" "n")) + (and:GPI (lshiftrt:GPI (match_dup 1) + (const_int 8)) + (match_operand:GPI 2 "const_int_operand" "n"))))] "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode) && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)" "rev16\\t%<w>0, %<w>1" @@ -7095,12 +7099,13 @@ (define_insn "*aarch64_rev16<mode>2_alt2" [(set (match_operand:GPI 0 "register_operand" "=r") - (ior:GPI (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r") - (const_int 8)) - (match_operand:GPI 2 "const_int_operand" "n")) - (and:GPI (ashift:GPI (match_dup 1) - (const_int 8)) - (match_operand:GPI 3 "const_int_operand" "n"))))] + (any_or_plus:GPI + (and:GPI (lshiftrt:GPI (match_operand:GPI 1 "register_operand" "r") + (const_int 8)) + (match_operand:GPI 2 "const_int_operand" "n")) + (and:GPI (ashift:GPI (match_dup 1) + (const_int 8)) + (match_operand:GPI 3 "const_int_operand" "n"))))] "aarch_rev16_shleft_mask_imm_p (operands[3], <MODE>mode) && aarch_rev16_shright_mask_imm_p (operands[2], <MODE>mode)" "rev16\\t%<w>0, %<w>1" @@ -7108,7 +7113,7 @@ ) ;; Similar pattern to match (rotate (bswap) 16) -(define_insn "aarch64_rev16si2_alt3" +(define_insn "*aarch64_rev16si2_alt3" [(set (match_operand:SI 0 "register_operand" "=r") (rotate:SI (bswap:SI (match_operand:SI 1 "register_operand" "r")) (const_int 16)))] diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 568786e37149..b788631a2e13 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -3694,6 +3694,9 @@ (pre_inc "preinc") (pre_dec "predec")]) +;; Prefer IOR form when expanding any_or_plus +(define_code_attr aop_pref_ior [(ior "") (xor "*") (plus "*")]) + ;; ------------------------------------------------------------------- ;; Int Iterators. ;; -------------------------------------------------------------------
