Relooper goes the other direction though. We don't need to produce high-level control flow. For a transpilation-to-Zig use case the algorithm can be extremely dumb. Naively translate every loop (or any other control flow containing nontrivial internal gotos) into a labeled switch, then partition the bodies at each goto statement, making a new label for each such location.
The only thing you're really losing is that the goto is bounded by an enclosing function, but that's also the case in C, C++ and other languages written by non-masochists. From a developer ergonomics perspective you _might_ want a proper goto instead of having to rely on a clunky general-purpose transformation as described above (though I've yet to see that use case), but from a transpilation perspective it's extremely easy to just treat labeled switch as a bunch of gotos, replace other control flow with gotos, and lower an entire function into something that compiles optimally.