https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120447
--- Comment #9 from Richard Sandiford <rsandifo at gcc dot gnu.org> --- I think the ICE is caused by a bad interaction between the AArch64 optimisation and r16-718, which added more checks for paradoxical subregs. The testcase works if r16-718 is reverted. I think the should go with something like this: diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc index 3f453cda67e..df7fa912ebb 100644 --- a/gcc/emit-rtl.cc +++ b/gcc/emit-rtl.cc @@ -998,10 +998,11 @@ validate_subreg (machine_mode omode, machine_mode imode, && known_le (osize, isize)) return false; - /* The outer size must be ordered wrt the register size, otherwise - we wouldn't know at compile time how many registers the outer - mode occupies. */ - if (!ordered_p (osize, regsize)) + /* If the inner size is greater than the register size, the inner value + is split into blocks of size REGSIZE. The outer size must then be + ordered wrt the register size, otherwise we wouldn't know at compile + time how many blocks the outer mode occupies. */ + if (maybe_ge (isize, regsize) && !ordered_p (osize, regsize)) return false; /* For normal pseudo registers, we want most of the same checks. Namely: Mind if I take the PR to test that?