Generating control flow with multiple return destinations

I’m currently trying to build in LLVM support for a feature in my research which causes certain function calls to have multiple possible return destinations. While I can make it work in C with handwritten asm-goto, that causes some significant performance issues due to poor register allocation. I’ve been looking at a couple options to translate this behavior into LLVM IR.

If I understand correctly, even if CallBr worked with non-asm-goto calls, the returned value is only visible in the fallthrough case, not in any of the indirect branches.

Similarly, using InvokeInst with some creative management of the landingpad would give the desired control flow, but the return values aren’t valid.

Is there any other way I could communicate through the IR that the function call can have multiple possible return destinations?

See also [RFC] Syncing Asm Goto with Outputs with GCC , which would lift the return value restrictions on callbr. You can always get around the issues with “return values” by just returning values in memory, though.

You can also always just emit a switch on the return value of a function to emulate “multiple destinations”, although that might not have the performance characteristics you want.

1 Like

It looks like I may need to return values in memory until that is implemented then. Does moving away from labels as data mean that it wouldn’t be possible to return the address of the label anymore with the && functionality?

Edit:
Nevermind, this in the github comments answers that

Also, there is one undesirable side effect where address of label would no longer refer to the same label as the asm goto IIRC. But I’d say support for outputs along all edges is probably more worthwhile than such a minute detail.