1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -verify-loop-info -irce-print-changed-loops -passes=irce -irce-allow-narrow-latch=true -S < %s 2>&1 | FileCheck %s
3 ; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,irce' -irce-allow-narrow-latch=true -S < %s 2>&1 | FileCheck %s
5 ; Check that we can remove trivially non-failing range check.
6 define i32 @test_increasing_slt_slt_wide_simple_no_postloop() {
7 ; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_simple_no_postloop() {
9 ; CHECK-NEXT: br label [[LOOP:%.*]]
11 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
12 ; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], 100
13 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]
15 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
16 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
17 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], 100
18 ; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]
20 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
21 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
22 ; CHECK: check_failed:
23 ; CHECK-NEXT: ret i32 -1
30 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
31 %rc = icmp slt i64 %iv, 100
32 br i1 %rc, label %backedge, label %check_failed
35 %iv.next = add i64 %iv, 1
36 %narrow.iv = trunc i64 %iv.next to i32
37 %latch.cond = icmp slt i32 %narrow.iv, 100
38 br i1 %latch.cond, label %loop, label %exit
47 ; This range check fails on the last iteration, so it needs a postloop.
48 define i32 @test_increasing_slt_slt_wide_simple_postloop() {
49 ; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_simple_postloop() {
51 ; CHECK-NEXT: br i1 true, label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
52 ; CHECK: loop.preheader:
53 ; CHECK-NEXT: br label [[LOOP:%.*]]
55 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
56 ; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], 99
57 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
59 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
60 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
61 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], 100
62 ; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
63 ; CHECK-NEXT: [[TMP0:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], 99
64 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
65 ; CHECK: main.exit.selector:
66 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
67 ; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
68 ; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
69 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], 100
70 ; CHECK-NEXT: br i1 [[TMP1]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
71 ; CHECK: main.pseudo.exit:
72 ; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
73 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
74 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
75 ; CHECK: exit.loopexit:
76 ; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
77 ; CHECK-NEXT: br label [[EXIT]]
79 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
80 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
81 ; CHECK: check_failed.loopexit:
82 ; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]
83 ; CHECK: check_failed.loopexit2:
84 ; CHECK-NEXT: br label [[CHECK_FAILED]]
85 ; CHECK: check_failed:
86 ; CHECK-NEXT: ret i32 -1
88 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
89 ; CHECK: loop.postloop:
90 ; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
91 ; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], 99
92 ; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
93 ; CHECK: backedge.postloop:
94 ; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
95 ; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
96 ; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], 100
97 ; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP0:![0-9]+]], !loop_constrainer.loop.clone [[META5:![0-9]+]]
104 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
105 %rc = icmp slt i64 %iv, 99
106 br i1 %rc, label %backedge, label %check_failed
109 %iv.next = add i64 %iv, 1
110 %narrow.iv = trunc i64 %iv.next to i32
111 %latch.cond = icmp slt i32 %narrow.iv, 100
112 br i1 %latch.cond, label %loop, label %exit
121 ; General case. If both %N and %M are non-negative, we do not need a preloop.
122 define i32 @test_increasing_slt_slt_wide_non-negative(ptr %n_ptr, ptr %m_ptr) {
123 ; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_non-negative
124 ; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
126 ; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6:![0-9]+]]
127 ; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4, !range [[RNG7:![0-9]+]]
128 ; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[N]] to i64
129 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 [[TMP0]])
130 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]
131 ; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
132 ; CHECK: loop.preheader:
133 ; CHECK-NEXT: br label [[LOOP:%.*]]
135 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
136 ; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], [[M]]
137 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
139 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
140 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
141 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]
142 ; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
143 ; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
144 ; CHECK-NEXT: br i1 [[TMP2]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
145 ; CHECK: main.exit.selector:
146 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
147 ; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
148 ; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
149 ; CHECK-NEXT: [[WIDE_N:%.*]] = sext i32 [[N]] to i64
150 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
151 ; CHECK-NEXT: br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
152 ; CHECK: main.pseudo.exit:
153 ; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
154 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
155 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
156 ; CHECK: exit.loopexit:
157 ; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
158 ; CHECK-NEXT: br label [[EXIT]]
160 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
161 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
162 ; CHECK: check_failed.loopexit:
163 ; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]
164 ; CHECK: check_failed.loopexit2:
165 ; CHECK-NEXT: br label [[CHECK_FAILED]]
166 ; CHECK: check_failed:
167 ; CHECK-NEXT: ret i32 -1
169 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
170 ; CHECK: loop.postloop:
171 ; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
172 ; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M]]
173 ; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
174 ; CHECK: backedge.postloop:
175 ; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
176 ; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
177 ; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]
178 ; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP8:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
182 %N = load i32, ptr %n_ptr, !range !2
183 %M = load i64, ptr %m_ptr, !range !1
187 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
188 %rc = icmp slt i64 %iv, %M
189 br i1 %rc, label %backedge, label %check_failed
192 %iv.next = add i64 %iv, 1
193 %narrow.iv = trunc i64 %iv.next to i32
194 %latch.cond = icmp slt i32 %narrow.iv, %N
195 br i1 %latch.cond, label %loop, label %exit
204 ; General case. Even though %M may be negative, we do not need a preloop because
205 ; we make a non-negativity runtime check against M and do not go to main loop if
207 define i32 @test_increasing_slt_slt_wide_general(ptr %n_ptr, ptr %m_ptr) {
208 ; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_general
209 ; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
211 ; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
212 ; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4
213 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[M]], -9223372036854775807
214 ; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 0)
215 ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[M]], [[SMAX]]
216 ; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 0)
217 ; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
218 ; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[SMAX1]], 1
219 ; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]
220 ; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[N]] to i64
221 ; CHECK-NEXT: [[SMIN2:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP4]])
222 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN2]], i64 0)
223 ; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]
224 ; CHECK-NEXT: br i1 [[TMP5]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
225 ; CHECK: loop.preheader:
226 ; CHECK-NEXT: br label [[LOOP:%.*]]
228 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
229 ; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], [[M]]
230 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT5:%.*]]
232 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
233 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
234 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]
235 ; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
236 ; CHECK-NEXT: [[TMP6:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
237 ; CHECK-NEXT: br i1 [[TMP6]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
238 ; CHECK: main.exit.selector:
239 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
240 ; CHECK-NEXT: [[NARROW_IV_LCSSA4:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
241 ; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
242 ; CHECK-NEXT: [[WIDE_N:%.*]] = sext i32 [[N]] to i64
243 ; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
244 ; CHECK-NEXT: br i1 [[TMP7]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
245 ; CHECK: main.pseudo.exit:
246 ; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
247 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
248 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
249 ; CHECK: exit.loopexit:
250 ; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
251 ; CHECK-NEXT: br label [[EXIT]]
253 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA4]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
254 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
255 ; CHECK: check_failed.loopexit:
256 ; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]
257 ; CHECK: check_failed.loopexit5:
258 ; CHECK-NEXT: br label [[CHECK_FAILED]]
259 ; CHECK: check_failed:
260 ; CHECK-NEXT: ret i32 -1
262 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
263 ; CHECK: loop.postloop:
264 ; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
265 ; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M]]
266 ; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
267 ; CHECK: backedge.postloop:
268 ; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
269 ; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
270 ; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]
271 ; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP9:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
275 %N = load i32, ptr %n_ptr, !range !2
276 %M = load i64, ptr %m_ptr
280 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
281 %rc = icmp slt i64 %iv, %M
282 br i1 %rc, label %backedge, label %check_failed
285 %iv.next = add i64 %iv, 1
286 %narrow.iv = trunc i64 %iv.next to i32
287 %latch.cond = icmp slt i32 %narrow.iv, %N
288 br i1 %latch.cond, label %loop, label %exit
297 ; General case with preloop.
298 define i32 @test_increasing_slt_slt_wide_general_preloop(ptr %n_ptr, ptr %m_ptr) {
299 ; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_general_preloop
300 ; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
302 ; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
303 ; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4
304 ; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 0)
305 ; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
306 ; CHECK-NEXT: [[EXIT_PRELOOP_AT:%.*]] = sub i64 -1, [[SMAX]]
307 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[M]], -9223372036854775807
308 ; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 1)
309 ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[M]], [[SMAX1]]
310 ; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[SMAX]], 1
311 ; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]
312 ; CHECK-NEXT: [[TMP4:%.*]] = zext nneg i32 [[N]] to i64
313 ; CHECK-NEXT: [[SMIN2:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP4]])
314 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN2]], i64 -1)
315 ; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i64 -1, [[EXIT_PRELOOP_AT]]
316 ; CHECK-NEXT: br i1 [[TMP5]], label [[LOOP_PRELOOP_PREHEADER:%.*]], label [[PRELOOP_PSEUDO_EXIT:%.*]]
317 ; CHECK: loop.preloop.preheader:
318 ; CHECK-NEXT: br label [[LOOP_PRELOOP:%.*]]
320 ; CHECK-NEXT: [[TMP6:%.*]] = icmp slt i64 [[INDVAR_END:%.*]], [[EXIT_MAINLOOP_AT]]
321 ; CHECK-NEXT: br i1 [[TMP6]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
322 ; CHECK: loop.preheader:
323 ; CHECK-NEXT: br label [[LOOP:%.*]]
325 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[IV_PRELOOP_COPY:%.*]], [[LOOP_PREHEADER]] ]
326 ; CHECK-NEXT: [[RC:%.*]] = icmp slt i64 [[IV]], [[M]]
327 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT8:%.*]]
329 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
330 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
331 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]
332 ; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
333 ; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
334 ; CHECK-NEXT: br i1 [[TMP7]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
335 ; CHECK: main.exit.selector:
336 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
337 ; CHECK-NEXT: [[NARROW_IV_LCSSA7:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
338 ; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
339 ; CHECK-NEXT: [[WIDE_N4:%.*]] = sext i32 [[N]] to i64
340 ; CHECK-NEXT: [[TMP8:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N4]]
341 ; CHECK-NEXT: br i1 [[TMP8]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
342 ; CHECK: main.pseudo.exit:
343 ; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ [[IV_PRELOOP_COPY]], [[MAINLOOP:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
344 ; CHECK-NEXT: [[INDVAR_END5:%.*]] = phi i64 [ [[INDVAR_END]], [[MAINLOOP]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
345 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
346 ; CHECK: exit.loopexit:
347 ; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
348 ; CHECK-NEXT: br label [[EXIT]]
350 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA7]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_PRELOOP_LCSSA:%.*]], [[PRELOOP_EXIT_SELECTOR:%.*]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
351 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
352 ; CHECK: check_failed.loopexit:
353 ; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]
354 ; CHECK: check_failed.loopexit6:
355 ; CHECK-NEXT: br label [[CHECK_FAILED]]
356 ; CHECK: check_failed.loopexit8:
357 ; CHECK-NEXT: br label [[CHECK_FAILED]]
358 ; CHECK: check_failed:
359 ; CHECK-NEXT: ret i32 -1
360 ; CHECK: loop.preloop:
361 ; CHECK-NEXT: [[IV_PRELOOP:%.*]] = phi i64 [ [[IV_NEXT_PRELOOP:%.*]], [[BACKEDGE_PRELOOP:%.*]] ], [ 0, [[LOOP_PRELOOP_PREHEADER]] ]
362 ; CHECK-NEXT: [[RC_PRELOOP:%.*]] = icmp slt i64 [[IV_PRELOOP]], [[M]]
363 ; CHECK-NEXT: br i1 [[RC_PRELOOP]], label [[BACKEDGE_PRELOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
364 ; CHECK: backedge.preloop:
365 ; CHECK-NEXT: [[IV_NEXT_PRELOOP]] = add i64 [[IV_PRELOOP]], 1
366 ; CHECK-NEXT: [[NARROW_IV_PRELOOP:%.*]] = trunc i64 [[IV_PRELOOP]] to i32
367 ; CHECK-NEXT: [[LATCH_COND_PRELOOP:%.*]] = icmp slt i32 [[NARROW_IV_PRELOOP]], [[N]]
368 ; CHECK-NEXT: [[WIDE_NARROW_IV_PRELOOP:%.*]] = sext i32 [[NARROW_IV_PRELOOP]] to i64
369 ; CHECK-NEXT: [[TMP9:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_PRELOOP]], [[EXIT_PRELOOP_AT]]
370 ; CHECK-NEXT: br i1 [[TMP9]], label [[LOOP_PRELOOP]], label [[PRELOOP_EXIT_SELECTOR]], !llvm.loop [[LOOP10:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
371 ; CHECK: preloop.exit.selector:
372 ; CHECK-NEXT: [[IV_NEXT_PRELOOP_LCSSA:%.*]] = phi i64 [ [[IV_NEXT_PRELOOP]], [[BACKEDGE_PRELOOP]] ]
373 ; CHECK-NEXT: [[NARROW_IV_PRELOOP_LCSSA]] = phi i32 [ [[NARROW_IV_PRELOOP]], [[BACKEDGE_PRELOOP]] ]
374 ; CHECK-NEXT: [[WIDE_NARROW_IV_PRELOOP_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV_PRELOOP]], [[BACKEDGE_PRELOOP]] ]
375 ; CHECK-NEXT: [[WIDE_N:%.*]] = sext i32 [[N]] to i64
376 ; CHECK-NEXT: [[TMP10:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_PRELOOP_LCSSA]], [[WIDE_N]]
377 ; CHECK-NEXT: br i1 [[TMP10]], label [[PRELOOP_PSEUDO_EXIT]], label [[EXIT]]
378 ; CHECK: preloop.pseudo.exit:
379 ; CHECK-NEXT: [[IV_PRELOOP_COPY]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
380 ; CHECK-NEXT: [[INDVAR_END]] = phi i64 [ -1, [[ENTRY]] ], [ [[WIDE_NARROW_IV_PRELOOP_LCSSA]], [[PRELOOP_EXIT_SELECTOR]] ]
381 ; CHECK-NEXT: br label [[MAINLOOP]]
383 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
384 ; CHECK: loop.postloop:
385 ; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
386 ; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M]]
387 ; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT6:%.*]]
388 ; CHECK: backedge.postloop:
389 ; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
390 ; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_POSTLOOP]] to i32
391 ; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]
392 ; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP11:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
396 %N = load i32, ptr %n_ptr, !range !2
397 %M = load i64, ptr %m_ptr
401 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
402 %rc = icmp slt i64 %iv, %M
403 br i1 %rc, label %backedge, label %check_failed
406 %iv.next = add i64 %iv, 1
407 %narrow.iv = trunc i64 %iv to i32
408 %latch.cond = icmp slt i32 %narrow.iv, %N
409 br i1 %latch.cond, label %loop, label %exit
418 ; Same as above, multiple checks.
419 define i32 @test_increasing_slt_slt_wide_multiple_checks(ptr %n_ptr, ptr %m1_ptr, ptr %m2_ptr, ptr %m3_ptr, ptr %m4_ptr) {
420 ; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_multiple_checks
421 ; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M1_PTR:%.*]], ptr [[M2_PTR:%.*]], ptr [[M3_PTR:%.*]], ptr [[M4_PTR:%.*]]) {
423 ; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
424 ; CHECK-NEXT: [[M1:%.*]] = load i64, ptr [[M1_PTR]], align 4
425 ; CHECK-NEXT: [[M2:%.*]] = load i64, ptr [[M2_PTR]], align 4
426 ; CHECK-NEXT: [[M3:%.*]] = load i64, ptr [[M3_PTR]], align 4
427 ; CHECK-NEXT: [[M4:%.*]] = load i64, ptr [[M4_PTR]], align 4
428 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[M2]], -9223372036854775807
429 ; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP0]], i64 0)
430 ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[M2]], [[SMAX]]
431 ; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M2]], i64 0)
432 ; CHECK-NEXT: [[SMAX1:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
433 ; CHECK-NEXT: [[TMP2:%.*]] = add nsw i64 [[SMAX1]], 1
434 ; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP1]], [[TMP2]]
435 ; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[M1]], -9223372036854775807
436 ; CHECK-NEXT: [[SMAX2:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP4]], i64 0)
437 ; CHECK-NEXT: [[TMP5:%.*]] = sub i64 [[M1]], [[SMAX2]]
438 ; CHECK-NEXT: [[SMIN3:%.*]] = call i64 @llvm.smin.i64(i64 [[M1]], i64 0)
439 ; CHECK-NEXT: [[SMAX4:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN3]], i64 -1)
440 ; CHECK-NEXT: [[TMP6:%.*]] = add nsw i64 [[SMAX4]], 1
441 ; CHECK-NEXT: [[TMP7:%.*]] = mul i64 [[TMP5]], [[TMP6]]
442 ; CHECK-NEXT: [[SMIN5:%.*]] = call i64 @llvm.smin.i64(i64 [[TMP3]], i64 [[TMP7]])
443 ; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[M3]], -9223372036854775807
444 ; CHECK-NEXT: [[SMAX6:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP8]], i64 0)
445 ; CHECK-NEXT: [[TMP9:%.*]] = sub i64 [[M3]], [[SMAX6]]
446 ; CHECK-NEXT: [[SMIN7:%.*]] = call i64 @llvm.smin.i64(i64 [[M3]], i64 0)
447 ; CHECK-NEXT: [[SMAX8:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN7]], i64 -1)
448 ; CHECK-NEXT: [[TMP10:%.*]] = add nsw i64 [[SMAX8]], 1
449 ; CHECK-NEXT: [[TMP11:%.*]] = mul i64 [[TMP9]], [[TMP10]]
450 ; CHECK-NEXT: [[SMIN9:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN5]], i64 [[TMP11]])
451 ; CHECK-NEXT: [[TMP12:%.*]] = add i64 [[M4]], -9223372036854775807
452 ; CHECK-NEXT: [[SMAX10:%.*]] = call i64 @llvm.smax.i64(i64 [[TMP12]], i64 0)
453 ; CHECK-NEXT: [[TMP13:%.*]] = sub i64 [[M4]], [[SMAX10]]
454 ; CHECK-NEXT: [[SMIN11:%.*]] = call i64 @llvm.smin.i64(i64 [[M4]], i64 0)
455 ; CHECK-NEXT: [[SMAX12:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN11]], i64 -1)
456 ; CHECK-NEXT: [[TMP14:%.*]] = add nsw i64 [[SMAX12]], 1
457 ; CHECK-NEXT: [[TMP15:%.*]] = mul i64 [[TMP13]], [[TMP14]]
458 ; CHECK-NEXT: [[SMIN13:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN9]], i64 [[TMP15]])
459 ; CHECK-NEXT: [[TMP16:%.*]] = zext nneg i32 [[N]] to i64
460 ; CHECK-NEXT: [[SMIN14:%.*]] = call i64 @llvm.smin.i64(i64 [[SMIN13]], i64 [[TMP16]])
461 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN14]], i64 0)
462 ; CHECK-NEXT: [[TMP17:%.*]] = icmp slt i64 0, [[EXIT_MAINLOOP_AT]]
463 ; CHECK-NEXT: br i1 [[TMP17]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
464 ; CHECK: loop.preheader:
465 ; CHECK-NEXT: br label [[LOOP:%.*]]
467 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
468 ; CHECK-NEXT: [[RC1:%.*]] = icmp slt i64 [[IV]], [[M1]]
469 ; CHECK-NEXT: [[RC2:%.*]] = icmp slt i64 [[IV]], [[M2]]
470 ; CHECK-NEXT: [[RC3:%.*]] = icmp slt i64 [[IV]], [[M3]]
471 ; CHECK-NEXT: [[RC4:%.*]] = icmp slt i64 [[IV]], [[M4]]
472 ; CHECK-NEXT: [[C1:%.*]] = and i1 true, true
473 ; CHECK-NEXT: [[C2:%.*]] = and i1 [[C1]], true
474 ; CHECK-NEXT: [[RC:%.*]] = and i1 [[C2]], true
475 ; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT17:%.*]]
477 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
478 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
479 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i32 [[NARROW_IV]], [[N]]
480 ; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = sext i32 [[NARROW_IV]] to i64
481 ; CHECK-NEXT: [[TMP18:%.*]] = icmp slt i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
482 ; CHECK-NEXT: br i1 [[TMP18]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
483 ; CHECK: main.exit.selector:
484 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
485 ; CHECK-NEXT: [[NARROW_IV_LCSSA16:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
486 ; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
487 ; CHECK-NEXT: [[WIDE_N:%.*]] = sext i32 [[N]] to i64
488 ; CHECK-NEXT: [[TMP19:%.*]] = icmp slt i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
489 ; CHECK-NEXT: br i1 [[TMP19]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
490 ; CHECK: main.pseudo.exit:
491 ; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
492 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
493 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
494 ; CHECK: exit.loopexit:
495 ; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
496 ; CHECK-NEXT: br label [[EXIT]]
498 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA16]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
499 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
500 ; CHECK: check_failed.loopexit:
501 ; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]
502 ; CHECK: check_failed.loopexit17:
503 ; CHECK-NEXT: br label [[CHECK_FAILED]]
504 ; CHECK: check_failed:
505 ; CHECK-NEXT: ret i32 -1
507 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
508 ; CHECK: loop.postloop:
509 ; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
510 ; CHECK-NEXT: [[RC1_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M1]]
511 ; CHECK-NEXT: [[RC2_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M2]]
512 ; CHECK-NEXT: [[RC3_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M3]]
513 ; CHECK-NEXT: [[RC4_POSTLOOP:%.*]] = icmp slt i64 [[IV_POSTLOOP]], [[M4]]
514 ; CHECK-NEXT: [[C1_POSTLOOP:%.*]] = and i1 [[RC1_POSTLOOP]], [[RC2_POSTLOOP]]
515 ; CHECK-NEXT: [[C2_POSTLOOP:%.*]] = and i1 [[C1_POSTLOOP]], [[RC3_POSTLOOP]]
516 ; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = and i1 [[C2_POSTLOOP]], [[RC4_POSTLOOP]]
517 ; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
518 ; CHECK: backedge.postloop:
519 ; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
520 ; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
521 ; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp slt i32 [[NARROW_IV_POSTLOOP]], [[N]]
522 ; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP12:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
526 %N = load i32, ptr %n_ptr, !range !2
527 %M1 = load i64, ptr %m1_ptr
528 %M2 = load i64, ptr %m2_ptr
529 %M3 = load i64, ptr %m3_ptr
530 %M4 = load i64, ptr %m4_ptr
534 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
535 %rc1 = icmp slt i64 %iv, %M1
536 %rc2 = icmp slt i64 %iv, %M2
537 %rc3 = icmp slt i64 %iv, %M3
538 %rc4 = icmp slt i64 %iv, %M4
539 %c1 = and i1 %rc1, %rc2
540 %c2 = and i1 %c1, %rc3
541 %rc = and i1 %c2, %rc4
542 br i1 %rc, label %backedge, label %check_failed
545 %iv.next = add i64 %iv, 1
546 %narrow.iv = trunc i64 %iv.next to i32
547 %latch.cond = icmp slt i32 %narrow.iv, %N
548 br i1 %latch.cond, label %loop, label %exit
557 ; Wide IV against narrow range check. We don't currently support it.
558 define i32 @test_increasing_slt_slt_wide_simple_negtest_narrow_rc() {
559 ; CHECK-LABEL: define i32 @test_increasing_slt_slt_wide_simple_negtest_narrow_rc() {
561 ; CHECK-NEXT: br label [[LOOP:%.*]]
563 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
564 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
565 ; CHECK-NEXT: [[RC:%.*]] = icmp slt i32 [[NARROW_IV]], 101
566 ; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]
568 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
569 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i64 [[IV]], 100
570 ; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]
572 ; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
573 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA1]]
574 ; CHECK: check_failed:
575 ; CHECK-NEXT: ret i32 -1
582 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
583 %narrow.iv = trunc i64 %iv to i32
584 %rc = icmp slt i32 %narrow.iv, 101
585 br i1 %rc, label %backedge, label %check_failed
588 %iv.next = add i64 %iv, 1
589 %latch.cond = icmp slt i64 %iv, 100
590 br i1 %latch.cond, label %loop, label %exit
599 ; Check that we can remove trivially non-failing range check.
600 define i32 @test_increasing_ult_ult_wide_simple_no_postloop() {
601 ; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_simple_no_postloop() {
603 ; CHECK-NEXT: br label [[LOOP:%.*]]
605 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
606 ; CHECK-NEXT: [[RC:%.*]] = icmp ult i64 [[IV]], 100
607 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]
609 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
610 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
611 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], 100
612 ; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]
614 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
615 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
616 ; CHECK: check_failed:
617 ; CHECK-NEXT: ret i32 -1
624 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
625 %rc = icmp ult i64 %iv, 100
626 br i1 %rc, label %backedge, label %check_failed
629 %iv.next = add i64 %iv, 1
630 %narrow.iv = trunc i64 %iv.next to i32
631 %latch.cond = icmp ult i32 %narrow.iv, 100
632 br i1 %latch.cond, label %loop, label %exit
641 ; This range check fails on the last iteration, so it needs a postloop.
642 define i32 @test_increasing_ult_ult_wide_simple_postloop() {
643 ; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_simple_postloop() {
645 ; CHECK-NEXT: br i1 true, label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
646 ; CHECK: loop.preheader:
647 ; CHECK-NEXT: br label [[LOOP:%.*]]
649 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
650 ; CHECK-NEXT: [[RC:%.*]] = icmp ult i64 [[IV]], 99
651 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
653 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
654 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
655 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], 100
656 ; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64
657 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], 99
658 ; CHECK-NEXT: br i1 [[TMP0]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
659 ; CHECK: main.exit.selector:
660 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
661 ; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
662 ; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
663 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], 100
664 ; CHECK-NEXT: br i1 [[TMP1]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
665 ; CHECK: main.pseudo.exit:
666 ; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
667 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
668 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
669 ; CHECK: exit.loopexit:
670 ; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
671 ; CHECK-NEXT: br label [[EXIT]]
673 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
674 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
675 ; CHECK: check_failed.loopexit:
676 ; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]
677 ; CHECK: check_failed.loopexit2:
678 ; CHECK-NEXT: br label [[CHECK_FAILED]]
679 ; CHECK: check_failed:
680 ; CHECK-NEXT: ret i32 -1
682 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
683 ; CHECK: loop.postloop:
684 ; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
685 ; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], 99
686 ; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
687 ; CHECK: backedge.postloop:
688 ; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
689 ; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
690 ; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], 100
691 ; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP13:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
698 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
699 %rc = icmp ult i64 %iv, 99
700 br i1 %rc, label %backedge, label %check_failed
703 %iv.next = add i64 %iv, 1
704 %narrow.iv = trunc i64 %iv.next to i32
705 %latch.cond = icmp ult i32 %narrow.iv, 100
706 br i1 %latch.cond, label %loop, label %exit
715 ; General case. If both %N and %M are non-negative, we do not need a preloop.
716 define i32 @test_increasing_ult_ult_wide_non-negative(ptr %n_ptr, ptr %m_ptr) {
717 ; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_non-negative
718 ; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
720 ; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
721 ; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4, !range [[RNG7]]
722 ; CHECK-NEXT: [[TMP0:%.*]] = zext nneg i32 [[N]] to i64
723 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[M]], i64 [[TMP0]])
724 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]
725 ; CHECK-NEXT: br i1 [[TMP1]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
726 ; CHECK: loop.preheader:
727 ; CHECK-NEXT: br label [[LOOP:%.*]]
729 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
730 ; CHECK-NEXT: [[RC:%.*]] = icmp ult i64 [[IV]], [[M]]
731 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
733 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
734 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
735 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], [[N]]
736 ; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64
737 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
738 ; CHECK-NEXT: br i1 [[TMP2]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
739 ; CHECK: main.exit.selector:
740 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
741 ; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
742 ; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
743 ; CHECK-NEXT: [[WIDE_N:%.*]] = zext i32 [[N]] to i64
744 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
745 ; CHECK-NEXT: br i1 [[TMP3]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
746 ; CHECK: main.pseudo.exit:
747 ; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
748 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
749 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
750 ; CHECK: exit.loopexit:
751 ; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
752 ; CHECK-NEXT: br label [[EXIT]]
754 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
755 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
756 ; CHECK: check_failed.loopexit:
757 ; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]
758 ; CHECK: check_failed.loopexit2:
759 ; CHECK-NEXT: br label [[CHECK_FAILED]]
760 ; CHECK: check_failed:
761 ; CHECK-NEXT: ret i32 -1
763 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
764 ; CHECK: loop.postloop:
765 ; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
766 ; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M]]
767 ; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
768 ; CHECK: backedge.postloop:
769 ; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
770 ; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
771 ; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], [[N]]
772 ; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP14:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
776 %N = load i32, ptr %n_ptr, !range !2
777 %M = load i64, ptr %m_ptr, !range !1
781 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
782 %rc = icmp ult i64 %iv, %M
783 br i1 %rc, label %backedge, label %check_failed
786 %iv.next = add i64 %iv, 1
787 %narrow.iv = trunc i64 %iv.next to i32
788 %latch.cond = icmp ult i32 %narrow.iv, %N
789 br i1 %latch.cond, label %loop, label %exit
798 ; General case. Even though %M may be negative, we do not need a preloop because
799 ; we make a non-negativity runtime check against M and do not go to main loop if
801 define i32 @test_increasing_ult_ult_wide_general(ptr %n_ptr, ptr %m_ptr) {
802 ; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_general
803 ; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M_PTR:%.*]]) {
805 ; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
806 ; CHECK-NEXT: [[M:%.*]] = load i64, ptr [[M_PTR]], align 4
807 ; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M]], i64 0)
808 ; CHECK-NEXT: [[TMP0:%.*]] = sub i64 [[M]], [[SMIN]]
809 ; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
810 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[SMAX]], 1
811 ; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP0]], [[TMP1]]
812 ; CHECK-NEXT: [[TMP3:%.*]] = zext nneg i32 [[N]] to i64
813 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP2]], i64 [[TMP3]])
814 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]
815 ; CHECK-NEXT: br i1 [[TMP4]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
816 ; CHECK: loop.preheader:
817 ; CHECK-NEXT: br label [[LOOP:%.*]]
819 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
820 ; CHECK-NEXT: [[RC:%.*]] = icmp ult i64 [[IV]], [[M]]
821 ; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT2:%.*]]
823 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
824 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
825 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], [[N]]
826 ; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64
827 ; CHECK-NEXT: [[TMP5:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
828 ; CHECK-NEXT: br i1 [[TMP5]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
829 ; CHECK: main.exit.selector:
830 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
831 ; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
832 ; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
833 ; CHECK-NEXT: [[WIDE_N:%.*]] = zext i32 [[N]] to i64
834 ; CHECK-NEXT: [[TMP6:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
835 ; CHECK-NEXT: br i1 [[TMP6]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
836 ; CHECK: main.pseudo.exit:
837 ; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
838 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
839 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
840 ; CHECK: exit.loopexit:
841 ; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
842 ; CHECK-NEXT: br label [[EXIT]]
844 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA1]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
845 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
846 ; CHECK: check_failed.loopexit:
847 ; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]
848 ; CHECK: check_failed.loopexit2:
849 ; CHECK-NEXT: br label [[CHECK_FAILED]]
850 ; CHECK: check_failed:
851 ; CHECK-NEXT: ret i32 -1
853 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
854 ; CHECK: loop.postloop:
855 ; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
856 ; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M]]
857 ; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
858 ; CHECK: backedge.postloop:
859 ; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
860 ; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
861 ; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], [[N]]
862 ; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP15:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
866 %N = load i32, ptr %n_ptr, !range !2
867 %M = load i64, ptr %m_ptr
871 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
872 %rc = icmp ult i64 %iv, %M
873 br i1 %rc, label %backedge, label %check_failed
876 %iv.next = add i64 %iv, 1
877 %narrow.iv = trunc i64 %iv.next to i32
878 %latch.cond = icmp ult i32 %narrow.iv, %N
879 br i1 %latch.cond, label %loop, label %exit
888 ; Same as above, multiple checks.
889 define i32 @test_increasing_ult_ult_wide_multiple_checks(ptr %n_ptr, ptr %m1_ptr, ptr %m2_ptr, ptr %m3_ptr, ptr %m4_ptr) {
890 ; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_multiple_checks
891 ; CHECK-SAME: (ptr [[N_PTR:%.*]], ptr [[M1_PTR:%.*]], ptr [[M2_PTR:%.*]], ptr [[M3_PTR:%.*]], ptr [[M4_PTR:%.*]]) {
893 ; CHECK-NEXT: [[N:%.*]] = load i32, ptr [[N_PTR]], align 4, !range [[RNG6]]
894 ; CHECK-NEXT: [[M1:%.*]] = load i64, ptr [[M1_PTR]], align 4
895 ; CHECK-NEXT: [[M2:%.*]] = load i64, ptr [[M2_PTR]], align 4
896 ; CHECK-NEXT: [[M3:%.*]] = load i64, ptr [[M3_PTR]], align 4
897 ; CHECK-NEXT: [[M4:%.*]] = load i64, ptr [[M4_PTR]], align 4
898 ; CHECK-NEXT: [[SMIN:%.*]] = call i64 @llvm.smin.i64(i64 [[M2]], i64 0)
899 ; CHECK-NEXT: [[TMP0:%.*]] = sub i64 [[M2]], [[SMIN]]
900 ; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN]], i64 -1)
901 ; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[SMAX]], 1
902 ; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[TMP0]], [[TMP1]]
903 ; CHECK-NEXT: [[SMIN1:%.*]] = call i64 @llvm.smin.i64(i64 [[M1]], i64 0)
904 ; CHECK-NEXT: [[TMP3:%.*]] = sub i64 [[M1]], [[SMIN1]]
905 ; CHECK-NEXT: [[SMAX2:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN1]], i64 -1)
906 ; CHECK-NEXT: [[TMP4:%.*]] = add nsw i64 [[SMAX2]], 1
907 ; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP3]], [[TMP4]]
908 ; CHECK-NEXT: [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[TMP2]], i64 [[TMP5]])
909 ; CHECK-NEXT: [[SMIN3:%.*]] = call i64 @llvm.smin.i64(i64 [[M3]], i64 0)
910 ; CHECK-NEXT: [[TMP6:%.*]] = sub i64 [[M3]], [[SMIN3]]
911 ; CHECK-NEXT: [[SMAX4:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN3]], i64 -1)
912 ; CHECK-NEXT: [[TMP7:%.*]] = add nsw i64 [[SMAX4]], 1
913 ; CHECK-NEXT: [[TMP8:%.*]] = mul i64 [[TMP6]], [[TMP7]]
914 ; CHECK-NEXT: [[UMIN5:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN]], i64 [[TMP8]])
915 ; CHECK-NEXT: [[SMIN6:%.*]] = call i64 @llvm.smin.i64(i64 [[M4]], i64 0)
916 ; CHECK-NEXT: [[TMP9:%.*]] = sub i64 [[M4]], [[SMIN6]]
917 ; CHECK-NEXT: [[SMAX7:%.*]] = call i64 @llvm.smax.i64(i64 [[SMIN6]], i64 -1)
918 ; CHECK-NEXT: [[TMP10:%.*]] = add nsw i64 [[SMAX7]], 1
919 ; CHECK-NEXT: [[TMP11:%.*]] = mul i64 [[TMP9]], [[TMP10]]
920 ; CHECK-NEXT: [[UMIN8:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN5]], i64 [[TMP11]])
921 ; CHECK-NEXT: [[TMP12:%.*]] = zext nneg i32 [[N]] to i64
922 ; CHECK-NEXT: [[EXIT_MAINLOOP_AT:%.*]] = call i64 @llvm.umin.i64(i64 [[UMIN8]], i64 [[TMP12]])
923 ; CHECK-NEXT: [[TMP13:%.*]] = icmp ult i64 0, [[EXIT_MAINLOOP_AT]]
924 ; CHECK-NEXT: br i1 [[TMP13]], label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
925 ; CHECK: loop.preheader:
926 ; CHECK-NEXT: br label [[LOOP:%.*]]
928 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
929 ; CHECK-NEXT: [[RC1:%.*]] = icmp ult i64 [[IV]], [[M1]]
930 ; CHECK-NEXT: [[RC2:%.*]] = icmp ult i64 [[IV]], [[M2]]
931 ; CHECK-NEXT: [[RC3:%.*]] = icmp ult i64 [[IV]], [[M3]]
932 ; CHECK-NEXT: [[RC4:%.*]] = icmp ult i64 [[IV]], [[M4]]
933 ; CHECK-NEXT: [[C1:%.*]] = and i1 true, true
934 ; CHECK-NEXT: [[C2:%.*]] = and i1 [[C1]], true
935 ; CHECK-NEXT: [[RC:%.*]] = and i1 [[C2]], true
936 ; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED_LOOPEXIT11:%.*]]
938 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
939 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV_NEXT]] to i32
940 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i32 [[NARROW_IV]], [[N]]
941 ; CHECK-NEXT: [[WIDE_NARROW_IV:%.*]] = zext i32 [[NARROW_IV]] to i64
942 ; CHECK-NEXT: [[TMP14:%.*]] = icmp ult i64 [[WIDE_NARROW_IV]], [[EXIT_MAINLOOP_AT]]
943 ; CHECK-NEXT: br i1 [[TMP14]], label [[LOOP]], label [[MAIN_EXIT_SELECTOR:%.*]]
944 ; CHECK: main.exit.selector:
945 ; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], [[BACKEDGE]] ]
946 ; CHECK-NEXT: [[NARROW_IV_LCSSA10:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
947 ; CHECK-NEXT: [[WIDE_NARROW_IV_LCSSA:%.*]] = phi i64 [ [[WIDE_NARROW_IV]], [[BACKEDGE]] ]
948 ; CHECK-NEXT: [[WIDE_N:%.*]] = zext i32 [[N]] to i64
949 ; CHECK-NEXT: [[TMP15:%.*]] = icmp ult i64 [[WIDE_NARROW_IV_LCSSA]], [[WIDE_N]]
950 ; CHECK-NEXT: br i1 [[TMP15]], label [[MAIN_PSEUDO_EXIT]], label [[EXIT:%.*]]
951 ; CHECK: main.pseudo.exit:
952 ; CHECK-NEXT: [[IV_COPY:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
953 ; CHECK-NEXT: [[INDVAR_END:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[WIDE_NARROW_IV_LCSSA]], [[MAIN_EXIT_SELECTOR]] ]
954 ; CHECK-NEXT: br label [[POSTLOOP:%.*]]
955 ; CHECK: exit.loopexit:
956 ; CHECK-NEXT: [[NARROW_IV_LCSSA_PH:%.*]] = phi i32 [ [[NARROW_IV_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP:%.*]] ]
957 ; CHECK-NEXT: br label [[EXIT]]
959 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i32 [ [[NARROW_IV_LCSSA10]], [[MAIN_EXIT_SELECTOR]] ], [ [[NARROW_IV_LCSSA_PH]], [[EXIT_LOOPEXIT:%.*]] ]
960 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA]]
961 ; CHECK: check_failed.loopexit:
962 ; CHECK-NEXT: br label [[CHECK_FAILED:%.*]]
963 ; CHECK: check_failed.loopexit11:
964 ; CHECK-NEXT: br label [[CHECK_FAILED]]
965 ; CHECK: check_failed:
966 ; CHECK-NEXT: ret i32 -1
968 ; CHECK-NEXT: br label [[LOOP_POSTLOOP:%.*]]
969 ; CHECK: loop.postloop:
970 ; CHECK-NEXT: [[IV_POSTLOOP:%.*]] = phi i64 [ [[IV_COPY]], [[POSTLOOP]] ], [ [[IV_NEXT_POSTLOOP:%.*]], [[BACKEDGE_POSTLOOP]] ]
971 ; CHECK-NEXT: [[RC1_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M1]]
972 ; CHECK-NEXT: [[RC2_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M2]]
973 ; CHECK-NEXT: [[RC3_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M3]]
974 ; CHECK-NEXT: [[RC4_POSTLOOP:%.*]] = icmp ult i64 [[IV_POSTLOOP]], [[M4]]
975 ; CHECK-NEXT: [[C1_POSTLOOP:%.*]] = and i1 [[RC1_POSTLOOP]], [[RC2_POSTLOOP]]
976 ; CHECK-NEXT: [[C2_POSTLOOP:%.*]] = and i1 [[C1_POSTLOOP]], [[RC3_POSTLOOP]]
977 ; CHECK-NEXT: [[RC_POSTLOOP:%.*]] = and i1 [[C2_POSTLOOP]], [[RC4_POSTLOOP]]
978 ; CHECK-NEXT: br i1 [[RC_POSTLOOP]], label [[BACKEDGE_POSTLOOP]], label [[CHECK_FAILED_LOOPEXIT:%.*]]
979 ; CHECK: backedge.postloop:
980 ; CHECK-NEXT: [[IV_NEXT_POSTLOOP]] = add i64 [[IV_POSTLOOP]], 1
981 ; CHECK-NEXT: [[NARROW_IV_POSTLOOP]] = trunc i64 [[IV_NEXT_POSTLOOP]] to i32
982 ; CHECK-NEXT: [[LATCH_COND_POSTLOOP:%.*]] = icmp ult i32 [[NARROW_IV_POSTLOOP]], [[N]]
983 ; CHECK-NEXT: br i1 [[LATCH_COND_POSTLOOP]], label [[LOOP_POSTLOOP]], label [[EXIT_LOOPEXIT]], !llvm.loop [[LOOP16:![0-9]+]], !loop_constrainer.loop.clone [[META5]]
987 %N = load i32, ptr %n_ptr, !range !2
988 %M1 = load i64, ptr %m1_ptr
989 %M2 = load i64, ptr %m2_ptr
990 %M3 = load i64, ptr %m3_ptr
991 %M4 = load i64, ptr %m4_ptr
995 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
996 %rc1 = icmp ult i64 %iv, %M1
997 %rc2 = icmp ult i64 %iv, %M2
998 %rc3 = icmp ult i64 %iv, %M3
999 %rc4 = icmp ult i64 %iv, %M4
1000 %c1 = and i1 %rc1, %rc2
1001 %c2 = and i1 %c1, %rc3
1002 %rc = and i1 %c2, %rc4
1003 br i1 %rc, label %backedge, label %check_failed
1006 %iv.next = add i64 %iv, 1
1007 %narrow.iv = trunc i64 %iv.next to i32
1008 %latch.cond = icmp ult i32 %narrow.iv, %N
1009 br i1 %latch.cond, label %loop, label %exit
1018 ; Wide IV against narrow range check. We don't currently support it.
1019 define i32 @test_increasing_ult_ult_wide_simple_negtest_narrow_rc() {
1020 ; CHECK-LABEL: define i32 @test_increasing_ult_ult_wide_simple_negtest_narrow_rc() {
1021 ; CHECK-NEXT: entry:
1022 ; CHECK-NEXT: br label [[LOOP:%.*]]
1024 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
1025 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
1026 ; CHECK-NEXT: [[RC:%.*]] = icmp ult i32 [[NARROW_IV]], 101
1027 ; CHECK-NEXT: br i1 [[RC]], label [[BACKEDGE]], label [[CHECK_FAILED:%.*]]
1029 ; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
1030 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp ult i64 [[IV]], 100
1031 ; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]
1033 ; CHECK-NEXT: [[NARROW_IV_LCSSA1:%.*]] = phi i32 [ [[NARROW_IV]], [[BACKEDGE]] ]
1034 ; CHECK-NEXT: ret i32 [[NARROW_IV_LCSSA1]]
1035 ; CHECK: check_failed:
1036 ; CHECK-NEXT: ret i32 -1
1043 %iv = phi i64 [ 0, %entry ], [ %iv.next, %backedge ]
1044 %narrow.iv = trunc i64 %iv to i32
1045 %rc = icmp ult i32 %narrow.iv, 101
1046 br i1 %rc, label %backedge, label %check_failed
1049 %iv.next = add i64 %iv, 1
1050 %latch.cond = icmp ult i64 %iv, 100
1051 br i1 %latch.cond, label %loop, label %exit
1060 ; Check that fake wide exit doesn't inhibit the transform.
1061 define i16 @test_fake_wide_exit(i64 %x) {
1062 ; CHECK-LABEL: define i16 @test_fake_wide_exit
1063 ; CHECK-SAME: (i64 [[X:%.*]]) {
1064 ; CHECK-NEXT: entry:
1065 ; CHECK-NEXT: br label [[LOOP:%.*]]
1067 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
1068 ; CHECK-NEXT: [[IV_WIDE:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[IV_WIDE_NEXT:%.*]], [[BACKEDGE]] ]
1069 ; CHECK-NEXT: [[RC:%.*]] = icmp slt i32 [[IV]], 100
1070 ; CHECK-NEXT: br i1 true, label [[CHECKED:%.*]], label [[CHECK_FAILED:%.*]]
1072 ; CHECK-NEXT: [[RC_WIDE:%.*]] = icmp ult i64 [[IV_WIDE]], [[X]]
1073 ; CHECK-NEXT: br i1 [[RC_WIDE]], label [[BACKEDGE]], label [[CHECK_FAILED]]
1075 ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
1076 ; CHECK-NEXT: [[IV_WIDE_NEXT]] = add i64 [[IV_WIDE]], 1
1077 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i32 [[IV_NEXT]] to i16
1078 ; CHECK-NEXT: [[LATCH_COND:%.*]] = icmp slt i16 [[NARROW_IV]], 100
1079 ; CHECK-NEXT: br i1 [[LATCH_COND]], label [[LOOP]], label [[EXIT:%.*]]
1081 ; CHECK-NEXT: [[NARROW_IV_LCSSA:%.*]] = phi i16 [ [[NARROW_IV]], [[BACKEDGE]] ]
1082 ; CHECK-NEXT: ret i16 [[NARROW_IV_LCSSA]]
1083 ; CHECK: check_failed:
1084 ; CHECK-NEXT: ret i16 -1
1090 %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]
1091 %iv.wide = phi i64 [ 0, %entry ], [ %iv.wide.next, %backedge ]
1092 %rc = icmp slt i32 %iv, 100
1093 br i1 %rc, label %checked, label %check_failed
1096 %rc.wide = icmp ult i64 %iv.wide, %x
1097 br i1 %rc.wide, label %backedge, label %check_failed
1100 %iv.next = add i32 %iv, 1
1101 %iv.wide.next = add i64 %iv.wide, 1
1102 %narrow.iv = trunc i32 %iv.next to i16
1103 %latch.cond = icmp slt i16 %narrow.iv, 100
1104 br i1 %latch.cond, label %loop, label %exit
1114 !0 = !{i32 0, i32 2147483647}
1115 !1 = !{i64 0, i64 9223372036854775807}
1116 !2 = !{i32 1, i32 2147483647}