[VPlan] Add incoming values for all predecessor to ResumePHI (NFCI).
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / uniform_across_vf_induction1.ll
blob5e8b60b910aed02100d152598c716d7de96845ad
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=2 %s -S | FileCheck %s
4 ; Tests for checking uniformity within a VF.
6 ; for (iv = 0 ; ; iv += 1) B[iv] = A[iv/1] + 42;
7 define void @ld_div1_step1_start0_ind1(ptr noalias %A, ptr noalias %B) {
8 ; CHECK-LABEL: define void @ld_div1_step1_start0_ind1
9 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
12 ; CHECK:       vector.ph:
13 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
14 ; CHECK:       vector.body:
15 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
16 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
17 ; CHECK-NEXT:    [[TMP1:%.*]] = udiv i64 [[TMP0]], 1
18 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP1]]
19 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i32 0
20 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x i64>, ptr [[TMP3]], align 8
21 ; CHECK-NEXT:    [[TMP4:%.*]] = add nsw <2 x i64> [[WIDE_LOAD]], splat (i64 42)
22 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
23 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[TMP5]], i32 0
24 ; CHECK-NEXT:    store <2 x i64> [[TMP4]], ptr [[TMP6]], align 8
25 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
26 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
27 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
28 ; CHECK:       middle.block:
29 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
30 ; CHECK:       scalar.ph:
31 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
32 ; CHECK-NEXT:    br label [[LOOP:%.*]]
33 ; CHECK:       loop:
34 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
35 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 1
36 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
37 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
38 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
39 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
40 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
41 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
42 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
43 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP3:![0-9]+]]
44 ; CHECK:       exit:
45 ; CHECK-NEXT:    ret void
47 entry:
48   br label %loop
49 loop:
50   %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop ]
51   %div = udiv i64 %iv, 1
52   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
53   %ld = load i64, ptr %gep_ld, align 8
54   %calc = add nsw i64 %ld, 42
55   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
56   store i64 %calc, ptr %gep_st, align 8
57   %iv_next = add nsw i64 %iv, 1
58   %cond = icmp eq i64 %iv_next, 1000
59   br i1 %cond, label %exit, label %loop
60 exit:
61   ret void
64 ; for (iv = 0 ; ; iv += 1) B[iv] = A[iv/2] + 42;
65 ; A[iv/2] is uniform for VF=2.
66 define void @ld_div2_step1_start0_ind1(ptr noalias %A, ptr noalias %B) {
67 ; CHECK-LABEL: define void @ld_div2_step1_start0_ind1
68 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
69 ; CHECK-NEXT:  entry:
70 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
71 ; CHECK:       vector.ph:
72 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
73 ; CHECK:       vector.body:
74 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
75 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
76 ; CHECK-NEXT:    [[TMP1:%.*]] = udiv i64 [[TMP0]], 2
77 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP1]]
78 ; CHECK-NEXT:    [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
79 ; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <2 x i64> poison, i64 [[TMP3]], i64 0
80 ; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT]], <2 x i64> poison, <2 x i32> zeroinitializer
81 ; CHECK-NEXT:    [[TMP4:%.*]] = add nsw <2 x i64> [[BROADCAST_SPLAT]], splat (i64 42)
82 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
83 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[TMP5]], i32 0
84 ; CHECK-NEXT:    store <2 x i64> [[TMP4]], ptr [[TMP6]], align 8
85 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
86 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
87 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
88 ; CHECK:       middle.block:
89 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
90 ; CHECK:       scalar.ph:
91 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
92 ; CHECK-NEXT:    br label [[LOOP:%.*]]
93 ; CHECK:       loop:
94 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
95 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 2
96 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
97 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
98 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
99 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
100 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
101 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
102 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
103 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP5:![0-9]+]]
104 ; CHECK:       exit:
105 ; CHECK-NEXT:    ret void
107 entry:
108   br label %loop
109 loop:
110   %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop ]
111   %div = udiv i64 %iv, 2
112   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
113   %ld = load i64, ptr %gep_ld, align 8
114   %calc = add nsw i64 %ld, 42
115   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
116   store i64 %calc, ptr %gep_st, align 8
117   %iv_next = add nsw i64 %iv, 1
118   %cond = icmp eq i64 %iv_next, 1000
119   br i1 %cond, label %exit, label %loop
120 exit:
121   ret void
124 ; for (iv = 0 ; ; iv += 1) B[iv] = A[iv/3] + 42;
125 define void @ld_div3_step1_start0_ind1(ptr noalias %A, ptr noalias %B) {
126 ; CHECK-LABEL: define void @ld_div3_step1_start0_ind1
127 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
128 ; CHECK-NEXT:  entry:
129 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
130 ; CHECK:       vector.ph:
131 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
132 ; CHECK:       vector.body:
133 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
134 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
135 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
136 ; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 3)
137 ; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x i64> [[TMP1]], i32 0
138 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP2]]
139 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
140 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP4]]
141 ; CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[TMP3]], align 8
142 ; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[TMP5]], align 8
143 ; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <2 x i64> poison, i64 [[TMP6]], i32 0
144 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <2 x i64> [[TMP8]], i64 [[TMP7]], i32 1
145 ; CHECK-NEXT:    [[TMP10:%.*]] = add nsw <2 x i64> [[TMP9]], splat (i64 42)
146 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
147 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[TMP11]], i32 0
148 ; CHECK-NEXT:    store <2 x i64> [[TMP10]], ptr [[TMP12]], align 8
149 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
150 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
151 ; CHECK-NEXT:    [[TMP13:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
152 ; CHECK-NEXT:    br i1 [[TMP13]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
153 ; CHECK:       middle.block:
154 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
155 ; CHECK:       scalar.ph:
156 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
157 ; CHECK-NEXT:    br label [[LOOP:%.*]]
158 ; CHECK:       loop:
159 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
160 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 3
161 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
162 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
163 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
164 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
165 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
166 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
167 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
168 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP7:![0-9]+]]
169 ; CHECK:       exit:
170 ; CHECK-NEXT:    ret void
172 entry:
173   br label %loop
174 loop:
175   %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop ]
176   %div = udiv i64 %iv, 3
177   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
178   %ld = load i64, ptr %gep_ld, align 8
179   %calc = add nsw i64 %ld, 42
180   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
181   store i64 %calc, ptr %gep_st, align 8
182   %iv_next = add nsw i64 %iv, 1
183   %cond = icmp eq i64 %iv_next, 1000
184   br i1 %cond, label %exit, label %loop
185 exit:
186   ret void
189 ; for (iv = 0 ; ; iv += 2) B[iv] = A[iv/1] + 42;
190 define void @ld_div1_step2_start0_ind1(ptr noalias %A, ptr noalias %B) {
191 ; CHECK-LABEL: define void @ld_div1_step2_start0_ind1
192 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
193 ; CHECK-NEXT:  entry:
194 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
195 ; CHECK:       vector.ph:
196 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
197 ; CHECK:       vector.body:
198 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
199 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 2>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
200 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 2
201 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
202 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 2
203 ; CHECK-NEXT:    [[TMP2:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 1)
204 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x i64> [[TMP2]], i32 0
205 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP3]]
206 ; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x i64> [[TMP2]], i32 1
207 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP5]]
208 ; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[TMP4]], align 8
209 ; CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 8
210 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <2 x i64> poison, i64 [[TMP7]], i32 0
211 ; CHECK-NEXT:    [[TMP10:%.*]] = insertelement <2 x i64> [[TMP9]], i64 [[TMP8]], i32 1
212 ; CHECK-NEXT:    [[TMP11:%.*]] = add nsw <2 x i64> [[TMP10]], splat (i64 42)
213 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
214 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
215 ; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <2 x i64> [[TMP11]], i32 0
216 ; CHECK-NEXT:    store i64 [[TMP14]], ptr [[TMP12]], align 8
217 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x i64> [[TMP11]], i32 1
218 ; CHECK-NEXT:    store i64 [[TMP15]], ptr [[TMP13]], align 8
219 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
220 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 4)
221 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp eq i64 [[INDEX_NEXT]], 500
222 ; CHECK-NEXT:    br i1 [[TMP16]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
223 ; CHECK:       middle.block:
224 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
225 ; CHECK:       scalar.ph:
226 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
227 ; CHECK-NEXT:    br label [[LOOP:%.*]]
228 ; CHECK:       loop:
229 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
230 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 1
231 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
232 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
233 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
234 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
235 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
236 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 2
237 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
238 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP9:![0-9]+]]
239 ; CHECK:       exit:
240 ; CHECK-NEXT:    ret void
242 entry:
243   br label %loop
244 loop:
245   %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop ]
246   %div = udiv i64 %iv, 1
247   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
248   %ld = load i64, ptr %gep_ld, align 8
249   %calc = add nsw i64 %ld, 42
250   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
251   store i64 %calc, ptr %gep_st, align 8
252   %iv_next = add nsw i64 %iv, 2
253   %cond = icmp eq i64 %iv_next, 1000
254   br i1 %cond, label %exit, label %loop
255 exit:
256   ret void
259 ; for (iv = 0 ; ; iv += 2) B[iv] = A[iv/2] + 42;
260 define void @ld_div2_step2_start0_ind1(ptr noalias %A, ptr noalias %B) {
261 ; CHECK-LABEL: define void @ld_div2_step2_start0_ind1
262 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
263 ; CHECK-NEXT:  entry:
264 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
265 ; CHECK:       vector.ph:
266 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
267 ; CHECK:       vector.body:
268 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
269 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 2
270 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
271 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 2
272 ; CHECK-NEXT:    [[TMP2:%.*]] = udiv i64 [[TMP0]], 2
273 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP2]]
274 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[TMP3]], i32 0
275 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x i64>, ptr [[TMP4]], align 8
276 ; CHECK-NEXT:    [[TMP5:%.*]] = add nsw <2 x i64> [[WIDE_LOAD]], splat (i64 42)
277 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
278 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
279 ; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <2 x i64> [[TMP5]], i32 0
280 ; CHECK-NEXT:    store i64 [[TMP8]], ptr [[TMP6]], align 8
281 ; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <2 x i64> [[TMP5]], i32 1
282 ; CHECK-NEXT:    store i64 [[TMP9]], ptr [[TMP7]], align 8
283 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
284 ; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 500
285 ; CHECK-NEXT:    br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
286 ; CHECK:       middle.block:
287 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
288 ; CHECK:       scalar.ph:
289 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
290 ; CHECK-NEXT:    br label [[LOOP:%.*]]
291 ; CHECK:       loop:
292 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
293 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 2
294 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
295 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
296 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
297 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
298 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
299 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 2
300 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
301 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP11:![0-9]+]]
302 ; CHECK:       exit:
303 ; CHECK-NEXT:    ret void
305 entry:
306   br label %loop
307 loop:
308   %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop ]
309   %div = udiv i64 %iv, 2
310   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
311   %ld = load i64, ptr %gep_ld, align 8
312   %calc = add nsw i64 %ld, 42
313   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
314   store i64 %calc, ptr %gep_st, align 8
315   %iv_next = add nsw i64 %iv, 2
316   %cond = icmp eq i64 %iv_next, 1000
317   br i1 %cond, label %exit, label %loop
318 exit:
319   ret void
322 ; for (iv = 0 ; ; iv += 2) B[iv] = A[iv/3] + 42;
323 define void @ld_div3_step2_start0_ind1(ptr noalias %A, ptr noalias %B) {
324 ; CHECK-LABEL: define void @ld_div3_step2_start0_ind1
325 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
326 ; CHECK-NEXT:  entry:
327 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
328 ; CHECK:       vector.ph:
329 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
330 ; CHECK:       vector.body:
331 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
332 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 2>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
333 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 2
334 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
335 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 2
336 ; CHECK-NEXT:    [[TMP2:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 3)
337 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x i64> [[TMP2]], i32 0
338 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP3]]
339 ; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x i64> [[TMP2]], i32 1
340 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP5]]
341 ; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[TMP4]], align 8
342 ; CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 8
343 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <2 x i64> poison, i64 [[TMP7]], i32 0
344 ; CHECK-NEXT:    [[TMP10:%.*]] = insertelement <2 x i64> [[TMP9]], i64 [[TMP8]], i32 1
345 ; CHECK-NEXT:    [[TMP11:%.*]] = add nsw <2 x i64> [[TMP10]], splat (i64 42)
346 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
347 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
348 ; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <2 x i64> [[TMP11]], i32 0
349 ; CHECK-NEXT:    store i64 [[TMP14]], ptr [[TMP12]], align 8
350 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x i64> [[TMP11]], i32 1
351 ; CHECK-NEXT:    store i64 [[TMP15]], ptr [[TMP13]], align 8
352 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
353 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 4)
354 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp eq i64 [[INDEX_NEXT]], 500
355 ; CHECK-NEXT:    br i1 [[TMP16]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
356 ; CHECK:       middle.block:
357 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
358 ; CHECK:       scalar.ph:
359 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
360 ; CHECK-NEXT:    br label [[LOOP:%.*]]
361 ; CHECK:       loop:
362 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
363 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 3
364 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
365 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
366 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
367 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
368 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
369 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 2
370 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
371 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP13:![0-9]+]]
372 ; CHECK:       exit:
373 ; CHECK-NEXT:    ret void
375 entry:
376   br label %loop
377 loop:
378   %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop ]
379   %div = udiv i64 %iv, 3
380   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
381   %ld = load i64, ptr %gep_ld, align 8
382   %calc = add nsw i64 %ld, 42
383   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
384   store i64 %calc, ptr %gep_st, align 8
385   %iv_next = add nsw i64 %iv, 2
386   %cond = icmp eq i64 %iv_next, 1000
387   br i1 %cond, label %exit, label %loop
388 exit:
389   ret void
392 ; for (iv = 0 ; ; iv += 3) B[iv] = A[iv/1] + 42;
393 define void @ld_div1_step3_start0_ind1(ptr noalias %A, ptr noalias %B) {
394 ; CHECK-LABEL: define void @ld_div1_step3_start0_ind1
395 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
396 ; CHECK-NEXT:  entry:
397 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
398 ; CHECK:       vector.ph:
399 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
400 ; CHECK:       vector.body:
401 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
402 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
403 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 3
404 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
405 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 3
406 ; CHECK-NEXT:    [[TMP2:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 1)
407 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x i64> [[TMP2]], i32 0
408 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP3]]
409 ; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x i64> [[TMP2]], i32 1
410 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP5]]
411 ; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[TMP4]], align 8
412 ; CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 8
413 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <2 x i64> poison, i64 [[TMP7]], i32 0
414 ; CHECK-NEXT:    [[TMP10:%.*]] = insertelement <2 x i64> [[TMP9]], i64 [[TMP8]], i32 1
415 ; CHECK-NEXT:    [[TMP11:%.*]] = add nsw <2 x i64> [[TMP10]], splat (i64 42)
416 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
417 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
418 ; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <2 x i64> [[TMP11]], i32 0
419 ; CHECK-NEXT:    store i64 [[TMP14]], ptr [[TMP12]], align 8
420 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x i64> [[TMP11]], i32 1
421 ; CHECK-NEXT:    store i64 [[TMP15]], ptr [[TMP13]], align 8
422 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
423 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 6)
424 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp eq i64 [[INDEX_NEXT]], 332
425 ; CHECK-NEXT:    br i1 [[TMP16]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
426 ; CHECK:       middle.block:
427 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
428 ; CHECK:       scalar.ph:
429 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 996, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
430 ; CHECK-NEXT:    br label [[LOOP:%.*]]
431 ; CHECK:       loop:
432 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
433 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 1
434 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
435 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
436 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
437 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
438 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
439 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 3
440 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
441 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP15:![0-9]+]]
442 ; CHECK:       exit:
443 ; CHECK-NEXT:    ret void
445 entry:
446   br label %loop
447 loop:
448   %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop ]
449   %div = udiv i64 %iv, 1
450   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
451   %ld = load i64, ptr %gep_ld, align 8
452   %calc = add nsw i64 %ld, 42
453   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
454   store i64 %calc, ptr %gep_st, align 8
455   %iv_next = add nsw i64 %iv, 3
456   %cond = icmp eq i64 %iv_next, 1000
457   br i1 %cond, label %exit, label %loop
458 exit:
459   ret void
462 ; for (iv = 0 ; ; iv += 3) B[iv] = A[iv/2] + 42;
463 define void @ld_div2_step3_start0_ind1(ptr noalias %A, ptr noalias %B) {
464 ; CHECK-LABEL: define void @ld_div2_step3_start0_ind1
465 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
466 ; CHECK-NEXT:  entry:
467 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
468 ; CHECK:       vector.ph:
469 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
470 ; CHECK:       vector.body:
471 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
472 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
473 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 3
474 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
475 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 3
476 ; CHECK-NEXT:    [[TMP2:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 2)
477 ; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x i64> [[TMP2]], i32 0
478 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP3]]
479 ; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x i64> [[TMP2]], i32 1
480 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP5]]
481 ; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[TMP4]], align 8
482 ; CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP6]], align 8
483 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <2 x i64> poison, i64 [[TMP7]], i32 0
484 ; CHECK-NEXT:    [[TMP10:%.*]] = insertelement <2 x i64> [[TMP9]], i64 [[TMP8]], i32 1
485 ; CHECK-NEXT:    [[TMP11:%.*]] = add nsw <2 x i64> [[TMP10]], splat (i64 42)
486 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
487 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
488 ; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <2 x i64> [[TMP11]], i32 0
489 ; CHECK-NEXT:    store i64 [[TMP14]], ptr [[TMP12]], align 8
490 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x i64> [[TMP11]], i32 1
491 ; CHECK-NEXT:    store i64 [[TMP15]], ptr [[TMP13]], align 8
492 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
493 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 6)
494 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp eq i64 [[INDEX_NEXT]], 332
495 ; CHECK-NEXT:    br i1 [[TMP16]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
496 ; CHECK:       middle.block:
497 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
498 ; CHECK:       scalar.ph:
499 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 996, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
500 ; CHECK-NEXT:    br label [[LOOP:%.*]]
501 ; CHECK:       loop:
502 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
503 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 2
504 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
505 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
506 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
507 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
508 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
509 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 3
510 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
511 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP17:![0-9]+]]
512 ; CHECK:       exit:
513 ; CHECK-NEXT:    ret void
515 entry:
516   br label %loop
517 loop:
518   %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop ]
519   %div = udiv i64 %iv, 2
520   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
521   %ld = load i64, ptr %gep_ld, align 8
522   %calc = add nsw i64 %ld, 42
523   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
524   store i64 %calc, ptr %gep_st, align 8
525   %iv_next = add nsw i64 %iv, 3
526   %cond = icmp eq i64 %iv_next, 1000
527   br i1 %cond, label %exit, label %loop
528 exit:
529   ret void
532 ; for (iv = 0 ; ; iv += 3) B[iv] = A[iv/3] + 42;
533 define void @ld_div3_step3_start0_ind1(ptr noalias %A, ptr noalias %B) {
534 ; CHECK-LABEL: define void @ld_div3_step3_start0_ind1
535 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
536 ; CHECK-NEXT:  entry:
537 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
538 ; CHECK:       vector.ph:
539 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
540 ; CHECK:       vector.body:
541 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
542 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 3
543 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
544 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 3
545 ; CHECK-NEXT:    [[TMP2:%.*]] = udiv i64 [[TMP0]], 3
546 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP2]]
547 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[TMP3]], i32 0
548 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x i64>, ptr [[TMP4]], align 8
549 ; CHECK-NEXT:    [[TMP5:%.*]] = add nsw <2 x i64> [[WIDE_LOAD]], splat (i64 42)
550 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
551 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
552 ; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <2 x i64> [[TMP5]], i32 0
553 ; CHECK-NEXT:    store i64 [[TMP8]], ptr [[TMP6]], align 8
554 ; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <2 x i64> [[TMP5]], i32 1
555 ; CHECK-NEXT:    store i64 [[TMP9]], ptr [[TMP7]], align 8
556 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
557 ; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 332
558 ; CHECK-NEXT:    br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]
559 ; CHECK:       middle.block:
560 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
561 ; CHECK:       scalar.ph:
562 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 996, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
563 ; CHECK-NEXT:    br label [[LOOP:%.*]]
564 ; CHECK:       loop:
565 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
566 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 3
567 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
568 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
569 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
570 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
571 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
572 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 3
573 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
574 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP19:![0-9]+]]
575 ; CHECK:       exit:
576 ; CHECK-NEXT:    ret void
578 entry:
579   br label %loop
580 loop:
581   %iv = phi i64 [ 0, %entry ], [ %iv_next, %loop ]
582   %div = udiv i64 %iv, 3
583   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
584   %ld = load i64, ptr %gep_ld, align 8
585   %calc = add nsw i64 %ld, 42
586   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
587   store i64 %calc, ptr %gep_st, align 8
588   %iv_next = add nsw i64 %iv, 3
589   %cond = icmp eq i64 %iv_next, 1000
590   br i1 %cond, label %exit, label %loop
591 exit:
592   ret void
595 ; for (iv = 1 ; ; iv += 1) B[iv] = A[iv/1] + 42;
596 define void @ld_div1_step1_start1_ind1(ptr noalias %A, ptr noalias %B) {
597 ; CHECK-LABEL: define void @ld_div1_step1_start1_ind1
598 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
599 ; CHECK-NEXT:  entry:
600 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
601 ; CHECK:       vector.ph:
602 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
603 ; CHECK:       vector.body:
604 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
605 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[INDEX]]
606 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
607 ; CHECK-NEXT:    [[TMP1:%.*]] = udiv i64 [[TMP0]], 1
608 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP1]]
609 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i32 0
610 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x i64>, ptr [[TMP3]], align 8
611 ; CHECK-NEXT:    [[TMP4:%.*]] = add nsw <2 x i64> [[WIDE_LOAD]], splat (i64 42)
612 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
613 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i64, ptr [[TMP5]], i32 0
614 ; CHECK-NEXT:    store <2 x i64> [[TMP4]], ptr [[TMP6]], align 8
615 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
616 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 998
617 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]]
618 ; CHECK:       middle.block:
619 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
620 ; CHECK:       scalar.ph:
621 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 999, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
622 ; CHECK-NEXT:    br label [[LOOP:%.*]]
623 ; CHECK:       loop:
624 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
625 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 1
626 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
627 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
628 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
629 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
630 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
631 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
632 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
633 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP21:![0-9]+]]
634 ; CHECK:       exit:
635 ; CHECK-NEXT:    ret void
637 entry:
638   br label %loop
639 loop:
640   %iv = phi i64 [ 1, %entry ], [ %iv_next, %loop ]
641   %div = udiv i64 %iv, 1
642   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
643   %ld = load i64, ptr %gep_ld, align 8
644   %calc = add nsw i64 %ld, 42
645   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
646   store i64 %calc, ptr %gep_st, align 8
647   %iv_next = add nsw i64 %iv, 1
648   %cond = icmp eq i64 %iv_next, 1000
649   br i1 %cond, label %exit, label %loop
650 exit:
651   ret void
654 ; for (iv = 1 ; ; iv += 1) B[iv] = A[iv/2] + 42;
655 define void @ld_div2_step1_start1_ind1(ptr noalias %A, ptr noalias %B) {
656 ; CHECK-LABEL: define void @ld_div2_step1_start1_ind1
657 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
658 ; CHECK-NEXT:  entry:
659 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
660 ; CHECK:       vector.ph:
661 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
662 ; CHECK:       vector.body:
663 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
664 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 1, i64 2>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
665 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[INDEX]]
666 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
667 ; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 2)
668 ; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x i64> [[TMP1]], i32 0
669 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP2]]
670 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
671 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP4]]
672 ; CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[TMP3]], align 8
673 ; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[TMP5]], align 8
674 ; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <2 x i64> poison, i64 [[TMP6]], i32 0
675 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <2 x i64> [[TMP8]], i64 [[TMP7]], i32 1
676 ; CHECK-NEXT:    [[TMP10:%.*]] = add nsw <2 x i64> [[TMP9]], splat (i64 42)
677 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
678 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[TMP11]], i32 0
679 ; CHECK-NEXT:    store <2 x i64> [[TMP10]], ptr [[TMP12]], align 8
680 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
681 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
682 ; CHECK-NEXT:    [[TMP13:%.*]] = icmp eq i64 [[INDEX_NEXT]], 998
683 ; CHECK-NEXT:    br i1 [[TMP13]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]
684 ; CHECK:       middle.block:
685 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
686 ; CHECK:       scalar.ph:
687 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 999, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
688 ; CHECK-NEXT:    br label [[LOOP:%.*]]
689 ; CHECK:       loop:
690 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
691 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 2
692 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
693 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
694 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
695 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
696 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
697 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
698 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
699 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP23:![0-9]+]]
700 ; CHECK:       exit:
701 ; CHECK-NEXT:    ret void
703 entry:
704   br label %loop
705 loop:
706   %iv = phi i64 [ 1, %entry ], [ %iv_next, %loop ]
707   %div = udiv i64 %iv, 2
708   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
709   %ld = load i64, ptr %gep_ld, align 8
710   %calc = add nsw i64 %ld, 42
711   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
712   store i64 %calc, ptr %gep_st, align 8
713   %iv_next = add nsw i64 %iv, 1
714   %cond = icmp eq i64 %iv_next, 1000
715   br i1 %cond, label %exit, label %loop
716 exit:
717   ret void
720 ; for (iv = 1 ; ; iv += 1) B[iv] = A[iv/3] + 42;
721 define void @ld_div3_step1_start1_ind1(ptr noalias %A, ptr noalias %B) {
722 ; CHECK-LABEL: define void @ld_div3_step1_start1_ind1
723 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
724 ; CHECK-NEXT:  entry:
725 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
726 ; CHECK:       vector.ph:
727 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
728 ; CHECK:       vector.body:
729 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
730 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 1, i64 2>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
731 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[INDEX]]
732 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[OFFSET_IDX]], 0
733 ; CHECK-NEXT:    [[TMP1:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 3)
734 ; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x i64> [[TMP1]], i32 0
735 ; CHECK-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP2]]
736 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i64> [[TMP1]], i32 1
737 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP4]]
738 ; CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[TMP3]], align 8
739 ; CHECK-NEXT:    [[TMP7:%.*]] = load i64, ptr [[TMP5]], align 8
740 ; CHECK-NEXT:    [[TMP8:%.*]] = insertelement <2 x i64> poison, i64 [[TMP6]], i32 0
741 ; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <2 x i64> [[TMP8]], i64 [[TMP7]], i32 1
742 ; CHECK-NEXT:    [[TMP10:%.*]] = add nsw <2 x i64> [[TMP9]], splat (i64 42)
743 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP0]]
744 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[TMP11]], i32 0
745 ; CHECK-NEXT:    store <2 x i64> [[TMP10]], ptr [[TMP12]], align 8
746 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
747 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
748 ; CHECK-NEXT:    [[TMP13:%.*]] = icmp eq i64 [[INDEX_NEXT]], 998
749 ; CHECK-NEXT:    br i1 [[TMP13]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP24:![0-9]+]]
750 ; CHECK:       middle.block:
751 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
752 ; CHECK:       scalar.ph:
753 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 999, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
754 ; CHECK-NEXT:    br label [[LOOP:%.*]]
755 ; CHECK:       loop:
756 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
757 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 3
758 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
759 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
760 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
761 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
762 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
763 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
764 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
765 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP25:![0-9]+]]
766 ; CHECK:       exit:
767 ; CHECK-NEXT:    ret void
769 entry:
770   br label %loop
771 loop:
772   %iv = phi i64 [ 1, %entry ], [ %iv_next, %loop ]
773   %div = udiv i64 %iv, 3
774   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
775   %ld = load i64, ptr %gep_ld, align 8
776   %calc = add nsw i64 %ld, 42
777   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
778   store i64 %calc, ptr %gep_st, align 8
779   %iv_next = add nsw i64 %iv, 1
780   %cond = icmp eq i64 %iv_next, 1000
781   br i1 %cond, label %exit, label %loop
782 exit:
783   ret void
786 ; for (iv = 1 ; ; iv += 2) B[iv] = A[iv/1] + 42;
787 define void @ld_div1_step2_start1_ind1(ptr noalias %A, ptr noalias %B) {
788 ; CHECK-LABEL: define void @ld_div1_step2_start1_ind1
789 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
790 ; CHECK-NEXT:  entry:
791 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
792 ; CHECK:       vector.ph:
793 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
794 ; CHECK:       vector.body:
795 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
796 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 1, i64 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
797 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 [[INDEX]], 2
798 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[TMP0]]
799 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 0
800 ; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 2
801 ; CHECK-NEXT:    [[TMP3:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 1)
802 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i32 0
803 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP4]]
804 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <2 x i64> [[TMP3]], i32 1
805 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP6]]
806 ; CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP5]], align 8
807 ; CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[TMP7]], align 8
808 ; CHECK-NEXT:    [[TMP10:%.*]] = insertelement <2 x i64> poison, i64 [[TMP8]], i32 0
809 ; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <2 x i64> [[TMP10]], i64 [[TMP9]], i32 1
810 ; CHECK-NEXT:    [[TMP12:%.*]] = add nsw <2 x i64> [[TMP11]], splat (i64 42)
811 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
812 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP2]]
813 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x i64> [[TMP12]], i32 0
814 ; CHECK-NEXT:    store i64 [[TMP15]], ptr [[TMP13]], align 8
815 ; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <2 x i64> [[TMP12]], i32 1
816 ; CHECK-NEXT:    store i64 [[TMP16]], ptr [[TMP14]], align 8
817 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
818 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 4)
819 ; CHECK-NEXT:    [[TMP17:%.*]] = icmp eq i64 [[INDEX_NEXT]], 498
820 ; CHECK-NEXT:    br i1 [[TMP17]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]]
821 ; CHECK:       middle.block:
822 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
823 ; CHECK:       scalar.ph:
824 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 997, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
825 ; CHECK-NEXT:    br label [[LOOP:%.*]]
826 ; CHECK:       loop:
827 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
828 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 1
829 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
830 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
831 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
832 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
833 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
834 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 2
835 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
836 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP27:![0-9]+]]
837 ; CHECK:       exit:
838 ; CHECK-NEXT:    ret void
840 entry:
841   br label %loop
842 loop:
843   %iv = phi i64 [ 1, %entry ], [ %iv_next, %loop ]
844   %div = udiv i64 %iv, 1
845   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
846   %ld = load i64, ptr %gep_ld, align 8
847   %calc = add nsw i64 %ld, 42
848   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
849   store i64 %calc, ptr %gep_st, align 8
850   %iv_next = add nsw i64 %iv, 2
851   %cond = icmp eq i64 %iv_next, 1000
852   br i1 %cond, label %exit, label %loop
853 exit:
854   ret void
857 ; for (iv = 1 ; ; iv += 2) B[iv] = A[iv/2] + 42;
858 define void @ld_div2_step2_start1_ind1(ptr noalias %A, ptr noalias %B) {
859 ; CHECK-LABEL: define void @ld_div2_step2_start1_ind1
860 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
861 ; CHECK-NEXT:  entry:
862 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
863 ; CHECK:       vector.ph:
864 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
865 ; CHECK:       vector.body:
866 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
867 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 [[INDEX]], 2
868 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[TMP0]]
869 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 0
870 ; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 2
871 ; CHECK-NEXT:    [[TMP3:%.*]] = udiv i64 [[TMP1]], 2
872 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP3]]
873 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[TMP4]], i32 0
874 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x i64>, ptr [[TMP5]], align 8
875 ; CHECK-NEXT:    [[TMP6:%.*]] = add nsw <2 x i64> [[WIDE_LOAD]], splat (i64 42)
876 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
877 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP2]]
878 ; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <2 x i64> [[TMP6]], i32 0
879 ; CHECK-NEXT:    store i64 [[TMP9]], ptr [[TMP7]], align 8
880 ; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <2 x i64> [[TMP6]], i32 1
881 ; CHECK-NEXT:    store i64 [[TMP10]], ptr [[TMP8]], align 8
882 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
883 ; CHECK-NEXT:    [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 498
884 ; CHECK-NEXT:    br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]]
885 ; CHECK:       middle.block:
886 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
887 ; CHECK:       scalar.ph:
888 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 997, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
889 ; CHECK-NEXT:    br label [[LOOP:%.*]]
890 ; CHECK:       loop:
891 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
892 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 2
893 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
894 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
895 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
896 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
897 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
898 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 2
899 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
900 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP29:![0-9]+]]
901 ; CHECK:       exit:
902 ; CHECK-NEXT:    ret void
904 entry:
905   br label %loop
906 loop:
907   %iv = phi i64 [ 1, %entry ], [ %iv_next, %loop ]
908   %div = udiv i64 %iv, 2
909   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
910   %ld = load i64, ptr %gep_ld, align 8
911   %calc = add nsw i64 %ld, 42
912   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
913   store i64 %calc, ptr %gep_st, align 8
914   %iv_next = add nsw i64 %iv, 2
915   %cond = icmp eq i64 %iv_next, 1000
916   br i1 %cond, label %exit, label %loop
917 exit:
918   ret void
921 ; for (iv = 1 ; ; iv += 2) B[iv] = A[iv/3] + 42;
922 define void @ld_div3_step2_start1_ind1(ptr noalias %A, ptr noalias %B) {
923 ; CHECK-LABEL: define void @ld_div3_step2_start1_ind1
924 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
925 ; CHECK-NEXT:  entry:
926 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
927 ; CHECK:       vector.ph:
928 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
929 ; CHECK:       vector.body:
930 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
931 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 1, i64 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
932 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 [[INDEX]], 2
933 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[TMP0]]
934 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 0
935 ; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 2
936 ; CHECK-NEXT:    [[TMP3:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 3)
937 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i32 0
938 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP4]]
939 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <2 x i64> [[TMP3]], i32 1
940 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP6]]
941 ; CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP5]], align 8
942 ; CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[TMP7]], align 8
943 ; CHECK-NEXT:    [[TMP10:%.*]] = insertelement <2 x i64> poison, i64 [[TMP8]], i32 0
944 ; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <2 x i64> [[TMP10]], i64 [[TMP9]], i32 1
945 ; CHECK-NEXT:    [[TMP12:%.*]] = add nsw <2 x i64> [[TMP11]], splat (i64 42)
946 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
947 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP2]]
948 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x i64> [[TMP12]], i32 0
949 ; CHECK-NEXT:    store i64 [[TMP15]], ptr [[TMP13]], align 8
950 ; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <2 x i64> [[TMP12]], i32 1
951 ; CHECK-NEXT:    store i64 [[TMP16]], ptr [[TMP14]], align 8
952 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
953 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 4)
954 ; CHECK-NEXT:    [[TMP17:%.*]] = icmp eq i64 [[INDEX_NEXT]], 498
955 ; CHECK-NEXT:    br i1 [[TMP17]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP30:![0-9]+]]
956 ; CHECK:       middle.block:
957 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
958 ; CHECK:       scalar.ph:
959 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 997, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
960 ; CHECK-NEXT:    br label [[LOOP:%.*]]
961 ; CHECK:       loop:
962 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
963 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 3
964 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
965 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
966 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
967 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
968 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
969 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 2
970 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
971 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP31:![0-9]+]]
972 ; CHECK:       exit:
973 ; CHECK-NEXT:    ret void
975 entry:
976   br label %loop
977 loop:
978   %iv = phi i64 [ 1, %entry ], [ %iv_next, %loop ]
979   %div = udiv i64 %iv, 3
980   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
981   %ld = load i64, ptr %gep_ld, align 8
982   %calc = add nsw i64 %ld, 42
983   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
984   store i64 %calc, ptr %gep_st, align 8
985   %iv_next = add nsw i64 %iv, 2
986   %cond = icmp eq i64 %iv_next, 1000
987   br i1 %cond, label %exit, label %loop
988 exit:
989   ret void
992 ; for (iv = 1 ; ; iv += 3) B[iv] = A[iv/1] + 42;
993 define void @ld_div1_step3_start1_ind1(ptr noalias %A, ptr noalias %B) {
994 ; CHECK-LABEL: define void @ld_div1_step3_start1_ind1
995 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
996 ; CHECK-NEXT:  entry:
997 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
998 ; CHECK:       vector.ph:
999 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1000 ; CHECK:       vector.body:
1001 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
1002 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 1, i64 4>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
1003 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 [[INDEX]], 3
1004 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[TMP0]]
1005 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 0
1006 ; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 3
1007 ; CHECK-NEXT:    [[TMP3:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 1)
1008 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i32 0
1009 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP4]]
1010 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <2 x i64> [[TMP3]], i32 1
1011 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP6]]
1012 ; CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP5]], align 8
1013 ; CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[TMP7]], align 8
1014 ; CHECK-NEXT:    [[TMP10:%.*]] = insertelement <2 x i64> poison, i64 [[TMP8]], i32 0
1015 ; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <2 x i64> [[TMP10]], i64 [[TMP9]], i32 1
1016 ; CHECK-NEXT:    [[TMP12:%.*]] = add nsw <2 x i64> [[TMP11]], splat (i64 42)
1017 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
1018 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP2]]
1019 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x i64> [[TMP12]], i32 0
1020 ; CHECK-NEXT:    store i64 [[TMP15]], ptr [[TMP13]], align 8
1021 ; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <2 x i64> [[TMP12]], i32 1
1022 ; CHECK-NEXT:    store i64 [[TMP16]], ptr [[TMP14]], align 8
1023 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1024 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 6)
1025 ; CHECK-NEXT:    [[TMP17:%.*]] = icmp eq i64 [[INDEX_NEXT]], 332
1026 ; CHECK-NEXT:    br i1 [[TMP17]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP32:![0-9]+]]
1027 ; CHECK:       middle.block:
1028 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
1029 ; CHECK:       scalar.ph:
1030 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 997, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
1031 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1032 ; CHECK:       loop:
1033 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1034 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 1
1035 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
1036 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
1037 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
1038 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
1039 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
1040 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 3
1041 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1042 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP33:![0-9]+]]
1043 ; CHECK:       exit:
1044 ; CHECK-NEXT:    ret void
1046 entry:
1047   br label %loop
1048 loop:
1049   %iv = phi i64 [ 1, %entry ], [ %iv_next, %loop ]
1050   %div = udiv i64 %iv, 1
1051   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
1052   %ld = load i64, ptr %gep_ld, align 8
1053   %calc = add nsw i64 %ld, 42
1054   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
1055   store i64 %calc, ptr %gep_st, align 8
1056   %iv_next = add nsw i64 %iv, 3
1057   %cond = icmp eq i64 %iv_next, 1000
1058   br i1 %cond, label %exit, label %loop
1059 exit:
1060   ret void
1063 ; for (iv = 1 ; ; iv += 3) B[iv] = A[iv/2] + 42;
1064 define void @ld_div2_step3_start1_ind1(ptr noalias %A, ptr noalias %B) {
1065 ; CHECK-LABEL: define void @ld_div2_step3_start1_ind1
1066 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
1067 ; CHECK-NEXT:  entry:
1068 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
1069 ; CHECK:       vector.ph:
1070 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1071 ; CHECK:       vector.body:
1072 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
1073 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 1, i64 4>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
1074 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 [[INDEX]], 3
1075 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[TMP0]]
1076 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 0
1077 ; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 3
1078 ; CHECK-NEXT:    [[TMP3:%.*]] = udiv <2 x i64> [[VEC_IND]], splat (i64 2)
1079 ; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i32 0
1080 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP4]]
1081 ; CHECK-NEXT:    [[TMP6:%.*]] = extractelement <2 x i64> [[TMP3]], i32 1
1082 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP6]]
1083 ; CHECK-NEXT:    [[TMP8:%.*]] = load i64, ptr [[TMP5]], align 8
1084 ; CHECK-NEXT:    [[TMP9:%.*]] = load i64, ptr [[TMP7]], align 8
1085 ; CHECK-NEXT:    [[TMP10:%.*]] = insertelement <2 x i64> poison, i64 [[TMP8]], i32 0
1086 ; CHECK-NEXT:    [[TMP11:%.*]] = insertelement <2 x i64> [[TMP10]], i64 [[TMP9]], i32 1
1087 ; CHECK-NEXT:    [[TMP12:%.*]] = add nsw <2 x i64> [[TMP11]], splat (i64 42)
1088 ; CHECK-NEXT:    [[TMP13:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
1089 ; CHECK-NEXT:    [[TMP14:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP2]]
1090 ; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <2 x i64> [[TMP12]], i32 0
1091 ; CHECK-NEXT:    store i64 [[TMP15]], ptr [[TMP13]], align 8
1092 ; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <2 x i64> [[TMP12]], i32 1
1093 ; CHECK-NEXT:    store i64 [[TMP16]], ptr [[TMP14]], align 8
1094 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1095 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 6)
1096 ; CHECK-NEXT:    [[TMP17:%.*]] = icmp eq i64 [[INDEX_NEXT]], 332
1097 ; CHECK-NEXT:    br i1 [[TMP17]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP34:![0-9]+]]
1098 ; CHECK:       middle.block:
1099 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
1100 ; CHECK:       scalar.ph:
1101 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 997, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
1102 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1103 ; CHECK:       loop:
1104 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1105 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 2
1106 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
1107 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
1108 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
1109 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
1110 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
1111 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 3
1112 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1113 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP35:![0-9]+]]
1114 ; CHECK:       exit:
1115 ; CHECK-NEXT:    ret void
1117 entry:
1118   br label %loop
1119 loop:
1120   %iv = phi i64 [ 1, %entry ], [ %iv_next, %loop ]
1121   %div = udiv i64 %iv, 2
1122   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
1123   %ld = load i64, ptr %gep_ld, align 8
1124   %calc = add nsw i64 %ld, 42
1125   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
1126   store i64 %calc, ptr %gep_st, align 8
1127   %iv_next = add nsw i64 %iv, 3
1128   %cond = icmp eq i64 %iv_next, 1000
1129   br i1 %cond, label %exit, label %loop
1130 exit:
1131   ret void
1134 ; for (iv = 1 ; ; iv += 3) B[iv] = A[iv/3] + 42;
1135 define void @ld_div3_step3_start1_ind1(ptr noalias %A, ptr noalias %B) {
1136 ; CHECK-LABEL: define void @ld_div3_step3_start1_ind1
1137 ; CHECK-SAME: (ptr noalias [[A:%.*]], ptr noalias [[B:%.*]]) {
1138 ; CHECK-NEXT:  entry:
1139 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
1140 ; CHECK:       vector.ph:
1141 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1142 ; CHECK:       vector.body:
1143 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
1144 ; CHECK-NEXT:    [[TMP0:%.*]] = mul i64 [[INDEX]], 3
1145 ; CHECK-NEXT:    [[OFFSET_IDX:%.*]] = add i64 1, [[TMP0]]
1146 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[OFFSET_IDX]], 0
1147 ; CHECK-NEXT:    [[TMP2:%.*]] = add i64 [[OFFSET_IDX]], 3
1148 ; CHECK-NEXT:    [[TMP3:%.*]] = udiv i64 [[TMP1]], 3
1149 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[TMP3]]
1150 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[TMP4]], i32 0
1151 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x i64>, ptr [[TMP5]], align 8
1152 ; CHECK-NEXT:    [[TMP6:%.*]] = add nsw <2 x i64> [[WIDE_LOAD]], splat (i64 42)
1153 ; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP1]]
1154 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[TMP2]]
1155 ; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <2 x i64> [[TMP6]], i32 0
1156 ; CHECK-NEXT:    store i64 [[TMP9]], ptr [[TMP7]], align 8
1157 ; CHECK-NEXT:    [[TMP10:%.*]] = extractelement <2 x i64> [[TMP6]], i32 1
1158 ; CHECK-NEXT:    store i64 [[TMP10]], ptr [[TMP8]], align 8
1159 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1160 ; CHECK-NEXT:    [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], 332
1161 ; CHECK-NEXT:    br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP36:![0-9]+]]
1162 ; CHECK:       middle.block:
1163 ; CHECK-NEXT:    br i1 false, label [[EXIT:%.*]], label [[SCALAR_PH]]
1164 ; CHECK:       scalar.ph:
1165 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 997, [[MIDDLE_BLOCK]] ], [ 1, [[ENTRY:%.*]] ]
1166 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1167 ; CHECK:       loop:
1168 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1169 ; CHECK-NEXT:    [[DIV:%.*]] = udiv i64 [[IV]], 3
1170 ; CHECK-NEXT:    [[GEP_LD:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[DIV]]
1171 ; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[GEP_LD]], align 8
1172 ; CHECK-NEXT:    [[CALC:%.*]] = add nsw i64 [[LD]], 42
1173 ; CHECK-NEXT:    [[GEP_ST:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
1174 ; CHECK-NEXT:    store i64 [[CALC]], ptr [[GEP_ST]], align 8
1175 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 3
1176 ; CHECK-NEXT:    [[COND:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1177 ; CHECK-NEXT:    br i1 [[COND]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP37:![0-9]+]]
1178 ; CHECK:       exit:
1179 ; CHECK-NEXT:    ret void
1181 entry:
1182   br label %loop
1183 loop:
1184   %iv = phi i64 [ 1, %entry ], [ %iv_next, %loop ]
1185   %div = udiv i64 %iv, 3
1186   %gep_ld = getelementptr inbounds i64, ptr %A, i64 %div
1187   %ld = load i64, ptr %gep_ld, align 8
1188   %calc = add nsw i64 %ld, 42
1189   %gep_st = getelementptr inbounds i64, ptr %B, i64 %iv
1190   store i64 %calc, ptr %gep_st, align 8
1191   %iv_next = add nsw i64 %iv, 3
1192   %cond = icmp eq i64 %iv_next, 1000
1193   br i1 %cond, label %exit, label %loop
1194 exit:
1195   ret void
1198 define void @test_step_is_not_invariant(ptr %A) {
1199 ; CHECK-LABEL: define void @test_step_is_not_invariant
1200 ; CHECK-SAME: (ptr [[A:%.*]]) {
1201 ; CHECK-NEXT:  entry:
1202 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
1203 ; CHECK:       vector.ph:
1204 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
1205 ; CHECK:       vector.body:
1206 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
1207 ; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <2 x i32> [ <i32 0, i32 1>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[VECTOR_BODY]] ]
1208 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i32 [[INDEX]] to i16
1209 ; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[TMP0]], 0
1210 ; CHECK-NEXT:    [[TMP2:%.*]] = add i16 [[TMP0]], 1
1211 ; CHECK-NEXT:    [[TMP3:%.*]] = mul nuw nsw <2 x i32> [[VEC_IND]], [[VEC_IND]]
1212 ; CHECK-NEXT:    [[TMP4:%.*]] = trunc <2 x i32> [[TMP3]] to <2 x i16>
1213 ; CHECK-NEXT:    [[TMP5:%.*]] = udiv <2 x i16> [[TMP4]], splat (i16 6)
1214 ; CHECK-NEXT:    [[TMP6:%.*]] = zext <2 x i16> [[TMP5]] to <2 x i64>
1215 ; CHECK-NEXT:    [[TMP7:%.*]] = extractelement <2 x i64> [[TMP6]], i32 0
1216 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i16, ptr [[A]], i64 [[TMP7]]
1217 ; CHECK-NEXT:    [[TMP9:%.*]] = extractelement <2 x i64> [[TMP6]], i32 1
1218 ; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds i16, ptr [[A]], i64 [[TMP9]]
1219 ; CHECK-NEXT:    store i16 [[TMP1]], ptr [[TMP8]], align 2
1220 ; CHECK-NEXT:    store i16 [[TMP2]], ptr [[TMP10]], align 2
1221 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
1222 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add <2 x i32> [[VEC_IND]], splat (i32 2)
1223 ; CHECK-NEXT:    [[TMP11:%.*]] = icmp eq i32 [[INDEX_NEXT]], 56
1224 ; CHECK-NEXT:    br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP38:![0-9]+]]
1225 ; CHECK:       middle.block:
1226 ; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[SCALAR_PH]]
1227 ; CHECK:       scalar.ph:
1228 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 56, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
1229 ; CHECK-NEXT:    br label [[LOOP:%.*]]
1230 ; CHECK:       loop:
1231 ; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1232 ; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i32 [[IV]], [[IV]]
1233 ; CHECK-NEXT:    [[DIV_LHS_TRUNC:%.*]] = trunc i32 [[MUL]] to i16
1234 ; CHECK-NEXT:    [[DIV5:%.*]] = udiv i16 [[DIV_LHS_TRUNC]], 6
1235 ; CHECK-NEXT:    [[CONV:%.*]] = trunc i32 [[IV]] to i16
1236 ; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i16 [[DIV5]] to i64
1237 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i16, ptr [[A]], i64 [[IDXPROM]]
1238 ; CHECK-NEXT:    store i16 [[CONV]], ptr [[ARRAYIDX]], align 2
1239 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
1240 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV_NEXT]], 56
1241 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[EXIT]], label [[LOOP]], !llvm.loop [[LOOP39:![0-9]+]]
1242 ; CHECK:       exit:
1243 ; CHECK-NEXT:    ret void
1245 entry:
1246   br label %loop
1248 loop:
1249   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1250   %mul = mul nuw nsw i32 %iv, %iv
1251   %div.lhs.trunc = trunc i32 %mul to i16
1252   %div5 = udiv i16 %div.lhs.trunc, 6
1253   %conv = trunc i32 %iv to i16
1254   %idxprom = zext i16 %div5 to i64
1255   %arrayidx = getelementptr inbounds i16, ptr %A, i64 %idxprom
1256   store i16 %conv, ptr %arrayidx, align 2
1257   %iv.next = add nuw nsw i32 %iv, 1
1258   %exitcond.not = icmp eq i32 %iv.next, 56
1259   br i1 %exitcond.not, label %exit, label %loop
1261 exit:
1262   ret void