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 "", "=r,r,i"(i8* %x, i8* blockaddress(@test8, %foo))
to label %asm.fallthrough [label %foo]
; After:
%res = callbr i8* asm "", "=r,r,!i"(i8* %x)
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.
Differential Revision: https://reviews.llvm.org/D129288
29 lines
646 B
LLVM
29 lines
646 B
LLVM
; RUN: rm -f %t.ll
|
|
; RUN: cat %s | sed -e 's/ 0, %2 / 1, %2 /' > %t.ll
|
|
; RUN: not llvm-diff %s %t.ll 2>&1 | FileCheck %s
|
|
|
|
; CHECK: in function foo:
|
|
; CHECK-NEXT: in block %6 / %6:
|
|
; CHECK-NEXT: > %7 = phi i32 [ 1, %2 ], [ -1, %1 ]
|
|
; CHECK-NEXT: > ret i32 %7
|
|
; CHECK-NEXT: < %7 = phi i32 [ 0, %2 ], [ -1, %1 ]
|
|
; CHECK-NEXT: < ret i32 %7
|
|
define i32 @foo(i32 %0) #0 {
|
|
callbr void asm sideeffect "", "!i,~{dirflag},~{fpsr},~{flags}"()
|
|
to label %2 [label %6]
|
|
|
|
2:
|
|
%3 = icmp eq i32 %0, 0
|
|
br i1 %3, label %6, label %4
|
|
|
|
4:
|
|
br label %5
|
|
|
|
5:
|
|
br label %5
|
|
|
|
6:
|
|
%7 = phi i32 [ 0, %2 ], [ -1, %1 ]
|
|
ret i32 %7
|
|
}
|