Following some recent discussions, this changes the representation of callbrs in IR. The current blockaddress arguments are replaced with ! label constraints that refer directly to callbr indirect destinations:
; Before: %res = callbr i8* asm "# $0\0A\09# ${2:l}", "=r,0,i,~{dirflag},~{fpsr},~{flags}"(i8* %0, i8* blockaddress(@test8, %foo)) to label %asm.fallthrough [label %foo] ; After: %res = callbr i8* asm "# $0\0A\09# ${2:l}", "=r,0,!i,~{dirflag},~{fpsr},~{flags}"(i8* %0) to label %asm.fallthrough [label %foo]
The benefit of this is that we can easily update the successors of a callbr, without having to worry about also updating blockaddress references. This should allow us to remove some limitations:
- Allow unrolling/peeling/rotation of callbr, or any other clone-based optimizations (https://github.com/llvm/llvm-project/issues/41834)
- Allow duplicate successors (https://github.com/llvm/llvm-project/issues/45248)
This is just the IR representation change though, I will follow up with patches to remove limtations in various transformation passes that are no longer needed.
I'd put if (isa<InlineAsm>(Callee)) around this whole upgrade section. While we only currently support inlineasm calee, the reader code is otherwise agnostic to the type of the callee, and it seems better to preserve that.
Also, this upgrade code seems potentially problematic -- a user could write the C code:
int foo() { label: asm goto("" : : "r"(&&label) : : label2); return 1; label2: return 2; }
which turns into
and this would error out on it.
(I'm not sure _why_ a user would write that, but we shouldn't fail in the bitcode reader if they do!)
I think it needs to:
(And of course, a test-case. Are there any test-cases for this code? I didn't see one.)