In this issue we try to call gen_rtx_SUBREG with arguments that will
trigger an assertion failure. In particular we're trying to create a
paradoxical subreg of an HFmode object where the paradoxical is in
DImode. That's obviously a change in size. validate_subreg returns
false for that case, thus triggering the assertion.
Like other cases in combine.cc and elsewhere we can check
validate_subreg before we call gen_rtx_SUBREG and if validate_subreg
returns false, we can return a safe value. So that's all this patch does.
Bootstrapped and regression tested on x86_64, also regression tested on
riscv{32,64}-elf. Pushing to the trunk.
Jeff
PR rtl-optimization/123380
gcc/
* combine.cc (gen_lowpart_for_combine): Don't try to create a
paradoxical SUBREG if it's going to be rejected by validate_subreg.
gcc/testsuite/
* gcc.target/riscv/pr123380.c: New test.
diff --git a/gcc/combine.cc b/gcc/combine.cc
index 09e24347b342..573ed716ad63 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -11856,7 +11856,8 @@ gen_lowpart_for_combine (machine_mode omode, rtx x)
/* If we want to refer to something bigger than the original memref,
generate a paradoxical subreg instead. That will force a reload
of the original memref X. */
- if (paradoxical_subreg_p (omode, imode))
+ if (paradoxical_subreg_p (omode, imode)
+ && validate_subreg (omode, GET_MODE (x), x, 0))
return gen_rtx_SUBREG (omode, x, 0);
poly_int64 offset = byte_lowpart_offset (omode, imode);
diff --git a/gcc/testsuite/gcc.target/riscv/pr123380.c
b/gcc/testsuite/gcc.target/riscv/pr123380.c
new file mode 100644
index 000000000000..1cbbc8436156
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr123380.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O2" { target { rv64 } } } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d -O2" { target { rv32 } } } */
+
+void *p;
+int d;
+char c;
+
+void
+foo (_Float16 *fp)
+{
+ _Float16 f = *fp;
+ do {
+ __builtin_strcat (p, 0);
+ __builtin_memmove (1 + (char *) &f, &f, 1);
+ } while (d);
+ c = f;
+}