[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LoopUnswitch / partial-unswitch-cost.ll
blob7298299047c6105c3e86576cd3b67ec36e78027f
1 ; RUN: opt -loop-unswitch -loop-unswitch-threshold=10 -verify-dom-info -verify-memoryssa -S -enable-new-pm=0 %s | FileCheck %s
3 declare void @clobber()
5 ; Test cases for partial unswitching, where the regular cost-model overestimates
6 ; the cost of unswitching, because it misses the fact that the unswitched paths
7 ; are no-ops.
10 define i32 @no_partial_unswitch_size_too_large_no_mustprogress(i32* %ptr, i32 %N) {
11 ; CHECK-LABEL: @no_partial_unswitch_size_too_large_no_mustprogress
12 ; CHECK-LABEL: entry:
13 ; CHECK-NEXT:   br label %loop.header
15 entry:
16   br label %loop.header
18 loop.header:
19   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
20   %lv = load i32, i32* %ptr
21   %sc = icmp eq i32 %lv, 100
22   br i1 %sc, label %noclobber, label %clobber
24 noclobber:
25   br label %loop.latch
27 clobber:
28   call void @clobber()
29   call void @clobber()
30   call void @clobber()
31   call void @clobber()
32   call void @clobber()
33   call void @clobber()
34   call void @clobber()
35   call void @clobber()
36   call void @clobber()
37   br label %loop.latch
39 loop.latch:
40   %c = icmp ult i32 %iv, %N
41   %iv.next = add i32 %iv, 1
42   br i1 %c, label %loop.header, label %exit
44 exit:
45   ret i32 10
48 define i32 @partial_unswitch_shortcut_mustprogress(i32* %ptr, i32 %N) mustprogress {
49 ; CHECK-LABEL: @partial_unswitch_shortcut_mustprogress
50 ; CHECK-LABEL: entry:
51 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
52 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
53 ; CHECK-NEXT:   br i1 [[C]], label %[[CRIT_TO_EXIT:[a-z._]+]], label %[[CRIT_TO_HEADER:[a-z._]+]]
55 ; CHECK:      [[CRIT_TO_HEADER]]:
56 ; CHECK-NEXT:   br label %loop.header
58 ; CHECK:      [[CRIT_TO_EXIT]]:
59 ; CHECK-NEXT:   br label %exit
61 entry:
62   br label %loop.header
64 loop.header:
65   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
66   %lv = load i32, i32* %ptr
67   %sc = icmp eq i32 %lv, 100
68   br i1 %sc, label %noclobber, label %clobber
70 noclobber:
71   br label %loop.latch
73 clobber:
74   call void @clobber()
75   call void @clobber()
76   call void @clobber()
77   call void @clobber()
78   call void @clobber()
79   call void @clobber()
80   call void @clobber()
81   call void @clobber()
82   call void @clobber()
83   br label %loop.latch
85 loop.latch:
86   %c = icmp ult i32 %iv, %N
87   %iv.next = add i32 %iv, 1
88   br i1 %c, label %loop.header, label %exit
90 exit:
91   ret i32 10
94 define i32 @partial_unswitch_shortcut_mustprogress_single_exit_on_path(i32* %ptr, i32 %N) mustprogress {
95 ; CHECK-LABEL: @partial_unswitch_shortcut_mustprogress_single_exit_on_path
96 ; CHECK-LABEL: entry:
97 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
98 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
99 ; CHECK-NEXT:   br i1 [[C]], label %[[CRIT_TO_EXIT:.+]], label %[[CRIT_TO_HEADER:[a-z._]+]]
101 ; CHECK:      [[CRIT_TO_HEADER]]:
102 ; CHECK-NEXT:   br label %loop.header
104 ; CHECK:      [[CRIT_TO_EXIT]]:
105 ; CHECK-NEXT:   br label %exit
107 entry:
108   br label %loop.header
110 loop.header:
111   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
112   %lv = load i32, i32* %ptr
113   %sc = icmp eq i32 %lv, 100
114   br i1 %sc, label %noclobber, label %clobber
116 noclobber:
117   %c.1 = icmp ult i32 %iv, 123
118   br i1 %c.1, label %loop.latch, label %exit.1
120 clobber:
121   call void @clobber()
122   call void @clobber()
123   call void @clobber()
124   call void @clobber()
125   call void @clobber()
126   call void @clobber()
127   call void @clobber()
128   call void @clobber()
129   call void @clobber()
130   %c = icmp ult i32 %iv, %N
131   br i1 %c, label %loop.latch, label %exit.2
133 loop.latch:
134   %iv.next = add i32 %iv, 1
135   br label %loop.header
137 exit.1:
138   ret i32 10
140 exit.2:
141   ret i32 10
144 define i32 @no_partial_unswitch_shortcut_mustprogress_no_exit_on_path(i32* %ptr, i32 %N) mustprogress {
145 ; CHECK-LABEL: @no_partial_unswitch_shortcut_mustprogress_no_exit_on_path
146 ; CHECK-LABEL: entry:
147 ; CHECK-NEXT:   br label %loop.header
149 entry:
150   br label %loop.header
152 loop.header:
153   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
154   %lv = load i32, i32* %ptr
155   %sc = icmp eq i32 %lv, 100
156   br i1 %sc, label %noclobber, label %clobber
158 noclobber:
159   br label %loop.latch
161 clobber:
162   call void @clobber()
163   call void @clobber()
164   call void @clobber()
165   call void @clobber()
166   call void @clobber()
167   call void @clobber()
168   call void @clobber()
169   call void @clobber()
170   call void @clobber()
171   %c = icmp ult i32 %iv, %N
172   br i1 %c, label %loop.latch, label %exit
174 loop.latch:
175   %iv.next = add i32 %iv, 1
176   br label %loop.header
178 exit:
179   ret i32 10
182 define i32 @no_partial_unswitch_shortcut_mustprogress_exit_value_used(i32* %ptr, i32 %N) mustprogress {
183 ; CHECK-LABEL: @no_partial_unswitch_shortcut_mustprogress_exit_value_use
184 ; CHECK-LABEL: entry:
185 ; CHECK-NEXT:   br label %loop.header
187 entry:
188   br label %loop.header
190 loop.header:
191   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
192   %red = phi i32 [ 0, %entry ], [ %red.next, %loop.latch ]
193   %lv = load i32, i32* %ptr
194   %sc = icmp eq i32 %lv, 100
195   br i1 %sc, label %noclobber, label %clobber
197 noclobber:
198   %red.add = add i32 %red, %lv
199   br label %loop.latch
201 clobber:
202   %red.mul = mul i32 %red, %lv
203   call void @clobber()
204   call void @clobber()
205   call void @clobber()
206   call void @clobber()
207   call void @clobber()
208   call void @clobber()
209   call void @clobber()
210   call void @clobber()
211   call void @clobber()
212   br label %loop.latch
214 loop.latch:
215   %red.next = phi i32 [ %red.add, %noclobber ], [ %red.mul, %clobber ]
216   %c = icmp ult i32 %iv, %N
217   %iv.next = add i32 %iv, 1
218   br i1 %c, label %loop.header, label %exit
220 exit:
221   ret i32 %red.next
224 define i32 @partial_unswitch_shortcut_multiple_exiting_blocks(i32* %ptr, i32 %N, i1 %ec.1) mustprogress {
225 ; CHECK-LABEL: @partial_unswitch_shortcut_multiple_exiting_blocks
226 ; CHECK-LABEL: entry:
227 ; CHECK-NEXT:   [[LV:%[0-9]+]] = load i32, i32* %ptr, align 4
228 ; CHECK-NEXT:   [[C:%[0-9]+]] = icmp eq i32 [[LV]], 100
229 ; CHECK-NEXT:   br i1 [[C]], label %[[CRIT_TO_EXIT:.+]], label %[[CRIT_TO_HEADER:[a-z._]+]]
231 ; CHECK:      [[CRIT_TO_HEADER]]:
232 ; CHECK-NEXT:   br label %loop.header
234 ; CHECK:      [[CRIT_TO_EXIT]]:
235 ; CHECK-NEXT:   br label %exit
237 entry:
238   br label %loop.header
240 loop.header:
241   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
242   %lv = load i32, i32* %ptr
243   %sc = icmp eq i32 %lv, 100
244   br i1 %sc, label %noclobber, label %clobber
246 noclobber:
247   br i1 %ec.1, label %loop.latch, label %exit
249 clobber:
250   call void @clobber()
251   call void @clobber()
252   call void @clobber()
253   call void @clobber()
254   call void @clobber()
255   call void @clobber()
256   call void @clobber()
257   call void @clobber()
258   call void @clobber()
259   br label %loop.latch
261 loop.latch:
262   %c = icmp ult i32 %iv, %N
263   %iv.next = add i32 %iv, 1
264   br i1 %c, label %loop.header, label %exit
266 exit:
267   ret i32 10
270 define i32 @no_partial_unswitch_shortcut_multiple_exit_blocks(i32* %ptr, i32 %N, i1 %ec.1) mustprogress {
271 ; CHECK-LABEL: @no_partial_unswitch_shortcut_multiple_exit_blocks
272 ; CHECK-LABEL: entry:
273 ; CHECK-NEXT:   br label %loop.header
275 entry:
276   br label %loop.header
278 loop.header:
279   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
280   %lv = load i32, i32* %ptr
281   %sc = icmp eq i32 %lv, 100
282   br i1 %sc, label %noclobber, label %clobber
284 noclobber:
285   br i1 %ec.1, label %loop.latch, label %exit.2
287 clobber:
288   call void @clobber()
289   call void @clobber()
290   call void @clobber()
291   call void @clobber()
292   call void @clobber()
293   call void @clobber()
294   call void @clobber()
295   call void @clobber()
296   call void @clobber()
297   br label %loop.latch
299 loop.latch:
300   %c = icmp ult i32 %iv, %N
301   %iv.next = add i32 %iv, 1
302   br i1 %c, label %loop.header, label %exit.1
304 exit.1:
305   ret i32 10
307 exit.2:
308   ret i32 20
311 define i32 @no_partial_unswitch_shortcut_mustprogress_store(i32* %ptr, i32* noalias %dst, i32 %N) mustprogress {
312 ; CHECK-LABEL: @no_partial_unswitch_shortcut_mustprogress_store
313 ; CHECK-LABEL: entry:
314 ; CHECK-NEXT:   br label %loop.header
316 entry:
317   br label %loop.header
319 loop.header:
320   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
321   %lv = load i32, i32* %ptr
322   %sc = icmp eq i32 %lv, 100
323   br i1 %sc, label %noclobber, label %clobber
325 noclobber:
326   store i32 0, i32* %dst
327   br label %loop.latch
329 clobber:
330   call void @clobber()
331   call void @clobber()
332   call void @clobber()
333   call void @clobber()
334   call void @clobber()
335   call void @clobber()
336   call void @clobber()
337   call void @clobber()
338   call void @clobber()
339   br label %loop.latch
341 loop.latch:
342   %c = icmp ult i32 %iv, %N
343   %iv.next = add i32 %iv, 1
344   br i1 %c, label %loop.header, label %exit
346 exit:
347   ret i32 10
350 define i32 @no_partial_unswitch_shortcut_mustprogress_store2(i32* %ptr, i32* noalias %dst, i32 %N) mustprogress {
351 ; CHECK-LABEL: @no_partial_unswitch_shortcut_mustprogress_store
352 ; CHECK-LABEL: entry:
353 ; CHECK-NEXT:   br label %loop.header
355 entry:
356   br label %loop.header
358 loop.header:
359   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
360   %lv = load i32, i32* %ptr
361   %sc = icmp eq i32 %lv, 100
362   br i1 %sc, label %noclobber, label %clobber
364 noclobber:
365   br label %loop.latch
367 clobber:
368   call void @clobber()
369   call void @clobber()
370   call void @clobber()
371   call void @clobber()
372   call void @clobber()
373   call void @clobber()
374   call void @clobber()
375   call void @clobber()
376   call void @clobber()
377   br label %loop.latch
379 loop.latch:
380   store i32 0, i32* %dst
381   %c = icmp ult i32 %iv, %N
382   %iv.next = add i32 %iv, 1
383   br i1 %c, label %loop.header, label %exit
385 exit:
386   ret i32 10
389 define i32 @no_partial_unswitch_shortcut_mustprogress_store3(i32* %ptr, i32* noalias %dst, i32 %N) mustprogress {
390 ; CHECK-LABEL: @no_partial_unswitch_shortcut_mustprogress_store
391 ; CHECK-LABEL: entry:
392 ; CHECK-NEXT:   br label %loop.header
394 entry:
395   br label %loop.header
397 loop.header:
398   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
399   store i32 0, i32* %dst
400   %lv = load i32, i32* %ptr
401   %sc = icmp eq i32 %lv, 100
402   br i1 %sc, label %noclobber, label %clobber
404 noclobber:
405   br label %loop.latch
407 clobber:
408   call void @clobber()
409   call void @clobber()
410   call void @clobber()
411   call void @clobber()
412   call void @clobber()
413   call void @clobber()
414   call void @clobber()
415   call void @clobber()
416   call void @clobber()
417   br label %loop.latch
419 loop.latch:
420   %c = icmp ult i32 %iv, %N
421   %iv.next = add i32 %iv, 1
422   br i1 %c, label %loop.header, label %exit
424 exit:
425   ret i32 10