[to-be-committed,RISC-V,PR,target/118146] Fix ICE for unsupported modes

Message ID b0fb1b92-65c1-4fdd-aa60-e53d842b4552@ventanamicro.com
State Committed
Commit 9576353454e6c2a20a9742e2f29f17830766cd8a
Headers
Series [to-be-committed,RISC-V,PR,target/118146] Fix ICE for unsupported modes |

Checks

Context Check Description
rivoscibot/toolchain-ci-rivos-lint success Lint passed
rivoscibot/toolchain-ci-rivos-apply-patch success Patch applied
rivoscibot/toolchain-ci-rivos-build--newlib-rv64gcv-lp64d-multilib success Build passed
rivoscibot/toolchain-ci-rivos-build--linux-rv64gc_zba_zbb_zbc_zbs-lp64d-multilib success Build passed
rivoscibot/toolchain-ci-rivos-build--linux-rv64gcv-lp64d-multilib success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
rivoscibot/toolchain-ci-rivos-test success Testing passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-aarch64-bootstrap success Build passed
linaro-tcwg-bot/tcwg_simplebootstrap_build--master-arm-bootstrap fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 fail Patch failed to apply

Commit Message

Jeffrey Law Feb. 9, 2025, 1:42 a.m. UTC
  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.

Jeff
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.
  

Patch

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 819e1538741..6e14126e3a4 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -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
index 00000000000..f3a7c4d96d8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr118146-1.c
@@ -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
index 00000000000..e7a5f39fa86
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr118146-2.c
@@ -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);
+}