diff mbox series

[avr,applied] Tweak 16-bit additions with constant

Message ID c4b3380f-75d6-46f9-a18e-f94be8282ebd@gjlay.de
State New
Headers show
Series [avr,applied] Tweak 16-bit additions with constant | expand

Commit Message

Georg-Johann Lay Aug. 18, 2024, 4:39 p.m. UTC
The 16-bit additions like addhi3 have two forms: One with a scratch:QI
and one without, where the latter is required because reload cannot
deal with a scratch when spill code pops a 16-bit addition.

Passes like combine and fwprop1 may come up with the non-scratch version,
which is sub-optimal in the case when the addition is performed in a
NO_LD_REGS register because the operands will be spilled to LD_REGS.
Having a scratch:QI at disposal can lead to better code with less spills.

Johann
diff mbox series

Patch

    AVR: Tweak 16-bit addition with const that didn't get a LD_REGS register.
    
    The 16-bit additions like addhi3 have two forms: One with a scratch:QI
    and one without, where the latter is required because reload cannot
    deal with a scratch when spill code pops a 16-bit addition.
    
    Passes like combine and fwprop1 may come up with the non-scratch version,
    which is sub-optimal in the case when the addition is performed in a
    NO_LD_REGS register because the operands will be spilled to LD_REGS.
    Having a scratch:QI at disposal can lead to better code with less spills.
    
    gcc/
            * config/avr/avr.md (*add<mode>3_split) [!reload_completed]:
            Add a scratch:QI to 16-bit additions with constant.

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 57f4a08c58c..c10709ecef0 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -1724,12 +1724,28 @@  (define_insn_and_split "*add<mode>3_split"
                    (match_operand:ALL2 2 "nonmemory_or_const_operand" "r,s,IJ YIJ,n Ynn")))]
   ""
   "#"
-  "&& reload_completed"
+  "&& 1"
   [(parallel [(set (match_dup 0)
                    (plus:ALL2 (match_dup 1)
                               (match_dup 2)))
               (clobber (reg:CC REG_CC))])]
-  ""
+  {
+    // Passes like combine and fwprop1 may remove the scratch from an
+    // addhi3 insn.  Add the scratch again because having a QImode
+    // scratch reg available is better than spilling the operands in
+    // the case when we don't get a d-regs register.
+    if (! reload_completed
+        && const_operand (operands[2], <MODE>mode)
+        && ! stack_register_operand (operands[0], HImode)
+        && ! stack_register_operand (operands[1], HImode))
+      {
+        emit (gen_add<mode>3_clobber (operands[0], operands[1], operands[2]));
+        DONE;
+      }
+
+    if (! reload_completed)
+      FAIL;
+  }
   [(set_attr "isa" "*,*,adiw,*")])
 
 ;; "*addhi3"