The old assembly-like languages (ARB_fragment_program, NV_fragment_program*, et al.) did indeed not have branches, only selection and conditional termination, because that was the extent of the capabilities of the underlying hardware. (I understand the execution on modern fragment processors can’t actually diverge within a single batch, either, so they execute both branches and select afterwards, but they are at least capable enough not to do that if the branch went the same way everywhere. But it’s been a long time since I’ve had a state-of-the-art GPU to play with.)