[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / Transforms / CallSiteSplitting / callsite-instructions-before-call.ll
blob067022cd38a32777cba0d8199522bc182ea68231
1 ; RUN: opt -S -callsite-splitting < %s | FileCheck --check-prefix=CHECK %s
2 ; RUN: opt -S -callsite-splitting -callsite-splitting-duplication-threshold=0 < %s | FileCheck --check-prefix=NODUP %s
4 ; Instructions before a call that will be pushed to its predecessors
5 ; with uses after the callsite, must be patched up as PHI nodes in
6 ; the join block.
7 define i32* @test_split_branch_phi(i32* %ptrarg, i32 %i) {
8 Header:
9   %tobool = icmp ne i32* %ptrarg, null
10   br i1 %tobool, label %TBB, label %CallSite
12 TBB:                                    ; preds = %Header
13   %arrayidx = getelementptr inbounds i32, i32* %ptrarg, i64 42
14   %0 = load i32, i32* %arrayidx, align 4
15   %tobool1 = icmp ne i32 %0, 0
16   br i1 %tobool1, label %CallSite, label %End
18 CallSite:                                          ; preds = %TBB, %Header
19   %somepointer = getelementptr i32, i32* %ptrarg, i64 18
20   call void @bar(i32* %ptrarg, i32 %i)
21   br label %End
23 End:                                           ; preds = %CallSite, %TBB
24   %somepointerphi = phi i32* [ %somepointer, %CallSite ], [ null, %TBB ]
25   ret i32* %somepointerphi
27 ; NODUP-LABEL: test_split_branch_phi
28 ; NODUP-NOT: split
29 ; CHECK-LABEL: Header.split
30 ; CHECK: %[[V1:somepointer[0-9]+]] = getelementptr i32, i32* %ptrarg, i64 18
31 ; CHECK: call void @bar(i32* null, i32 %i)
32 ; CHECK: br label %CallSite
33 ; CHECK-LABEL: TBB.split:
34 ; CHECK: %[[V2:somepointer[0-9]+]] = getelementptr i32, i32* %ptrarg, i64 18
35 ; CHECK: call void @bar(i32* nonnull %ptrarg, i32 %i)
36 ; CHECK: br label %CallSite
37 ; CHECK: CallSite:
38 ; CHECK: phi i32* [ %[[V1]], %Header.split ], [ %[[V2]], %TBB.split ]
41 define void @split_branch_no_extra_phi(i32* %ptrarg, i32 %i) {
42 Header:
43   %tobool = icmp ne i32* %ptrarg, null
44   br i1 %tobool, label %TBB, label %CallSite
46 TBB:                                    ; preds = %Header
47   %arrayidx = getelementptr inbounds i32, i32* %ptrarg, i64 42
48   %0 = load i32, i32* %arrayidx, align 4
49   %tobool1 = icmp ne i32 %0, 0
50   br i1 %tobool1, label %CallSite, label %End
52 CallSite:                                          ; preds = %TBB, %Header
53   %i.add = add i32 %i, 99
54   call void @bar(i32* %ptrarg, i32 %i.add)
55   br label %End
57 End:                                           ; preds = %CallSite, %TBB
58   ret void
60 ; NODUP-LABEL: split_branch_no_extra_phi
61 ; NODUP-NOT: split
62 ; CHECK-LABEL: split_branch_no_extra_phi
63 ; CHECK-LABEL: Header.split
64 ; CHECK: %[[V1:.+]] = add i32 %i, 99
65 ; CHECK: call void @bar(i32* null, i32 %[[V1]])
66 ; CHECK: br label %CallSite
67 ; CHECK-LABEL: TBB.split:
68 ; CHECK: %[[V2:.+]] = add i32 %i, 99
69 ; CHECK: call void @bar(i32* nonnull %ptrarg, i32 %[[V2]])
70 ; CHECK: br label %CallSite
71 ; CHECK: CallSite:
72 ; CHECK-NOT: phi
75 ; In this test case, the codesize cost of the instructions before the call to
76 ; bar() is equal to the default DuplicationThreshold of 5, because calls are
77 ; more expensive.
78 define void @test_no_split_threshold(i32* %ptrarg, i32 %i) {
79 Header:
80   %tobool = icmp ne i32* %ptrarg, null
81   br i1 %tobool, label %TBB, label %CallSite
83 TBB:                                    ; preds = %Header
84   %arrayidx = getelementptr inbounds i32, i32* %ptrarg, i64 42
85   %0 = load i32, i32* %arrayidx, align 4
86   %tobool1 = icmp ne i32 %0, 0
87   br i1 %tobool1, label %CallSite, label %End
89 CallSite:                                          ; preds = %TBB, %Header
90   %i2 = add i32 %i, 10
91   call void @bari(i32 %i2)
92   call void @bari(i32 %i2)
93   call void @bar(i32* %ptrarg, i32 %i2)
94   br label %End
96 End:                                           ; preds = %CallSite, %TBB
97   ret void
99 ; NODUP-LABEL: test_no_split_threshold
100 ; NODUP-NOT: split
101 ; CHECK-LABEL: test_no_split_threshold
102 ; CHECK-NOT: split
103 ; CHECK-LABEL: CallSite:
104 ; CHECK: call void @bar(i32* %ptrarg, i32 %i2)
106 ; In this test case, the phi node %l in CallSite should be removed, as after
107 ; moving the call to the split blocks we can use the values directly.
108 define void @test_remove_unused_phi(i32* %ptrarg, i32 %i) {
109 Header:
110   %l1 = load i32, i32* undef, align 16
111   %tobool = icmp ne i32* %ptrarg, null
112   br i1 %tobool, label %TBB, label %CallSite
114 TBB:                                    ; preds = %Header
115   %arrayidx = getelementptr inbounds i32, i32* %ptrarg, i64 42
116   %0 = load i32, i32* %arrayidx, align 4
117   %l2 = load i32, i32* undef, align 16
118   %tobool1 = icmp ne i32 %0, 0
119   br i1 %tobool1, label %CallSite, label %End
121 CallSite:                                          ; preds = %TBB, %Header
122   %l = phi i32 [ %l1, %Header ], [ %l2, %TBB ]
123   call void @bar(i32* %ptrarg, i32 %l)
124   br label %End
126 End:                                           ; preds = %CallSite, %TBB
127   ret void
129 ; NODUP-LABEL: test_remove_unused_phi
130 ; NODUP-NOT: split
131 ; CHECK-LABEL: test_remove_unused_phi
132 ; CHECK-LABEL: Header.split
133 ; CHECK: call void @bar(i32* null, i32 %l1)
134 ; CHECK: br label %CallSite
135 ; CHECK-LABEL: TBB.split:
136 ; CHECK: call void @bar(i32* nonnull %ptrarg, i32 %l2)
137 ; CHECK: br label %CallSite
138 ; CHECK-LABEL: CallSite:
139 ; CHECK-NOT: phi
141 ; In this test case, we need to insert a new PHI node in TailBB to combine
142 ; the loads we moved to the predecessors.
143 define void @test_add_new_phi(i32* %ptrarg, i32 %i) {
144 Header:
145   %tobool = icmp ne i32* %ptrarg, null
146   br i1 %tobool, label %TBB, label %CallSite
148 TBB:
149   br i1 undef, label %CallSite, label %End
151 CallSite:
152   %arrayidx112 = getelementptr inbounds i32, i32* undef, i64 1
153   %0 = load i32, i32* %arrayidx112, align 4
154   call void @bar(i32* %ptrarg, i32 %i)
155   %sub = sub nsw i32 %0, undef
156   br label %End
158 End:                                           ; preds = %CallSite, %TBB
159   ret void
161 ; NODUP-LABEL: test_add_new_phi
162 ; NODUP-NOT: split
163 ; CHECK-LABEL: test_add_new_phi
164 ; CHECK-LABEL: Header.split
165 ; CHECK: %[[V1:.+]] = load i32, i32*
166 ; CHECK: call void @bar(i32* null, i32 %i)
167 ; CHECK: br label %CallSite
168 ; CHECK-LABEL: TBB.split:
169 ; CHECK: %[[V2:.+]] = load i32, i32*
170 ; CHECK: call void @bar(i32* nonnull %ptrarg, i32 %i)
171 ; CHECK: br label %CallSite
172 ; CHECK-LABEL: CallSite:
173 ; CHECK-NEXT: %[[V3:.+]] = phi i32 [ %[[V1]], %Header.split ], [ %[[V2]], %TBB.split ]
174 ; CHECK: %sub = sub nsw i32 %[[V3]], undef
176 define i32 @test_firstnophi(i32* %a, i32 %v) {
177 Header:
178   %tobool1 = icmp eq i32* %a, null
179   br i1 %tobool1, label %Tail, label %TBB
181 TBB:
182   %cmp = icmp eq i32 %v, 1
183   br i1 %cmp, label %Tail, label %End
185 Tail:
186   %p = phi i32[1,%Header], [2, %TBB]
187   store i32 %v, i32* %a
188   %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
189   ret i32 %r
191 End:
192   ret i32 %v
194 ; NODUP-LABEL: @test_firstnophi
195 ; NODUP-NOT: split:
196 ; CHECK-LABEL: @test_firstnophi
197 ; CHECK-LABEL: Header.split:
198 ; CHECK-NEXT: store i32 %v, i32* %a
199 ; CHECK-NEXT: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1)
200 ; CHECK-NEXT: br label %Tail
201 ; CHECK-LABEL: TBB.split:
202 ; CHECK-NEXT: store i32 %v, i32* %a
203 ; CHECK-NEXT: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2)
204 ; CHECK-NEXT br label %Tail
205 ; CHECK-LABEL: Tail:
206 ; CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Header.split ], [ %[[CALL2]], %TBB.split ]
207 ; CHECK: ret i32 %[[MERGED]]
208 define i32 @callee(i32* %a, i32 %v, i32 %p) {
209     ret i32 0
212 define void @test_no_remove_used_phi(i32* %ptrarg, i32 %i) {
213 Header:
214   %l1 = load i32, i32* undef, align 16
215   %tobool = icmp ne i32* %ptrarg, null
216   br i1 %tobool, label %TBB, label %CallSite
218 TBB:                                    ; preds = %Header
219   %arrayidx = getelementptr inbounds i32, i32* %ptrarg, i64 42
220   %0 = load i32, i32* %arrayidx, align 4
221   %l2 = load i32, i32* undef, align 16
222   %tobool1 = icmp ne i32 %0, 0
223   br i1 %tobool1, label %CallSite, label %End
225 CallSite:                                          ; preds = %TBB, %Header
226   %l = phi i32 [ %l1, %Header ], [ %l2, %TBB ]
227   call void @bar(i32* %ptrarg, i32 %l)
228   call void @bari(i32 %l)
229   br label %End
231 End:                                           ; preds = %CallSite, %TBB
232   ret void
234 ; NODUP-LABEL: @test_no_remove_used_phi
235 ; NODUP-NOT: split
236 ; CHECK-LABEL: @test_no_remove_used_phi
237 ; CHECK-LABEL: Header.split:
238 ; CHECK: call void @bar(i32* null, i32 %l1)
239 ; CHECK-NEXT: br label %CallSite
240 ; CHECK-LABEL: TBB.split:
241 ; CHECK: call void @bar(i32* nonnull %ptrarg, i32 %l2)
242 ; CHECK-NEXT br label %CallSite
243 ; CHECK-LABEL: CallSite:
244 ; CHECK-NEXT:  %l = phi i32 [ %l1, %Header.split ], [ %l2, %TBB.split ]
245 ; CHECK: call void @bari(i32 %l)
247 define void @bar(i32*, i32) {
248     ret void
251 define  void @bari(i32) {
252     ret void