]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[RISC-V][PR target/118146] Fix ICE for unsupported modes
authorJeff Law <jlaw@ventanamicro.com>
Sun, 9 Feb 2025 05:07:16 +0000 (22:07 -0700)
committerJeff Law <jlaw@ventanamicro.com>
Sun, 9 Feb 2025 05:09:18 +0000 (22:09 -0700)
There's some special case code in the risc-v move expander to try and optimize
cases where the source is a subreg of a vector and the destination is a scalar
mode.

The code works fine except when we have no support for the given mode. ie HF or
BF when those extensions aren't enabled.  We'll end up tripping an assert in
that case when we should have just let standard expansion do its thing.

Tested in my system for rv32 and rv64, but I'll wait for the pre-commit tester
to render a verdict before moving forward.

PR target/118146
gcc/
* config/riscv/riscv.cc (riscv_legitimize_move): Handle subreg
of vector source better to avoid ICE.

gcc/testsuite
* gcc.target/riscv/pr118146-1.c: New test.
* gcc.target/riscv/pr118146-2.c: New test.

gcc/config/riscv/riscv.cc
gcc/testsuite/gcc.target/riscv/pr118146-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/pr118146-2.c [new file with mode: 0644]

index 819e1538741734f0c0e234f6b9abfaee5b7b019c..6e14126e3a4a82a464d97858861ceba45421c2b9 100644 (file)
@@ -3587,6 +3587,9 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
          nunits = nunits * 2;
        }
 
+      /* This test can fail if (for example) we want a HF and Z[v]fh is
+        not enabled.  In that case we just want to let the standard
+        expansion path run.  */
       if (riscv_vector::get_vector_mode (smode, nunits).exists (&vmode))
        {
          rtx v = gen_lowpart (vmode, SUBREG_REG (src));
@@ -3636,12 +3639,10 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
            emit_move_insn (dest, gen_lowpart (GET_MODE (dest), int_reg));
          else
            emit_move_insn (dest, int_reg);
+         return true;
        }
-      else
-       gcc_unreachable ();
-
-      return true;
     }
+
   /* Expand
        (set (reg:QI target) (mem:QI (address)))
      to
diff --git a/gcc/testsuite/gcc.target/riscv/pr118146-1.c b/gcc/testsuite/gcc.target/riscv/pr118146-1.c
new file mode 100644 (file)
index 0000000..f3a7c4d
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d  -O" { target { rv64 } } } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -O" { target { rv32 } } } */
+
+
+
+typedef __attribute__((__vector_size__(sizeof(_Float16)))) short V;
+_Float16 f;
+
+void
+foo(V v)
+{
+  f -= *(_Float16 *)&v;
+}
diff --git a/gcc/testsuite/gcc.target/riscv/pr118146-2.c b/gcc/testsuite/gcc.target/riscv/pr118146-2.c
new file mode 100644 (file)
index 0000000..a37158a
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -std=gnu23 -O2" { target { rv64 } } } */
+/* { dg-options "-march=rv32gcv -mabi=ilp32d -std=gnu23 -O2" { target { rv32 } } } */
+
+long print_halffloat_j;
+int *print_halffloat_block;
+void ftoastr(float);
+enum { BFLOATING_POINTvoid } print_halffloat() {
+  union {
+    _Float16 x;
+    char b[];
+  } u;
+  print_halffloat_j = 0;
+  for (; print_halffloat_j < sizeof(_Float16); print_halffloat_j++)
+    u.b[print_halffloat_j] = print_halffloat_block[print_halffloat_j];
+  ftoastr(u.x);
+}