https://gcc.gnu.org/g:83340869a21baafc889c05b6b5c632a226c509bc

commit r15-9536-g83340869a21baafc889c05b6b5c632a226c509bc
Author: Keith Packard <kei...@keithp.com>
Date:   Wed Apr 16 14:10:18 2025 -0600

    [PATCH] rx: avoid adding setpsw for rx_cmpstrn when len is const
    
    pattern using rx_cmpstrn is cmpstrsi for which len is a constant -1,
    so we'll be moving the setpsw instructions from rx_cmpstrn to
    cmpstrnsi as follows:
    
     1. Adjust the predicate on the length operand from "register_operand"
        to "nonmemory_operand". This will allow constants to appear here,
        instead of having them already transferred into a register.
    
     2. Check to see if the len value is constant, and then check if it is
        actually zero. In that case, short-circuit the rest of the pattern
        and set the result register to 0.
    
     3. Emit 'setpsw c' and 'setpsw z' instructions when the len is not a
        constant, in case it turns out to be zero at runtime.
    
     4. Remove the two 'setpsw' instructions from rx_cmpstrn.
    
    gcc/
            * config/rx/rx.md (cmpstrnsi): Allow constant length.  For
            static length 0, just store 0 into the output register.
            For dynamic zero, set C/Z appropriately.
            (rxcmpstrn): No longer set C/Z.

Diff:
---
 gcc/config/rx/rx.md | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index edb2c96603f5..a3d966efdcc9 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -2541,10 +2541,17 @@
        (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand")     ;; 
String1
                             (match_operand:BLK 2 "memory_operand")]    ;; 
String2
                            UNSPEC_CMPSTRN))
-   (use (match_operand:SI                       3 "register_operand"))  ;; Max 
Length
+   (use (match_operand:SI                       3 "nonmemory_operand")) ;; Max 
Length
    (match_operand:SI                            4 "immediate_operand")] ;; 
Known Align
   "rx_allow_string_insns"
   {
+    bool const_len = CONST_INT_P (operands[3]);
+    if (const_len && operands[3] == CONST0_RTX (SImode))
+      {
+       emit_move_insn (operands[0], CONST0_RTX (SImode));
+       DONE;
+      }
+
     rtx str1 = gen_rtx_REG (SImode, 1);
     rtx str2 = gen_rtx_REG (SImode, 2);
     rtx len  = gen_rtx_REG (SImode, 3);
@@ -2553,6 +2560,13 @@
     emit_move_insn (str2, force_operand (XEXP (operands[2], 0), NULL_RTX));
     emit_move_insn (len, operands[3]);
 
+    /* Set flags in case len is zero */
+    if (!const_len)
+      {
+       emit_insn (gen_setpsw (GEN_INT ('C')));
+       emit_insn (gen_setpsw (GEN_INT ('Z')));
+      }
+
     emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2]));
     DONE;
   }
@@ -2590,9 +2604,7 @@
    (clobber (reg:SI 3))
    (clobber (reg:CC CC_REG))]
   "rx_allow_string_insns"
-  "setpsw  z           ; Set flags in case len is zero
-   setpsw  c
-   scmpu               ; Perform the string comparison
+  "scmpu               ; Perform the string comparison
    mov     #-1, %0      ; Set up -1 result (which cannot be created
                         ; by the SC insn)
    bnc    ?+           ; If Carry is not set skip over

Reply via email to