1 ; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -S < %s | FileCheck %s --check-prefix=CHECK
2 ; RUN: opt -passes=loop-vectorize -force-vector-interleave=4 -force-vector-width=4 -S < %s | FileCheck %s --check-prefix=CHECK
3 ; RUN: opt -passes=loop-vectorize -force-vector-interleave=4 -force-vector-width=1 -S < %s | FileCheck %s --check-prefix=CHECK
5 define i64 @select_icmp_const_1(ptr %a, i64 %n) {
6 ; CHECK-LABEL: define i64 @select_icmp_const_1
7 ; CHECK-NOT: vector.body:
12 for.body: ; preds = %entry, %for.body
13 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
14 %rdx = phi i64 [ %cond, %for.body ], [ 3, %entry ]
15 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
16 %0 = load i64, ptr %arrayidx, align 8
17 %cmp2 = icmp eq i64 %0, 3
18 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
19 %inc = add nuw nsw i64 %iv, 1
20 %exitcond.not = icmp eq i64 %inc, %n
21 br i1 %exitcond.not, label %exit, label %for.body
23 exit: ; preds = %for.body
27 define i64 @select_icmp_const_2(ptr %a, i64 %n) {
28 ; CHECK-LABEL: define i64 @select_icmp_const_2
29 ; CHECK-NOT: vector.body:
34 for.body: ; preds = %entry, %for.body
35 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
36 %rdx = phi i64 [ %cond, %for.body ], [ 3, %entry ]
37 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
38 %0 = load i64, ptr %arrayidx, align 8
39 %cmp2 = icmp eq i64 %0, 3
40 %cond = select i1 %cmp2, i64 %rdx, i64 %iv
41 %inc = add nuw nsw i64 %iv, 1
42 %exitcond.not = icmp eq i64 %inc, %n
43 br i1 %exitcond.not, label %exit, label %for.body
45 exit: ; preds = %for.body
49 define i64 @select_icmp_const_3_variable_rdx_start(ptr %a, i64 %rdx.start, i64 %n) {
50 ; CHECK-LABEL: define i64 @select_icmp_const_3_variable_rdx_start
51 ; CHECK-NOT: vector.body:
56 for.body: ; preds = %entry, %for.body
57 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
58 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
59 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
60 %0 = load i64, ptr %arrayidx, align 8
61 %cmp2 = icmp eq i64 %0, 3
62 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
63 %inc = add nuw nsw i64 %iv, 1
64 %exitcond.not = icmp eq i64 %inc, %n
65 br i1 %exitcond.not, label %exit, label %for.body
67 exit: ; preds = %for.body
71 define i64 @select_fcmp_const_fast(ptr %a, i64 %n) {
72 ; CHECK-LABEL: define i64 @select_fcmp_const_fast
73 ; CHECK-NOT: vector.body:
78 for.body: ; preds = %entry, %for.body
79 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
80 %rdx = phi i64 [ %cond, %for.body ], [ 2, %entry ]
81 %arrayidx = getelementptr inbounds float, ptr %a, i64 %iv
82 %0 = load float, ptr %arrayidx, align 4
83 %cmp2 = fcmp fast ueq float %0, 3.0
84 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
85 %inc = add nuw nsw i64 %iv, 1
86 %exitcond.not = icmp eq i64 %inc, %n
87 br i1 %exitcond.not, label %exit, label %for.body
89 exit: ; preds = %for.body
93 define i64 @select_fcmp_const(ptr %a, i64 %n) {
94 ; CHECK-LABEL: define i64 @select_fcmp_const
95 ; CHECK-NOT: vector.body:
100 for.body: ; preds = %entry, %for.body
101 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
102 %rdx = phi i64 [ %cond, %for.body ], [ 2, %entry ]
103 %arrayidx = getelementptr inbounds float, ptr %a, i64 %iv
104 %0 = load float, ptr %arrayidx, align 4
105 %cmp2 = fcmp ueq float %0, 3.0
106 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
107 %inc = add nuw nsw i64 %iv, 1
108 %exitcond.not = icmp eq i64 %inc, %n
109 br i1 %exitcond.not, label %exit, label %for.body
111 exit: ; preds = %for.body
115 define i64 @select_icmp(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
116 ; CHECK-LABEL: define i64 @select_icmp
117 ; CHECK-NOT: vector.body:
122 for.body: ; preds = %entry, %for.body
123 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
124 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
125 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
126 %0 = load i64, ptr %arrayidx, align 8
127 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv
128 %1 = load i64, ptr %arrayidx1, align 8
129 %cmp2 = icmp sgt i64 %0, %1
130 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
131 %inc = add nuw nsw i64 %iv, 1
132 %exitcond.not = icmp eq i64 %inc, %n
133 br i1 %exitcond.not, label %exit, label %for.body
135 exit: ; preds = %for.body
139 define i64 @select_fcmp(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
140 ; CHECK-LABEL: define i64 @select_fcmp
141 ; CHECK-NOT: vector.body:
146 for.body: ; preds = %entry, %for.body
147 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
148 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
149 %arrayidx = getelementptr inbounds float, ptr %a, i64 %iv
150 %0 = load float, ptr %arrayidx, align 4
151 %arrayidx1 = getelementptr inbounds float, ptr %b, i64 %iv
152 %1 = load float, ptr %arrayidx1, align 4
153 %cmp2 = fcmp ogt float %0, %1
154 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
155 %inc = add nuw nsw i64 %iv, 1
156 %exitcond.not = icmp eq i64 %inc, %n
157 br i1 %exitcond.not, label %exit, label %for.body
159 exit: ; preds = %for.body
163 define i64 @select_icmp_min_valid_iv_start(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
164 ; CHECK-LABEL: define i64 @select_icmp_min_valid_iv_start
165 ; CHECK-NOT: vector.body:
170 for.body: ; preds = %entry, %for.body
171 %iv.j = phi i64 [ %inc3, %for.body ], [ -9223372036854775807, %entry]
172 %iv.i = phi i64 [ %inc, %for.body ], [ 0, %entry ]
173 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
174 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv.i
175 %0 = load i64, ptr %arrayidx, align 8
176 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv.i
177 %1 = load i64, ptr %arrayidx1, align 8
178 %cmp2 = icmp sgt i64 %0, %1
179 %cond = select i1 %cmp2, i64 %iv.j, i64 %rdx
180 %inc = add nuw nsw i64 %iv.i, 1
181 %inc3 = add nsw i64 %iv.j, 1
182 %exitcond.not = icmp eq i64 %inc, %n
183 br i1 %exitcond.not, label %exit, label %for.body
185 exit: ; preds = %for.body
191 define float @not_vectorized_select_float_induction_icmp(ptr %a, ptr %b, float %rdx.start, i64 %n) {
192 ; CHECK-LABEL: @not_vectorized_select_float_induction_icmp
193 ; CHECK-NOT: vector.body:
198 for.body: ; preds = %entry, %for.body
199 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]
200 %fiv = phi float [ %conv3, %for.body ], [ 0.000000e+00, %entry ]
201 %rdx = phi float [ %cond, %for.body ], [ %rdx.start, %entry ]
202 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
203 %0 = load i64, ptr %arrayidx, align 8
204 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv
205 %1 = load i64, ptr %arrayidx1, align 8
206 %cmp2 = icmp sgt i64 %0, %1
207 %cond = select i1 %cmp2, float %fiv, float %rdx
208 %conv3 = fadd float %fiv, 1.000000e+00
209 %inc = add nuw nsw i64 %iv, 1
210 %exitcond.not = icmp eq i64 %inc, %n
211 br i1 %exitcond.not, label %exit, label %for.body
213 exit: ; preds = %for.body
217 define i64 @not_vectorized_select_decreasing_induction_icmp_const_start(ptr %a) {
218 ; CHECK-LABEL: @not_vectorized_select_decreasing_induction_icmp_const_start
219 ; CHECK-NOT: vector.body:
224 for.body: ; preds = %entry, %for.body
225 %iv = phi i64 [ 19999, %entry ], [ %dec, %for.body ]
226 %rdx = phi i64 [ 331, %entry ], [ %spec.select, %for.body ]
227 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
228 %0 = load i64, ptr %arrayidx, align 8
229 %cmp = icmp sgt i64 %0, 3
230 %spec.select = select i1 %cmp, i64 %iv, i64 %rdx
231 %dec = add nsw i64 %iv, -1
232 %cmp.not = icmp eq i64 %iv, 0
233 br i1 %cmp.not, label %exit, label %for.body
235 exit: ; preds = %for.body
239 define i64 @not_vectorized_select_decreasing_induction_icmp_non_const_start(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
240 ; CHECK-LABEL: @not_vectorized_select_decreasing_induction_icmp_non_const_start
241 ; CHECK-NOT: vector.body:
246 for.body: ; preds = %entry, %for.body
247 %i.0.in10 = phi i64 [ %iv, %for.body ], [ %n, %entry ]
248 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
249 %iv = add nsw i64 %i.0.in10, -1
250 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
251 %0 = load i64, ptr %arrayidx, align 8
252 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv
253 %1 = load i64, ptr %arrayidx1, align 8
254 %cmp2 = icmp sgt i64 %0, %1
255 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
256 %cmp = icmp ugt i64 %i.0.in10, 1
257 br i1 %cmp, label %for.body, label %exit
259 exit: ; preds = %for.body
263 ; The sentinel value for increasing-IV vectorization is -LONG_MAX, and since
264 ; the IV hits this value, it is impossible to vectorize this case.
265 define i64 @not_vectorized_select_icmp_iv_out_of_bound(ptr %a, ptr %b, i64 %rdx.start, i64 %n) {
266 ; CHECK-LABEL: @not_vectorized_select_icmp_iv_out_of_bound
267 ; CHECK-NOT: vector.body:
272 for.body: ; preds = %entry, %for.body
273 %iv.j = phi i64 [ %inc3, %for.body ], [ -9223372036854775808, %entry]
274 %iv.i = phi i64 [ %inc, %for.body ], [ 0, %entry ]
275 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
276 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv.i
277 %0 = load i64, ptr %arrayidx, align 8
278 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv.i
279 %1 = load i64, ptr %arrayidx1, align 8
280 %cmp2 = icmp sgt i64 %0, %1
281 %cond = select i1 %cmp2, i64 %iv.j, i64 %rdx
282 %inc = add nuw nsw i64 %iv.i, 1
283 %inc3 = add nsw i64 %iv.j, 1
284 %exitcond.not = icmp eq i64 %inc, %n
285 br i1 %exitcond.not, label %exit, label %for.body
287 exit: ; preds = %for.body
291 ; The sentinel value for decreasing-IV vectorization is LONG_MAX, and since
292 ; the IV hits this value, it is impossible to vectorize this case.
293 define i64 @not_vectorized_select_decreasing_induction_icmp_iv_out_of_bound(ptr %a) {
294 ; CHECK-LABEL: @not_vectorized_select_decreasing_induction_icmp_iv_out_of_bound
295 ; CHECK-NOT: vector.body:
300 for.body: ; preds = %entry, %for.body
301 %iv = phi i64 [ 9223372036854775807, %entry ], [ %dec, %for.body ]
302 %rdx = phi i64 [ 331, %entry ], [ %spec.select, %for.body ]
303 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
304 %0 = load i64, ptr %arrayidx, align 8
305 %cmp1 = icmp sgt i64 %0, 3
306 %spec.select = select i1 %cmp1, i64 %iv, i64 %rdx
307 %dec = add nsw i64 %iv, -1
308 %cmp.not = icmp eq i64 %iv, 0
309 br i1 %cmp.not, label %exit, label %for.body
311 exit: ; preds = %for.body
315 define i64 @not_vectorized_select_icmp_non_const_iv_start_value(ptr %a, ptr %b, i64 %ivstart, i64 %rdx.start, i64 %n) {
316 ; CHECK-LABEL: define i64 @not_vectorized_select_icmp_non_const_iv_start_value
317 ; CHECK-NOT: vector.body:
322 for.body: ; preds = %entry, %for.body
323 %iv = phi i64 [ %inc, %for.body ], [ %ivstart, %entry ]
324 %rdx = phi i64 [ %cond, %for.body ], [ %rdx.start, %entry ]
325 %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
326 %0 = load i64, ptr %arrayidx, align 8
327 %arrayidx1 = getelementptr inbounds i64, ptr %b, i64 %iv
328 %1 = load i64, ptr %arrayidx1, align 8
329 %cmp2 = icmp sgt i64 %0, %1
330 %cond = select i1 %cmp2, i64 %iv, i64 %rdx
331 %inc = add nuw nsw i64 %iv, 1
332 %exitcond.not = icmp eq i64 %inc, %n
333 br i1 %exitcond.not, label %exit, label %for.body
335 exit: ; preds = %for.body