[RISC-V][PR target/118146] Fix ICE for unsupported modes

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.
This commit is contained in:
Jeff Law 2025-02-08 22:07:16 -07:00
parent 58856a6ec5
commit 9576353454
3 changed files with 36 additions and 4 deletions

View 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

View file

@ -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;
}

View file

@ -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);
}