This patch introduces a vector cost model for the Spacemit-X60 core,
using dynamic LMUL scaling with the -madjust-lmul-cost flag.

Compared to the previous patch, I dropped the local 'vector_lmul'
attribute and the corresponding LMUL-aware cost logic in spacemit-x60.md.
Instead, Spacemit-X60 tuning now enables -madjust-lmul-cost implicitly,
and riscv_sched_adjust_cost is updated so that the adjustment applies to
spacemit_x60 in addition to the generic out-of-order model.

The stress tests I previously used to tune individual instruction costs
(with the LMUL-aware logic implemented directly in spacemit-x60.md)
now show a regression in performance. The most likely cause is the implicit
-madjust-lmul-cost scaling, since some instructions performed better
with non-power-of-two scaling (or with no LMUL scaling at all), so the
uniform ×(1,2,4,8) adjustment affects performance.

Updated performance results:

| Benchmark        | Metric | Trunk            | Vector Cost Model | Δ (%)   |
|------------------|--------|------------------|-------------------|---------|
| SciMark2-C       | cycles | 311,450,555,453  | 313,278,899,107   | +0.56%  |
|------------------|--------|------------------|-------------------|---------|
| tramp3d-v4       | cycles | 23,788,980,247   | 21,073,526,428    | -12.89% |
|------------------|--------|------------------|-------------------|---------|
| Freebench/neural | cycles | 471,707,641      | 435,842,612       | -8.23%  |
|------------------|--------|------------------|-------------------|---------|

Benchmarks were run from the LLVM test-suite
(MultiSource/Benchmarks) using:

taskset -c 0 perf stat -r 10 ./...

SciMark2-C (ANSI C), FreeBench/neural, and tramp3d-v4
were used as representative numerical workloads.

For tramp3d-v4, the workload parameters (--cartvis 1.0 0.0, --rhomin 1e-8,
-n 20) increase floating-point intensity and dependency pressure, placing
greater stress on the scheduler.

2026-02-13  Nikola Ratkovac  <[email protected]>

gcc/ChangeLog:

        * config/riscv/spacemit-x60.md: Add primary vector pipeline model
        for Spacemit-X60.
        (spacemit_x60_dummy): Rename from spacemi6_x60_dummy.
        * config/riscv/riscv.cc (riscv_sched_adjust_cost): Support spacemit_x60.
        (riscv_override_options_internal): Enable TARGET_ADJUST_LMUL_COST
        for spacemit_x60.



CONFIDENTIALITY: The contents of this e-mail are confidential and intended only 
for the above addressee(s). If you are not the intended recipient, or the 
person responsible for delivering it to the intended recipient, copying or 
delivering it to anyone else or using it in any unauthorized manner is 
prohibited and may be unlawful. If you receive this e-mail by mistake, please 
notify the sender and the systems administrator at [email protected] 
immediately.
---
 gcc/config/riscv/riscv.cc        |  11 +-
 gcc/config/riscv/spacemit-x60.md | 233 ++++++++++++++++++++++++++++++-
 2 files changed, 234 insertions(+), 10 deletions(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 3baf0a936..8fd4c8ced 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -11842,9 +11842,12 @@ static int
 riscv_sched_adjust_cost (rtx_insn *, int, rtx_insn *insn, int cost,
                         unsigned int)
 {
-  /* Only do adjustments for the generic out-of-order scheduling model.  */
-  if (!TARGET_VECTOR || riscv_microarchitecture != generic_ooo)
-    return cost;
+
+  /* Only do adjustments for the generic out-of-order and spacemit_x60
+     scheduling model.  */
+  if (!TARGET_VECTOR || (riscv_microarchitecture != generic_ooo
+    && riscv_microarchitecture != spacemit_x60))
+  return cost;
 
   if (recog_memoized (insn) < 0)
     return cost;
@@ -12284,6 +12287,8 @@ riscv_override_options_internal (struct gcc_options 
*opts)
   const char *tune_string = get_tune_str (opts);
   cpu = riscv_parse_tune (tune_string, false);
   riscv_microarchitecture = cpu->microarchitecture;
+  if (riscv_microarchitecture == spacemit_x60)
+    opts->x_TARGET_ADJUST_LMUL_COST = 1;
   tune_param = opts->x_optimize_size
                 ? &optimize_size_tune_info
                 : cpu->tune_param;
diff --git a/gcc/config/riscv/spacemit-x60.md b/gcc/config/riscv/spacemit-x60.md
index fdd7b87b3..6f9d48928 100644
--- a/gcc/config/riscv/spacemit-x60.md
+++ b/gcc/config/riscv/spacemit-x60.md
@@ -26,10 +26,9 @@
 ;; There's actually two VXU units and ops get split across them
 ;; to give the illusion of a single wider unit with higher 
 ;; performance.  There are a few ops that can only be fed into
-;; one of the two units.  Probably best to initially model as
-;; a single unit
+;; one of the two units.  For the purposes of this scheduling
+;; model, the VXU is treated as a single unit.
 ;;
-;; The VXU is not currently modeled.
 ;; Some ops like shadd.uw and add.uw, cpop take an extra cycle
 ;; Given everything is in-order, anti-dependencies probably matter
 ;; FP sign injection isn't handled correctly
@@ -38,7 +37,7 @@
 (define_automaton "spacemit_x60")
 (define_cpu_unit "spacemit_x60_alu0,spacemit_x60_alu1" "spacemit_x60")
 (define_cpu_unit "spacemit_x60_lsu0,spacemit_x60_lsu1" "spacemit_x60")
-;;(define_cpu_unit "spacemit_x60_vxu0" "spacemit_x60")
+(define_cpu_unit "spacemit_x60_vxu0" "spacemit_x60")
 (define_cpu_unit "spacemit_x60_fpalu" "spacemit_x60")
 (define_cpu_unit "spacemit_x60_fdivsqrt" "spacemit_x60")
 
@@ -183,8 +182,228 @@
            (eq_attr "mode" "DF")))
   "spacemit_x60_fdivsqrt*7")
 
