Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / IndVarSimplify / widen-nonnegative.ll
blobe00eaafa3f19243001d3b2dadc7c2f983958bcee
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -S -passes='indvars' -verify-loop-info -verify-dom-info -verify-scev | FileCheck %s
4 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
6 ; Simple case of direct extend of index
7 ; --------------------------------------
9 define void @sext_no_offset(ptr %A, i32 %M) {
10 ; CHECK-LABEL: @sext_no_offset(
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
13 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
14 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
15 ; CHECK:       for.body:
16 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
17 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
18 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
19 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
20 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
21 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
22 ; CHECK:       exit:
23 ; CHECK-NEXT:    ret void
25 entry:
26   br label %for.body
28 for.body:
29   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
30   %idxprom.us = sext i32 %j.016.us to i64
31   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
32   tail call void @use_ptr(ptr %arrayidx.us)
33   %inc.us = add nuw nsw i32 %j.016.us, 1
34   %cmp2.us = icmp slt i32 %inc.us, %M
35   br i1 %cmp2.us, label %for.body, label %exit
37 exit:
38   ret void
41 define void @zext_no_offset(ptr %A, i32 %M) {
42 ; CHECK-LABEL: @zext_no_offset(
43 ; CHECK-NEXT:  entry:
44 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
45 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
46 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
47 ; CHECK:       for.body:
48 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
49 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
50 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
51 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
52 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
53 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
54 ; CHECK:       exit:
55 ; CHECK-NEXT:    ret void
57 entry:
58   br label %for.body
60 for.body:
61   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
62   %idxprom.us = zext i32 %j.016.us to i64
63   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
64   tail call void @use_ptr(ptr %arrayidx.us)
65   %inc.us = add nuw nsw i32 %j.016.us, 1
66   %cmp2.us = icmp slt i32 %inc.us, %M
67   br i1 %cmp2.us, label %for.body, label %exit
69 exit:
70   ret void
73 define void @zext_nneg_no_offset(ptr %A, i32 %M) {
74 ; CHECK-LABEL: @zext_nneg_no_offset(
75 ; CHECK-NEXT:  entry:
76 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
77 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
78 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
79 ; CHECK:       for.body:
80 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
81 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
82 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
83 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
84 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
85 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
86 ; CHECK:       exit:
87 ; CHECK-NEXT:    ret void
89 entry:
90   br label %for.body
92 for.body:
93   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
94   %idxprom.us = zext nneg i32 %j.016.us to i64
95   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
96   tail call void @use_ptr(ptr %arrayidx.us)
97   %inc.us = add nuw nsw i32 %j.016.us, 1
98   %cmp2.us = icmp slt i32 %inc.us, %M
99   br i1 %cmp2.us, label %for.body, label %exit
101 exit:
102   ret void
105 ; Offset with a loop invariant value, various combinations
106 ; --------------------------------------
108 define void @sext_add_nsw(ptr %A, i32 %offset, i32 %M) {
109 ; CHECK-LABEL: @sext_add_nsw(
110 ; CHECK-NEXT:  entry:
111 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[OFFSET:%.*]] to i64
112 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
113 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
114 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
115 ; CHECK:       for.body:
116 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
117 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], [[TMP0]]
118 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
119 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
120 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
121 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
122 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
123 ; CHECK:       exit:
124 ; CHECK-NEXT:    ret void
126 entry:
127   br label %for.body
129 for.body:
130   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
131   %add.us = add nsw i32 %j.016.us, %offset
132   %idxprom.us = sext i32 %add.us to i64
133   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
134   tail call void @use_ptr(ptr %arrayidx.us)
135   %inc.us = add nuw nsw i32 %j.016.us, 1
136   %cmp2.us = icmp slt i32 %inc.us, %M
137   br i1 %cmp2.us, label %for.body, label %exit
139 exit:
140   ret void
143 define void @sext_add_nuw(ptr %A, i32 %offset, i32 %M) {
144 ; CHECK-LABEL: @sext_add_nuw(
145 ; CHECK-NEXT:  entry:
146 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[OFFSET:%.*]] to i64
147 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
148 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
149 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
150 ; CHECK:       for.body:
151 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
152 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
153 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc nuw i64 [[TMP1]] to i32
154 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[TMP2]] to i64
155 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
156 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
157 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
158 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
159 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
160 ; CHECK:       exit:
161 ; CHECK-NEXT:    ret void
163 entry:
164   br label %for.body
166 for.body:
167   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
168   %add.us = add nuw i32 %j.016.us, %offset
169   %idxprom.us = sext i32 %add.us to i64
170   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
171   tail call void @use_ptr(ptr %arrayidx.us)
172   %inc.us = add nuw nsw i32 %j.016.us, 1
173   %cmp2.us = icmp slt i32 %inc.us, %M
174   br i1 %cmp2.us, label %for.body, label %exit
176 exit:
177   ret void
180 define void @sext_add_noflags(ptr %A, i32 %offset, i32 %M) {
181 ; CHECK-LABEL: @sext_add_noflags(
182 ; CHECK-NEXT:  entry:
183 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
184 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
185 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
186 ; CHECK:       for.body:
187 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
188 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32
189 ; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP0]], [[OFFSET:%.*]]
190 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
191 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
192 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
193 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
194 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
195 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
196 ; CHECK:       exit:
197 ; CHECK-NEXT:    ret void
199 entry:
200   br label %for.body
202 for.body:
203   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
204   %add.us = add i32 %j.016.us, %offset
205   %idxprom.us = sext i32 %add.us to i64
206   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
207   tail call void @use_ptr(ptr %arrayidx.us)
208   %inc.us = add nuw nsw i32 %j.016.us, 1
209   %cmp2.us = icmp slt i32 %inc.us, %M
210   br i1 %cmp2.us, label %for.body, label %exit
212 exit:
213   ret void
216 define void @zext_add_nsw(ptr %A, i32 %offset, i32 %M) {
217 ; CHECK-LABEL: @zext_add_nsw(
218 ; CHECK-NEXT:  entry:
219 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[OFFSET:%.*]] to i64
220 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
221 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
222 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
223 ; CHECK:       for.body:
224 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
225 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], [[TMP0]]
226 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc nsw i64 [[TMP1]] to i32
227 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[TMP2]] to i64
228 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
229 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
230 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
231 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
232 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
233 ; CHECK:       exit:
234 ; CHECK-NEXT:    ret void
236 entry:
237   br label %for.body
239 for.body:
240   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
241   %add.us = add nsw i32 %j.016.us, %offset
242   %idxprom.us = zext i32 %add.us to i64
243   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
244   tail call void @use_ptr(ptr %arrayidx.us)
245   %inc.us = add nuw nsw i32 %j.016.us, 1
246   %cmp2.us = icmp slt i32 %inc.us, %M
247   br i1 %cmp2.us, label %for.body, label %exit
249 exit:
250   ret void
253 define void @zext_add_nuw(ptr %A, i32 %offset, i32 %M) {
254 ; CHECK-LABEL: @zext_add_nuw(
255 ; CHECK-NEXT:  entry:
256 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[OFFSET:%.*]] to i64
257 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
258 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
259 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
260 ; CHECK:       for.body:
261 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
262 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
263 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
264 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
265 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
266 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
267 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
268 ; CHECK:       exit:
269 ; CHECK-NEXT:    ret void
271 entry:
272   br label %for.body
274 for.body:
275   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
276   %add.us = add nuw i32 %j.016.us, %offset
277   %idxprom.us = zext i32 %add.us to i64
278   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
279   tail call void @use_ptr(ptr %arrayidx.us)
280   %inc.us = add nuw nsw i32 %j.016.us, 1
281   %cmp2.us = icmp slt i32 %inc.us, %M
282   br i1 %cmp2.us, label %for.body, label %exit
284 exit:
285   ret void
288 define void @zext_add_noflags(ptr %A, i32 %offset, i32 %M) {
289 ; CHECK-LABEL: @zext_add_noflags(
290 ; CHECK-NEXT:  entry:
291 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
292 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
293 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
294 ; CHECK:       for.body:
295 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
296 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32
297 ; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP0]], [[OFFSET:%.*]]
298 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64
299 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
300 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
301 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
302 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
303 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
304 ; CHECK:       exit:
305 ; CHECK-NEXT:    ret void
307 entry:
308   br label %for.body
310 for.body:
311   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
312   %add.us = add i32 %j.016.us, %offset
313   %idxprom.us = zext i32 %add.us to i64
314   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
315   tail call void @use_ptr(ptr %arrayidx.us)
316   %inc.us = add nuw nsw i32 %j.016.us, 1
317   %cmp2.us = icmp slt i32 %inc.us, %M
318   br i1 %cmp2.us, label %for.body, label %exit
320 exit:
321   ret void
324 define void @zext_nneg_add_nsw(ptr %A, i32 %offset, i32 %M) {
325 ; CHECK-LABEL: @zext_nneg_add_nsw(
326 ; CHECK-NEXT:  entry:
327 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[OFFSET:%.*]] to i64
328 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
329 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
330 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
331 ; CHECK:       for.body:
332 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
333 ; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], [[TMP0]]
334 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
335 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
336 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
337 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
338 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
339 ; CHECK:       exit:
340 ; CHECK-NEXT:    ret void
342 entry:
343   br label %for.body
345 for.body:
346   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
347   %add.us = add nsw i32 %j.016.us, %offset
348   %idxprom.us = zext nneg i32 %add.us to i64
349   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
350   tail call void @use_ptr(ptr %arrayidx.us)
351   %inc.us = add nuw nsw i32 %j.016.us, 1
352   %cmp2.us = icmp slt i32 %inc.us, %M
353   br i1 %cmp2.us, label %for.body, label %exit
355 exit:
356   ret void
359 define void @zext_nneg_add_nuw(ptr %A, i32 %offset, i32 %M) {
360 ; CHECK-LABEL: @zext_nneg_add_nuw(
361 ; CHECK-NEXT:  entry:
362 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[OFFSET:%.*]] to i64
363 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
364 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
365 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
366 ; CHECK:       for.body:
367 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
368 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
369 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
370 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
371 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
372 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
373 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
374 ; CHECK:       exit:
375 ; CHECK-NEXT:    ret void
377 entry:
378   br label %for.body
380 for.body:
381   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
382   %add.us = add nuw i32 %j.016.us, %offset
383   %idxprom.us = zext nneg i32 %add.us to i64
384   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
385   tail call void @use_ptr(ptr %arrayidx.us)
386   %inc.us = add nuw nsw i32 %j.016.us, 1
387   %cmp2.us = icmp slt i32 %inc.us, %M
388   br i1 %cmp2.us, label %for.body, label %exit
390 exit:
391   ret void
394 define void @zext_nneg_add_noflags(ptr %A, i32 %offset, i32 %M) {
395 ; CHECK-LABEL: @zext_nneg_add_noflags(
396 ; CHECK-NEXT:  entry:
397 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
398 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
399 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
400 ; CHECK:       for.body:
401 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
402 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32
403 ; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP0]], [[OFFSET:%.*]]
404 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext nneg i32 [[ADD_US]] to i64
405 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
406 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
407 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
408 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
409 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
410 ; CHECK:       exit:
411 ; CHECK-NEXT:    ret void
413 entry:
414   br label %for.body
416 for.body:
417   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
418   %add.us = add i32 %j.016.us, %offset
419   %idxprom.us = zext nneg i32 %add.us to i64
420   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
421   tail call void @use_ptr(ptr %arrayidx.us)
422   %inc.us = add nuw nsw i32 %j.016.us, 1
423   %cmp2.us = icmp slt i32 %inc.us, %M
424   br i1 %cmp2.us, label %for.body, label %exit
426 exit:
427   ret void
430 ; Offset is multiplied by a multiple
431 ; --------------------------------------
433 define void @sext_mul_nsw(ptr %A, i32 %multiple, i32 %M) {
434 ; CHECK-LABEL: @sext_mul_nsw(
435 ; CHECK-NEXT:  entry:
436 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[MULTIPLE:%.*]] to i64
437 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
438 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
439 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
440 ; CHECK:       for.body:
441 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
442 ; CHECK-NEXT:    [[TMP1:%.*]] = mul nsw i64 [[INDVARS_IV]], [[TMP0]]
443 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
444 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
445 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
446 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
447 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
448 ; CHECK:       exit:
449 ; CHECK-NEXT:    ret void
451 entry:
452   br label %for.body
454 for.body:
455   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
456   %mul.us = mul nsw i32 %j.016.us, %multiple
457   %idxprom.us = sext i32 %mul.us to i64
458   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
459   tail call void @use_ptr(ptr %arrayidx.us)
460   %inc.us = add nuw nsw i32 %j.016.us, 1
461   %cmp2.us = icmp slt i32 %inc.us, %M
462   br i1 %cmp2.us, label %for.body, label %exit
464 exit:
465   ret void
468 define void @sext_mul_nuw(ptr %A, i32 %multiple, i32 %M) {
469 ; CHECK-LABEL: @sext_mul_nuw(
470 ; CHECK-NEXT:  entry:
471 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[MULTIPLE:%.*]] to i64
472 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
473 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
474 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
475 ; CHECK:       for.body:
476 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
477 ; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
478 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc nuw i64 [[TMP1]] to i32
479 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[TMP2]] to i64
480 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
481 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
482 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
483 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
484 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
485 ; CHECK:       exit:
486 ; CHECK-NEXT:    ret void
488 entry:
489   br label %for.body
491 for.body:
492   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
493   %mul.us = mul nuw i32 %j.016.us, %multiple
494   %idxprom.us = sext i32 %mul.us to i64
495   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
496   tail call void @use_ptr(ptr %arrayidx.us)
497   %inc.us = add nuw nsw i32 %j.016.us, 1
498   %cmp2.us = icmp slt i32 %inc.us, %M
499   br i1 %cmp2.us, label %for.body, label %exit
501 exit:
502   ret void
505 define void @sext_mul_noflags(ptr %A, i32 %multiple, i32 %M) {
506 ; CHECK-LABEL: @sext_mul_noflags(
507 ; CHECK-NEXT:  entry:
508 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
509 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
510 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
511 ; CHECK:       for.body:
512 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
513 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32
514 ; CHECK-NEXT:    [[MUL_US:%.*]] = mul i32 [[TMP0]], [[MULTIPLE:%.*]]
515 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[MUL_US]] to i64
516 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
517 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
518 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
519 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
520 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
521 ; CHECK:       exit:
522 ; CHECK-NEXT:    ret void
524 entry:
525   br label %for.body
527 for.body:
528   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
529   %mul.us = mul i32 %j.016.us, %multiple
530   %idxprom.us = sext i32 %mul.us to i64
531   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
532   tail call void @use_ptr(ptr %arrayidx.us)
533   %inc.us = add nuw nsw i32 %j.016.us, 1
534   %cmp2.us = icmp slt i32 %inc.us, %M
535   br i1 %cmp2.us, label %for.body, label %exit
537 exit:
538   ret void
541 define void @zext_mul_nsw(ptr %A, i32 %multiple, i32 %M) {
542 ; CHECK-LABEL: @zext_mul_nsw(
543 ; CHECK-NEXT:  entry:
544 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[MULTIPLE:%.*]] to i64
545 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
546 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
547 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
548 ; CHECK:       for.body:
549 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
550 ; CHECK-NEXT:    [[TMP1:%.*]] = mul nsw i64 [[INDVARS_IV]], [[TMP0]]
551 ; CHECK-NEXT:    [[TMP2:%.*]] = trunc nsw i64 [[TMP1]] to i32
552 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[TMP2]] to i64
553 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
554 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
555 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
556 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
557 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
558 ; CHECK:       exit:
559 ; CHECK-NEXT:    ret void
561 entry:
562   br label %for.body
564 for.body:
565   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
566   %mul.us = mul nsw i32 %j.016.us, %multiple
567   %idxprom.us = zext i32 %mul.us to i64
568   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
569   tail call void @use_ptr(ptr %arrayidx.us)
570   %inc.us = add nuw nsw i32 %j.016.us, 1
571   %cmp2.us = icmp slt i32 %inc.us, %M
572   br i1 %cmp2.us, label %for.body, label %exit
574 exit:
575   ret void
578 define void @zext_mul_nuw(ptr %A, i32 %multiple, i32 %M) {
579 ; CHECK-LABEL: @zext_mul_nuw(
580 ; CHECK-NEXT:  entry:
581 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[MULTIPLE:%.*]] to i64
582 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
583 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
584 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
585 ; CHECK:       for.body:
586 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
587 ; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
588 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
589 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
590 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
591 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
592 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
593 ; CHECK:       exit:
594 ; CHECK-NEXT:    ret void
596 entry:
597   br label %for.body
599 for.body:
600   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
601   %mul.us = mul nuw i32 %j.016.us, %multiple
602   %idxprom.us = zext i32 %mul.us to i64
603   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
604   tail call void @use_ptr(ptr %arrayidx.us)
605   %inc.us = add nuw nsw i32 %j.016.us, 1
606   %cmp2.us = icmp slt i32 %inc.us, %M
607   br i1 %cmp2.us, label %for.body, label %exit
609 exit:
610   ret void
613 define void @zext_mul_noflags(ptr %A, i32 %multiple, i32 %M) {
614 ; CHECK-LABEL: @zext_mul_noflags(
615 ; CHECK-NEXT:  entry:
616 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
617 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
618 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
619 ; CHECK:       for.body:
620 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
621 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32
622 ; CHECK-NEXT:    [[MUL_US:%.*]] = mul i32 [[TMP0]], [[MULTIPLE:%.*]]
623 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[MUL_US]] to i64
624 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
625 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
626 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
627 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
628 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
629 ; CHECK:       exit:
630 ; CHECK-NEXT:    ret void
632 entry:
633   br label %for.body
635 for.body:
636   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
637   %mul.us = mul i32 %j.016.us, %multiple
638   %idxprom.us = zext i32 %mul.us to i64
639   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
640   tail call void @use_ptr(ptr %arrayidx.us)
641   %inc.us = add nuw nsw i32 %j.016.us, 1
642   %cmp2.us = icmp slt i32 %inc.us, %M
643   br i1 %cmp2.us, label %for.body, label %exit
645 exit:
646   ret void
649 define void @zext_nneg_mul_nsw(ptr %A, i32 %multiple, i32 %M) {
650 ; CHECK-LABEL: @zext_nneg_mul_nsw(
651 ; CHECK-NEXT:  entry:
652 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[MULTIPLE:%.*]] to i64
653 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
654 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
655 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
656 ; CHECK:       for.body:
657 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
658 ; CHECK-NEXT:    [[TMP1:%.*]] = mul nsw i64 [[INDVARS_IV]], [[TMP0]]
659 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
660 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
661 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
662 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
663 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
664 ; CHECK:       exit:
665 ; CHECK-NEXT:    ret void
667 entry:
668   br label %for.body
670 for.body:
671   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
672   %mul.us = mul nsw i32 %j.016.us, %multiple
673   %idxprom.us = zext nneg i32 %mul.us to i64
674   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
675   tail call void @use_ptr(ptr %arrayidx.us)
676   %inc.us = add nuw nsw i32 %j.016.us, 1
677   %cmp2.us = icmp slt i32 %inc.us, %M
678   br i1 %cmp2.us, label %for.body, label %exit
680 exit:
681   ret void
684 define void @zext_nneg_mul_nuw(ptr %A, i32 %multiple, i32 %M) {
685 ; CHECK-LABEL: @zext_nneg_mul_nuw(
686 ; CHECK-NEXT:  entry:
687 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[MULTIPLE:%.*]] to i64
688 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
689 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
690 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
691 ; CHECK:       for.body:
692 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
693 ; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
694 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
695 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
696 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
697 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
698 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
699 ; CHECK:       exit:
700 ; CHECK-NEXT:    ret void
702 entry:
703   br label %for.body
705 for.body:
706   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
707   %mul.us = mul nuw i32 %j.016.us, %multiple
708   %idxprom.us = zext nneg i32 %mul.us to i64
709   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
710   tail call void @use_ptr(ptr %arrayidx.us)
711   %inc.us = add nuw nsw i32 %j.016.us, 1
712   %cmp2.us = icmp slt i32 %inc.us, %M
713   br i1 %cmp2.us, label %for.body, label %exit
715 exit:
716   ret void
719 define void @zext_nneg_mul_noflags(ptr %A, i32 %multiple, i32 %M) {
720 ; CHECK-LABEL: @zext_nneg_mul_noflags(
721 ; CHECK-NEXT:  entry:
722 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
723 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
724 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
725 ; CHECK:       for.body:
726 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
727 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32
728 ; CHECK-NEXT:    [[MUL_US:%.*]] = mul i32 [[TMP0]], [[MULTIPLE:%.*]]
729 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext nneg i32 [[MUL_US]] to i64
730 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
731 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
732 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
733 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
734 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
735 ; CHECK:       exit:
736 ; CHECK-NEXT:    ret void
738 entry:
739   br label %for.body
741 for.body:
742   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
743   %mul.us = mul i32 %j.016.us, %multiple
744   %idxprom.us = zext nneg i32 %mul.us to i64
745   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
746   tail call void @use_ptr(ptr %arrayidx.us)
747   %inc.us = add nuw nsw i32 %j.016.us, 1
748   %cmp2.us = icmp slt i32 %inc.us, %M
749   br i1 %cmp2.us, label %for.body, label %exit
751 exit:
752   ret void
755 declare dso_local void @use_ptr(ptr %0)