Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / iv-select-cmp.ll
blob6108dbd0b191e672d3bb8b2f028cbc2209081b8b
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:
9 entry:
10   br label %for.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
24   ret i64 %cond
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:
31 entry:
32   br label %for.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
46   ret i64 %cond
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:
53 entry:
54   br label %for.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
68   ret i64 %cond
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:
75 entry:
76   br label %for.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
90   ret i64 %cond
93 define i64 @select_fcmp_const(ptr %a, i64 %n) {
94 ; CHECK-LABEL: define i64 @select_fcmp_const
95 ; CHECK-NOT:   vector.body:
97 entry:
98   br label %for.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
112   ret i64 %cond
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:
119 entry:
120   br label %for.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
136   ret i64 %cond
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:
143 entry:
144   br label %for.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
160   ret i64 %cond
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:
167 entry:
168   br label %for.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
186   ret i64 %cond
189 ; Negative tests
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:
195 entry:
196   br label %for.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
214   ret float %cond
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:
221 entry:
222   br label %for.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
236   ret i64 %spec.select
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:
243 entry:
244   br label %for.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
260   ret i64 %cond
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:
269 entry:
270   br label %for.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
288   ret i64 %cond
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:
297 entry:
298   br label %for.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
312   ret i64 %spec.select
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:
319 entry:
320   br label %for.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
336   ret i64 %cond