-(define_insn_reservation "spacemi6_x60_dummy" 1
+;; ----------------------------------------------------
+;; Vector
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_vsetvl" 1
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vsetvl_pre,vsetvl,rdvlenb,rdvl"))
+  "spacemit_x60_vxu0")
+
+;; ----------------------------------------------------
+;; Vector Memory (load/store)
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_vec_load" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vlde,vldr,vldff"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_store" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vste,vstr,vstm"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_mask_load" 1
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vldm"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_strided" 10
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vlds,vsts"))
+  "spacemit_x60_vxu0*7")
+
+(define_insn_reservation "spacemit_x60_vec_indexed" 10
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vldux,vldox,vstux,vstox,\
+      vlsegdux,vlsegdox,vssegtux,vssegtox"))
+  "spacemit_x60_vxu0*7")
+
+(define_insn_reservation "spacemit_x60_vec_segmented" 8
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vlsegde,vlsegds,vlsegdff,vssegte,vssegts"))
+  "spacemit_x60_vxu0*7")
+
+;; ----------------------------------------------------
+;; Vector Integer Arithmetic
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_vec_ialu" 1
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vialu,vicalu,viminmax,vbrev,vext,\
+       vbrev8,vclz,vctz,vcpop,vrol,vror,vandn"))
+  "spacemit_x60_vxu0")
+
+(define_insn_reservation "spacemit_x60_vec_shift" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vshift"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_sshift" 1
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vsshift"))
+  "spacemit_x60_vxu0")
+
+(define_insn_reservation "spacemit_x60_vec_cmp" 4
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vicmp"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_imul" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vimul"))
+  "spacemit_x60_vxu0")
+
+(define_insn_reservation "spacemit_x60_vec_imuladd" 4
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vimuladd"))
+  "spacemit_x60_vxu0")
+
+(define_insn_reservation "spacemit_x60_vec_iwalu" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "viwalu,viwmul,viwmuladd,vwsll"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_div" 12
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vidiv"))
+  "spacemit_x60_vxu0*7")
+
+;; ----------------------------------------------------
+;; Vector Fixed Point
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_vec_fixed_point" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vsalu,vaalu"))
+  "spacemit_x60_vxu0")
+
+(define_insn_reservation "spacemit_x60_vec_fixed_point_slow" 4
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vsmul"))
+  "spacemit_x60_vxu0*4")
+
+(define_insn_reservation "spacemit_x60_vec_narrow_fixed_point" 4
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vnshift,vnclip"))
+  "spacemit_x60_vxu0*4")
+
+;; ----------------------------------------------------
+;; Vector Floating Point
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_vec_falu" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vfalu,vfmul,vfmuladd,vfminmax,vfrecp,\
+       vfcvtitof,vfcvtftoi,vfmerge"))
+  "spacemit_x60_vxu0")
+
+(define_insn_reservation "spacemit_x60_vec_fwalu" 4
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vfwalu,vfwmul,vfwmuladd,vfwmaccbf16,vfwcvtitof,\
+      vfwcvtftoi,vfwcvtftof,vfwcvtbf16,vfncvtitof,vfncvtftoi,vfncvtftof,\
+      vfncvtbf16,sf_vfnrclip,sf_vqmacc"))
+  "spacemit_x60_vxu0*4")
+
+(define_insn_reservation "spacemit_x60_vec_fcmp" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vfcmp"))
+  "spacemit_x60_vxu0")
+
+(define_insn_reservation "spacemit_x60_vec_fmov" 4
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vfmovfv,vfmov"))
+  "spacemit_x60_vxu0*4")
+
+(define_insn_reservation "spacemit_x60_vec_fsimple" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vfmovvf,vfclass,vfsgnj"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_fsqrt_fdiv" 12
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vfsqrt,vfdiv"))
+  "spacemit_x60_vxu0*7")
+
+;; ----------------------------------------------------
+;; Vector Mask Operations
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_vec_mask_alu" 4
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vmalu"))
+  "spacemit_x60_vxu0")
+
+(define_insn_reservation "spacemit_x60_vec_mask_pop" 6
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vmpop,vmffs"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_mask_special" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vmidx,vmiota"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_mask_vmsfs" 4
   (and (eq_attr "tune" "spacemit_x60")
-       (eq_attr "type" 
"viminmax,vfmuladd,vfmovvf,vssegte,vlsegds,rdvlenb,vaesef,vfcmp,vmpop,vwsll,vsha2cl,vfwcvtbf16,vfncvtftoi,vgather,vsha2ch,vsts,vldm,vmsfs,vfmul,vcompress,vaesz,vssegtox,vstox,vclmulh,vghsh,vaalu,vslideup,vfalu,vaeskf1,vfcvtitof,vaesdm,vmffs,vandn,vstm,vgmul,vlds,viwmul,vfmerge,vlsegdff,vshift,vaesem,vaesdf,vste,ghost,viwred,vsalu,vfwredu,vmidx,sf_vfnrclip,vstux,vfslide1down,vfcvtftoi,vfncvtitof,vnshift,vsm3me,vired,vlde,vfwalu,sf_vc_se,vlsegdux,vicmp,vfncvtftof,vror,vfwmaccbf16,vfminmax,vldff,vstr,vsm3c,vfwcvtftoi,vbrev,vaeskf2,vidiv,vfwcvtftof,rdvl,vimul,vfsgnj,vimovvx,vsha2ms,vialu,vfredo,vctz,vlsegde,viwmuladd,vcpop,vsetvl,vldux,vfwmuladd,vector,wrvxrm,vsshift,vfredu,vimerge,vlsegdox,vfrecp,vnclip,vfclass,vbrev8,vslidedown,vldox,vmalu,vext,vimuladd,sf_vqmacc,vldr,vrol,vmov,vsmul,vclmul,vfmov,vislide1up,vssegtux,vclz,rdfrm,vfwcvtitof,vfncvtbf16,vfmovfv,vislide1down,vfwmul,vfsqrt,vrev8,vicalu,vimov,wrfrm,vfdiv,sf_vc,vsm4k,vmiota,vsm4r,viwalu,vsetvl_pre,vimovxv,vfwredo,vfslide1up,vssegts"))
-  "nothing")
+       (eq_attr "type" "vmsfs"))
+  "spacemit_x60_vxu0")
 
