https://gcc.gnu.org/g:059098aa2c3dcadd6859fd079787006bdccdb5ca

commit 059098aa2c3dcadd6859fd079787006bdccdb5ca
Author: Jeff Law <[email protected]>
Date:   Sat Nov 15 09:26:25 2025 -0700

    [RISC-V] Avoid most calls to gen_extend_insn
    
    Yet more infrastructure on our way to eliminating some define_insn_and_split
    constructs.
    
    The RISC-V port is using gen_extend_insn to directly generate a SIGN or ZERO
    extend insn.  This is undesirable because we don't actually have a full set 
of
    extension instructions, particularly zero extension for the base 
architecture.
    
    We've gotten away with this because we've had a define_insn_and_splits which
    claim to support the full set of zero/sign extensions.  We very much want to
    eliminate that little white lie.  So we need to fix those pesky calls to
    gen_extend_insn.
    
    Similar to a patch from earlier this week convert_modes comes to the rescue.
    It'll run through the expander path allowing us to generate the desired 
code.
    In most cases it's a trivial replacement.
    
    One case is left in the tree.  For that case the source operand is known to 
be
    a MEM and we can always extend a load from a MEM.  Converting this one would
    result in infinite recursion through riscv_legitimize_move.
    
    One case is perhaps nontrivial.  convert_move will emit the code to perform 
the
    conversion into a fresh pseudo register.  In one case we need to make sure 
that
    value is copied into the output register for an insn.  So a trivial
    emit_move_insn is needed.
    
    Built and regression tested on riscv32-elf and riscv64-elf.  It's also
    bootstrapped on the Pioneer.  Regression testing is in progress, but won't
    finish for many hours.  The BPI is spinning this change right now, but won't
    have results until tomorrow night.
    
    gcc/
            * config/riscv/riscv.cc (risc_legitimize_move): Use convert_modes
            rather than gen_extend_insn for most cases.
            * config/riscv/riscv.md (addv<mode>4): Likewise.
            (uaddv<mode>4, subv<mode>4, usubv<mode>4): Likewise.
            (mulv<mode>4, umulv<mode>4): Likewise.
            * config/riscv/sync.md (atomic_compare_and_swap<mode>): Likewise.
    
    (cherry picked from commit 1569b0ad0e5a6b4d94d28fd9feffc6ae6ff3afdf)

Diff:
---
 gcc/config/riscv/riscv.cc | 13 ++++++------
 gcc/config/riscv/riscv.md | 52 ++++++++++-------------------------------------
 gcc/config/riscv/sync.md  | 16 +++------------
 3 files changed, 21 insertions(+), 60 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index cbee4363b715..159bf89878e5 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -3756,8 +3756,7 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx 
src)
              /* The low-part must be zero-extended when ELEN == 32 and
                 mode == 64.  */
              if (num == 2 && i == 0)
-               emit_insn (gen_extend_insn (int_reg, result, mode, smode,
-                                           true));
+               int_reg = convert_modes (mode, smode, result, true);
 
              if (i == 1)
                {
@@ -3804,6 +3803,8 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx 
src)
 
       temp_reg = gen_reg_rtx (word_mode);
       zero_extend_p = (LOAD_EXTEND_OP (mode) == ZERO_EXTEND);
+      /* SRC is a MEM, so we can always extend it directly, so
+        no need to indirect through convert_modes.  */
       emit_insn (gen_extend_insn (temp_reg, src, word_mode, mode,
                                  zero_extend_p));
       riscv_emit_move (dest, gen_lowpart (mode, temp_reg));
@@ -3858,9 +3859,8 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx 
src)
     {
       rtx mask = force_reg (word_mode, gen_int_mode (-65536, word_mode));
       rtx temp = gen_reg_rtx (word_mode);
-      emit_insn (gen_extend_insn (temp,
-                                 gen_lowpart (HImode, src),
-                                 word_mode, HImode, 1));
+      temp = convert_modes (word_mode, HImode,
+                           gen_lowpart (HImode, src), true);
       if (word_mode == SImode)
        emit_insn (gen_iorsi3 (temp, mask, temp));
       else
@@ -15840,7 +15840,8 @@ synthesize_and (rtx operands[3])
       if (tmode != VOIDmode)
        {
          rtx tmp = gen_lowpart (tmode, operands[1]);
-         emit_insn (gen_extend_insn (operands[0], tmp, word_mode, tmode, 1));
+         emit_move_insn (operands[0], convert_modes (word_mode, tmode,
+                                                     tmp, true));
          return true;
        }
     }
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index d179f1f49c89..fced2da2e604 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -791,14 +791,8 @@
       rtx t6 = gen_reg_rtx (DImode);
 
       emit_insn (gen_addsi3_extended (t6, operands[1], operands[2]));
-      if (GET_CODE (operands[1]) != CONST_INT)
-       emit_insn (gen_extend_insn (t4, operands[1], DImode, SImode, 0));
-      else
-       t4 = operands[1];
-      if (GET_CODE (operands[2]) != CONST_INT)
-       emit_insn (gen_extend_insn (t5, operands[2], DImode, SImode, 0));
-      else
-       t5 = operands[2];
+      t4 = convert_modes (DImode, SImode, operands[1], false);
+      t5 = convert_modes (DImode, SImode, operands[2], false);
       emit_insn (gen_adddi3 (t3, t4, t5));
       rtx t7 = gen_lowpart (SImode, t6);
       SUBREG_PROMOTED_VAR_P (t7) = 1;
@@ -835,10 +829,7 @@
       rtx t3 = gen_reg_rtx (DImode);
       rtx t4 = gen_reg_rtx (DImode);
 
