diff options
author | Jennifer Schmitz <jschmitz@nvidia.com> | 2025-05-15 07:16:15 -0700 |
---|---|---|
committer | Jennifer Schmitz <jschmitz@nvidia.com> | 2025-05-19 08:18:56 +0200 |
commit | 2ec5082dd24cef5149ba645ee88a9acd8b4c290a (patch) | |
tree | 74b945b5f2d36dbbb1b9f8feb6eb228831bf7202 /gcc | |
parent | c9eb473fb9946f642506d24f4131d7c83855fd78 (diff) | |
download | gcc-2ec5082dd24cef5149ba645ee88a9acd8b4c290a.zip gcc-2ec5082dd24cef5149ba645ee88a9acd8b4c290a.tar.gz gcc-2ec5082dd24cef5149ba645ee88a9acd8b4c290a.tar.bz2 |
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 <jschmitz@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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/regcprop.cc | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr120276.c | 20 |
2 files changed, 24 insertions, 0 deletions
diff --git a/gcc/regcprop.cc b/gcc/regcprop.cc index 4fa1305..98ab3f7 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 0000000..9717a71 --- /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 |