https://gcc.gnu.org/g:1bede52d8c4ba434a8f4786f84f85922cc0c6152
commit r16-6940-g1bede52d8c4ba434a8f4786f84f85922cc0c6152 Author: Jeff Law <[email protected]> Date: Tue Jan 20 15:03:28 2026 -0700 [PR rtl-optimization/123380] Avoid creating bogus SUBREG in combine 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. 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: --- gcc/combine.cc | 3 ++- gcc/testsuite/gcc.target/riscv/pr123380.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) 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; +}
