[DAG] TransformFPLoadStorePair - early out if we're not loading a simple type
[llvm-project.git] / llvm / test / Transforms / IRCE / wide_indvar.ll
blobb9be8ae8417353b912db1cd4a828a964e3bb3719
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() {
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    br label [[LOOP:%.*]]
10 ; CHECK:       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:%.*]]
14 ; CHECK:       backedge:
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:%.*]]
19 ; CHECK:       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
26 entry:
27   br label %loop
29 loop:
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
34 backedge:
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
40 exit:
41   ret i32 %narrow.iv
43 check_failed:
44   ret i32 -1
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() {
50 ; CHECK-NEXT:  entry:
51 ; CHECK-NEXT:    br i1 true, label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
52 ; CHECK:       loop.preheader:
53 ; CHECK-NEXT:    br label [[LOOP:%.*]]
54 ; CHECK:       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:%.*]]
58 ; CHECK:       backedge:
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]]
78 ; CHECK:       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
87 ; CHECK:       postloop:
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]+]]
100 entry:
101   br label %loop
103 loop:
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
108 backedge:
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
114 exit:
115   ret i32 %narrow.iv
117 check_failed:
118   ret i32 -1
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:%.*]]) {
125 ; CHECK-NEXT:  entry:
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:%.*]]
134 ; CHECK:       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:%.*]]
138 ; CHECK:       backedge:
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]]
159 ; CHECK:       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
168 ; CHECK:       postloop:
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]]
181 entry:
182   %N = load i32, ptr %n_ptr, !range !2
183   %M = load i64, ptr %m_ptr, !range !1
184   br label %loop
186 loop:
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
191 backedge:
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
197 exit:
198   ret i32 %narrow.iv
200 check_failed:
201   ret i32 -1
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
206 ; M was negative.
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:%.*]]) {
210 ; CHECK-NEXT:  entry:
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:%.*]]
227 ; CHECK:       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:%.*]]
231 ; CHECK:       backedge:
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]]
252 ; CHECK:       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
261 ; CHECK:       postloop:
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]]
274 entry:
275   %N = load i32, ptr %n_ptr, !range !2
276   %M = load i64, ptr %m_ptr
277   br label %loop
279 loop:
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
284 backedge:
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
290 exit:
291   ret i32 %narrow.iv
293 check_failed:
294   ret i32 -1
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:%.*]]) {
301 ; CHECK-NEXT:  entry:
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:%.*]]
319 ; CHECK:       mainloop:
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:%.*]]
324 ; CHECK:       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:%.*]]
328 ; CHECK:       backedge:
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]]
349 ; CHECK:       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]]
382 ; CHECK:       postloop:
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]]
395 entry:
396   %N = load i32, ptr %n_ptr, !range !2
397   %M = load i64, ptr %m_ptr
398   br label %loop
400 loop:
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
405 backedge:
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
411 exit:
412   ret i32 %narrow.iv
414 check_failed:
415   ret i32 -1
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:%.*]]) {
422 ; CHECK-NEXT:  entry:
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:%.*]]
466 ; CHECK:       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:%.*]]
476 ; CHECK:       backedge:
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]]
497 ; CHECK:       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
506 ; CHECK:       postloop:
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]]
525 entry:
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
531   br label %loop
533 loop:
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
544 backedge:
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
550 exit:
551   ret i32 %narrow.iv
553 check_failed:
554   ret i32 -1
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() {
560 ; CHECK-NEXT:  entry:
561 ; CHECK-NEXT:    br label [[LOOP:%.*]]
562 ; CHECK:       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:%.*]]
567 ; CHECK:       backedge:
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:%.*]]
571 ; CHECK:       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
578 entry:
579   br label %loop
581 loop:
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
587 backedge:
588   %iv.next = add i64 %iv, 1
589   %latch.cond = icmp slt i64 %iv, 100
590   br i1 %latch.cond, label %loop, label %exit
592 exit:
593   ret i32 %narrow.iv
595 check_failed:
596   ret i32 -1
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() {
602 ; CHECK-NEXT:  entry:
603 ; CHECK-NEXT:    br label [[LOOP:%.*]]
604 ; CHECK:       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:%.*]]
608 ; CHECK:       backedge:
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:%.*]]
613 ; CHECK:       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
620 entry:
621   br label %loop
623 loop:
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
628 backedge:
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
634 exit:
635   ret i32 %narrow.iv
637 check_failed:
638   ret i32 -1
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() {
644 ; CHECK-NEXT:  entry:
645 ; CHECK-NEXT:    br i1 true, label [[LOOP_PREHEADER:%.*]], label [[MAIN_PSEUDO_EXIT:%.*]]
646 ; CHECK:       loop.preheader:
647 ; CHECK-NEXT:    br label [[LOOP:%.*]]
648 ; CHECK:       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:%.*]]
652 ; CHECK:       backedge:
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]]
672 ; CHECK:       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
681 ; CHECK:       postloop:
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]]
694 entry:
695   br label %loop
697 loop:
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
702 backedge:
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
708 exit:
709   ret i32 %narrow.iv
711 check_failed:
712   ret i32 -1
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:%.*]]) {
719 ; CHECK-NEXT:  entry:
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:%.*]]
728 ; CHECK:       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:%.*]]
732 ; CHECK:       backedge:
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]]
753 ; CHECK:       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
762 ; CHECK:       postloop:
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]]
775 entry:
776   %N = load i32, ptr %n_ptr, !range !2
777   %M = load i64, ptr %m_ptr, !range !1
778   br label %loop
780 loop:
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
785 backedge:
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
791 exit:
792   ret i32 %narrow.iv
794 check_failed:
795   ret i32 -1
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
800 ; M was negative.
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:%.*]]) {
804 ; CHECK-NEXT:  entry:
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:%.*]]
818 ; CHECK:       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:%.*]]
822 ; CHECK:       backedge:
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]]
843 ; CHECK:       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
852 ; CHECK:       postloop:
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]]
865 entry:
866   %N = load i32, ptr %n_ptr, !range !2
867   %M = load i64, ptr %m_ptr
868   br label %loop
870 loop:
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
875 backedge:
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
881 exit:
882   ret i32 %narrow.iv
884 check_failed:
885   ret i32 -1
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:%.*]]) {
892 ; CHECK-NEXT:  entry:
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:%.*]]
927 ; CHECK:       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:%.*]]
937 ; CHECK:       backedge:
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]]
958 ; CHECK:       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
967 ; CHECK:       postloop:
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]]
986 entry:
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
992   br label %loop
994 loop:
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
1005 backedge:
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
1011 exit:
1012   ret i32 %narrow.iv
1014 check_failed:
1015   ret i32 -1
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:%.*]]
1023 ; CHECK:       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:%.*]]
1028 ; CHECK:       backedge:
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:%.*]]
1032 ; CHECK:       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
1039 entry:
1040   br label %loop
1042 loop:
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
1048 backedge:
1049   %iv.next = add i64 %iv, 1
1050   %latch.cond = icmp ult i64 %iv, 100
1051   br i1 %latch.cond, label %loop, label %exit
1053 exit:
1054   ret i32 %narrow.iv
1056 check_failed:
1057   ret i32 -1
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:%.*]]
1066 ; CHECK:       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:%.*]]
1071 ; CHECK:       checked:
1072 ; CHECK-NEXT:    [[RC_WIDE:%.*]] = icmp ult i64 [[IV_WIDE]], [[X]]
1073 ; CHECK-NEXT:    br i1 [[RC_WIDE]], label [[BACKEDGE]], label [[CHECK_FAILED]]
1074 ; CHECK:       backedge:
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:%.*]]
1080 ; CHECK:       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
1086 entry:
1087   br label %loop
1089 loop:
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
1095 checked:
1096   %rc.wide = icmp ult i64 %iv.wide, %x
1097   br i1 %rc.wide, label %backedge, label %check_failed
1099 backedge:
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
1106 exit:
1107   ret i16 %narrow.iv
1109 check_failed:
1110   ret i16 -1
1114 !0 = !{i32 0, i32 2147483647}
1115 !1 = !{i64 0, i64 9223372036854775807}
1116 !2 = !{i32 1, i32 2147483647}