1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -S < %s | FileCheck %s --check-prefix=CHECK
3 ; RUN: opt -passes=loop-vectorize -force-vector-interleave=4 -force-vector-width=4 -S < %s | FileCheck %s --check-prefix=CHECK
4 ; RUN: opt -passes=loop-vectorize -force-vector-interleave=4 -force-vector-width=1 -S < %s | FileCheck %s --check-prefix=CHECK
6 define i64 @select_icmp_const_1(ptr %a, i64 %n) {
7 ; CHECK-LABEL: define i64 @select_icmp_const_1(
8 ; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) {
9 ; CHECK-NEXT: [[ENTRY:.*]]:
10 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
11 ; CHECK: [[FOR_BODY]]:
12 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
13 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ 3, %[[ENTRY]] ]
14 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
15 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
16 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[TMP0]], 3
17 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV]], i64 [[RDX]]
18 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1
19 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
20 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
22 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
23 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
28 for.body: ; preds = %entry, %for.body
29 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
30 %rdx = phi i64 [ %cond, %for.body ], [ 3, %entry ]
31 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
32 %0 = load i64, ptr %arrayidx, align 8
33 %cmp2 = icmp eq i64 %0, 3
34 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
35 %inc = add nuw nsw i64 %iv, 1
36 %exitcond.not = icmp eq i64 %inc, %n
37 br i1 %exitcond.not, label %exit, label %for.body
39 exit: ; preds = %for.body
43 define i64 @select_icmp_const_2(ptr %a, i64 %n) {
44 ; CHECK-LABEL: define i64 @select_icmp_const_2(
45 ; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) {
46 ; CHECK-NEXT: [[ENTRY:.*]]:
47 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
48 ; CHECK: [[FOR_BODY]]:
49 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
50 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ 3, %[[ENTRY]] ]
51 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
52 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
53 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[TMP0]], 3
54 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[RDX]], i64 [[IV]]
55 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1
56 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
57 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
59 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
60 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
65 for.body: ; preds = %entry, %for.body
66 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
67 %rdx = phi i64 [ %cond, %for.body ], [ 3, %entry ]
68 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
69 %0 = load i64, ptr %arrayidx, align 8
70 %cmp2 = icmp eq i64 %0, 3
71 %cond = select i1 %cmp2, i64 %rdx, i64 %iv
72 %inc = add nuw nsw i64 %iv, 1
73 %exitcond.not = icmp eq i64 %inc, %n
74 br i1 %exitcond.not, label %exit, label %for.body
76 exit: ; preds = %for.body
80 define i64 @select_icmp_const_3_variable_rdx_start(ptr %a, i64 %rdx.start, i64 %n) {
81 ; CHECK-LABEL: define i64 @select_icmp_const_3_variable_rdx_start(
82 ; CHECK-SAME: ptr [[A:%.*]], i64 [[RDX_START:%.*]], i64 [[N:%.*]]) {
83 ; CHECK-NEXT: [[ENTRY:.*]]:
84 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
85 ; CHECK: [[FOR_BODY]]:
86 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
87 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ [[RDX_START]], %[[ENTRY]] ]
88 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
89 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
90 ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[TMP0]], 3
91 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV]], i64 [[RDX]]
92 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1
93 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
94 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
96 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
97 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
102 for.body: ; preds = %entry, %for.body
103 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
104 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
105 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
106 %0 = load i64, ptr %arrayidx, align 8
107 %cmp2 = icmp eq i64 %0, 3
108 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
109 %inc = add nuw nsw i64 %iv, 1
110 %exitcond.not = icmp eq i64 %inc, %n
111 br i1 %exitcond.not, label %exit, label %for.body
113 exit: ; preds = %for.body
117 define i64 @select_fcmp_const_fast(ptr %a, i64 %n) {
118 ; CHECK-LABEL: define i64 @select_fcmp_const_fast(
119 ; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) {
120 ; CHECK-NEXT: [[ENTRY:.*]]:
121 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
122 ; CHECK: [[FOR_BODY]]:
123 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
124 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ 2, %[[ENTRY]] ]
125 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[IV]]
126 ; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4
127 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp fast ueq float [[TMP0]], 3.000000e+00
128 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV]], i64 [[RDX]]
129 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1
130 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
131 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
133 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
134 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
139 for.body: ; preds = %entry, %for.body
140 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
141 %rdx = phi i64 [ %cond, %for.body ], [ 2, %entry ]
142 %arrayidx = getelementptr inbounds float, ptr %a, i64 %iv
143 %0 = load float, ptr %arrayidx, align 4
144 %cmp2 = fcmp fast ueq float %0, 3.0
145 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
146 %inc = add nuw nsw i64 %iv, 1
147 %exitcond.not = icmp eq i64 %inc, %n
148 br i1 %exitcond.not, label %exit, label %for.body
150 exit: ; preds = %for.body
154 define i64 @select_fcmp_const(ptr %a, i64 %n) {
155 ; CHECK-LABEL: define i64 @select_fcmp_const(
156 ; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) {
157 ; CHECK-NEXT: [[ENTRY:.*]]:
158 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
159 ; CHECK: [[FOR_BODY]]:
160 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
161 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ 2, %[[ENTRY]] ]
162 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[IV]]
163 ; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4
164 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ueq float [[TMP0]], 3.000000e+00
165 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV]], i64 [[RDX]]
166 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1
167 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
168 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
170 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
171 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
176 for.body: ; preds = %entry, %for.body
177 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
178 %rdx = phi i64 [ %cond, %for.body ], [ 2, %entry ]
179 %arrayidx = getelementptr inbounds float, ptr %a, i64 %iv
180 %0 = load float, ptr %arrayidx, align 4
181 %cmp2 = fcmp ueq float %0, 3.0
182 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
183 %inc = add nuw nsw i64 %iv, 1
184 %exitcond.not = icmp eq i64 %inc, %n
185 br i1 %exitcond.not, label %exit, label %for.body
187 exit: ; preds = %for.body
191 define i64 @select_icmp(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
192 ; CHECK-LABEL: define i64 @select_icmp(
193 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[RDX_START:%.*]], i64 [[N:%.*]]) {
194 ; CHECK-NEXT: [[ENTRY:.*]]:
195 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
196 ; CHECK: [[FOR_BODY]]:
197 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
198 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ [[RDX_START]], %[[ENTRY]] ]
199 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
200 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
201 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
202 ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8
203 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
204 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV]], i64 [[RDX]]
205 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1
206 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
207 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
209 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
210 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
215 for.body: ; preds = %entry, %for.body
216 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
217 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
218 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
219 %0 = load i64, ptr %arrayidx, align 8
220 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv
221 %1 = load i64, ptr %arrayidx1, align 8
222 %cmp2 = icmp sgt i64 %0, %1
223 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
224 %inc = add nuw nsw i64 %iv, 1
225 %exitcond.not = icmp eq i64 %inc, %n
226 br i1 %exitcond.not, label %exit, label %for.body
228 exit: ; preds = %for.body
232 define i64 @select_fcmp(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
233 ; CHECK-LABEL: define i64 @select_fcmp(
234 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[RDX_START:%.*]], i64 [[N:%.*]]) {
235 ; CHECK-NEXT: [[ENTRY:.*]]:
236 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
237 ; CHECK: [[FOR_BODY]]:
238 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
239 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ [[RDX_START]], %[[ENTRY]] ]
240 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[A]], i64 [[IV]]
241 ; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4
242 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, ptr [[B]], i64 [[IV]]
243 ; CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[ARRAYIDX1]], align 4
244 ; CHECK-NEXT: [[CMP2:%.*]] = fcmp ogt float [[TMP0]], [[TMP1]]
245 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV]], i64 [[RDX]]
246 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1
247 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
248 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
250 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
251 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
256 for.body: ; preds = %entry, %for.body
257 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
258 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
259 %arrayidx = getelementptr inbounds float, ptr %a, i64 %iv
260 %0 = load float, ptr %arrayidx, align 4
261 %arrayidx1 = getelementptr inbounds float, ptr %b, i64 %iv
262 %1 = load float, ptr %arrayidx1, align 4
263 %cmp2 = fcmp ogt float %0, %1
264 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
265 %inc = add nuw nsw i64 %iv, 1
266 %exitcond.not = icmp eq i64 %inc, %n
267 br i1 %exitcond.not, label %exit, label %for.body
269 exit: ; preds = %for.body
273 define i64 @select_icmp_min_valid_iv_start(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
274 ; CHECK-LABEL: define i64 @select_icmp_min_valid_iv_start(
275 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[RDX_START:%.*]], i64 [[N:%.*]]) {
276 ; CHECK-NEXT: [[ENTRY:.*]]:
277 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
278 ; CHECK: [[FOR_BODY]]:
279 ; CHECK-NEXT: [[IV_J:%.*]] = phi i64 [ [[INC3:%.*]], %[[FOR_BODY]] ], [ -9223372036854775807, %[[ENTRY]] ]
280 ; CHECK-NEXT: [[IV_I:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
281 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ [[RDX_START]], %[[ENTRY]] ]
282 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV_I]]
283 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
284 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV_I]]
285 ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8
286 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
287 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV_J]], i64 [[RDX]]
288 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV_I]], 1
289 ; CHECK-NEXT: [[INC3]] = add nsw i64 [[IV_J]], 1
290 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
291 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
293 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
294 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
299 for.body: ; preds = %entry, %for.body
300 %iv.j = phi i64 [ %inc3, %for.body ], [ -9223372036854775807, %entry]
301 %iv.i = phi i64 [ %inc, %for.body ], [ 0, %entry ]
302 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
303 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv.i
304 %0 = load i64, ptr %arrayidx, align 8
305 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv.i
306 %1 = load i64, ptr %arrayidx1, align 8
307 %cmp2 = icmp sgt i64 %0, %1
308 %cond = select i1 %cmp2, i64 %iv.j, i64 %rdx
309 %inc = add nuw nsw i64 %iv.i, 1
310 %inc3 = add nsw i64 %iv.j, 1
311 %exitcond.not = icmp eq i64 %inc, %n
312 br i1 %exitcond.not, label %exit, label %for.body
314 exit: ; preds = %for.body
320 define float @not_vectorized_select_float_induction_icmp(ptr %a, ptr %b, float %rdx.start, i64 %n) {
321 ; CHECK-LABEL: define float @not_vectorized_select_float_induction_icmp(
322 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], float [[RDX_START:%.*]], i64 [[N:%.*]]) {
323 ; CHECK-NEXT: [[ENTRY:.*]]:
324 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
325 ; CHECK: [[FOR_BODY]]:
326 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
327 ; CHECK-NEXT: [[FIV:%.*]] = phi float [ [[CONV3:%.*]], %[[FOR_BODY]] ], [ 0.000000e+00, %[[ENTRY]] ]
328 ; CHECK-NEXT: [[RDX:%.*]] = phi float [ [[COND:%.*]], %[[FOR_BODY]] ], [ [[RDX_START]], %[[ENTRY]] ]
329 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
330 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
331 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
332 ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8
333 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
334 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], float [[FIV]], float [[RDX]]
335 ; CHECK-NEXT: [[CONV3]] = fadd float [[FIV]], 1.000000e+00
336 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1
337 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
338 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
340 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi float [ [[COND]], %[[FOR_BODY]] ]
341 ; CHECK-NEXT: ret float [[COND_LCSSA]]
346 for.body: ; preds = %entry, %for.body
347 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
348 %fiv = phi float [ %conv3, %for.body ], [ 0.000000e+00, %entry ]
349 %rdx = phi float [ %cond, %for.body ], [ %rdx.start, %entry ]
350 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
351 %0 = load i64, ptr %arrayidx, align 8
352 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv
353 %1 = load i64, ptr %arrayidx1, align 8
354 %cmp2 = icmp sgt i64 %0, %1
355 %cond = select i1 %cmp2, float %fiv, float %rdx
356 %conv3 = fadd float %fiv, 1.000000e+00
357 %inc = add nuw nsw i64 %iv, 1
358 %exitcond.not = icmp eq i64 %inc, %n
359 br i1 %exitcond.not, label %exit, label %for.body
361 exit: ; preds = %for.body
365 define i64 @not_vectorized_select_decreasing_induction_icmp_const_start(ptr %a) {
366 ; CHECK-LABEL: define i64 @not_vectorized_select_decreasing_induction_icmp_const_start(
367 ; CHECK-SAME: ptr [[A:%.*]]) {
368 ; CHECK-NEXT: [[ENTRY:.*]]:
369 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
370 ; CHECK: [[FOR_BODY]]:
371 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 19999, %[[ENTRY]] ], [ [[DEC:%.*]], %[[FOR_BODY]] ]
372 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ 331, %[[ENTRY]] ], [ [[SPEC_SELECT:%.*]], %[[FOR_BODY]] ]
373 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
374 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
375 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[TMP0]], 3
376 ; CHECK-NEXT: [[SPEC_SELECT]] = select i1 [[CMP]], i64 [[IV]], i64 [[RDX]]
377 ; CHECK-NEXT: [[DEC]] = add nsw i64 [[IV]], -1
378 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i64 [[IV]], 0
379 ; CHECK-NEXT: br i1 [[CMP_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
381 ; CHECK-NEXT: [[SPEC_SELECT_LCSSA:%.*]] = phi i64 [ [[SPEC_SELECT]], %[[FOR_BODY]] ]
382 ; CHECK-NEXT: ret i64 [[SPEC_SELECT_LCSSA]]
387 for.body: ; preds = %entry, %for.body
388 %iv = phi i64 [ 19999, %entry ], [ %dec, %for.body ]
389 %rdx = phi i64 [ 331, %entry ], [ %spec.select, %for.body ]
390 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
391 %0 = load i64, ptr %arrayidx, align 8
392 %cmp = icmp sgt i64 %0, 3
393 %spec.select = select i1 %cmp, i64 %iv, i64 %rdx
394 %dec = add nsw i64 %iv, -1
395 %cmp.not = icmp eq i64 %iv, 0
396 br i1 %cmp.not, label %exit, label %for.body
398 exit: ; preds = %for.body
402 define i64 @not_vectorized_select_decreasing_induction_icmp_non_const_start(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
403 ; CHECK-LABEL: define i64 @not_vectorized_select_decreasing_induction_icmp_non_const_start(
404 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[RDX_START:%.*]], i64 [[N:%.*]]) {
405 ; CHECK-NEXT: [[ENTRY:.*]]:
406 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
407 ; CHECK: [[FOR_BODY]]:
408 ; CHECK-NEXT: [[I_0_IN10:%.*]] = phi i64 [ [[IV:%.*]], %[[FOR_BODY]] ], [ [[N]], %[[ENTRY]] ]
409 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ [[RDX_START]], %[[ENTRY]] ]
410 ; CHECK-NEXT: [[IV]] = add nsw i64 [[I_0_IN10]], -1
411 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
412 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
413 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
414 ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8
415 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
416 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV]], i64 [[RDX]]
417 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[I_0_IN10]], 1
418 ; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_BODY]], label %[[EXIT:.*]]
420 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
421 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
426 for.body: ; preds = %entry, %for.body
427 %i.0.in10 = phi i64 [ %iv, %for.body ], [ %n, %entry ]
428 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
429 %iv = add nsw i64 %i.0.in10, -1
430 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
431 %0 = load i64, ptr %arrayidx, align 8
432 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv
433 %1 = load i64, ptr %arrayidx1, align 8
434 %cmp2 = icmp sgt i64 %0, %1
435 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
436 %cmp = icmp ugt i64 %i.0.in10, 1
437 br i1 %cmp, label %for.body, label %exit
439 exit: ; preds = %for.body
443 ; The sentinel value for increasing-IV vectorization is -LONG_MAX, and since
444 ; the IV hits this value, it is impossible to vectorize this case.
445 define i64 @not_vectorized_select_icmp_iv_out_of_bound(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
446 ; CHECK-LABEL: define i64 @not_vectorized_select_icmp_iv_out_of_bound(
447 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[RDX_START:%.*]], i64 [[N:%.*]]) {
448 ; CHECK-NEXT: [[ENTRY:.*]]:
449 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
450 ; CHECK: [[FOR_BODY]]:
451 ; CHECK-NEXT: [[IV_J:%.*]] = phi i64 [ [[INC3:%.*]], %[[FOR_BODY]] ], [ -9223372036854775808, %[[ENTRY]] ]
452 ; CHECK-NEXT: [[IV_I:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ 0, %[[ENTRY]] ]
453 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ [[RDX_START]], %[[ENTRY]] ]
454 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV_I]]
455 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
456 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV_I]]
457 ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8
458 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
459 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV_J]], i64 [[RDX]]
460 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV_I]], 1
461 ; CHECK-NEXT: [[INC3]] = add nsw i64 [[IV_J]], 1
462 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
463 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
465 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
466 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
471 for.body: ; preds = %entry, %for.body
472 %iv.j = phi i64 [ %inc3, %for.body ], [ -9223372036854775808, %entry]
473 %iv.i = phi i64 [ %inc, %for.body ], [ 0, %entry ]
474 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
475 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv.i
476 %0 = load i64, ptr %arrayidx, align 8
477 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv.i
478 %1 = load i64, ptr %arrayidx1, align 8
479 %cmp2 = icmp sgt i64 %0, %1
480 %cond = select i1 %cmp2, i64 %iv.j, i64 %rdx
481 %inc = add nuw nsw i64 %iv.i, 1
482 %inc3 = add nsw i64 %iv.j, 1
483 %exitcond.not = icmp eq i64 %inc, %n
484 br i1 %exitcond.not, label %exit, label %for.body
486 exit: ; preds = %for.body
490 ; The sentinel value for decreasing-IV vectorization is LONG_MAX, and since
491 ; the IV hits this value, it is impossible to vectorize this case.
492 define i64 @not_vectorized_select_decreasing_induction_icmp_iv_out_of_bound(ptr %a) {
493 ; CHECK-LABEL: define i64 @not_vectorized_select_decreasing_induction_icmp_iv_out_of_bound(
494 ; CHECK-SAME: ptr [[A:%.*]]) {
495 ; CHECK-NEXT: [[ENTRY:.*]]:
496 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
497 ; CHECK: [[FOR_BODY]]:
498 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 9223372036854775807, %[[ENTRY]] ], [ [[DEC:%.*]], %[[FOR_BODY]] ]
499 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ 331, %[[ENTRY]] ], [ [[SPEC_SELECT:%.*]], %[[FOR_BODY]] ]
500 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
501 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
502 ; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[TMP0]], 3
503 ; CHECK-NEXT: [[SPEC_SELECT]] = select i1 [[CMP1]], i64 [[IV]], i64 [[RDX]]
504 ; CHECK-NEXT: [[DEC]] = add nsw i64 [[IV]], -1
505 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i64 [[IV]], 0
506 ; CHECK-NEXT: br i1 [[CMP_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
508 ; CHECK-NEXT: [[SPEC_SELECT_LCSSA:%.*]] = phi i64 [ [[SPEC_SELECT]], %[[FOR_BODY]] ]
509 ; CHECK-NEXT: ret i64 [[SPEC_SELECT_LCSSA]]
514 for.body: ; preds = %entry, %for.body
515 %iv = phi i64 [ 9223372036854775807, %entry ], [ %dec, %for.body ]
516 %rdx = phi i64 [ 331, %entry ], [ %spec.select, %for.body ]
517 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
518 %0 = load i64, ptr %arrayidx, align 8
519 %cmp1 = icmp sgt i64 %0, 3
520 %spec.select = select i1 %cmp1, i64 %iv, i64 %rdx
521 %dec = add nsw i64 %iv, -1
522 %cmp.not = icmp eq i64 %iv, 0
523 br i1 %cmp.not, label %exit, label %for.body
525 exit: ; preds = %for.body
529 define i64 @not_vectorized_select_icmp_non_const_iv_start_value(ptr %a, ptr %b, i64 %ivstart, i64 %rdx.start, i64 %n) {
530 ; CHECK-LABEL: define i64 @not_vectorized_select_icmp_non_const_iv_start_value(
531 ; CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[IVSTART:%.*]], i64 [[RDX_START:%.*]], i64 [[N:%.*]]) {
532 ; CHECK-NEXT: [[ENTRY:.*]]:
533 ; CHECK-NEXT: br label %[[FOR_BODY:.*]]
534 ; CHECK: [[FOR_BODY]]:
535 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INC:%.*]], %[[FOR_BODY]] ], [ [[IVSTART]], %[[ENTRY]] ]
536 ; CHECK-NEXT: [[RDX:%.*]] = phi i64 [ [[COND:%.*]], %[[FOR_BODY]] ], [ [[RDX_START]], %[[ENTRY]] ]
537 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
538 ; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
539 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i64, ptr [[B]], i64 [[IV]]
540 ; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8
541 ; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[TMP0]], [[TMP1]]
542 ; CHECK-NEXT: [[COND]] = select i1 [[CMP2]], i64 [[IV]], i64 [[RDX]]
543 ; CHECK-NEXT: [[INC]] = add nuw nsw i64 [[IV]], 1
544 ; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], [[N]]
545 ; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT:.*]], label %[[FOR_BODY]]
547 ; CHECK-NEXT: [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
548 ; CHECK-NEXT: ret i64 [[COND_LCSSA]]
553 for.body: ; preds = %entry, %for.body
554 %iv = phi i64 [ %inc, %for.body ], [ %ivstart, %entry ]
555 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
556 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
557 %0 = load i64, ptr %arrayidx, align 8
558 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv
559 %1 = load i64, ptr %arrayidx1, align 8
560 %cmp2 = icmp sgt i64 %0, %1
561 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
562 %inc = add nuw nsw i64 %iv, 1
563 %exitcond.not = icmp eq i64 %inc, %n
564 br i1 %exitcond.not, label %exit, label %for.body
566 exit: ; preds = %for.body