https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122583
--- Comment #12 from Robin Dapp <rdapp at gcc dot gnu.org> ---
(In reply to Andrew Stubbs from comment #11)
> The problem doesn't reproduce because it wasn't that testcase that was the
> reproducer (doh!).
>
> Testcase gfortran.dg/recursive_alloc_comp_4.f08 still ICEs trying to
> simplify this subreg during the combine pass:
>
> (set (reg:SI 827 [ _295 ])
> (subreg:SI (vec_merge:V4DI (vec_duplicate:V4DI (reg:DI 752 [ SR.134 ]))
> (reg:V4DI 790)
> (const_int 8 [0x8])) 0))
>
> It's fine if I disallow packed alignment. I've not looked deeper at what
> that code is trying to do.
Judging by gcn_can_change_mode_class you explicitly permit scalar subregs of
vector regs:
/* Vector/scalar conversions are only permitted when the scalar mode
is the same or smaller than the inner vector mode. */
if ((VECTOR_MODE_P (from) && !VECTOR_MODE_P (to)
&& GET_MODE_SIZE (to) >= GET_MODE_SIZE (GET_MODE_INNER (from)))
|| (VECTOR_MODE_P (to) && !VECTOR_MODE_P (from)
&& GET_MODE_SIZE (from) >= GET_MODE_SIZE (GET_MODE_INNER (to))))
return false;
I guess what should eventually happen (in reload or so) is a spill of the
vector reg and a load of the SI reg from that address.
To me, at least superficially, it seems that disallowing packed alignment is
just hiding this latent issue. Maybe a bad interaction with another
subreg-related hook? One way or another, if this type of subreg is permitted,
it is bound to appear somewhere.
Where exactly do things go wrong in combine?