[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / llvm / test / Transforms / LoopUnroll / multiple-exits.ll
blob9f40f51c10e63f068ad0c9ceb35e3ecb1d09e803
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -loop-unroll -S < %s | FileCheck %s
4 declare void @bar()
6 define void @test1() {
7 ; CHECK-LABEL: @test1(
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    br label [[LOOP:%.*]]
10 ; CHECK:       loop:
11 ; CHECK-NEXT:    call void @bar()
12 ; CHECK-NEXT:    br label [[LATCH:%.*]]
13 ; CHECK:       latch:
14 ; CHECK-NEXT:    call void @bar()
15 ; CHECK-NEXT:    call void @bar()
16 ; CHECK-NEXT:    br label [[LATCH_1:%.*]]
17 ; CHECK:       latch.1:
18 ; CHECK-NEXT:    call void @bar()
19 ; CHECK-NEXT:    call void @bar()
20 ; CHECK-NEXT:    br label [[LATCH_2:%.*]]
21 ; CHECK:       latch.2:
22 ; CHECK-NEXT:    call void @bar()
23 ; CHECK-NEXT:    call void @bar()
24 ; CHECK-NEXT:    br label [[LATCH_3:%.*]]
25 ; CHECK:       latch.3:
26 ; CHECK-NEXT:    call void @bar()
27 ; CHECK-NEXT:    call void @bar()
28 ; CHECK-NEXT:    br label [[LATCH_4:%.*]]
29 ; CHECK:       latch.4:
30 ; CHECK-NEXT:    call void @bar()
31 ; CHECK-NEXT:    call void @bar()
32 ; CHECK-NEXT:    br label [[LATCH_5:%.*]]
33 ; CHECK:       latch.5:
34 ; CHECK-NEXT:    call void @bar()
35 ; CHECK-NEXT:    call void @bar()
36 ; CHECK-NEXT:    br label [[LATCH_6:%.*]]
37 ; CHECK:       latch.6:
38 ; CHECK-NEXT:    call void @bar()
39 ; CHECK-NEXT:    call void @bar()
40 ; CHECK-NEXT:    br label [[LATCH_7:%.*]]
41 ; CHECK:       latch.7:
42 ; CHECK-NEXT:    call void @bar()
43 ; CHECK-NEXT:    call void @bar()
44 ; CHECK-NEXT:    br label [[LATCH_8:%.*]]
45 ; CHECK:       latch.8:
46 ; CHECK-NEXT:    call void @bar()
47 ; CHECK-NEXT:    call void @bar()
48 ; CHECK-NEXT:    br label [[LATCH_9:%.*]]
49 ; CHECK:       latch.9:
50 ; CHECK-NEXT:    call void @bar()
51 ; CHECK-NEXT:    call void @bar()
52 ; CHECK-NEXT:    br i1 false, label [[LATCH_10:%.*]], label [[EXIT:%.*]]
53 ; CHECK:       latch.10:
54 ; CHECK-NEXT:    call void @bar()
55 ; CHECK-NEXT:    br label [[EXIT]]
56 ; CHECK:       exit:
57 ; CHECK-NEXT:    ret void
59 entry:
60   br label %loop
61 loop:
62   %iv = phi i64 [0, %entry], [%iv.next, %latch]
63   %iv.next = add i64 %iv, 1
64   call void @bar()
65   %cmp1 = icmp ult i64 %iv, 10
66   br i1 %cmp1, label %latch, label %exit
67 latch:
68   call void @bar()
69   %cmp2 = icmp ult i64 %iv, 20
70   br i1 %cmp2, label %loop, label %exit
71 exit:
72   ret void
75 ; Fully unroll this loop by 10, but leave the unrolled latch
76 ; tests since we don't know if %N < 10, and break the backedge.
77 define void @test2(i64 %N) {
78 ; CHECK-LABEL: @test2(
79 ; CHECK-NEXT:  entry:
80 ; CHECK-NEXT:    br label [[LOOP:%.*]]
81 ; CHECK:       loop:
82 ; CHECK-NEXT:    call void @bar()
83 ; CHECK-NEXT:    br label [[LATCH:%.*]]
84 ; CHECK:       latch:
85 ; CHECK-NEXT:    call void @bar()
86 ; CHECK-NEXT:    br i1 true, label [[LOOP_1:%.*]], label [[EXIT:%.*]]
87 ; CHECK:       loop.1:
88 ; CHECK-NEXT:    call void @bar()
89 ; CHECK-NEXT:    br label [[LATCH_1:%.*]]
90 ; CHECK:       latch.1:
91 ; CHECK-NEXT:    call void @bar()
92 ; CHECK-NEXT:    [[CMP2_1:%.*]] = icmp ule i64 1, [[N:%.*]]
93 ; CHECK-NEXT:    br i1 [[CMP2_1]], label [[LOOP_2:%.*]], label [[EXIT]]
94 ; CHECK:       loop.2:
95 ; CHECK-NEXT:    call void @bar()
96 ; CHECK-NEXT:    br label [[LATCH_2:%.*]]
97 ; CHECK:       latch.2:
98 ; CHECK-NEXT:    call void @bar()
99 ; CHECK-NEXT:    [[CMP2_2:%.*]] = icmp ule i64 2, [[N]]
100 ; CHECK-NEXT:    br i1 [[CMP2_2]], label [[LOOP_3:%.*]], label [[EXIT]]
101 ; CHECK:       loop.3:
102 ; CHECK-NEXT:    call void @bar()
103 ; CHECK-NEXT:    br label [[LATCH_3:%.*]]
104 ; CHECK:       latch.3:
105 ; CHECK-NEXT:    call void @bar()
106 ; CHECK-NEXT:    [[CMP2_3:%.*]] = icmp ule i64 3, [[N]]
107 ; CHECK-NEXT:    br i1 [[CMP2_3]], label [[LOOP_4:%.*]], label [[EXIT]]
108 ; CHECK:       loop.4:
109 ; CHECK-NEXT:    call void @bar()
110 ; CHECK-NEXT:    br label [[LATCH_4:%.*]]
111 ; CHECK:       latch.4:
112 ; CHECK-NEXT:    call void @bar()
113 ; CHECK-NEXT:    [[CMP2_4:%.*]] = icmp ule i64 4, [[N]]
114 ; CHECK-NEXT:    br i1 [[CMP2_4]], label [[LOOP_5:%.*]], label [[EXIT]]
115 ; CHECK:       loop.5:
116 ; CHECK-NEXT:    call void @bar()
117 ; CHECK-NEXT:    br label [[LATCH_5:%.*]]
118 ; CHECK:       latch.5:
119 ; CHECK-NEXT:    call void @bar()
120 ; CHECK-NEXT:    [[CMP2_5:%.*]] = icmp ule i64 5, [[N]]
121 ; CHECK-NEXT:    br i1 [[CMP2_5]], label [[LOOP_6:%.*]], label [[EXIT]]
122 ; CHECK:       loop.6:
123 ; CHECK-NEXT:    call void @bar()
124 ; CHECK-NEXT:    br label [[LATCH_6:%.*]]
125 ; CHECK:       latch.6:
126 ; CHECK-NEXT:    call void @bar()
127 ; CHECK-NEXT:    [[CMP2_6:%.*]] = icmp ule i64 6, [[N]]
128 ; CHECK-NEXT:    br i1 [[CMP2_6]], label [[LOOP_7:%.*]], label [[EXIT]]
129 ; CHECK:       loop.7:
130 ; CHECK-NEXT:    call void @bar()
131 ; CHECK-NEXT:    br label [[LATCH_7:%.*]]
132 ; CHECK:       latch.7:
133 ; CHECK-NEXT:    call void @bar()
134 ; CHECK-NEXT:    [[CMP2_7:%.*]] = icmp ule i64 7, [[N]]
135 ; CHECK-NEXT:    br i1 [[CMP2_7]], label [[LOOP_8:%.*]], label [[EXIT]]
136 ; CHECK:       loop.8:
137 ; CHECK-NEXT:    call void @bar()
138 ; CHECK-NEXT:    br label [[LATCH_8:%.*]]
139 ; CHECK:       latch.8:
140 ; CHECK-NEXT:    call void @bar()
141 ; CHECK-NEXT:    [[CMP2_8:%.*]] = icmp ule i64 8, [[N]]
142 ; CHECK-NEXT:    br i1 [[CMP2_8]], label [[LOOP_9:%.*]], label [[EXIT]]
143 ; CHECK:       loop.9:
144 ; CHECK-NEXT:    call void @bar()
145 ; CHECK-NEXT:    br label [[LATCH_9:%.*]]
146 ; CHECK:       latch.9:
147 ; CHECK-NEXT:    call void @bar()
148 ; CHECK-NEXT:    [[CMP2_9:%.*]] = icmp ule i64 9, [[N]]
149 ; CHECK-NEXT:    br i1 [[CMP2_9]], label [[LOOP_10:%.*]], label [[EXIT]]
150 ; CHECK:       loop.10:
151 ; CHECK-NEXT:    call void @bar()
152 ; CHECK-NEXT:    br label [[LATCH_10:%.*]]
153 ; CHECK:       latch.10:
154 ; CHECK-NEXT:    call void @bar()
155 ; CHECK-NEXT:    [[CMP2_10:%.*]] = icmp ule i64 10, [[N]]
156 ; CHECK-NEXT:    br i1 [[CMP2_10]], label [[LOOP_11:%.*]], label [[EXIT]]
157 ; CHECK:       loop.11:
158 ; CHECK-NEXT:    call void @bar()
159 ; CHECK-NEXT:    br i1 false, label [[LATCH_11:%.*]], label [[EXIT]]
160 ; CHECK:       latch.11:
161 ; CHECK-NEXT:    call void @bar()
162 ; CHECK-NEXT:    br label [[EXIT]]
163 ; CHECK:       exit:
164 ; CHECK-NEXT:    ret void
166 entry:
167   br label %loop
168 loop:
169   %iv = phi i64 [0, %entry], [%iv.next, %latch]
170   %iv.next = add i64 %iv, 1
171   call void @bar()
172   %cmp1 = icmp ule i64 %iv, 10
173   br i1 %cmp1, label %latch, label %exit
174 latch:
175   call void @bar()
176   %cmp2 = icmp ule i64 %iv, %N
177   br i1 %cmp2, label %loop, label %exit
178 exit:
179   ret void
183 ; TODO: We could partially unroll this by 2.
184 define void @test3(i64 %N, i64 %M) {
185 ; CHECK-LABEL: @test3(
186 ; CHECK-NEXT:  entry:
187 ; CHECK-NEXT:    [[N_MASKED:%.*]] = and i64 [[N:%.*]], 65520
188 ; CHECK-NEXT:    [[M_MASKED:%.*]] = and i64 [[M:%.*]], 65520
189 ; CHECK-NEXT:    br label [[LOOP:%.*]]
190 ; CHECK:       loop:
191 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
192 ; CHECK-NEXT:    [[IV_NEXT]] = add i64 [[IV]], 1
193 ; CHECK-NEXT:    call void @bar()
194 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ule i64 [[IV]], [[N_MASKED]]
195 ; CHECK-NEXT:    br i1 [[CMP1]], label [[LATCH]], label [[EXIT:%.*]]
196 ; CHECK:       latch:
197 ; CHECK-NEXT:    call void @bar()
198 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ule i64 [[IV]], [[M_MASKED]]
199 ; CHECK-NEXT:    br i1 [[CMP2]], label [[LOOP]], label [[EXIT]]
200 ; CHECK:       exit:
201 ; CHECK-NEXT:    ret void
203 entry:
204   %N.masked = and i64 %N, 65520 ; 0xfff0
205   %M.masked = and i64 %M, 65520 ; 0xfff0
206   br label %loop
207 loop:
208   %iv = phi i64 [0, %entry], [%iv.next, %latch]
209   %iv.next = add i64 %iv, 1
210   call void @bar()
211   %cmp1 = icmp ule i64 %iv, %N.masked
212   br i1 %cmp1, label %latch, label %exit
213 latch:
214   call void @bar()
215   %cmp2 = icmp ule i64 %iv, %M.masked
216   br i1 %cmp2, label %loop, label %exit
217 exit:
218   ret void