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

commit r16-5842-g5fd09b47d9a75eb235ad46ebd206c4a870d64958
Author: Robin Dapp <[email protected]>
Date:   Tue Dec 2 13:00:51 2025 -0700

    [PATCH] RISC-V: Make vlsegff similar to vleff [PR122656].
    
    When we expand
      void d() { __riscv_vlseg2e32ff_v_i32mf2x2(&a, &c, b); }
    without a destination register we ICE because
    use_exact_insn wrongly adds arguments that we don't need and
      gcc_assert (opno == insn_data[icode].n_generator_args);
    triggers.
    
    Currently we expand a segmented fault-only-first load via use_exact_insn
    because its insn pattern wants a Pmode register as source.  We can't go
    the use_contiguous_load route because that one adds a vector-mode memory
    operand.
    
    It doesn't need to be like that, though, and this patch makes the
    segmented load similar to the regular FoF load in terms of source
    operand.  Also the patch only adds additional expansion arguments like
    the rounding mode only if the insn needs it and the number of operands is
    less than what we need, not unequal.
    
    Regtested on rv64gcv_zvl512b.
    
    Regards
     Robin
    
            PR target/122656
    
    gcc/ChangeLog:
    
            * config/riscv/riscv-vector-builtins-bases.cc: Use
            use_contiguous_load for vlsegff.
            * config/riscv/riscv-vector-builtins.cc 
(function_expander::use_exact_insn):
            Only add rounding mode operand if insn requires it and number of
            arguments is < required.
            (function_expander::use_ternop_insn): Ditto.
            (function_expander::use_widen_ternop_insn): Ditto.
            * config/riscv/vector.md: Use vector-mode source operand.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/rvv/base/pr122656-1.c: New test.
            * gcc.target/riscv/rvv/base/pr122656-2.c: New test.`

Diff:
---
 gcc/config/riscv/riscv-vector-builtins-bases.cc      | 3 ++-
 gcc/config/riscv/riscv-vector-builtins.cc            | 9 ++++++---
 gcc/config/riscv/vector.md                           | 4 ++--
 gcc/testsuite/gcc.target/riscv/rvv/base/pr122656-1.c | 7 +++++++
 gcc/testsuite/gcc.target/riscv/rvv/base/pr122656-2.c | 7 +++++++
 5 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/gcc/config/riscv/riscv-vector-builtins-bases.cc 
b/gcc/config/riscv/riscv-vector-builtins-bases.cc
index 22b77ccd3d5c..d00403a1fc5d 100644
--- a/gcc/config/riscv/riscv-vector-builtins-bases.cc
+++ b/gcc/config/riscv/riscv-vector-builtins-bases.cc
@@ -2130,7 +2130,8 @@ public:
 
   rtx expand (function_expander &e) const override
   {
-    return e.use_exact_insn (code_for_pred_fault_load (e.vector_mode ()));
+    return e.use_contiguous_load_insn
+      (code_for_pred_fault_load (e.vector_mode ()));
   }
 };
 
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index d37cc43ebe5a..f92e94b781d7 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -4709,7 +4709,8 @@ function_expander::use_exact_insn (insn_code icode)
 
   /* The RVV floating-point only support dynamic rounding mode in the
      FRM register.  */
-  if (opno != insn_data[icode].n_generator_args)
+  if (base->may_require_frm_p ()
+      && opno < insn_data[icode].n_generator_args)
     add_input_operand (Pmode, gen_int_mode (riscv_vector::FRM_DYN, Pmode));
 
   return generate_insn (icode);
@@ -4894,7 +4895,8 @@ function_expander::use_ternop_insn (bool vd_accum_p, 
insn_code icode)
 
   /* The RVV floating-point only support dynamic rounding mode in the
      FRM register.  */
-  if (opno != insn_data[icode].n_generator_args)
+  if (base->may_require_frm_p ()
+      && opno < insn_data[icode].n_generator_args)
     add_input_operand (Pmode, gen_int_mode (riscv_vector::FRM_DYN, Pmode));
 
   return generate_insn (icode);
@@ -4938,7 +4940,8 @@ function_expander::use_widen_ternop_insn (insn_code icode)
 
   /* The RVV floating-point only support dynamic rounding mode in the
      FRM register.  */
-  if (opno != insn_data[icode].n_generator_args)
+  if (base->may_require_frm_p ()
+      && opno < insn_data[icode].n_generator_args)
     add_input_operand (Pmode, gen_int_mode (riscv_vector::FRM_DYN, Pmode));
 
   return generate_insn (icode);
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index a345946f6011..c4f60bfe3889 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -8669,7 +8669,7 @@
             (reg:SI VL_REGNUM)
             (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
          (unspec:VT
-           [(match_operand 3 "pmode_reg_or_0_operand"   "   rJ,    rJ,    rJ")
+           [(match_operand:VT 3 "memory_operand"        "    m,     m,     m")
             (mem:BLK (scratch))] UNSPEC_VLEFF)
          (match_operand:VT 2 "vector_merge_operand"     "    0,    vu,    
vu")))
    (set (reg:SI VL_REGNUM)
@@ -8684,7 +8684,7 @@
                [(match_dup 3) (mem:BLK (scratch))] UNSPEC_VLEFF)
             (match_dup 2))] UNSPEC_MODIFY_VL))]
   "TARGET_VECTOR"
-  "vlseg<nf>e<sew>ff.v\t%0,(%z3)%p1"
+  "vlseg<nf>e<sew>ff.v\t%0,%3%p1"
   [(set_attr "type" "vlsegdff")
    (set_attr "mode" "<MODE>")])
 
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr122656-1.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr122656-1.c
new file mode 100644
index 000000000000..76adbed3f61a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr122656-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "riscv_vector.h"
+int a;
+long b, c;
+void d() { __riscv_vlseg2e32ff_v_i32mf2x2(&a, &c, b); } /* { dg-error "invalid 
argument to built-in function" } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr122656-2.c 
b/gcc/testsuite/gcc.target/riscv/rvv/base/pr122656-2.c
new file mode 100644
index 000000000000..395dc7f38c3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr122656-2.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "riscv_vector.h"
+int a;
+long b, c;
+void d() { vint32mf2x2_t v = __riscv_vlseg2e32ff_v_i32mf2x2(&a, &c, b); }

Reply via email to