https://gcc.gnu.org/g:df00ab045c155e2edfb8ffa55e42109bf1402934

commit r17-1447-gdf00ab045c155e2edfb8ffa55e42109bf1402934
Author: JRobinNTA <[email protected]>
Date:   Tue Jun 9 06:58:14 2026 -0600

    [PATCH] RISC-V: Fix static rounding mode splicing for xtheadvector 
[PR125395]
    
    When generating assembly for T-Head vector float conversions,
    the backend used hardcoded pointer math that failed to account
    for static rounding mode suffixes (e.g., .rtz). Additionally,
    intercept blocks for VFCVT and VFWCVT were entirely missing,
    allowing illegal static rounding modes to leak into the assembler.
    
    This patch adds the missing conversion blocks and introduces
    an offset calculation to safely bypass the mnemonic regardless
    of standard RVV rounding suffixes.
    
            PR target/125395
    gcc/ChangeLog:
    
            * config/riscv/thead.cc (th_asm_output_opcode): Add VFCVT
            and VFWCVT blocks. Add offset logic for static rounding suffixes.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/rvv/xtheadvector/pr125395.c: New test.

Diff:
---
 gcc/config/riscv/thead.cc                          | 72 +++++++++++++++++++---
 .../gcc.target/riscv/rvv/xtheadvector/pr125395.c   | 26 ++++++++
 2 files changed, 88 insertions(+), 10 deletions(-)

diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index b16b2c443bed..acf661f83e73 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -1144,29 +1144,81 @@ th_asm_output_opcode (FILE *asm_out_file, const char *p)
          return p+6;
        }
 
-      if (get_attr_type (current_output_insn) == TYPE_VFNCVTFTOI ||
-         get_attr_type (current_output_insn) == TYPE_VFNCVTITOF)
+      if (get_attr_type (current_output_insn) == TYPE_VFCVTFTOI
+         || get_attr_type (current_output_insn) == TYPE_VFCVTITOF)
        {
          if (strstr (p, "xu"))
            {
-             get_attr_type (current_output_insn) == TYPE_VFNCVTFTOI
-                          ? fputs ("th.vfncvt.xu.f.v", asm_out_file)
-                          : fputs ("th.vfncvt.f.xu.v", asm_out_file);
-             return p+13;
+             get_attr_type (current_output_insn) == TYPE_VFCVTFTOI
+               ? fputs ("th.vfcvt.xu.f.v", asm_out_file)
+               : fputs ("th.vfcvt.f.xu.v", asm_out_file);
+             if (strstr (p, ".rtz") || strstr (p, ".rod"))
+               return p + 16;
+             return p + 12;
+           }
+         else
+           {
+             get_attr_type (current_output_insn) == TYPE_VFCVTFTOI
+               ? fputs ("th.vfcvt.x.f.v", asm_out_file)
+               : fputs ("th.vfcvt.f.x.v", asm_out_file);
+             if (strstr (p, ".rtz") || strstr (p, ".rod"))
+               return p + 15;
+             return p + 11;
+           }
+       }
+
+      if (get_attr_type (current_output_insn) == TYPE_VFWCVTFTOI
+         || get_attr_type (current_output_insn) == TYPE_VFWCVTITOF)
+       {
+         if (strstr (p, "xu"))
+           {
+             get_attr_type (current_output_insn) == TYPE_VFWCVTFTOI
+               ? fputs ("th.vfwcvt.xu.f.v", asm_out_file)
+               : fputs ("th.vfwcvt.f.xu.v", asm_out_file);
+             if (strstr (p, ".rtz") || strstr (p, ".rod"))
+               return p + 17;
+             return p + 13;
+           }
+         else
+           {
+             get_attr_type (current_output_insn) == TYPE_VFWCVTFTOI
+               ? fputs ("th.vfwcvt.x.f.v", asm_out_file)
+               : fputs ("th.vfwcvt.f.x.v", asm_out_file);
+             if (strstr (p, ".rtz") || strstr (p, ".rod"))
+               return p + 16;
+             return p + 12;
+           }
        }
+
+      if (get_attr_type (current_output_insn) == TYPE_VFNCVTFTOI
+         || get_attr_type (current_output_insn) == TYPE_VFNCVTITOF)
+       {
+         if (strstr (p, "xu"))
+           {
+             get_attr_type (current_output_insn) == TYPE_VFNCVTFTOI
+               ? fputs ("th.vfncvt.xu.f.v", asm_out_file)
+               : fputs ("th.vfncvt.f.xu.v", asm_out_file);
+             if (strstr (p, ".rtz") || strstr (p, ".rod"))
+               return p + 17;
+             return p + 13;
+           }
          else
            {
              get_attr_type (current_output_insn) == TYPE_VFNCVTFTOI
-                          ? fputs ("th.vfncvt.x.f.v", asm_out_file)
-                          : fputs ("th.vfncvt.f.x.v", asm_out_file);
-             return p+12;
+               ? fputs ("th.vfncvt.x.f.v", asm_out_file)
+               : fputs ("th.vfncvt.f.x.v", asm_out_file);
+             if (strstr (p, ".rtz") || strstr (p, ".rod"))
+               return p + 16;
+             return p + 12;
            }
        }
 
       if (get_attr_type (current_output_insn) == TYPE_VFNCVTFTOF)
        {
          fputs ("th.vfncvt.f.f.v", asm_out_file);
-         return p+12;
+         if (strstr (p, ".rtz") || strstr (p, ".rod"))
+           return p + 16;
+         return p + 12;
        }
 
       if (get_attr_type (current_output_insn) == TYPE_VFREDU
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr125395.c 
b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr125395.c
new file mode 100644
index 000000000000..5d160a22e3cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr125395.c
@@ -0,0 +1,26 @@
+/* { dg-do assemble } */
+/* { dg-options "-march=rv32gc_xtheadvector -mabi=ilp32d -O2 -save-temps" { 
target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadvector -mabi=lp64d -O2 -save-temps" { 
target { rv64 } } } */
+
+#include "riscv_vector.h"
+
+/* Test that static rounding modes do not cause string splicing in 
th_asm_output_opcode. */
+
+vint32m1_t test_vfncvt_ftoi(vfloat64m2_t src, size_t vl) {
+  return __riscv_vfncvt_rtz_x_f_w_i32m1(src, vl);
+}
+
+vfloat32m1_t test_vfncvt_ftof(vfloat64m2_t src, size_t vl) {
+  return __riscv_vfncvt_rod_f_f_w_f32m1(src, vl);
+}
+
+vint64m4_t test_vfwcvt_ftoi(vfloat32m2_t src, size_t vl) {
+  return __riscv_vfwcvt_rtz_x_f_v_i64m4(src, vl);
+}
+
+/* { dg-final { scan-assembler-not "\\.rtz" } } */
+/* { dg-final { scan-assembler-not "\\.rod" } } */
+/* { dg-final { scan-assembler-not "th\\.vfncvt\\..*\\.w" } } */
+/* { dg-final { scan-assembler-times "th\\.vfncvt\\.x\\.f\\.v\\s+" 1 } } */
+/* { dg-final { scan-assembler-times "th\\.vfncvt\\.f\\.f\\.v\\s+" 1 } } */
+/* { dg-final { scan-assembler-times "th\\.vfwcvt\\.x\\.f\\.v\\s+" 1 } } */

Reply via email to