https://gcc.gnu.org/g:2ec5082dd24cef5149ba645ee88a9acd8b4c290a
commit r16-727-g2ec5082dd24cef5149ba645ee88a9acd8b4c290a Author: Jennifer Schmitz <jschm...@nvidia.com> Date: Thu May 15 07:16:15 2025 -0700 regcprop: Return from copy_value for unordered modes The ICE in PR120276 resulted from a comparison of VNx4QI and V8QI using partial_subreg_p in the function copy_value during the RTL pass regcprop, failing the assertion in inline bool partial_subreg_p (machine_mode outermode, machine_mode innermode) { /* Modes involved in a subreg must be ordered. In particular, we must always know at compile time whether the subreg is paradoxical. */ poly_int64 outer_prec = GET_MODE_PRECISION (outermode); poly_int64 inner_prec = GET_MODE_PRECISION (innermode); gcc_checking_assert (ordered_p (outer_prec, inner_prec)); return maybe_lt (outer_prec, inner_prec); } Returning from the function if the modes are not ordered before reaching the call to partial_subreg_p resolves the ICE and passes bootstrap and testing without regression. OK for mainline? Signed-off-by: Jennifer Schmitz <jschm...@nvidia.com> gcc/ PR middle-end/120276 * regcprop.cc (copy_value): Return in case of unordered modes. gcc/testsuite/ PR middle-end/120276 * gcc.dg/torture/pr120276.c: New test. Diff: --- gcc/regcprop.cc | 4 ++++ gcc/testsuite/gcc.dg/torture/pr120276.c | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/gcc/regcprop.cc b/gcc/regcprop.cc index 4fa1305526cc..98ab3f77e835 100644 --- a/gcc/regcprop.cc +++ b/gcc/regcprop.cc @@ -332,6 +332,10 @@ copy_value (rtx dest, rtx src, struct value_data *vd) if (vd->e[sr].mode == VOIDmode) set_value_regno (sr, vd->e[dr].mode, vd); + else if (!ordered_p (GET_MODE_PRECISION (vd->e[sr].mode), + GET_MODE_PRECISION (GET_MODE (src)))) + return; + /* If we are narrowing the input to a smaller number of hard regs, and it is in big endian, we are really extracting a high part. Since we generally associate a low part of a value with the value itself, diff --git a/gcc/testsuite/gcc.dg/torture/pr120276.c b/gcc/testsuite/gcc.dg/torture/pr120276.c new file mode 100644 index 000000000000..9717a7103e5e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr120276.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=armv8.2-a+sve" { target aarch64*-*-* } } */ + +int a; +char b[1]; +int c[18]; +void d(char *); +void e() { + int f; + char *g; + a = 0; + for (; a < 18; a++) { + int h = f = 0; + for (; f < 4; f++) { + g[a * 4 + f] = c[a] >> h; + h += 8; + } + } + d(b); +} \ No newline at end of file