+;; ----------------------------------------------------
+;; Vector Permutations
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_vec_mov" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vmov,vimovxv,vimovvx,vimov"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_merge" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vimerge"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_gather" 4
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vgather"))
+  "spacemit_x60_vxu0*4")
+
+(define_insn_reservation "spacemit_x60_vec_compress" 4
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vcompress"))
+  "spacemit_x60_vxu0*3")
+
+(define_insn_reservation "spacemit_x60_vec_slide" 2
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vslideup,vslidedown,vislide1up,\
+      vislide1down,vfslide1up,vfslide1down"))
+  "spacemit_x60_vxu0")
+
+;; ----------------------------------------------------
+;; Vector Reductions
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_vec_red" 8
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vired,viwred,vfredu,vfwredu"))
+  "spacemit_x60_vxu0*2")
+
+(define_insn_reservation "spacemit_x60_vec_ordered_red" 10
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vfredo,vfwredo"))
+  "spacemit_x60_vxu0*7")
+
+;; ----------------------------------------------------
+;; Vector Unknown
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_dummy" 1
+  (and (eq_attr "tune" "spacemit_x60")
+       (eq_attr "type" "vaesef,
+      vsha2cl,vsha2ch,vaesz,vclmulh,vghsh,vaeskf1,vaesdm,vgmul,
+      vaesem,vaesdf,ghost,vsm3me,sf_vc_se,vsm3c,
+      vaeskf2,vsha2ms,vector,wrvxrm,
+      vclmul,rdfrm,wrfrm,sf_vc,vsm4k,vsm4r"))
+  "nothing")
\ No newline at end of file
-- 
2.43.0

Reply via email to