]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] RISC-V: Fix static rounding mode splicing for xtheadvector [PR125395]
authorJRobinNTA <johnrobin044@gmail.com>
Tue, 9 Jun 2026 12:58:14 +0000 (06:58 -0600)
committerJeff Law <jeffrey.law@oss.qualcomm.com>
Tue, 9 Jun 2026 12:58:52 +0000 (06:58 -0600)
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.

gcc/config/riscv/thead.cc
gcc/testsuite/gcc.target/riscv/rvv/xtheadvector/pr125395.c [new file with mode: 0644]

index b16b2c443bed0a5466834f5849cd590cf3424c57..acf661f83e739bb47382f35480551e0cff21fc1d 100644 (file)
@@ -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 (file)
index 0000000..5d160a2
--- /dev/null
@@ -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 } } */