xref: /llvm-project/llvm/test/Transforms/IndVarSimplify/widen-nonnegative-countdown.ll (revision 4b22a923c4bfd0aa1d483149f84b6787263c2d76)
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
3
4target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
5
6; This file covers proving non-negative IVs for IV widening on common
7; count down loop structures.  Count down loops are tricky to prove
8; non-negative for since we canonicalize a sub to add, and loose the
9; sub nuw fact.
10
11; use(a[i]) loops
12; -------------------------------------------------------------------
13
14define void @zext_postinc_constant_start(ptr %A) {
15; CHECK-LABEL: @zext_postinc_constant_start(
16; CHECK-NEXT:  entry:
17; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
18; CHECK:       for.body:
19; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
20; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
21; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
22; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
23; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6
24; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
25; CHECK:       exit:
26; CHECK-NEXT:    ret void
27;
28entry:
29  br label %for.body
30
31for.body:
32  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
33  %idxprom.us = zext i32 %j.016.us to i64
34  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
35  tail call void @use_ptr(ptr %arrayidx.us)
36  %inc.us = add nsw i32 %j.016.us, -1
37  %cmp2.us = icmp ugt i32 %inc.us, 6
38  br i1 %cmp2.us, label %for.body, label %exit
39
40exit:
41  ret void
42}
43
44
45define void @zext_preinc_constant_start(ptr %A) {
46; CHECK-LABEL: @zext_preinc_constant_start(
47; CHECK-NEXT:  entry:
48; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
49; CHECK:       for.body:
50; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
51; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
52; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
53; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
54; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6
55; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
56; CHECK:       exit:
57; CHECK-NEXT:    ret void
58;
59entry:
60  br label %for.body
61
62for.body:
63  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
64  %idxprom.us = zext i32 %j.016.us to i64
65  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
66  tail call void @use_ptr(ptr %arrayidx.us)
67  %inc.us = add nsw i32 %j.016.us, -1
68  %cmp2.us = icmp ugt i32 %j.016.us, 6
69  br i1 %cmp2.us, label %for.body, label %exit
70
71exit:
72  ret void
73}
74
75define void @zext_postinc(ptr %A, i32 %start) {
76; CHECK-LABEL: @zext_postinc(
77; CHECK-NEXT:  entry:
78; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
79; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
80; CHECK:       for.body.preheader:
81; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START]] to i64
82; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
83; CHECK:       for.body:
84; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
85; CHECK-NEXT:    [[J_016_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[FOR_BODY]] ], [ [[START]], [[FOR_BODY_PREHEADER]] ]
86; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
87; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
88; CHECK-NEXT:    [[INC_US]] = add nsw i32 [[J_016_US]], -1
89; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i32 [[INC_US]], 6
90; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
91; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
92; CHECK:       exit.loopexit:
93; CHECK-NEXT:    br label [[EXIT]]
94; CHECK:       exit:
95; CHECK-NEXT:    ret void
96;
97entry:
98  %nonpos = icmp slt i32 %start, 2
99  br i1 %nonpos, label %exit, label %for.body
100
101for.body:
102  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
103  %idxprom.us = zext i32 %j.016.us to i64
104  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
105  tail call void @use_ptr(ptr %arrayidx.us)
106  %inc.us = add nsw i32 %j.016.us, -1
107  %cmp2.us = icmp ugt i32 %inc.us, 6
108  br i1 %cmp2.us, label %for.body, label %exit
109
110exit:
111  ret void
112}
113
114
115define void @zext_preinc(ptr %A, i32 %start) {
116; CHECK-LABEL: @zext_preinc(
117; CHECK-NEXT:  entry:
118; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
119; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
120; CHECK:       for.body.preheader:
121; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START]] to i64
122; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
123; CHECK:       for.body:
124; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
125; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
126; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
127; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6
128; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
129; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
130; CHECK:       exit.loopexit:
131; CHECK-NEXT:    br label [[EXIT]]
132; CHECK:       exit:
133; CHECK-NEXT:    ret void
134;
135entry:
136  %nonpos = icmp slt i32 %start, 2
137  br i1 %nonpos, label %exit, label %for.body
138
139for.body:
140  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
141  %idxprom.us = zext i32 %j.016.us to i64
142  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
143  tail call void @use_ptr(ptr %arrayidx.us)
144  %inc.us = add nsw i32 %j.016.us, -1
145  %cmp2.us = icmp ugt i32 %j.016.us, 6
146  br i1 %cmp2.us, label %for.body, label %exit
147
148exit:
149  ret void
150}
151
152define void @sext_postinc_constant_start(ptr %A) {
153; CHECK-LABEL: @sext_postinc_constant_start(
154; CHECK-NEXT:  entry:
155; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
156; CHECK:       for.body:
157; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
158; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
159; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
160; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
161; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6
162; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
163; CHECK:       exit:
164; CHECK-NEXT:    ret void
165;
166entry:
167  br label %for.body
168
169for.body:
170  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
171  %idxprom.us = sext i32 %j.016.us to i64
172  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
173  tail call void @use_ptr(ptr %arrayidx.us)
174  %inc.us = add nsw i32 %j.016.us, -1
175  %cmp2.us = icmp ugt i32 %inc.us, 6
176  br i1 %cmp2.us, label %for.body, label %exit
177
178exit:
179  ret void
180}
181
182
183define void @sext_preinc_constant_start(ptr %A) {
184; CHECK-LABEL: @sext_preinc_constant_start(
185; CHECK-NEXT:  entry:
186; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
187; CHECK:       for.body:
188; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
189; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
190; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
191; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
192; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6
193; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
194; CHECK:       exit:
195; CHECK-NEXT:    ret void
196;
197entry:
198  br label %for.body
199
200for.body:
201  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
202  %idxprom.us = sext i32 %j.016.us to i64
203  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
204  tail call void @use_ptr(ptr %arrayidx.us)
205  %inc.us = add nsw i32 %j.016.us, -1
206  %cmp2.us = icmp ugt i32 %j.016.us, 6
207  br i1 %cmp2.us, label %for.body, label %exit
208
209exit:
210  ret void
211}
212
213define void @sext_postinc(ptr %A, i32 %start) {
214; CHECK-LABEL: @sext_postinc(
215; CHECK-NEXT:  entry:
216; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
217; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
218; CHECK:       for.body.preheader:
219; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[START]] to i64
220; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
221; CHECK:       for.body:
222; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
223; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
224; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
225; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
226; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV_NEXT]] to i32
227; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i32 [[TMP1]], 6
228; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
229; CHECK:       exit.loopexit:
230; CHECK-NEXT:    br label [[EXIT]]
231; CHECK:       exit:
232; CHECK-NEXT:    ret void
233;
234entry:
235  %nonpos = icmp slt i32 %start, 2
236  br i1 %nonpos, label %exit, label %for.body
237
238for.body:
239  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
240  %idxprom.us = sext i32 %j.016.us to i64
241  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
242  tail call void @use_ptr(ptr %arrayidx.us)
243  %inc.us = add nsw i32 %j.016.us, -1
244  %cmp2.us = icmp ugt i32 %inc.us, 6
245  br i1 %cmp2.us, label %for.body, label %exit
246
247exit:
248  ret void
249}
250
251
252define void @sext_preinc(ptr %A, i32 %start) {
253; CHECK-LABEL: @sext_preinc(
254; CHECK-NEXT:  entry:
255; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
256; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
257; CHECK:       for.body.preheader:
258; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[START]] to i64
259; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
260; CHECK:       for.body:
261; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
262; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
263; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
264; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
265; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
266; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i32 [[TMP1]], 6
267; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
268; CHECK:       exit.loopexit:
269; CHECK-NEXT:    br label [[EXIT]]
270; CHECK:       exit:
271; CHECK-NEXT:    ret void
272;
273entry:
274  %nonpos = icmp slt i32 %start, 2
275  br i1 %nonpos, label %exit, label %for.body
276
277for.body:
278  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
279  %idxprom.us = sext i32 %j.016.us to i64
280  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
281  tail call void @use_ptr(ptr %arrayidx.us)
282  %inc.us = add nsw i32 %j.016.us, -1
283  %cmp2.us = icmp ugt i32 %j.016.us, 6
284  br i1 %cmp2.us, label %for.body, label %exit
285
286exit:
287  ret void
288}
289
290; use(a[i + 1]) loops
291; -------------------------------------------------------------------
292
293define void @zext_postinc_constant_start_offset_constant_one(ptr %A) {
294; CHECK-LABEL: @zext_postinc_constant_start_offset_constant_one(
295; CHECK-NEXT:  entry:
296; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
297; CHECK:       for.body:
298; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
299; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
300; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP0]]
301; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
302; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
303; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6
304; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
305; CHECK:       exit:
306; CHECK-NEXT:    ret void
307;
308entry:
309  br label %for.body
310
311for.body:
312  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
313  %add.us = add i32 %j.016.us, 1
314  %idxprom.us = zext i32 %add.us to i64
315  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
316  tail call void @use_ptr(ptr %arrayidx.us)
317  %inc.us = add nsw i32 %j.016.us, -1
318  %cmp2.us = icmp ugt i32 %inc.us, 6
319  br i1 %cmp2.us, label %for.body, label %exit
320
321exit:
322  ret void
323}
324
325
326define void @zext_preinc_constant_start_offset_constant_one(ptr %A) {
327; CHECK-LABEL: @zext_preinc_constant_start_offset_constant_one(
328; CHECK-NEXT:  entry:
329; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
330; CHECK:       for.body:
331; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
332; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
333; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP0]]
334; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
335; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
336; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6
337; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
338; CHECK:       exit:
339; CHECK-NEXT:    ret void
340;
341entry:
342  br label %for.body
343
344for.body:
345  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
346  %add.us = add i32 %j.016.us, 1
347  %idxprom.us = zext i32 %add.us to i64
348  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
349  tail call void @use_ptr(ptr %arrayidx.us)
350  %inc.us = add nsw i32 %j.016.us, -1
351  %cmp2.us = icmp ugt i32 %j.016.us, 6
352  br i1 %cmp2.us, label %for.body, label %exit
353
354exit:
355  ret void
356}
357
358define void @zext_postinc_offset_constant_one(ptr %A, i32 %start) {
359; CHECK-LABEL: @zext_postinc_offset_constant_one(
360; CHECK-NEXT:  entry:
361; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
362; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
363; CHECK:       for.body.preheader:
364; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START]] to i64
365; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
366; CHECK:       for.body:
367; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
368; CHECK-NEXT:    [[J_016_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[FOR_BODY]] ], [ [[START]], [[FOR_BODY_PREHEADER]] ]
369; CHECK-NEXT:    [[TMP1:%.*]] = trunc nuw i64 [[INDVARS_IV]] to i32
370; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP1]], 1
371; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64
372; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
373; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
374; CHECK-NEXT:    [[INC_US]] = add nsw i32 [[J_016_US]], -1
375; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i32 [[INC_US]], 6
376; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
377; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
378; CHECK:       exit.loopexit:
379; CHECK-NEXT:    br label [[EXIT]]
380; CHECK:       exit:
381; CHECK-NEXT:    ret void
382;
383entry:
384  %nonpos = icmp slt i32 %start, 2
385  br i1 %nonpos, label %exit, label %for.body
386
387for.body:
388  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
389  %add.us = add i32 %j.016.us, 1
390  %idxprom.us = zext i32 %add.us to i64
391  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
392  tail call void @use_ptr(ptr %arrayidx.us)
393  %inc.us = add nsw i32 %j.016.us, -1
394  %cmp2.us = icmp ugt i32 %inc.us, 6
395  br i1 %cmp2.us, label %for.body, label %exit
396
397exit:
398  ret void
399}
400
401
402define void @zext_preinc_offset_constant_one(ptr %A, i32 %start) {
403; CHECK-LABEL: @zext_preinc_offset_constant_one(
404; CHECK-NEXT:  entry:
405; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
406; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
407; CHECK:       for.body.preheader:
408; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START]] to i64
409; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
410; CHECK:       for.body:
411; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
412; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
413; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
414; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
415; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6
416; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
417; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
418; CHECK:       exit.loopexit:
419; CHECK-NEXT:    br label [[EXIT]]
420; CHECK:       exit:
421; CHECK-NEXT:    ret void
422;
423entry:
424  %nonpos = icmp slt i32 %start, 2
425  br i1 %nonpos, label %exit, label %for.body
426
427for.body:
428  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
429  %add.us = add i32 %j.016.us, 1
430  %idxprom.us = zext i32 %add.us to i64
431  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
432  tail call void @use_ptr(ptr %arrayidx.us)
433  %inc.us = add nsw i32 %j.016.us, -1
434  %cmp2.us = icmp ugt i32 %j.016.us, 6
435  br i1 %cmp2.us, label %for.body, label %exit
436
437exit:
438  ret void
439}
440
441define void @sext_postinc_constant_start_offset_constant_one(ptr %A) {
442; CHECK-LABEL: @sext_postinc_constant_start_offset_constant_one(
443; CHECK-NEXT:  entry:
444; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
445; CHECK:       for.body:
446; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
447; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
448; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP0]]
449; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
450; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
451; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6
452; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
453; CHECK:       exit:
454; CHECK-NEXT:    ret void
455;
456entry:
457  br label %for.body
458
459for.body:
460  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
461  %add.us = add i32 %j.016.us, 1
462  %idxprom.us = sext i32 %add.us to i64
463  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
464  tail call void @use_ptr(ptr %arrayidx.us)
465  %inc.us = add nsw i32 %j.016.us, -1
466  %cmp2.us = icmp ugt i32 %inc.us, 6
467  br i1 %cmp2.us, label %for.body, label %exit
468
469exit:
470  ret void
471}
472
473
474define void @sext_preinc_constant_start_offset_constant_one(ptr %A) {
475; CHECK-LABEL: @sext_preinc_constant_start_offset_constant_one(
476; CHECK-NEXT:  entry:
477; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
478; CHECK:       for.body:
479; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
480; CHECK-NEXT:    [[TMP0:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1
481; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP0]]
482; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
483; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
484; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6
485; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
486; CHECK:       exit:
487; CHECK-NEXT:    ret void
488;
489entry:
490  br label %for.body
491
492for.body:
493  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
494  %add.us = add i32 %j.016.us, 1
495  %idxprom.us = sext i32 %add.us to i64
496  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
497  tail call void @use_ptr(ptr %arrayidx.us)
498  %inc.us = add nsw i32 %j.016.us, -1
499  %cmp2.us = icmp ugt i32 %j.016.us, 6
500  br i1 %cmp2.us, label %for.body, label %exit
501
502exit:
503  ret void
504}
505
506define void @sext_postinc_offset_constant_one(ptr %A, i32 %start) {
507; CHECK-LABEL: @sext_postinc_offset_constant_one(
508; CHECK-NEXT:  entry:
509; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
510; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
511; CHECK:       for.body.preheader:
512; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[START]] to i64
513; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
514; CHECK:       for.body:
515; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
516; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
517; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP1]], 1
518; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
519; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
520; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
521; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
522; CHECK-NEXT:    [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV_NEXT]] to i32
523; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6
524; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
525; CHECK:       exit.loopexit:
526; CHECK-NEXT:    br label [[EXIT]]
527; CHECK:       exit:
528; CHECK-NEXT:    ret void
529;
530entry:
531  %nonpos = icmp slt i32 %start, 2
532  br i1 %nonpos, label %exit, label %for.body
533
534for.body:
535  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
536  %add.us = add i32 %j.016.us, 1
537  %idxprom.us = sext i32 %add.us to i64
538  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
539  tail call void @use_ptr(ptr %arrayidx.us)
540  %inc.us = add nsw i32 %j.016.us, -1
541  %cmp2.us = icmp ugt i32 %inc.us, 6
542  br i1 %cmp2.us, label %for.body, label %exit
543
544exit:
545  ret void
546}
547
548
549define void @sext_preinc_offset_constant_one(ptr %A, i32 %start) {
550; CHECK-LABEL: @sext_preinc_offset_constant_one(
551; CHECK-NEXT:  entry:
552; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
553; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
554; CHECK:       for.body.preheader:
555; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[START]] to i64
556; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
557; CHECK:       for.body:
558; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
559; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
560; CHECK-NEXT:    [[ADD_US:%.*]] = add nuw i32 [[TMP1]], 1
561; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
562; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
563; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
564; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
565; CHECK-NEXT:    [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
566; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6
567; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
568; CHECK:       exit.loopexit:
569; CHECK-NEXT:    br label [[EXIT]]
570; CHECK:       exit:
571; CHECK-NEXT:    ret void
572;
573entry:
574  %nonpos = icmp slt i32 %start, 2
575  br i1 %nonpos, label %exit, label %for.body
576
577for.body:
578  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
579  %add.us = add i32 %j.016.us, 1
580  %idxprom.us = sext i32 %add.us to i64
581  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
582  tail call void @use_ptr(ptr %arrayidx.us)
583  %inc.us = add nsw i32 %j.016.us, -1
584  %cmp2.us = icmp ugt i32 %j.016.us, 6
585  br i1 %cmp2.us, label %for.body, label %exit
586
587exit:
588  ret void
589}
590
591; use(a[i - 1]) loops
592; -------------------------------------------------------------------
593
594define void @zext_postinc_constant_start_offset_constant_minus_one(ptr %A) {
595; CHECK-LABEL: @zext_postinc_constant_start_offset_constant_minus_one(
596; CHECK-NEXT:  entry:
597; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
598; CHECK:       for.body:
599; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
600; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
601; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV_NEXT]]
602; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
603; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6
604; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
605; CHECK:       exit:
606; CHECK-NEXT:    ret void
607;
608entry:
609  br label %for.body
610
611for.body:
612  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
613  %add.us = add i32 %j.016.us, -1
614  %idxprom.us = zext i32 %add.us to i64
615  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
616  tail call void @use_ptr(ptr %arrayidx.us)
617  %inc.us = add nsw i32 %j.016.us, -1
618  %cmp2.us = icmp ugt i32 %inc.us, 6
619  br i1 %cmp2.us, label %for.body, label %exit
620
621exit:
622  ret void
623}
624
625
626define void @zext_preinc_constant_start_offset_constant_minus_one(ptr %A) {
627; CHECK-LABEL: @zext_preinc_constant_start_offset_constant_minus_one(
628; CHECK-NEXT:  entry:
629; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
630; CHECK:       for.body:
631; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
632; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
633; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV_NEXT]]
634; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
635; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6
636; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
637; CHECK:       exit:
638; CHECK-NEXT:    ret void
639;
640entry:
641  br label %for.body
642
643for.body:
644  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
645  %add.us = add i32 %j.016.us, -1
646  %idxprom.us = zext i32 %add.us to i64
647  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
648  tail call void @use_ptr(ptr %arrayidx.us)
649  %inc.us = add nsw i32 %j.016.us, -1
650  %cmp2.us = icmp ugt i32 %j.016.us, 6
651  br i1 %cmp2.us, label %for.body, label %exit
652
653exit:
654  ret void
655}
656
657define void @zext_postinc_offset_constant_minus_one(ptr %A, i32 %start) {
658; CHECK-LABEL: @zext_postinc_offset_constant_minus_one(
659; CHECK-NEXT:  entry:
660; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
661; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
662; CHECK:       for.body.preheader:
663; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START]] to i64
664; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
665; CHECK:       for.body:
666; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
667; CHECK-NEXT:    [[J_016_US:%.*]] = phi i32 [ [[INC_US:%.*]], [[FOR_BODY]] ], [ [[START]], [[FOR_BODY_PREHEADER]] ]
668; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
669; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
670; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
671; CHECK-NEXT:    [[INC_US]] = add nsw i32 [[J_016_US]], -1
672; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i32 [[INC_US]], 6
673; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
674; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
675; CHECK:       exit.loopexit:
676; CHECK-NEXT:    br label [[EXIT]]
677; CHECK:       exit:
678; CHECK-NEXT:    ret void
679;
680entry:
681  %nonpos = icmp slt i32 %start, 2
682  br i1 %nonpos, label %exit, label %for.body
683
684for.body:
685  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
686  %add.us = add i32 %j.016.us, -1
687  %idxprom.us = zext i32 %add.us to i64
688  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
689  tail call void @use_ptr(ptr %arrayidx.us)
690  %inc.us = add nsw i32 %j.016.us, -1
691  %cmp2.us = icmp ugt i32 %inc.us, 6
692  br i1 %cmp2.us, label %for.body, label %exit
693
694exit:
695  ret void
696}
697
698
699define void @zext_preinc_offset_constant_minus_one(ptr %A, i32 %start) {
700; CHECK-LABEL: @zext_preinc_offset_constant_minus_one(
701; CHECK-NEXT:  entry:
702; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
703; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
704; CHECK:       for.body.preheader:
705; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[START]] to i64
706; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
707; CHECK:       for.body:
708; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
709; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
710; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
711; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
712; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6
713; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
714; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
715; CHECK:       exit.loopexit:
716; CHECK-NEXT:    br label [[EXIT]]
717; CHECK:       exit:
718; CHECK-NEXT:    ret void
719;
720entry:
721  %nonpos = icmp slt i32 %start, 2
722  br i1 %nonpos, label %exit, label %for.body
723
724for.body:
725  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
726  %add.us = add i32 %j.016.us, -1
727  %idxprom.us = zext i32 %add.us to i64
728  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
729  tail call void @use_ptr(ptr %arrayidx.us)
730  %inc.us = add nsw i32 %j.016.us, -1
731  %cmp2.us = icmp ugt i32 %j.016.us, 6
732  br i1 %cmp2.us, label %for.body, label %exit
733
734exit:
735  ret void
736}
737
738define void @sext_postinc_constant_start_offset_constant_minus_one(ptr %A) {
739; CHECK-LABEL: @sext_postinc_constant_start_offset_constant_minus_one(
740; CHECK-NEXT:  entry:
741; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
742; CHECK:       for.body:
743; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
744; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
745; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV_NEXT]]
746; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
747; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV_NEXT]], 6
748; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
749; CHECK:       exit:
750; CHECK-NEXT:    ret void
751;
752entry:
753  br label %for.body
754
755for.body:
756  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
757  %add.us = add i32 %j.016.us, -1
758  %idxprom.us = sext i32 %add.us to i64
759  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
760  tail call void @use_ptr(ptr %arrayidx.us)
761  %inc.us = add nsw i32 %j.016.us, -1
762  %cmp2.us = icmp ugt i32 %inc.us, 6
763  br i1 %cmp2.us, label %for.body, label %exit
764
765exit:
766  ret void
767}
768
769
770define void @sext_preinc_constant_start_offset_constant_minus_one(ptr %A) {
771; CHECK-LABEL: @sext_preinc_constant_start_offset_constant_minus_one(
772; CHECK-NEXT:  entry:
773; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
774; CHECK:       for.body:
775; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 1024, [[ENTRY:%.*]] ]
776; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
777; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV_NEXT]]
778; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
779; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i64 [[INDVARS_IV]], 6
780; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT:%.*]]
781; CHECK:       exit:
782; CHECK-NEXT:    ret void
783;
784entry:
785  br label %for.body
786
787for.body:
788  %j.016.us = phi i32 [ 1024, %entry ], [ %inc.us, %for.body ]
789  %add.us = add i32 %j.016.us, -1
790  %idxprom.us = sext i32 %add.us to i64
791  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
792  tail call void @use_ptr(ptr %arrayidx.us)
793  %inc.us = add nsw i32 %j.016.us, -1
794  %cmp2.us = icmp ugt i32 %j.016.us, 6
795  br i1 %cmp2.us, label %for.body, label %exit
796
797exit:
798  ret void
799}
800
801define void @sext_postinc_offset_constant_minus_one(ptr %A, i32 %start) {
802; CHECK-LABEL: @sext_postinc_offset_constant_minus_one(
803; CHECK-NEXT:  entry:
804; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
805; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
806; CHECK:       for.body.preheader:
807; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[START]] to i64
808; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
809; CHECK:       for.body:
810; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
811; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
812; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP1]], -1
813; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
814; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
815; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
816; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
817; CHECK-NEXT:    [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV_NEXT]] to i32
818; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6
819; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
820; CHECK:       exit.loopexit:
821; CHECK-NEXT:    br label [[EXIT]]
822; CHECK:       exit:
823; CHECK-NEXT:    ret void
824;
825entry:
826  %nonpos = icmp slt i32 %start, 2
827  br i1 %nonpos, label %exit, label %for.body
828
829for.body:
830  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
831  %add.us = add i32 %j.016.us, -1
832  %idxprom.us = sext i32 %add.us to i64
833  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
834  tail call void @use_ptr(ptr %arrayidx.us)
835  %inc.us = add nsw i32 %j.016.us, -1
836  %cmp2.us = icmp ugt i32 %inc.us, 6
837  br i1 %cmp2.us, label %for.body, label %exit
838
839exit:
840  ret void
841}
842
843
844define void @sext_preinc_offset_constant_minus_one(ptr %A, i32 %start) {
845; CHECK-LABEL: @sext_preinc_offset_constant_minus_one(
846; CHECK-NEXT:  entry:
847; CHECK-NEXT:    [[NONPOS:%.*]] = icmp slt i32 [[START:%.*]], 2
848; CHECK-NEXT:    br i1 [[NONPOS]], label [[EXIT:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
849; CHECK:       for.body.preheader:
850; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[START]] to i64
851; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
852; CHECK:       for.body:
853; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[TMP0]], [[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
854; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
855; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP1]], -1
856; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
857; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
858; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
859; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
860; CHECK-NEXT:    [[TMP2:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
861; CHECK-NEXT:    [[CMP2_US:%.*]] = icmp ugt i32 [[TMP2]], 6
862; CHECK-NEXT:    br i1 [[CMP2_US]], label [[FOR_BODY]], label [[EXIT_LOOPEXIT:%.*]]
863; CHECK:       exit.loopexit:
864; CHECK-NEXT:    br label [[EXIT]]
865; CHECK:       exit:
866; CHECK-NEXT:    ret void
867;
868entry:
869  %nonpos = icmp slt i32 %start, 2
870  br i1 %nonpos, label %exit, label %for.body
871
872for.body:
873  %j.016.us = phi i32 [ %start, %entry ], [ %inc.us, %for.body ]
874  %add.us = add i32 %j.016.us, -1
875  %idxprom.us = sext i32 %add.us to i64
876  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
877  tail call void @use_ptr(ptr %arrayidx.us)
878  %inc.us = add nsw i32 %j.016.us, -1
879  %cmp2.us = icmp ugt i32 %j.016.us, 6
880  br i1 %cmp2.us, label %for.body, label %exit
881
882exit:
883  ret void
884}
885
886declare dso_local void @use_ptr(ptr %0)
887
888
889