https://gcc.gnu.org/g:5bae3e8edcce9d53350c52ba5bcab6b7749fd1f5

commit r16-7482-g5bae3e8edcce9d53350c52ba5bcab6b7749fd1f5
Author: Hans-Peter Nilsson <[email protected]>
Date:   Thu Feb 5 18:34:24 2026 +0100

    CRIS: Make sure movsf doesn't have two memory operands
    
    Experimenting, I noticed movsf could get two memory operands, and
    when the pass I was hacking, adjusted both operands, the rtl-ssa
    framework didn't like the situation and signalled failure, for
    example compiling gcc.c-torture/compile/pr85945.c.  While that's
    arguably a wart in rtl-ssa and may be a problem by itself, this
    shouldn't happen: one operand should be either a register or
    constant 0.  It usually doesn't matter because RA fixes up
    operands per the constraints.  Still, this is low-handing fruit
    for improved performance, letting the RTL passes work on more
    correct information ...and also, a plausible excuse for not also
    hacking rtl-ssa proper.  Either way, the port is responsible for
    guarding operand validity, so tweak it.  Incidental observation:
    the two-memory-operands case happened already at expand time.
    This mem-to-mem situation doesn't happen for movsi, because it has
    special precautions to keep one operand a register or const_int 0,
    which were added for reasons of condition-code handling.  That
    particular condition, checking for REG_P or the subreg being REG_P
    looks too restrictive though, not allowing the (subreg mem) case
    that register_operand deliberately allows.
    
            * config/cris/cris.md (SISF): New mode_iterator for SI and SF.
            ("mov<mode>"): Make "movsi" a define_expand to include SFmode by
            means of the SISF iterator and adjust to also handle SFmode.
            ("*movsf_internal"): Anonymize "movsf"; make it a match-only 
pattern.
            Add conditions to guard from source and destination both being 
memory
            operands.

Diff:
---
 gcc/config/cris/cris.md | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md
index 6c5945d3ab56..c18813f306a9 100644
--- a/gcc/config/cris/cris.md
+++ b/gcc/config/cris/cris.md
@@ -173,6 +173,9 @@
 (define_mode_iterator BWD [SI HI QI])
 (define_mode_iterator BWDD [DI SI HI QI])
 
+;; Need to handle SI and SF similarly, at least in the expander.
+(define_mode_iterator SISF [SI SF])
+
 ;; To be able to refer to the same mode_attr for both a multi-mode
 ;; and a mode-specific pattern, we use some singleton iterators.
 (define_mode_iterator DI_ [DI])
@@ -560,11 +563,11 @@
 
 ;; Normal move patterns from SI on.
 
-(define_expand "movsi"
+(define_expand "mov<mode>"
   [(parallel
     [(set
-      (match_operand:SI 0 "nonimmediate_operand")
-      (match_operand:SI 1 "general_operand"))
+      (match_operand:SISF 0 "nonimmediate_operand")
+      (match_operand:SISF 1 "general_operand"))
      (clobber (reg:CC CRIS_CC0_REGNUM))])]
   ""
 {
@@ -572,14 +575,16 @@
      input.  */
   if (MEM_P (operands[0])
       && ! REG_S_P (operands[1])
-      && operands[1] != const0_rtx
+      && operands[1] != CONST0_RTX (<MODE>mode)
       && can_create_pseudo_p ())
-    operands[1] = force_reg (SImode, operands[1]);
+    operands[1] = force_reg (<MODE>mode, operands[1]);
 
    /* At post-reload time, we'll get here for e.g. split multi-mode insns
       with a memory destination.  Go directly to the clobber-less variant.
-      FIXME: Also applies to special-register source or destination.  */
-   if (reload_completed
+      FIXME: Also applies to special-register source or destination.
+      Only do this for integer modes.  */
+   if (SCALAR_INT_MODE_P (<MODE>mode)
+       && reload_completed
        && (MEM_P (operands[0]) || operands[1] == const0_rtx))
      {
         emit_insn (gen_rtx_SET (operands[0], operands[1]));
@@ -778,11 +783,13 @@
 ;; all ones); the worthwhile one is "0.0".
 ;; It will use clear, so we know ALL types of immediate 0 never change cc.
 
-(define_insn "movsf"
+(define_insn "*movsf_internal"
   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,Q>,r, 
r,Q>,g,g,r,r,x,Q>,m,x, x")
        (match_operand:SF 1 "general_operand"       "r,r, Q>,G,G, G,r,g,x,r,x, 
x,Q>,g"))
    (clobber (reg:CC CRIS_CC0_REGNUM))]
-  ""
+  "(register_operand (operands[0], SFmode)
+    || register_operand (operands[1], SFmode)
+    || operands[1] == CONST0_RTX (SFmode))"
   "@
    move.d %1,%0
    move.d %1,%0

Reply via email to