1; RUN: opt < %s -callsite-splitting -S | FileCheck %s
2; RUN: opt < %s  -passes='function(callsite-splitting)' -S | FileCheck %s
3
4; CHECK-LABEL: @test_simple
5; CHECK-LABEL: Header:
6; CHECK-NEXT: br i1 undef, label %Header.split
7; CHECK-LABEL: Header.split:
8; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 %p)
9; CHECK-LABEL: TBB:
10; CHECK: br i1 %cmp, label %TBB.split
11; CHECK-LABEL: TBB.split:
12; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 %v, i32 %p)
13; CHECK-LABEL: Tail
14; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB.split ]
15; CHECK: ret i32 %[[MERGED]]
16define i32 @test_simple(i32* %a, i32 %v, i32 %p) {
17Header:
18  br i1 undef, label %Tail, label %End
19
20TBB:
21  %cmp = icmp eq i32* %a, null
22  br i1 %cmp, label %Tail, label %End
23
24Tail:
25  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
26  ret i32 %r
27
28End:
29  ret i32 %v
30}
31
32; CHECK-LABEL: @test_eq_eq_eq_untaken
33; CHECK-LABEL: Header:
34; CHECK: br i1 %tobool1, label %TBB1, label %Header.split
35; CHECK-LABEL: Header.split:
36; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 %p)
37; CHECK-LABEL: TBB2:
38; CHECK: br i1 %cmp2, label %TBB2.split, label %End
39; CHECK-LABEL: TBB2.split:
40; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 1, i32 99)
41; CHECK-LABEL: Tail
42; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB2.split ]
43; CHECK: ret i32 %[[MERGED]]
44define i32 @test_eq_eq_eq_untaken2(i32* %a, i32 %v, i32 %p) {
45Header:
46  %tobool1 = icmp eq i32* %a, null
47  br i1 %tobool1, label %TBB1, label %Tail
48
49TBB1:
50  %cmp1 = icmp eq i32 %v, 1
51  br i1 %cmp1, label %TBB2, label %End
52
53TBB2:
54  %cmp2 = icmp eq i32 %p, 99
55  br i1 %cmp2, label %Tail, label %End
56
57Tail:
58  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
59  ret i32 %r
60
61End:
62  ret i32 %v
63}
64
65; CHECK-LABEL: @test_eq_ne_eq_untaken
66; CHECK-LABEL: Header:
67; CHECK: br i1 %tobool1, label %TBB1, label %Header.split
68; CHECK-LABEL: Header.split:
69; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 %p)
70; CHECK-LABEL: TBB2:
71; CHECK: br i1 %cmp2, label %TBB2.split, label %End
72; CHECK-LABEL: TBB2.split:
73; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 %v, i32 99)
74; CHECK-LABEL: Tail
75; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB2.split ]
76; CHECK: ret i32 %[[MERGED]]
77define i32 @test_eq_ne_eq_untaken(i32* %a, i32 %v, i32 %p) {
78Header:
79  %tobool1 = icmp eq i32* %a, null
80  br i1 %tobool1, label %TBB1, label %Tail
81
82TBB1:
83  %cmp1 = icmp ne i32 %v, 1
84  br i1 %cmp1, label %TBB2, label %End
85
86TBB2:
87  %cmp2 = icmp eq i32 %p, 99
88  br i1 %cmp2, label %Tail, label %End
89
90Tail:
91  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
92  ret i32 %r
93
94End:
95  ret i32 %v
96}
97
98; CHECK-LABEL: @test_header_header2_tbb
99; CHECK: Header2:
100; CHECK:br i1 %tobool2, label %Header2.split, label %TBB1
101; CHECK-LABEL: Header2.split:
102; CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 10)
103; CHECK-LABEL: TBB2:
104; CHECK: br i1 %cmp2, label %TBB2.split, label %End
105; CHECK-LABEL: TBB2.split:
106; NOTE: CallSiteSplitting cannot infer that %a is null here, as it currently
107;       only supports recording conditions along a single predecessor path.
108; CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 1, i32 99)
109; CHECK-LABEL: Tail
110; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header2.split ], [ %[[CALL2]], %TBB2.split ]
111; CHECK: ret i32 %[[MERGED]]
112define i32 @test_header_header2_tbb(i32* %a, i32 %v, i32 %p) {
113Header:
114  %tobool1 = icmp eq i32* %a, null
115  br i1 %tobool1, label %TBB1, label %Header2
116
117Header2:
118  %tobool2 = icmp eq i32 %p, 10
119  br i1 %tobool2, label %Tail, label %TBB1
120
121TBB1:
122  %cmp1 = icmp eq i32 %v, 1
123  br i1 %cmp1, label %TBB2, label %End
124
125TBB2:
126  %cmp2 = icmp eq i32 %p, 99
127  br i1 %cmp2, label %Tail, label %End
128
129Tail:
130  %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
131  ret i32 %r
132
133End:
134  ret i32 %v
135}
136
137define i32 @callee(i32* %a, i32 %v, i32 %p) {
138  ret i32 10
139}
140