1 ; RUN: opt -S -loop-vectorize -dce -force-vector-width=2 -force-vector-interleave=1 < %s | FileCheck %s
3 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
5 @A = common global [1024 x i32] zeroinitializer, align 16
6 @fA = common global [1024 x float] zeroinitializer, align 16
7 @dA = common global [1024 x double] zeroinitializer, align 16
11 ; Turn this into a max reduction. Make sure we use a splat to initialize the
12 ; vector for the reduction.
13 ; CHECK-LABEL: @max_red(
14 ; CHECK: %[[VAR:.*]] = insertelement <2 x i32> poison, i32 %max, i32 0
15 ; CHECK: {{.*}} = shufflevector <2 x i32> %[[VAR]], <2 x i32> poison, <2 x i32> zeroinitializer
16 ; CHECK: icmp sgt <2 x i32>
17 ; CHECK: select <2 x i1>
19 ; CHECK: call i32 @llvm.vector.reduce.smax.v2i32
21 define i32 @max_red(i32 %max) {
26 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
27 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
28 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
29 %0 = load i32, i32* %arrayidx, align 4
30 %cmp3 = icmp sgt i32 %0, %max.red.08
31 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
32 %indvars.iv.next = add i64 %indvars.iv, 1
33 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
34 %exitcond = icmp eq i32 %lftr.wideiv, 1024
35 br i1 %exitcond, label %for.end, label %for.body
41 ; Turn this into a max reduction. The select has its inputs reversed therefore
42 ; this is a max reduction.
43 ; CHECK-LABEL: @max_red_inverse_select(
44 ; CHECK: icmp slt <2 x i32>
45 ; CHECK: select <2 x i1>
47 ; CHECK: call i32 @llvm.vector.reduce.smax.v2i32
49 define i32 @max_red_inverse_select(i32 %max) {
54 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
55 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
56 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
57 %0 = load i32, i32* %arrayidx, align 4
58 %cmp3 = icmp slt i32 %max.red.08, %0
59 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
60 %indvars.iv.next = add i64 %indvars.iv, 1
61 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
62 %exitcond = icmp eq i32 %lftr.wideiv, 1024
63 br i1 %exitcond, label %for.end, label %for.body
69 ; Turn this into a min reduction.
70 ; CHECK-LABEL: @min_red(
71 ; CHECK: icmp slt <2 x i32>
72 ; CHECK: select <2 x i1>
74 ; CHECK: call i32 @llvm.vector.reduce.smin.v2i32
76 define i32 @min_red(i32 %max) {
81 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
82 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
83 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
84 %0 = load i32, i32* %arrayidx, align 4
85 %cmp3 = icmp slt i32 %0, %max.red.08
86 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
87 %indvars.iv.next = add i64 %indvars.iv, 1
88 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
89 %exitcond = icmp eq i32 %lftr.wideiv, 1024
90 br i1 %exitcond, label %for.end, label %for.body
96 ; Turn this into a min reduction. The select has its inputs reversed therefore
97 ; this is a min reduction.
98 ; CHECK-LABEL: @min_red_inverse_select(
99 ; CHECK: icmp sgt <2 x i32>
100 ; CHECK: select <2 x i1>
101 ; CHECK: middle.block
102 ; CHECK: call i32 @llvm.vector.reduce.smin.v2i32
104 define i32 @min_red_inverse_select(i32 %max) {
109 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
110 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
111 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
112 %0 = load i32, i32* %arrayidx, align 4
113 %cmp3 = icmp sgt i32 %max.red.08, %0
114 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
115 %indvars.iv.next = add i64 %indvars.iv, 1
116 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
117 %exitcond = icmp eq i32 %lftr.wideiv, 1024
118 br i1 %exitcond, label %for.end, label %for.body
126 ; Turn this into a max reduction.
127 ; CHECK-LABEL: @umax_red(
128 ; CHECK: icmp ugt <2 x i32>
129 ; CHECK: select <2 x i1>
130 ; CHECK: middle.block
131 ; CHECK: call i32 @llvm.vector.reduce.umax.v2i32
133 define i32 @umax_red(i32 %max) {
138 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
139 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
140 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
141 %0 = load i32, i32* %arrayidx, align 4
142 %cmp3 = icmp ugt i32 %0, %max.red.08
143 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
144 %indvars.iv.next = add i64 %indvars.iv, 1
145 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
146 %exitcond = icmp eq i32 %lftr.wideiv, 1024
147 br i1 %exitcond, label %for.end, label %for.body
153 ; Turn this into a max reduction. The select has its inputs reversed therefore
154 ; this is a max reduction.
155 ; CHECK-LABEL: @umax_red_inverse_select(
156 ; CHECK: icmp ult <2 x i32>
157 ; CHECK: select <2 x i1>
158 ; CHECK: middle.block
159 ; CHECK: call i32 @llvm.vector.reduce.umax.v2i32
161 define i32 @umax_red_inverse_select(i32 %max) {
166 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
167 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
168 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
169 %0 = load i32, i32* %arrayidx, align 4
170 %cmp3 = icmp ult i32 %max.red.08, %0
171 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
172 %indvars.iv.next = add i64 %indvars.iv, 1
173 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
174 %exitcond = icmp eq i32 %lftr.wideiv, 1024
175 br i1 %exitcond, label %for.end, label %for.body
181 ; Turn this into a min reduction.
182 ; CHECK-LABEL: @umin_red(
183 ; CHECK: icmp ult <2 x i32>
184 ; CHECK: select <2 x i1>
185 ; CHECK: middle.block
186 ; CHECK: call i32 @llvm.vector.reduce.umin.v2i32
188 define i32 @umin_red(i32 %max) {
193 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
194 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
195 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
196 %0 = load i32, i32* %arrayidx, align 4
197 %cmp3 = icmp ult i32 %0, %max.red.08
198 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
199 %indvars.iv.next = add i64 %indvars.iv, 1
200 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
201 %exitcond = icmp eq i32 %lftr.wideiv, 1024
202 br i1 %exitcond, label %for.end, label %for.body
208 ; Turn this into a min reduction. The select has its inputs reversed therefore
209 ; this is a min reduction.
210 ; CHECK-LABEL: @umin_red_inverse_select(
211 ; CHECK: icmp ugt <2 x i32>
212 ; CHECK: select <2 x i1>
213 ; CHECK: middle.block
214 ; CHECK: call i32 @llvm.vector.reduce.umin.v2i32
216 define i32 @umin_red_inverse_select(i32 %max) {
221 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
222 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
223 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
224 %0 = load i32, i32* %arrayidx, align 4
225 %cmp3 = icmp ugt i32 %max.red.08, %0
226 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
227 %indvars.iv.next = add i64 %indvars.iv, 1
228 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
229 %exitcond = icmp eq i32 %lftr.wideiv, 1024
230 br i1 %exitcond, label %for.end, label %for.body
237 ; Turn this into a min reduction (select inputs are reversed).
238 ; CHECK-LABEL: @sge_min_red(
239 ; CHECK: icmp sge <2 x i32>
240 ; CHECK: select <2 x i1>
241 ; CHECK: middle.block
242 ; CHECK: call i32 @llvm.vector.reduce.smin.v2i32
244 define i32 @sge_min_red(i32 %max) {
249 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
250 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
251 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
252 %0 = load i32, i32* %arrayidx, align 4
253 %cmp3 = icmp sge i32 %0, %max.red.08
254 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0
255 %indvars.iv.next = add i64 %indvars.iv, 1
256 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
257 %exitcond = icmp eq i32 %lftr.wideiv, 1024
258 br i1 %exitcond, label %for.end, label %for.body
265 ; Turn this into a max reduction (select inputs are reversed).
266 ; CHECK-LABEL: @sle_min_red(
267 ; CHECK: icmp sle <2 x i32>
268 ; CHECK: select <2 x i1>
269 ; CHECK: middle.block
270 ; CHECK: call i32 @llvm.vector.reduce.smax.v2i32
272 define i32 @sle_min_red(i32 %max) {
277 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
278 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
279 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
280 %0 = load i32, i32* %arrayidx, align 4
281 %cmp3 = icmp sle i32 %0, %max.red.08
282 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0
283 %indvars.iv.next = add i64 %indvars.iv, 1
284 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
285 %exitcond = icmp eq i32 %lftr.wideiv, 1024
286 br i1 %exitcond, label %for.end, label %for.body
293 ; Turn this into a min reduction (select inputs are reversed).
294 ; CHECK-LABEL: @uge_min_red(
295 ; CHECK: icmp uge <2 x i32>
296 ; CHECK: select <2 x i1>
297 ; CHECK: middle.block
298 ; CHECK: call i32 @llvm.vector.reduce.umin.v2i32
300 define i32 @uge_min_red(i32 %max) {
305 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
306 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
307 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
308 %0 = load i32, i32* %arrayidx, align 4
309 %cmp3 = icmp uge i32 %0, %max.red.08
310 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0
311 %indvars.iv.next = add i64 %indvars.iv, 1
312 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
313 %exitcond = icmp eq i32 %lftr.wideiv, 1024
314 br i1 %exitcond, label %for.end, label %for.body
321 ; Turn this into a max reduction (select inputs are reversed).
322 ; CHECK-LABEL: @ule_min_red(
323 ; CHECK: icmp ule <2 x i32>
324 ; CHECK: select <2 x i1>
325 ; CHECK: middle.block
326 ; CHECK: call i32 @llvm.vector.reduce.umax.v2i32
328 define i32 @ule_min_red(i32 %max) {
333 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
334 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
335 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
336 %0 = load i32, i32* %arrayidx, align 4
337 %cmp3 = icmp ule i32 %0, %max.red.08
338 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0
339 %indvars.iv.next = add i64 %indvars.iv, 1
340 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
341 %exitcond = icmp eq i32 %lftr.wideiv, 1024
342 br i1 %exitcond, label %for.end, label %for.body
349 ; CHECK-LABEL: @no_red_1(
350 ; CHECK-NOT: icmp <2 x i32>
351 define i32 @no_red_1(i32 %max) {
356 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
357 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
358 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
359 %arrayidx1 = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 1, i64 %indvars.iv
360 %0 = load i32, i32* %arrayidx, align 4
361 %1 = load i32, i32* %arrayidx1, align 4
362 %cmp3 = icmp sgt i32 %0, %1
363 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
364 %indvars.iv.next = add i64 %indvars.iv, 1
365 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
366 %exitcond = icmp eq i32 %lftr.wideiv, 1024
367 br i1 %exitcond, label %for.end, label %for.body
373 ; CHECK-LABEL: @no_red_2(
374 ; CHECK-NOT: icmp <2 x i32>
375 define i32 @no_red_2(i32 %max) {
380 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
381 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
382 %arrayidx = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 0, i64 %indvars.iv
383 %arrayidx1 = getelementptr inbounds [1024 x i32], [1024 x i32]* @A, i64 1, i64 %indvars.iv
384 %0 = load i32, i32* %arrayidx, align 4
385 %1 = load i32, i32* %arrayidx1, align 4
386 %cmp3 = icmp sgt i32 %0, %max.red.08
387 %max.red.0 = select i1 %cmp3, i32 %0, i32 %1
388 %indvars.iv.next = add i64 %indvars.iv, 1
389 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
390 %exitcond = icmp eq i32 %lftr.wideiv, 1024
391 br i1 %exitcond, label %for.end, label %for.body
401 ; Turn this into a max reduction in the presence of a no-nans-fp-math attribute.
402 ; CHECK-LABEL: @max_red_float(
403 ; CHECK: fcmp fast ogt <2 x float>
404 ; CHECK: select <2 x i1>
405 ; CHECK: middle.block
406 ; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32
408 define float @max_red_float(float %max) #0 {
413 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
414 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
415 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
416 %0 = load float, float* %arrayidx, align 4
417 %cmp3 = fcmp fast ogt float %0, %max.red.08
418 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
419 %indvars.iv.next = add i64 %indvars.iv, 1
420 %exitcond = icmp eq i64 %indvars.iv.next, 1024
421 br i1 %exitcond, label %for.end, label %for.body
427 ; CHECK-LABEL: @max_red_float_ge(
428 ; CHECK: fcmp fast oge <2 x float>
429 ; CHECK: select <2 x i1>
430 ; CHECK: middle.block
431 ; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32
433 define float @max_red_float_ge(float %max) #0 {
438 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
439 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
440 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
441 %0 = load float, float* %arrayidx, align 4
442 %cmp3 = fcmp fast oge float %0, %max.red.08
443 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
444 %indvars.iv.next = add i64 %indvars.iv, 1
445 %exitcond = icmp eq i64 %indvars.iv.next, 1024
446 br i1 %exitcond, label %for.end, label %for.body
452 ; CHECK-LABEL: @inverted_max_red_float(
453 ; CHECK: fcmp fast olt <2 x float>
454 ; CHECK: select <2 x i1>
455 ; CHECK: middle.block
456 ; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32
458 define float @inverted_max_red_float(float %max) #0 {
463 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
464 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
465 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
466 %0 = load float, float* %arrayidx, align 4
467 %cmp3 = fcmp fast olt float %0, %max.red.08
468 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0
469 %indvars.iv.next = add i64 %indvars.iv, 1
470 %exitcond = icmp eq i64 %indvars.iv.next, 1024
471 br i1 %exitcond, label %for.end, label %for.body
477 ; CHECK-LABEL: @inverted_max_red_float_le(
478 ; CHECK: fcmp fast ole <2 x float>
479 ; CHECK: select <2 x i1>
480 ; CHECK: middle.block
481 ; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32
483 define float @inverted_max_red_float_le(float %max) #0 {
488 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
489 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
490 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
491 %0 = load float, float* %arrayidx, align 4
492 %cmp3 = fcmp fast ole float %0, %max.red.08
493 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0
494 %indvars.iv.next = add i64 %indvars.iv, 1
495 %exitcond = icmp eq i64 %indvars.iv.next, 1024
496 br i1 %exitcond, label %for.end, label %for.body
502 ; CHECK-LABEL: @unordered_max_red_float(
503 ; CHECK: fcmp fast ugt <2 x float>
504 ; CHECK: select <2 x i1>
505 ; CHECK: middle.block
506 ; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32
508 define float @unordered_max_red_float(float %max) #0 {
513 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
514 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
515 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
516 %0 = load float, float* %arrayidx, align 4
517 %cmp3 = fcmp fast ugt float %0, %max.red.08
518 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
519 %indvars.iv.next = add i64 %indvars.iv, 1
520 %exitcond = icmp eq i64 %indvars.iv.next, 1024
521 br i1 %exitcond, label %for.end, label %for.body
527 ; CHECK-LABEL: @unordered_max_red_float_ge(
528 ; CHECK: fcmp fast uge <2 x float>
529 ; CHECK: select <2 x i1>
530 ; CHECK: middle.block
531 ; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32
533 define float @unordered_max_red_float_ge(float %max) #0 {
538 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
539 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
540 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
541 %0 = load float, float* %arrayidx, align 4
542 %cmp3 = fcmp fast uge float %0, %max.red.08
543 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
544 %indvars.iv.next = add i64 %indvars.iv, 1
545 %exitcond = icmp eq i64 %indvars.iv.next, 1024
546 br i1 %exitcond, label %for.end, label %for.body
552 ; CHECK-LABEL: @inverted_unordered_max_red_float(
553 ; CHECK: fcmp fast ult <2 x float>
554 ; CHECK: select <2 x i1>
555 ; CHECK: middle.block
556 ; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32
558 define float @inverted_unordered_max_red_float(float %max) #0 {
563 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
564 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
565 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
566 %0 = load float, float* %arrayidx, align 4
567 %cmp3 = fcmp fast ult float %0, %max.red.08
568 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0
569 %indvars.iv.next = add i64 %indvars.iv, 1
570 %exitcond = icmp eq i64 %indvars.iv.next, 1024
571 br i1 %exitcond, label %for.end, label %for.body
577 ; CHECK-LABEL: @inverted_unordered_max_red_float_le(
578 ; CHECK: fcmp fast ule <2 x float>
579 ; CHECK: select <2 x i1>
580 ; CHECK: middle.block
581 ; CHECK: call fast float @llvm.vector.reduce.fmax.v2f32
583 define float @inverted_unordered_max_red_float_le(float %max) #0 {
588 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
589 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
590 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
591 %0 = load float, float* %arrayidx, align 4
592 %cmp3 = fcmp fast ule float %0, %max.red.08
593 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0
594 %indvars.iv.next = add i64 %indvars.iv, 1
595 %exitcond = icmp eq i64 %indvars.iv.next, 1024
596 br i1 %exitcond, label %for.end, label %for.body
604 ; Turn this into a min reduction in the presence of a no-nans-fp-math attribute.
605 ; CHECK-LABEL: @min_red_float(
606 ; CHECK: fcmp fast olt <2 x float>
607 ; CHECK: select <2 x i1>
608 ; CHECK: middle.block
609 ; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32
611 define float @min_red_float(float %min) #0 {
616 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
617 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
618 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
619 %0 = load float, float* %arrayidx, align 4
620 %cmp3 = fcmp fast olt float %0, %min.red.08
621 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08
622 %indvars.iv.next = add i64 %indvars.iv, 1
623 %exitcond = icmp eq i64 %indvars.iv.next, 1024
624 br i1 %exitcond, label %for.end, label %for.body
630 ; CHECK-LABEL: @min_red_float_le(
631 ; CHECK: fcmp fast ole <2 x float>
632 ; CHECK: select <2 x i1>
633 ; CHECK: middle.block
634 ; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32
636 define float @min_red_float_le(float %min) #0 {
641 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
642 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
643 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
644 %0 = load float, float* %arrayidx, align 4
645 %cmp3 = fcmp fast ole float %0, %min.red.08
646 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08
647 %indvars.iv.next = add i64 %indvars.iv, 1
648 %exitcond = icmp eq i64 %indvars.iv.next, 1024
649 br i1 %exitcond, label %for.end, label %for.body
655 ; CHECK-LABEL: @inverted_min_red_float(
656 ; CHECK: fcmp fast ogt <2 x float>
657 ; CHECK: select <2 x i1>
658 ; CHECK: middle.block
659 ; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32
661 define float @inverted_min_red_float(float %min) #0 {
666 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
667 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
668 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
669 %0 = load float, float* %arrayidx, align 4
670 %cmp3 = fcmp fast ogt float %0, %min.red.08
671 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0
672 %indvars.iv.next = add i64 %indvars.iv, 1
673 %exitcond = icmp eq i64 %indvars.iv.next, 1024
674 br i1 %exitcond, label %for.end, label %for.body
680 ; CHECK-LABEL: @inverted_min_red_float_ge(
681 ; CHECK: fcmp fast oge <2 x float>
682 ; CHECK: select <2 x i1>
683 ; CHECK: middle.block
684 ; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32
686 define float @inverted_min_red_float_ge(float %min) #0 {
691 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
692 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
693 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
694 %0 = load float, float* %arrayidx, align 4
695 %cmp3 = fcmp fast oge float %0, %min.red.08
696 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0
697 %indvars.iv.next = add i64 %indvars.iv, 1
698 %exitcond = icmp eq i64 %indvars.iv.next, 1024
699 br i1 %exitcond, label %for.end, label %for.body
705 ; CHECK-LABEL: @unordered_min_red_float(
706 ; CHECK: fcmp fast ult <2 x float>
707 ; CHECK: select <2 x i1>
708 ; CHECK: middle.block
709 ; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32
711 define float @unordered_min_red_float(float %min) #0 {
716 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
717 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
718 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
719 %0 = load float, float* %arrayidx, align 4
720 %cmp3 = fcmp fast ult float %0, %min.red.08
721 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08
722 %indvars.iv.next = add i64 %indvars.iv, 1
723 %exitcond = icmp eq i64 %indvars.iv.next, 1024
724 br i1 %exitcond, label %for.end, label %for.body
730 ; CHECK-LABEL: @unordered_min_red_float_le(
731 ; CHECK: fcmp fast ule <2 x float>
732 ; CHECK: select <2 x i1>
733 ; CHECK: middle.block
734 ; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32
736 define float @unordered_min_red_float_le(float %min) #0 {
741 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
742 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
743 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
744 %0 = load float, float* %arrayidx, align 4
745 %cmp3 = fcmp fast ule float %0, %min.red.08
746 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08
747 %indvars.iv.next = add i64 %indvars.iv, 1
748 %exitcond = icmp eq i64 %indvars.iv.next, 1024
749 br i1 %exitcond, label %for.end, label %for.body
755 ; CHECK-LABEL: @inverted_unordered_min_red_float(
756 ; CHECK: fcmp fast ugt <2 x float>
757 ; CHECK: select <2 x i1>
758 ; CHECK: middle.block
759 ; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32
761 define float @inverted_unordered_min_red_float(float %min) #0 {
766 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
767 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
768 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
769 %0 = load float, float* %arrayidx, align 4
770 %cmp3 = fcmp fast ugt float %0, %min.red.08
771 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0
772 %indvars.iv.next = add i64 %indvars.iv, 1
773 %exitcond = icmp eq i64 %indvars.iv.next, 1024
774 br i1 %exitcond, label %for.end, label %for.body
780 ; CHECK-LABEL: @inverted_unordered_min_red_float_ge(
781 ; CHECK: fcmp fast uge <2 x float>
782 ; CHECK: select <2 x i1>
783 ; CHECK: middle.block
784 ; CHECK: call fast float @llvm.vector.reduce.fmin.v2f32
786 define float @inverted_unordered_min_red_float_ge(float %min) #0 {
791 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
792 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
793 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
794 %0 = load float, float* %arrayidx, align 4
795 %cmp3 = fcmp fast uge float %0, %min.red.08
796 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0
797 %indvars.iv.next = add i64 %indvars.iv, 1
798 %exitcond = icmp eq i64 %indvars.iv.next, 1024
799 br i1 %exitcond, label %for.end, label %for.body
805 ; Make sure we handle doubles, too.
806 ; CHECK-LABEL: @min_red_double(
807 ; CHECK: fcmp fast olt <2 x double>
808 ; CHECK: select <2 x i1>
809 ; CHECK: middle.block
810 ; CHECK: call fast double @llvm.vector.reduce.fmin.v2f64
812 define double @min_red_double(double %min) #0 {
817 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
818 %min.red.08 = phi double [ %min, %entry ], [ %min.red.0, %for.body ]
819 %arrayidx = getelementptr inbounds [1024 x double], [1024 x double]* @dA, i64 0, i64 %indvars.iv
820 %0 = load double, double* %arrayidx, align 4
821 %cmp3 = fcmp fast olt double %0, %min.red.08
822 %min.red.0 = select i1 %cmp3, double %0, double %min.red.08
823 %indvars.iv.next = add i64 %indvars.iv, 1
824 %exitcond = icmp eq i64 %indvars.iv.next, 1024
825 br i1 %exitcond, label %for.end, label %for.body
828 ret double %min.red.0
832 ; Don't this into a max reduction. The no-nans-fp-math attribute is missing
833 ; CHECK-LABEL: @max_red_float_nans(
834 ; CHECK-NOT: <2 x float>
836 define float @max_red_float_nans(float %max) {
841 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
842 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
843 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
844 %0 = load float, float* %arrayidx, align 4
845 %cmp3 = fcmp fast ogt float %0, %max.red.08
846 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
847 %indvars.iv.next = add i64 %indvars.iv, 1
848 %exitcond = icmp eq i64 %indvars.iv.next, 1024
849 br i1 %exitcond, label %for.end, label %for.body
855 ; As above, with the no-signed-zeros-fp-math attribute missing
856 ; CHECK-LABEL: @max_red_float_nsz(
857 ; CHECK-NOT: <2 x float>
859 define float @max_red_float_nsz(float %max) #1 {
864 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
865 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
866 %arrayidx = getelementptr inbounds [1024 x float], [1024 x float]* @fA, i64 0, i64 %indvars.iv
867 %0 = load float, float* %arrayidx, align 4
868 %cmp3 = fcmp fast ogt float %0, %max.red.08
869 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
870 %indvars.iv.next = add i64 %indvars.iv, 1
871 %exitcond = icmp eq i64 %indvars.iv.next, 1024
872 br i1 %exitcond, label %for.end, label %for.body
878 ; Make sure any check-not directives are not triggered by function declarations.
881 attributes #0 = { "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" }
882 attributes #1 = { "no-nans-fp-math"="true" }