[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / LoopDeletion / multiple-exits.ll
blob760c3aae4ee763ae635d61cda8b7d523fc74509b
1 ; Checks whether dead loops with multiple exits can be eliminated.
2 ; Note that we loop simplify and LCSSA over the test cases to make sure the
3 ; critical components remain after those passes and are visible to the loop
4 ; deletion pass.
6 ; RUN: opt < %s -loop-simplify -lcssa -S | FileCheck %s --check-prefixes=CHECK,BEFORE
7 ; RUN: opt < %s -loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER
9 ; RUN: opt < %s -passes=no-op-loop -S | FileCheck %s --check-prefixes=CHECK,BEFORE
10 ; RUN: opt < %s -passes=loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER
13 define void @foo(i64 %n, i64 %m) nounwind {
14 ; CHECK-LABEL: @foo(
16 entry:
17   br label %bb
18 ; CHECK:       entry:
19 ; BEFORE-NEXT:   br label %bb
20 ; AFTER-NEXT:    br label %return
22 bb:
23   %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb2 ]
24   %t0 = add i64 %x.0, 1
25   %t1 = icmp slt i64 %x.0, %n
26   br i1 %t1, label %bb2, label %return
27 ; BEFORE:      bb:
28 ; BEFORE:        br i1 {{.*}}, label %bb2, label %return
29 ; AFTER-NOT:   bb:
30 ; AFTER-NOT:     br
32 bb2:
33   %t2 = icmp slt i64 %x.0, %m
34   br i1 %t1, label %bb, label %return
35 ; BEFORE:      bb2:
36 ; BEFORE:        br i1 {{.*}}, label %bb, label %return
37 ; AFTER-NOT:   bb2:
38 ; AFTER-NOT:     br
40 return:
41   ret void
42 ; CHECK:       return:
43 ; CHECK-NEXT:    ret void
46 define i64 @bar(i64 %n, i64 %m, i64 %maybe_zero) nounwind {
47 ; CHECK-LABEL: @bar(
49 entry:
50   br label %bb
51 ; CHECK:       entry:
52 ; BEFORE-NEXT:   br label %bb
53 ; AFTER-NEXT:    br label %return
55 bb:
56   %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ]
57   %t0 = add i64 %x.0, 1
58   %t1 = icmp slt i64 %x.0, %n
59   br i1 %t1, label %bb2, label %return
60 ; BEFORE:      bb:
61 ; BEFORE:        br i1 {{.*}}, label %bb2, label %return
62 ; AFTER-NOT:   bb:
63 ; AFTER-NOT:     br
65 bb2:
66   %t2 = icmp slt i64 %x.0, %m
67   ; This unused division prevents unifying this loop exit path with others
68   ; because it can be deleted but cannot be hoisted.
69   %unused1 = udiv i64 42, %maybe_zero
70   br i1 %t2, label %bb3, label %return
71 ; BEFORE:      bb2:
72 ; BEFORE:        br i1 {{.*}}, label %bb3, label %return
73 ; AFTER-NOT:   bb2:
74 ; AFTER-NOT:     br
76 bb3:
77   %t3 = icmp slt i64 %x.0, %m
78   ; This unused division prevents unifying this loop exit path with others
79   ; because it can be deleted but cannot be hoisted.
80   %unused2 = sdiv i64 42, %maybe_zero
81   br i1 %t3, label %bb, label %return
82 ; BEFORE:      bb3:
83 ; BEFORE:        br i1 {{.*}}, label %bb, label %return
84 ; AFTER-NOT:   bb3:
85 ; AFTER-NOT:     br
87 return:
88   %x.lcssa = phi i64 [ 10, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
89   ret i64 %x.lcssa
90 ; CHECK:       return:
91 ; BEFORE-NEXT:   %[[X:.*]] = phi i64 [ 10, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
92 ; AFTER-NEXT:    %[[X:.*]] = phi i64 [ 10, %entry ]
93 ; CHECK-NEXT:    ret i64 %[[X]]
96 ; This function has a loop which looks like @bar's but that cannot be deleted
97 ; because which path we exit through determines which value is selected.
98 define i64 @baz(i64 %n, i64 %m, i64 %maybe_zero) nounwind {
99 ; CHECK-LABEL:  @baz(
101 entry:
102   br label %bb
103 ; CHECK:       entry:
104 ; CHECK-NEXT:    br label %bb
107   %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ]
108   %t0 = add i64 %x.0, 1
109   %t1 = icmp slt i64 %x.0, %n
110   br i1 %t1, label %bb2, label %return
111 ; CHECK:       bb:
112 ; CHECK:         br i1 {{.*}}, label %bb2, label %return
114 bb2:
115   %t2 = icmp slt i64 %x.0, %m
116   ; This unused division prevents unifying this loop exit path with others
117   ; because it can be deleted but cannot be hoisted.
118   %unused1 = udiv i64 42, %maybe_zero
119   br i1 %t2, label %bb3, label %return
120 ; CHECK:       bb2:
121 ; CHECK:         br i1 {{.*}}, label %bb3, label %return
123 bb3:
124   %t3 = icmp slt i64 %x.0, %m
125   ; This unused division prevents unifying this loop exit path with others
126   ; because it can be deleted but cannot be hoisted.
127   %unused2 = sdiv i64 42, %maybe_zero
128   br i1 %t3, label %bb, label %return
129 ; CHECK:       bb3:
130 ; CHECK:         br i1 {{.*}}, label %bb, label %return
132 return:
133   %x.lcssa = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
134   ret i64 %x.lcssa
135 ; CHECK: return:
136 ; CHECK-NEXT:  %[[X:.*]] = phi i64 [ 12, %bb ], [ 10, %bb2 ], [ 10, %bb3 ]
137 ; CHECK-NEXT:  ret i64 %[[X]]