https://gcc.gnu.org/g:fa548c5afa5736f335f40f19a338f59296833569
commit r16-4493-gfa548c5afa5736f335f40f19a338f59296833569 Author: Georg-Johann Lay <[email protected]> Date: Sun Oct 19 16:42:07 2025 +0200 AVR: The nzb=1 patterns with IOR, XOR, AND work the same way with PLUS. gcc/ * config/avr/avr.cc (avr_nonzero_bits_lsr_operands_p): Also handle PLUS. * config/avr/avr.md (pixaop): New code iterator for PLUS, IOR, XOR, AND. (nzb=1 insns): Use pixaop instead of bitop code iterator. Handle PLUS in outputs. Diff: --- gcc/config/avr/avr.cc | 3 +- gcc/config/avr/avr.md | 131 ++++++++++++++++++++++++++------------------------ 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 0cee92565777..227c12a9b320 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -15222,7 +15222,7 @@ avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op, /* A helper for the insn condition of "*nzb=1.<code>.lsr[.not]_split" - where <code> is AND, IOR or XOR. Return true when + where <code> is AND, IOR, XOR or PLUS. Return true when OP[0] <code>= OP[1] >> OP[2] @@ -15251,6 +15251,7 @@ avr_nonzero_bits_lsr_operands_p (rtx_code code, rtx *op) case IOR: case XOR: + case PLUS: return op1_non0 >> offs == 1; case AND: diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 103b38dc38c6..30a02a4b6c9d 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -343,6 +343,7 @@ (define_code_iterator piaop [plus ior and]) (define_code_iterator pixop [plus ior xor]) (define_code_iterator bitop [xor ior and]) +(define_code_iterator pixaop [plus ior xor and]) (define_code_iterator xior [xor ior]) (define_code_iterator eqne [eq ne]) (define_code_iterator gelt [ge lt]) @@ -10519,41 +10520,41 @@ ;; split by that pass must have insn attribute "nzb" set to "yes". Moreover, ;; the insns to split must be single_sets and must not touch control flow. -(define_code_attr nzb_constr_rdr [(and "r") (ior "d") (xor "r")]) -(define_code_attr nzb_use1_nnr [(and "n") (ior "n") (xor "r")]) +(define_code_attr nzb_constr_rdrr [(and "r") (ior "d") (xor "r") (plus "r")]) +(define_code_attr nzb_use1_nnrn [(and "n") (ior "n") (xor "r") (plus "n")]) (define_insn_and_split "*nzb=1.<code>.zerox_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (zero_extract:QI (match_operand:QI 1 "register_operand") - (const_int 1) - (match_operand:QI 2 "const_0_to_7_operand")) - (match_operand:QI 3 "register_operand")))] + (pixaop:QI (zero_extract:QI (match_operand:QI 1 "register_operand") + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed - && (<CODE> == IOR || <CODE> == XOR + && (<CODE> == IOR || <CODE> == XOR || <CODE> == PLUS || nonzero_bits (operands[3], QImode) == 1)" { gcc_unreachable (); } "optimize && avropt_use_nonzero_bits && !reload_completed" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (match_dup 1) - (const_int 1) - (match_dup 2)) - (unspec:QI [(match_dup 3) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (match_dup 1) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" [(set_attr "nzb" "yes")]) (define_insn "*nzb=1.<code>.zerox" - [(set (match_operand:QI 0 "register_operand" "=<nzb_constr_rdr>") - (bitop:QI (zero_extract:QI (match_operand:QI 1 "register_operand" "r") - (const_int 1) - (match_operand:QI 2 "const_0_to_7_operand" "n")) - (unspec:QI [(match_operand:QI 3 "register_operand" "0") - ] UNSPEC_NZB))) - (use (match_operand:QI 4 "nonmemory_operand" "<nzb_use1_nnr>")) + [(set (match_operand:QI 0 "register_operand" "=<nzb_constr_rdrr>") + (pixaop:QI (zero_extract:QI (match_operand:QI 1 "register_operand" "r") + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand" "n")) + (unspec:QI [(match_operand:QI 3 "register_operand" "0") + ] UNSPEC_NZB))) + (use (match_operand:QI 4 "nonmemory_operand" "<nzb_use1_nnrn>")) (clobber (reg:CC REG_CC))] "optimize && avropt_use_nonzero_bits" { @@ -10563,6 +10564,8 @@ return "sbrc %1,%2\;ori %0,1"; else if (<CODE> == XOR) return "sbrc %1,%2\;eor %0,%4"; + else if (<CODE> == PLUS) + return "sbrc %1,%2\;inc %0"; else gcc_unreachable (); } @@ -10570,9 +10573,9 @@ (define_insn_and_split "*nzb=1.<code>.lsr_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (lshiftrt:QI (match_operand:QI 1 "register_operand") - (match_operand:QI 2 "const_0_to_7_operand")) - (match_operand:QI 3 "register_operand")))] + (pixaop:QI (lshiftrt:QI (match_operand:QI 1 "register_operand") + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed && avr_nonzero_bits_lsr_operands_p (<CODE>, operands)" @@ -10580,11 +10583,11 @@ "optimize && avropt_use_nonzero_bits && !reload_completed" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (match_dup 1) - (const_int 1) - (match_dup 2)) - (unspec:QI [(match_dup 3) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (match_dup 1) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" @@ -10592,26 +10595,26 @@ (define_insn_and_split "*nzb=1.<code>.zerox.not_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (zero_extract:QI (xor:QI (match_operand:QI 1 "register_operand") - (match_operand:QI 4 "const_int_operand")) - (const_int 1) - (match_operand:QI 2 "const_0_to_7_operand")) - (match_operand:QI 3 "register_operand")))] + (pixaop:QI (zero_extract:QI (xor:QI (match_operand:QI 1 "register_operand") + (match_operand:QI 4 "const_int_operand")) + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed && INTVAL (operands[2]) == exact_log2 (0xff & INTVAL (operands[4])) - && (<CODE> == IOR + && (<CODE> == IOR || <CODE> == XOR || <CODE> == PLUS || nonzero_bits (operands[3], QImode) == 1)" { gcc_unreachable (); } "optimize && avropt_use_nonzero_bits && !reload_completed" ; "*nzb=1.<code>.zerox.not" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (not:QI (match_dup 1)) - (const_int 1) - (match_dup 2)) - (unspec:QI [(match_dup 3) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (not:QI (match_dup 1)) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" @@ -10619,10 +10622,10 @@ (define_insn_and_split "*nzb=1.<code>.lsr.not_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (lshiftrt:QI (xor:QI (match_operand:QI 1 "register_operand") - (match_operand:QI 4 "const_int_operand")) - (match_operand:QI 2 "const_0_to_7_operand")) - (match_operand:QI 3 "register_operand")))] + (pixaop:QI (lshiftrt:QI (xor:QI (match_operand:QI 1 "register_operand") + (match_operand:QI 4 "const_int_operand")) + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed && INTVAL (operands[2]) == exact_log2 (0xff & INTVAL (operands[4])) @@ -10632,11 +10635,11 @@ && !reload_completed" ; "*nzb=1.<code>.zerox.not" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (not:QI (match_dup 1)) - (const_int 1) - (match_dup 2)) - (unspec:QI [(match_dup 3) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (not:QI (match_dup 1)) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" @@ -10644,36 +10647,36 @@ (define_insn_and_split "*nzb=1.<code>.ge0_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (ge:QI (match_operand:QI 1 "register_operand") - (const_int 0)) - (match_operand:QI 2 "register_operand")))] + (pixaop:QI (ge:QI (match_operand:QI 1 "register_operand") + (const_int 0)) + (match_operand:QI 2 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed - && (<CODE> == IOR || <CODE> == XOR + && (<CODE> == IOR || <CODE> == XOR || <CODE> == PLUS || nonzero_bits (operands[2], QImode) == 1)" { gcc_unreachable (); } "optimize && avropt_use_nonzero_bits && !reload_completed" ; "*nzb=1.<code>.zerox.not" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (not:QI (match_dup 1)) - (const_int 1) - (const_int 7)) - (unspec:QI [(match_dup 2) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (not:QI (match_dup 1)) + (const_int 1) + (const_int 7)) + (unspec:QI [(match_dup 2) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" [(set_attr "nzb" "yes")]) (define_insn "*nzb=1.<code>.zerox.not" - [(set (match_operand:QI 0 "register_operand" "=<nzb_constr_rdr>") - (bitop:QI (zero_extract:QI (not:QI (match_operand:QI 1 "register_operand" "r")) - (const_int 1) - (match_operand:QI 2 "const_0_to_7_operand" "n")) - (unspec:QI [(match_operand:QI 3 "register_operand" "0") - ] UNSPEC_NZB))) - (use (match_operand:QI 4 "nonmemory_operand" "<nzb_use1_nnr>")) + [(set (match_operand:QI 0 "register_operand" "=<nzb_constr_rdrr>") + (pixaop:QI (zero_extract:QI (not:QI (match_operand:QI 1 "register_operand" "r")) + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand" "n")) + (unspec:QI [(match_operand:QI 3 "register_operand" "0") + ] UNSPEC_NZB))) + (use (match_operand:QI 4 "nonmemory_operand" "<nzb_use1_nnrn>")) (clobber (reg:CC REG_CC))] "optimize && avropt_use_nonzero_bits" { @@ -10683,6 +10686,8 @@ return "sbrs %1,%2\;ori %0,1"; else if (<CODE> == XOR) return "sbrs %1,%2\;eor %0,%4"; + else if (<CODE> == PLUS) + return "sbrs %1,%2\;inc %0"; else gcc_unreachable (); }
