https://gcc.gnu.org/g:f84dfd8305963f124c624570bb6eb0c84149f67a

commit r17-2125-gf84dfd8305963f124c624570bb6eb0c84149f67a
Author: Georg-Johann Lay <[email protected]>
Date:   Fri Jul 3 17:30:04 2026 +0200

    AVR: Adding +/-1 to a lower reg doesn't need a scratch.
    
    Adding +/-1 to a lower register can be performed by sequences like
       sec
       adc r14, __zero_reg__
       adc r15, __zero_reg__
    resp.
       sec
       sbc r14, __zero_reg__
       sbc r15, __zero_reg__
    that don't need a scratch reg.  The code size is unchanged but
    the register pressure goes down.
    
    gcc/
            * config/avr/avr.cc (avr_out_plus_1): Handle +/-1 on the
            lower regs without needing a scratch.
            * config/avr/avr.md (add<mode>3_clobber, *add<mode>3_clobber)
            (add<mode>3, *add<mode>3, addpsi3, *addpsi3): Add constraint
            alternative "Y01 Ym1" for +/-1 without scratch.

Diff:
---
 gcc/config/avr/avr.cc | 16 ++++++++++++++++
 gcc/config/avr/avr.md | 48 ++++++++++++++++++++++++------------------------
 2 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index ebc3def80df0..cdf676ca312f 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -8921,6 +8921,22 @@ avr_out_plus_1 (rtx xinsn, rtx *xop, int *plen, rtx_code 
code,
   if (xval == const0_rtx)
     return;
 
+  // Adding +/-1 to a lower reg doesn't need a scratch.
+
+  if (IN_RANGE (n_bytes, 2, 4)
+      && code_sat == UNKNOWN
+      && (xval == const1_rtx || xval == constm1_rtx)
+      && ! test_hard_reg_class (LD_REGS, xop[0]))
+    {
+      avr_asm_len ("sec", nullptr, plen, 1);
+
+      for (auto r = REGNO (xop[0]); r < REGNO (xop[0]) + n_bytes; ++r)
+       avr_asm_len (xval == const1_rtx
+                    ? "adc %0,__zero_reg__"
+                    : "sbc %0,__zero_reg__", &all_regs_rtx[r], plen, 1);
+      return;
+    }
+
   if (MINUS == code)
     xval = simplify_unary_operation (NEG, imode, xval, imode);
 
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 57d63a8f7463..f57df70db930 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -1817,10 +1817,10 @@
 ;; "addhq3_clobber" "adduhq3_clobber"
 ;; "addha3_clobber" "adduha3_clobber"
 (define_insn_and_split "add<mode>3_clobber"
-  [(set (match_operand:ALL2 0 "register_operand"            "=!w    ,d    ,r")
-        (plus:ALL2 (match_operand:ALL2 1 "register_operand"  "%0    ,0    ,0")
-                   (match_operand:ALL2 2 "const_operand"     "IJ YIJ,n Ynn,n 
Ynn")))
-   (clobber (match_scratch:QI 3                             "=X     ,X    
,&d"))]
+  [(set (match_operand:ALL2 0 "register_operand"            "=!w    ,d    ,*l  
   ,r")
+        (plus:ALL2 (match_operand:ALL2 1 "register_operand"  "%0    ,0    ,0   
   ,0")
+                   (match_operand:ALL2 2 "const_operand"     "IJ YIJ,n Ynn,Y01 
Ym1,n Ynn")))
+   (clobber (match_scratch:QI 3                             "=X     ,X    ,X   
   ,&d"))]
   ""
   "#"
   "&& reload_completed"
@@ -1831,10 +1831,10 @@
 ;; "*addhq3_clobber"  "*adduhq3_clobber"
 ;; "*addha3_clobber"  "*adduha3_clobber"
 (define_insn "*add<mode>3_clobber"
-  [(set (match_operand:ALL2 0 "register_operand"            "=!w    ,d    ,r")
-        (plus:ALL2 (match_operand:ALL2 1 "register_operand"  "%0    ,0    ,0")
-                   (match_operand:ALL2 2 "const_operand"     "IJ YIJ,n Ynn,n 
Ynn")))
-   (clobber (match_scratch:QI 3                             "=X     ,X    
,&d"))
+  [(set (match_operand:ALL2 0 "register_operand"            "=!w    ,d    ,*l  
   ,r")
+        (plus:ALL2 (match_operand:ALL2 1 "register_operand"  "%0    ,0    ,0   
   ,0")
+                   (match_operand:ALL2 2 "const_operand"     "IJ YIJ,n Ynn,Y01 
Ym1,n Ynn")))
+   (clobber (match_scratch:QI 3                             "=X     ,X    ,X   
   ,&d"))
    (clobber (reg:CC REG_CC))]
   "reload_completed"
   {
@@ -1848,10 +1848,10 @@
 ;; "addsq3" "addusq3"
 ;; "addsa3" "addusa3"
 (define_insn_and_split "add<mode>3"
-  [(set (match_operand:ALL4 0 "register_operand"          "=??r,d ,r")
-        (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
-                   (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
-   (clobber (match_scratch:QI 3                             "=X,X ,&d"))]
+  [(set (match_operand:ALL4 0 "register_operand"          "=??r,d ,*r     ,r")
+        (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0      ,0")
+                   (match_operand:ALL4 2 "nonmemory_operand" "r,i ,Y01 Ym1,n 
Ynn")))
+   (clobber (match_scratch:QI 3                             "=X,X ,X      
,&d"))]
   ""
   "#"
   "&& reload_completed"
@@ -1859,10 +1859,10 @@
   { DONE_ADD_CCC })
 
 (define_insn "*add<mode>3"
-  [(set (match_operand:ALL4 0 "register_operand"          "=??r,d ,r")
-        (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
-                   (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
-   (clobber (match_scratch:QI 3                             "=X,X ,&d"))
+  [(set (match_operand:ALL4 0 "register_operand"          "=??r,d ,*r     ,r")
+        (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0      ,0")
+                   (match_operand:ALL4 2 "nonmemory_operand" "r,i ,Y01 Ym1,n 
Ynn")))
+   (clobber (match_scratch:QI 3                             "=X,X ,X      
,&d"))
    (clobber (reg:CC REG_CC))]
   "reload_completed"
   {
@@ -1951,10 +1951,10 @@
 
 
 (define_insn_and_split "addpsi3"
-  [(set (match_operand:PSI 0 "register_operand"         "=??r,d ,d,r")
-        (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
-                  (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
-   (clobber (match_scratch:QI 3                           "=X,X ,X,&d"))]
+  [(set (match_operand:PSI 0 "register_operand"         "=??r,d ,d,*r     ,r")
+        (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0      ,0")
+                  (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,Y01 
Ym1,n")))
+   (clobber (match_scratch:QI 3                           "=X,X ,X,X      
,&d"))]
   ""
   "#"
   "&& reload_completed"
@@ -1962,10 +1962,10 @@
   { DONE_ADD_CCC })
 
 (define_insn "*addpsi3"
-  [(set (match_operand:PSI 0 "register_operand"         "=??r,d ,d,r")
-        (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
-                  (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
-   (clobber (match_scratch:QI 3                           "=X,X ,X,&d"))
+  [(set (match_operand:PSI 0 "register_operand"         "=??r,d ,d,*r     ,r")
+        (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0      ,0")
+                  (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,Y01 
Ym1,n")))
+   (clobber (match_scratch:QI 3                           "=X,X ,X,X      
,&d"))
    (clobber (reg:CC REG_CC))]
   "reload_completed"
   {

Reply via email to