-      if (GET_CODE (operands[1]) != CONST_INT)
-       emit_insn (gen_extend_insn (t3, operands[1], DImode, SImode, 0));
-      else
-       t3 = operands[1];
+      t3 = convert_modes (DImode, SImode, operands[1], 0);
       emit_insn (gen_addsi3_extended (t4, operands[1], operands[2]));
       rtx t5 = gen_lowpart (SImode, t4);
       SUBREG_PROMOTED_VAR_P (t5) = 1;
@@ -982,14 +973,8 @@
       rtx t6 = gen_reg_rtx (DImode);
 
       emit_insn (gen_subsi3_extended (t6, operands[1], operands[2]));
-      if (GET_CODE (operands[1]) != CONST_INT)
-       emit_insn (gen_extend_insn (t4, operands[1], DImode, SImode, 0));
-      else
-       t4 = operands[1];
-      if (GET_CODE (operands[2]) != CONST_INT)
-       emit_insn (gen_extend_insn (t5, operands[2], DImode, SImode, 0));
-      else
-       t5 = operands[2];
+      t4 = convert_modes (DImode, SImode, operands[1], false);
+      t5 = convert_modes (DImode, SImode, operands[2], false);
       emit_insn (gen_subdi3 (t3, t4, t5));
       rtx t7 = gen_lowpart (SImode, t6);
       SUBREG_PROMOTED_VAR_P (t7) = 1;
@@ -1029,10 +1014,7 @@
       rtx t3 = gen_reg_rtx (DImode);
       rtx t4 = gen_reg_rtx (DImode);
 
-      if (GET_CODE (operands[1]) != CONST_INT)
-       emit_insn (gen_extend_insn (t3, operands[1], DImode, SImode, 0));
-      else
-       t3 = operands[1];
+      t3 = convert_modes (DImode, SImode, operands[1], false);
       emit_insn (gen_subsi3_extended (t4, operands[1], operands[2]));
       rtx t5 = gen_lowpart (SImode, t4);
       SUBREG_PROMOTED_VAR_P (t5) = 1;
@@ -1192,18 +1174,12 @@
       rtx t5 = gen_reg_rtx (DImode);
       rtx t6 = gen_reg_rtx (DImode);
 
-      if (GET_CODE (operands[1]) != CONST_INT)
-       emit_insn (gen_extend_insn (t4, operands[1], DImode, SImode, 0));
-      else
-       t4 = operands[1];
-      if (GET_CODE (operands[2]) != CONST_INT)
-       emit_insn (gen_extend_insn (t5, operands[2], DImode, SImode, 0));
-      else
-       t5 = operands[2];
+      t4 = convert_modes (DImode, SImode, operands[1], false);
+      t5 = convert_modes (DImode, SImode, operands[2], false);
       emit_insn (gen_muldi3 (t3, t4, t5));
 
       emit_move_insn (operands[0], gen_lowpart (SImode, t3));
-      emit_insn (gen_extend_insn (t6, operands[0], DImode, SImode, 0));
+      t6 = convert_modes (DImode, SImode, operands[0], false);
 
       riscv_expand_conditional_branch (operands[3], NE, t6, t3);
     }
@@ -1239,14 +1215,8 @@
       rtx t7 = gen_reg_rtx (DImode);
       rtx t8 = gen_reg_rtx (DImode);
 
-      if (GET_CODE (operands[1]) != CONST_INT)
-       emit_insn (gen_extend_insn (t3, operands[1], DImode, SImode, 0));
-      else
-       t3 = operands[1];
-      if (GET_CODE (operands[2]) != CONST_INT)
-       emit_insn (gen_extend_insn (t4, operands[2], DImode, SImode, 0));
-      else
-       t4 = operands[2];
+      t3 = convert_modes (DImode, SImode, operands[1], false);
+      t4 = convert_modes (DImode, SImode, operands[2], false);
 
       emit_insn (gen_ashldi3 (t5, t3, GEN_INT (32)));
       emit_insn (gen_ashldi3 (t6, t4, GEN_INT (32)));
diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md
index 37f15d816595..01eab1a1ef36 100644
--- a/gcc/config/riscv/sync.md
+++ b/gcc/config/riscv/sync.md
@@ -603,8 +603,7 @@
     {
       /* We don't have SI mode compare on RV64, so we need to make sure 
expected
         value is sign-extended.  */
-      rtx tmp0 = gen_reg_rtx (word_mode);
-      emit_insn (gen_extend_insn (tmp0, operands[3], word_mode, <MODE>mode, 
0));
+      rtx tmp0 = convert_modes (word_mode, <MODE>mode, operands[3], false);
       operands[3] = gen_lowpart (<MODE>mode, tmp0);
     }
 
@@ -702,17 +701,8 @@
                                                         operands[6],
                                                         operands[7]));
 
-  rtx val = gen_reg_rtx (SImode);
-  if (operands[1] != const0_rtx)
-    emit_move_insn (val, gen_rtx_SIGN_EXTEND (SImode, operands[1]));
-  else
-    emit_move_insn (val, const0_rtx);
-
-  rtx exp = gen_reg_rtx (SImode);
-  if (operands[3] != const0_rtx)
-    emit_move_insn (exp, gen_rtx_SIGN_EXTEND (SImode, operands[3]));
-  else
-    emit_move_insn (exp, const0_rtx);
+  rtx val = convert_modes (SImode, <SHORT:MODE>mode, operands[1], false);
+  rtx exp = convert_modes (SImode, <SHORT:MODE>mode, operands[3], false);
 
   rtx compare = val;
   if (exp != const0_rtx)

Reply via email to