[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / LICM / hoist-mustexec.ll
blob592e20566a8226a113d29ff747a12f6fc69ef609
1 ; REQUIRES: asserts
2 ; RUN: opt -S -basic-aa -licm -ipt-expensive-asserts=true < %s | FileCheck %s
3 ; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop-mssa(licm)' -ipt-expensive-asserts=true -S %s | FileCheck %s
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-unknown-linux-gnu"
7 declare void @f() nounwind
8 declare void @llvm.experimental.guard(i1,...)
10 ; constant fold on first ieration
11 define i32 @test1(i32* noalias nocapture readonly %a) nounwind uwtable {
12 ; CHECK-LABEL: @test1(
13 entry:
14 ; CHECK: %i1 = load i32, i32* %a, align 4
15 ; CHECK-NEXT: br label %for.body
16   br label %for.body
18 for.body:
19   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
20   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
21   %r.chk = icmp ult i32 %iv, 2000
22   br i1 %r.chk, label %continue, label %fail
23 continue:
24   %i1 = load i32, i32* %a, align 4
25   %add = add nsw i32 %i1, %acc
26   %inc = add nuw nsw i32 %iv, 1
27   %exitcond = icmp eq i32 %inc, 1000
28   br i1 %exitcond, label %for.cond.cleanup, label %for.body
30 for.cond.cleanup:
31   ret i32 %add
33 fail:
34   call void @f()
35   ret i32 -1
38 ; Same as test1, but with a floating point IR and fcmp
39 define i32 @test_fcmp(i32* noalias nocapture readonly %a) nounwind uwtable {
40 ; CHECK-LABEL: @test_fcmp(
41 entry:
42 ; CHECK: %i1 = load i32, i32* %a, align 4
43 ; CHECK-NEXT: br label %for.body
44   br label %for.body
46 for.body:
47   %iv = phi float [ 0.0, %entry ], [ %inc, %continue ]
48   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
49   %r.chk = fcmp olt float %iv, 2000.0
50   br i1 %r.chk, label %continue, label %fail
51 continue:
52   %i1 = load i32, i32* %a, align 4
53   %add = add nsw i32 %i1, %acc
54   %inc = fadd float %iv, 1.0
55   %exitcond = fcmp ogt float %inc, 1000.0
56   br i1 %exitcond, label %for.cond.cleanup, label %for.body
58 for.cond.cleanup:
59   ret i32 %add
61 fail:
62   call void @f()
63   ret i32 -1
66 ; Count down from a.length w/entry guard
67 ; TODO: currently unable to prove the following:
68 ; ule i32 (add nsw i32 %len, -1), %len where len is [0, 512]
69 define i32 @test2(i32* noalias nocapture readonly %a) nounwind uwtable {
70 ; CHECK-LABEL: @test2(
71 entry:
72   %len = load i32, i32* %a, align 4, !range !{i32 0, i32 512}
73   %is.non.pos = icmp eq i32 %len, 0
74   br i1 %is.non.pos, label %fail, label %preheader
75 preheader:
76   %lenminusone = add nsw i32 %len, -1
77   br label %for.body
78 for.body:
79   %iv = phi i32 [ %lenminusone, %preheader ], [ %dec, %continue ]
80   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
81   %r.chk = icmp ule i32 %iv, %len
82   br i1 %r.chk, label %continue, label %fail
83 continue:
84 ; CHECK-LABEL: continue
85 ; CHECK: %i1 = load i32, i32* %a, align 4
86   %i1 = load i32, i32* %a, align 4
87   %add = add nsw i32 %i1, %acc
88   %dec = add nsw i32 %iv, -1
89   %exitcond = icmp eq i32 %dec, 0
90   br i1 %exitcond, label %for.cond.cleanup, label %for.body
92 for.cond.cleanup:
93   ret i32 %add
95 fail:
96   call void @f()
97   ret i32 -1
100 ; trivially true for zero
101 define i32 @test3(i32* noalias nocapture readonly %a) nounwind uwtable {
102 ; CHECK-LABEL: @test3(
103 entry:
104   %len = load i32, i32* %a, align 4, !range !{i32 0, i32 512}
105   %is.zero = icmp eq i32 %len, 0
106   br i1 %is.zero, label %fail, label %preheader
107 preheader:
108 ; CHECK: %i1 = load i32, i32* %a, align 4
109 ; CHECK-NEXT: br label %for.body
110   br label %for.body
111 for.body:
112   %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]
113   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
114   %r.chk = icmp ule i32 %iv, %len
115   br i1 %r.chk, label %continue, label %fail
116 continue:
117   %i1 = load i32, i32* %a, align 4
118   %add = add nsw i32 %i1, %acc
119   %inc = add nuw nsw i32 %iv, 1
120   %exitcond = icmp eq i32 %inc, 1000
121   br i1 %exitcond, label %for.cond.cleanup, label %for.body
123 for.cond.cleanup:
124   ret i32 %add
126 fail:
127   call void @f()
128   ret i32 -1
131 ; requires fact length is non-zero
132 define i32 @test4(i32* noalias nocapture readonly %a) nounwind uwtable {
133 ; CHECK-LABEL: @test4(
134 ; CHECK-NEXT:  entry:
135 ; CHECK-NEXT:    [[LEN:%.*]] = load i32, i32* [[A:%.*]], align 4, !range !0
136 ; CHECK-NEXT:    [[IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0
137 ; CHECK-NEXT:    br i1 [[IS_ZERO]], label [[FAIL:%.*]], label [[PREHEADER:%.*]]
138 ; CHECK:       preheader:
139 ; CHECK-NEXT:    [[I1:%.*]] = load i32, i32* [[A]], align 4
140 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
141 ; CHECK:       for.body:
142 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[INC:%.*]], [[CONTINUE:%.*]] ]
143 ; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ADD:%.*]], [[CONTINUE]] ]
144 ; CHECK-NEXT:    [[R_CHK:%.*]] = icmp ult i32 [[IV]], [[LEN]]
145 ; CHECK-NEXT:    br i1 [[R_CHK]], label [[CONTINUE]], label [[FAIL_LOOPEXIT:%.*]]
146 ; CHECK:       continue:
147 ; CHECK-NEXT:    [[ADD]] = add nsw i32 [[I1]], [[ACC]]
148 ; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[IV]], 1
149 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i32 [[INC]], 1000
150 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY]]
151 ; CHECK:       for.cond.cleanup:
152 ; CHECK-NEXT:    [[ADD_LCSSA:%.*]] = phi i32 [ [[ADD]], [[CONTINUE]] ]
153 ; CHECK-NEXT:    ret i32 [[ADD_LCSSA]]
154 ; CHECK:       fail.loopexit:
155 ; CHECK-NEXT:    br label [[FAIL]]
156 ; CHECK:       fail:
157 ; CHECK-NEXT:    call void @f()
158 ; CHECK-NEXT:    ret i32 -1
160 entry:
161   %len = load i32, i32* %a, align 4, !range !{i32 0, i32 512}
162   %is.zero = icmp eq i32 %len, 0
163   br i1 %is.zero, label %fail, label %preheader
164 preheader:
165   br label %for.body
166 for.body:
167   %iv = phi i32 [ 0, %preheader ], [ %inc, %continue ]
168   %acc = phi i32 [ 0, %preheader ], [ %add, %continue ]
169   %r.chk = icmp ult i32 %iv, %len
170   br i1 %r.chk, label %continue, label %fail
171 continue:
172   %i1 = load i32, i32* %a, align 4
173   %add = add nsw i32 %i1, %acc
174   %inc = add nuw nsw i32 %iv, 1
175   %exitcond = icmp eq i32 %inc, 1000
176   br i1 %exitcond, label %for.cond.cleanup, label %for.body
178 for.cond.cleanup:
179   ret i32 %add
181 fail:
182   call void @f()
183   ret i32 -1
186 ; variation on test1 with branch swapped
187 define i32 @test-brswap(i32* noalias nocapture readonly %a) nounwind uwtable {
188 ; CHECK-LABEL: @test-brswap(
189 entry:
190 ; CHECK: %i1 = load i32, i32* %a, align 4
191 ; CHECK-NEXT: br label %for.body
192   br label %for.body
194 for.body:
195   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
196   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
197   %r.chk = icmp ugt i32 %iv, 2000
198   br i1 %r.chk, label %fail, label %continue
199 continue:
200   %i1 = load i32, i32* %a, align 4
201   %add = add nsw i32 %i1, %acc
202   %inc = add nuw nsw i32 %iv, 1
203   %exitcond = icmp eq i32 %inc, 1000
204   br i1 %exitcond, label %for.cond.cleanup, label %for.body
206 for.cond.cleanup:
207   ret i32 %add
209 fail:
210   call void @f()
211   ret i32 -1
214 define i32 @test-nonphi(i32* noalias nocapture readonly %a) nounwind uwtable {
215 ; CHECK-LABEL: @test-nonphi(
216 entry:
217   br label %for.body
219 for.body:
220 ; CHECK-LABEL: continue
221 ; CHECK: %i1 = load i32, i32* %a, align 4
222   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
223   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
224   %xor = xor i32 %iv, 72
225   %r.chk = icmp ugt i32 %xor, 2000
226   br i1 %r.chk, label %fail, label %continue
227 continue:
228   %i1 = load i32, i32* %a, align 4
229   %add = add nsw i32 %i1, %acc
230   %inc = add nuw nsw i32 %iv, 1
231   %exitcond = icmp eq i32 %inc, 1000
232   br i1 %exitcond, label %for.cond.cleanup, label %for.body
234 for.cond.cleanup:
235   ret i32 %add
237 fail:
238   call void @f()
239   ret i32 -1
242 define i32 @test-wrongphi(i32* noalias nocapture readonly %a) nounwind uwtable {
243 ; CHECK-LABEL: @test-wrongphi(
244 entry:
245   br label %for.body
247 for.body:
248   %iv = phi i32 [ 0, %entry ], [ %inc, %continue ]
249   %acc = phi i32 [ 0, %entry ], [ %add, %continue ]
250   %cond = icmp ult i32 %iv, 500
251   br i1 %cond, label %dummy_block1, label %dummy_block2
253 dummy_block1:
254   br label %dummy_block2
256 dummy_block2:
257   %wrongphi = phi i32 [11, %for.body], [12, %dummy_block1]
258   %r.chk = icmp ugt i32 %wrongphi, 2000
259   br i1 %r.chk, label %fail, label %continue
260 continue:
261 ; CHECK-LABEL: continue
262 ; CHECK: %i1 = load i32, i32* %a, align 4
263   %i1 = load i32, i32* %a, align 4
264   %add = add nsw i32 %i1, %acc
265   %inc = add nuw nsw i32 %iv, 1
266   %exitcond = icmp eq i32 %inc, 1000
267   br i1 %exitcond, label %for.cond.cleanup, label %for.body
269 for.cond.cleanup:
270   ret i32 %add
272 fail:
273   call void @f()
274   ret i32 -1
277 ; This works because loop-simplify is run implicitly, but test for it anyways
278 define i32 @test-multiple-latch(i32* noalias nocapture readonly %a) nounwind uwtable {
279 ; CHECK-LABEL: @test-multiple-latch(
280 entry:
281 ; CHECK: %i1 = load i32, i32* %a, align 4
282 ; CHECK-NEXT: br label %for.body
283   br label %for.body
285 for.body:
286   %iv = phi i32 [ 0, %entry ], [ %inc, %continue1 ], [ %inc, %continue2 ]
287   %acc = phi i32 [ 0, %entry ], [ %add, %continue1 ], [ %add, %continue2 ]
288   %r.chk = icmp ult i32 %iv, 2000
289   br i1 %r.chk, label %continue1, label %fail
290 continue1:
291   %i1 = load i32, i32* %a, align 4
292   %add = add nsw i32 %i1, %acc
293   %inc = add nuw nsw i32 %iv, 1
294   %cmp = icmp eq i32 %add, 0
295   br i1 %cmp, label %continue2, label %for.body
296 continue2:
297   %exitcond = icmp eq i32 %inc, 1000
298   br i1 %exitcond, label %for.cond.cleanup, label %for.body
300 for.cond.cleanup:
301   ret i32 %add
303 fail:
304   call void @f()
305   ret i32 -1
308 define void @test-hoisting-in-presence-of-guards(i1 %c, i32* %p) {
310 ; CHECK-LABEL: @test-hoisting-in-presence-of-guards
311 ; CHECK:       entry:
312 ; CHECK:         %a = load i32, i32* %p
313 ; CHECK:         %invariant_cond = icmp ne i32 %a, 100
314 ; CHECK:       loop:
316 entry:
317   br label %loop
319 loop:
320   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
321   %iv.next = add i32 %iv, 1
322   %a = load i32, i32* %p
323   %invariant_cond = icmp ne i32 %a, 100
324   call void (i1, ...) @llvm.experimental.guard(i1 %invariant_cond) [ "deopt"() ]
325   %loop_cond = icmp slt i32 %iv.next, 1000
326   br i1 %loop_cond, label %loop, label %exit
328 exit:
329   ret void
333 declare void @may_throw() inaccessiblememonly
335 ; Test that we can sink a mustexecute load from loop header even in presence of
336 ; throwing instructions after it.
337 define void @test_hoist_from_header_01(i32* %p, i32 %n) {
339 ; CHECK-LABEL: @test_hoist_from_header_01(
340 ; CHECK:       entry:
341 ; CHECK-NEXT:  %load = load i32, i32* %p
342 ; CHECK-NOT:   load i32
344 entry:
345   br label %loop
347 loop:
348   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
349   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
350   %load = load i32, i32* %p
351   call void @may_throw()
352   %cond = icmp slt i32 %iv, %n
353   br i1 %cond, label %if.true, label %if.false
355 if.true:
356   %a = add i32 %iv, %iv
357   br label %backedge
359 if.false:
360   %b = mul i32 %iv, %iv
361   br label %backedge
363 backedge:
364   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
365   %iv.next = add i32 %iv, %merge
366   %loop.cond = icmp ult i32 %iv.next, %load
367   br i1 %loop.cond, label %loop, label %exit
369 exit:
370   ret void
373 define void @test_hoist_from_header_02(i32* %p, i32 %n) {
375 ; CHECK-LABEL: @test_hoist_from_header_02(
376 ; CHECK:       entry:
377 ; CHECK-NEXT:  %load = load i32, i32* %p
378 ; CHECK-NOT:   load i32
380 entry:
381   br label %loop
383 loop:
384   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
385   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
386   %load = load i32, i32* %p
387   %cond = icmp slt i32 %iv, %n
388   br i1 %cond, label %if.true, label %if.false
390 if.true:
391   call void @may_throw()
392   %a = add i32 %iv, %iv
393   br label %backedge
395 if.false:
396   %b = mul i32 %iv, %iv
397   br label %backedge
399 backedge:
400   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
401   %iv.next = add i32 %iv, %merge
402   %loop.cond = icmp ult i32 %iv.next, %load
403   br i1 %loop.cond, label %loop, label %exit
405 exit:
406   ret void
409 define void @test_hoist_from_header_03(i32* %p, i32 %n) {
411 ; CHECK-LABEL: @test_hoist_from_header_03(
412 ; CHECK:       entry:
413 ; CHECK-NEXT:  %load = load i32, i32* %p
414 ; CHECK-NOT:   load i32
416 entry:
417   br label %loop
419 loop:
420   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
421   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
422   %load = load i32, i32* %p
423   %cond = icmp slt i32 %iv, %n
424   br i1 %cond, label %if.true, label %if.false
426 if.true:
427   %a = add i32 %iv, %iv
428   br label %backedge
430 if.false:
431   %b = mul i32 %iv, %iv
432   br label %backedge
434 backedge:
435   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
436   call void @may_throw()
437   %iv.next = add i32 %iv, %merge
438   %loop.cond = icmp ult i32 %iv.next, %load
439   br i1 %loop.cond, label %loop, label %exit
441 exit:
442   ret void
445 ; Check that a throwing instruction prohibits hoisting across it.
446 define void @test_hoist_from_header_04(i32* %p, i32 %n) {
448 ; CHECK-LABEL: @test_hoist_from_header_04(
449 ; CHECK:       entry:
450 ; CHECK:       loop:
451 ; CHECK:       %load = load i32, i32* %p
453 entry:
454   br label %loop
456 loop:
457   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
458   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
459   call void @may_throw()
460   %load = load i32, i32* %p
461   %cond = icmp slt i32 %iv, %n
462   br i1 %cond, label %if.true, label %if.false
464 if.true:
465   %a = add i32 %iv, %iv
466   br label %backedge
468 if.false:
469   %b = mul i32 %iv, %iv
470   br label %backedge
472 backedge:
473   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
474   %iv.next = add i32 %iv, %merge
475   %loop.cond = icmp ult i32 %iv.next, %load
476   br i1 %loop.cond, label %loop, label %exit
478 exit:
479   ret void
482 ; Check that we can hoist a mustexecute load from backedge even if something
483 ; throws after it.
484 define void @test_hoist_from_backedge_01(i32* %p, i32 %n) {
486 ; CHECK-LABEL: @test_hoist_from_backedge_01(
487 ; CHECK:       entry:
488 ; CHECK-NEXT:  %load = load i32, i32* %p
489 ; CHECK-NOT:   load i32
491 entry:
492   br label %loop
494 loop:
495   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
496   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
497   %cond = icmp slt i32 %iv, %n
498   br i1 %cond, label %if.true, label %if.false
500 if.true:
501   %a = add i32 %iv, %iv
502   br label %backedge
504 if.false:
505   %b = mul i32 %iv, %iv
506   br label %backedge
508 backedge:
509   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
510   %iv.next = add i32 %iv, %merge
511   %load = load i32, i32* %p
512   call void @may_throw()
513   %loop.cond = icmp ult i32 %iv.next, %load
514   br i1 %loop.cond, label %loop, label %exit
516 exit:
517   ret void
520 ; Check that we don't hoist the load if something before it can throw.
521 define void @test_hoist_from_backedge_02(i32* %p, i32 %n) {
523 ; CHECK-LABEL: @test_hoist_from_backedge_02(
524 ; CHECK:       entry:
525 ; CHECK:       loop:
526 ; CHECK:       %load = load i32, i32* %p
528 entry:
529   br label %loop
531 loop:
532   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
533   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
534   %cond = icmp slt i32 %iv, %n
535   br i1 %cond, label %if.true, label %if.false
537 if.true:
538   %a = add i32 %iv, %iv
539   br label %backedge
541 if.false:
542   %b = mul i32 %iv, %iv
543   br label %backedge
545 backedge:
546   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
547   %iv.next = add i32 %iv, %merge
548   call void @may_throw()
549   %load = load i32, i32* %p
550   %loop.cond = icmp ult i32 %iv.next, %load
551   br i1 %loop.cond, label %loop, label %exit
553 exit:
554   ret void
557 define void @test_hoist_from_backedge_03(i32* %p, i32 %n) {
559 ; CHECK-LABEL: @test_hoist_from_backedge_03(
560 ; CHECK:       entry:
561 ; CHECK:       loop:
562 ; CHECK:       %load = load i32, i32* %p
564 entry:
565   br label %loop
567 loop:
568   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
569   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
570   %cond = icmp slt i32 %iv, %n
571   br i1 %cond, label %if.true, label %if.false
573 if.true:
574   %a = add i32 %iv, %iv
575   br label %backedge
577 if.false:
578   %b = mul i32 %iv, %iv
579   call void @may_throw()
580   br label %backedge
582 backedge:
583   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
584   %iv.next = add i32 %iv, %merge
585   %load = load i32, i32* %p
586   %loop.cond = icmp ult i32 %iv.next, %load
587   br i1 %loop.cond, label %loop, label %exit
589 exit:
590   ret void
593 define void @test_hoist_from_backedge_04(i32* %p, i32 %n) {
595 ; CHECK-LABEL: @test_hoist_from_backedge_04(
596 ; CHECK:       entry:
597 ; CHECK:       loop:
598 ; CHECK:       %load = load i32, i32* %p
600 entry:
601   br label %loop
603 loop:
604   %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
605   %dummy = phi i32 [ 0, %entry ], [ %merge, %backedge ]
606   call void @may_throw()
607   %cond = icmp slt i32 %iv, %n
608   br i1 %cond, label %if.true, label %if.false
610 if.true:
611   %a = add i32 %iv, %iv
612   br label %backedge
614 if.false:
615   %b = mul i32 %iv, %iv
616   br label %backedge
618 backedge:
619   %merge = phi i32 [ %a, %if.true ], [ %b, %if.false ]
620   %iv.next = add i32 %iv, %merge
621   %load = load i32, i32* %p
622   %loop.cond = icmp ult i32 %iv.next, %load
623   br i1 %loop.cond, label %loop, label %exit
625 exit:
626   ret void