ELF: Have __rela_iplt_{start,end} surround .rela.iplt with --pack-dyn-relocs=android.
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / iv-select-cmp.ll
blobb989b8bbe52291a2c20e42fea68861d0a01e1539
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]]
21 ; CHECK:       [[EXIT]]:
22 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
23 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
25 entry:
26   br label %for.body
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
40   ret i64 %cond
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]]
58 ; CHECK:       [[EXIT]]:
59 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
60 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
62 entry:
63   br label %for.body
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
77   ret i64 %cond
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]]
95 ; CHECK:       [[EXIT]]:
96 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
97 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
99 entry:
100   br label %for.body
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
114   ret i64 %cond
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]]
132 ; CHECK:       [[EXIT]]:
133 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
134 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
136 entry:
137   br label %for.body
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
151   ret i64 %cond
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]]
169 ; CHECK:       [[EXIT]]:
170 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
171 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
173 entry:
174   br label %for.body
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
188   ret i64 %cond
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]]
208 ; CHECK:       [[EXIT]]:
209 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
210 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
212 entry:
213   br label %for.body
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
229   ret i64 %cond
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]]
249 ; CHECK:       [[EXIT]]:
250 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
251 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
253 entry:
254   br label %for.body
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
270   ret i64 %cond
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]]
292 ; CHECK:       [[EXIT]]:
293 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
294 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
296 entry:
297   br label %for.body
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
315   ret i64 %cond
318 ; Negative tests
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]]
339 ; CHECK:       [[EXIT]]:
340 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi float [ [[COND]], %[[FOR_BODY]] ]
341 ; CHECK-NEXT:    ret float [[COND_LCSSA]]
343 entry:
344   br label %for.body
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
362   ret float %cond
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]]
380 ; CHECK:       [[EXIT]]:
381 ; CHECK-NEXT:    [[SPEC_SELECT_LCSSA:%.*]] = phi i64 [ [[SPEC_SELECT]], %[[FOR_BODY]] ]
382 ; CHECK-NEXT:    ret i64 [[SPEC_SELECT_LCSSA]]
384 entry:
385   br label %for.body
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
399   ret i64 %spec.select
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:.*]]
419 ; CHECK:       [[EXIT]]:
420 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
421 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
423 entry:
424   br label %for.body
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
440   ret i64 %cond
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]]
464 ; CHECK:       [[EXIT]]:
465 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
466 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
468 entry:
469   br label %for.body
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
487   ret i64 %cond
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]]
507 ; CHECK:       [[EXIT]]:
508 ; CHECK-NEXT:    [[SPEC_SELECT_LCSSA:%.*]] = phi i64 [ [[SPEC_SELECT]], %[[FOR_BODY]] ]
509 ; CHECK-NEXT:    ret i64 [[SPEC_SELECT_LCSSA]]
511 entry:
512   br label %for.body
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
526   ret i64 %spec.select
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]]
546 ; CHECK:       [[EXIT]]:
547 ; CHECK-NEXT:    [[COND_LCSSA:%.*]] = phi i64 [ [[COND]], %[[FOR_BODY]] ]
548 ; CHECK-NEXT:    ret i64 [[COND_LCSSA]]
550 entry:
551   br label %for.body
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
567   ret i64 %cond