https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122448
--- Comment #9 from Robin Dapp <rdapp at gcc dot gnu.org> ---
The simple patch wasn't sufficient.
The issue is a gap in the current implementation:
In the hoisting ("lift up") phase we hoist vsetvls as far up as possible but
without considering that this could clobber the hard reg used as vsetvl
destination in other branches. I guess it's just luck that we didn't hit
this earlier.
AFAICT each time we hoist a vsetvl into a basic block we must ensure that
vsetvl's destination register is not used in any successors but the one we're
hoisting from. At first sight the live_in data of the successors appears
sufficient but that's actually too conservative. We can still have uses in
compatible vsetvls in those other successors and those are not a problem as
we fuse or hoist them separately. At this point it becomes a new dataflow
problem :/
The whole hoisting phase being speculative makes things more complicated.
It feels like this all should be doable in a more elegant way than the many
special cases we have in place right now. But obviously not before stage 1.