2017-12-24 04:02:26 +08:00
|
|
|
; RUN: opt < %s -callsite-splitting -S | FileCheck %s
|
|
|
|
; RUN: opt < %s -passes='function(callsite-splitting)' -S | FileCheck %s
|
|
|
|
|
|
|
|
; CHECK-LABEL: @test_simple
|
|
|
|
; CHECK-LABEL: Header:
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK-NEXT: br i1 undef, label %Header.split
|
|
|
|
; CHECK-LABEL: Header.split:
|
2018-02-13 22:48:39 +08:00
|
|
|
; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 %p)
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK-LABEL: TBB:
|
|
|
|
; CHECK: br i1 %cmp, label %TBB.split
|
|
|
|
; CHECK-LABEL: TBB.split:
|
2017-12-24 04:02:26 +08:00
|
|
|
; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 %v, i32 %p)
|
|
|
|
; CHECK-LABEL: Tail
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB.split ]
|
2017-12-24 04:02:26 +08:00
|
|
|
; CHECK: ret i32 %[[MERGED]]
|
|
|
|
define i32 @test_simple(i32* %a, i32 %v, i32 %p) {
|
|
|
|
Header:
|
|
|
|
br i1 undef, label %Tail, label %End
|
|
|
|
|
|
|
|
TBB:
|
|
|
|
%cmp = icmp eq i32* %a, null
|
|
|
|
br i1 %cmp, label %Tail, label %End
|
|
|
|
|
|
|
|
Tail:
|
|
|
|
%r = call i32 @callee(i32* %a, i32 %v, i32 %p)
|
|
|
|
ret i32 %r
|
|
|
|
|
|
|
|
End:
|
|
|
|
ret i32 %v
|
|
|
|
}
|
|
|
|
|
|
|
|
; CHECK-LABEL: @test_eq_eq_eq_untaken
|
|
|
|
; CHECK-LABEL: Header:
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK: br i1 %tobool1, label %TBB1, label %Header.split
|
|
|
|
; CHECK-LABEL: Header.split:
|
2018-02-13 22:48:39 +08:00
|
|
|
; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 %p)
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK-LABEL: TBB2:
|
|
|
|
; CHECK: br i1 %cmp2, label %TBB2.split, label %End
|
|
|
|
; CHECK-LABEL: TBB2.split:
|
2017-12-24 04:02:26 +08:00
|
|
|
; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 1, i32 99)
|
|
|
|
; CHECK-LABEL: Tail
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB2.split ]
|
2017-12-24 04:02:26 +08:00
|
|
|
; CHECK: ret i32 %[[MERGED]]
|
|
|
|
define i32 @test_eq_eq_eq_untaken2(i32* %a, i32 %v, i32 %p) {
|
|
|
|
Header:
|
|
|
|
%tobool1 = icmp eq i32* %a, null
|
|
|
|
br i1 %tobool1, label %TBB1, label %Tail
|
|
|
|
|
|
|
|
TBB1:
|
|
|
|
%cmp1 = icmp eq i32 %v, 1
|
|
|
|
br i1 %cmp1, label %TBB2, label %End
|
|
|
|
|
|
|
|
TBB2:
|
|
|
|
%cmp2 = icmp eq i32 %p, 99
|
|
|
|
br i1 %cmp2, label %Tail, label %End
|
|
|
|
|
|
|
|
Tail:
|
|
|
|
%r = call i32 @callee(i32* %a, i32 %v, i32 %p)
|
|
|
|
ret i32 %r
|
|
|
|
|
|
|
|
End:
|
|
|
|
ret i32 %v
|
|
|
|
}
|
|
|
|
|
|
|
|
; CHECK-LABEL: @test_eq_ne_eq_untaken
|
|
|
|
; CHECK-LABEL: Header:
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK: br i1 %tobool1, label %TBB1, label %Header.split
|
|
|
|
; CHECK-LABEL: Header.split:
|
2018-02-13 22:48:39 +08:00
|
|
|
; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 %p)
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK-LABEL: TBB2:
|
|
|
|
; CHECK: br i1 %cmp2, label %TBB2.split, label %End
|
|
|
|
; CHECK-LABEL: TBB2.split:
|
2017-12-24 04:02:26 +08:00
|
|
|
; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 %v, i32 99)
|
|
|
|
; CHECK-LABEL: Tail
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB2.split ]
|
2017-12-24 04:02:26 +08:00
|
|
|
; CHECK: ret i32 %[[MERGED]]
|
|
|
|
define i32 @test_eq_ne_eq_untaken(i32* %a, i32 %v, i32 %p) {
|
|
|
|
Header:
|
|
|
|
%tobool1 = icmp eq i32* %a, null
|
|
|
|
br i1 %tobool1, label %TBB1, label %Tail
|
|
|
|
|
|
|
|
TBB1:
|
|
|
|
%cmp1 = icmp ne i32 %v, 1
|
|
|
|
br i1 %cmp1, label %TBB2, label %End
|
|
|
|
|
|
|
|
TBB2:
|
|
|
|
%cmp2 = icmp eq i32 %p, 99
|
|
|
|
br i1 %cmp2, label %Tail, label %End
|
|
|
|
|
|
|
|
Tail:
|
|
|
|
%r = call i32 @callee(i32* %a, i32 %v, i32 %p)
|
|
|
|
ret i32 %r
|
|
|
|
|
|
|
|
End:
|
|
|
|
ret i32 %v
|
|
|
|
}
|
|
|
|
|
|
|
|
; CHECK-LABEL: @test_header_header2_tbb
|
|
|
|
; CHECK: Header2:
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK:br i1 %tobool2, label %Header2.split, label %TBB1
|
|
|
|
; CHECK-LABEL: Header2.split:
|
2018-02-13 22:48:39 +08:00
|
|
|
; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 10)
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK-LABEL: TBB2:
|
|
|
|
; CHECK: br i1 %cmp2, label %TBB2.split, label %End
|
|
|
|
; CHECK-LABEL: TBB2.split:
|
2017-12-24 04:02:26 +08:00
|
|
|
; NOTE: CallSiteSplitting cannot infer that %a is null here, as it currently
|
|
|
|
; only supports recording conditions along a single predecessor path.
|
|
|
|
; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 1, i32 99)
|
|
|
|
; CHECK-LABEL: Tail
|
2018-02-14 21:59:12 +08:00
|
|
|
; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header2.split ], [ %[[CALL2]], %TBB2.split ]
|
2017-12-24 04:02:26 +08:00
|
|
|
; CHECK: ret i32 %[[MERGED]]
|
|
|
|
define i32 @test_header_header2_tbb(i32* %a, i32 %v, i32 %p) {
|
|
|
|
Header:
|
|
|
|
%tobool1 = icmp eq i32* %a, null
|
|
|
|
br i1 %tobool1, label %TBB1, label %Header2
|
|
|
|
|
|
|
|
Header2:
|
|
|
|
%tobool2 = icmp eq i32 %p, 10
|
|
|
|
br i1 %tobool2, label %Tail, label %TBB1
|
|
|
|
|
|
|
|
TBB1:
|
|
|
|
%cmp1 = icmp eq i32 %v, 1
|
|
|
|
br i1 %cmp1, label %TBB2, label %End
|
|
|
|
|
|
|
|
TBB2:
|
|
|
|
%cmp2 = icmp eq i32 %p, 99
|
|
|
|
br i1 %cmp2, label %Tail, label %End
|
|
|
|
|
|
|
|
Tail:
|
|
|
|
%r = call i32 @callee(i32* %a, i32 %v, i32 %p)
|
|
|
|
ret i32 %r
|
|
|
|
|
|
|
|
End:
|
|
|
|
ret i32 %v
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @callee(i32* %a, i32 %v, i32 %p) {
|
|
|
|
ret i32 10
|
|
|
|
}
|