Thanks for the changes. I noticed that when `hs_control_point_phase` is synthesized in `control_point_normalizer_emit_hs_input()` no `ret` instruction is added at the end, which then results, after CF normalization, in a unterminated `label`. I guess in this case we should either avoid adding the `label` op, or terminate it with `ret`. I don't think I have any preference between the two.
Also, I don't like the idea of having `dcl_*` declarations inside blocks. To me they should be regarded as metadata rather than instructions. Notice that (I think) the first block can still be the target of a back edge, so those declarations could be "executed" more than once, and it's not completely clear to me what that would mean. If this is so the SPIR-V backend has a block to stash code into while it's processing the declarations, than I think it should be on the backend to address this requirement in some other way (for example generating an additional synthetic block at the beginning).