1 ; RUN: opt -S -loop-vectorize -dce -instcombine -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> undef, i32 %max, i32 0
15 ; CHECK: {{.*}} = shufflevector <2 x i32> %[[VAR]], <2 x i32> undef, <2 x i32> zeroinitializer
16 ; CHECK: icmp sgt <2 x i32>
17 ; CHECK: select <2 x i1>
19 ; CHECK: icmp sgt <2 x i32>
22 define i32 @max_red(i32 %max) {
27 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
28 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
29 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
30 %0 = load i32* %arrayidx, align 4
31 %cmp3 = icmp sgt i32 %0, %max.red.08
32 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
33 %indvars.iv.next = add i64 %indvars.iv, 1
34 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
35 %exitcond = icmp eq i32 %lftr.wideiv, 1024
36 br i1 %exitcond, label %for.end, label %for.body
42 ; Turn this into a max reduction. The select has its inputs reversed therefore
43 ; this is a max reduction.
44 ; CHECK-LABEL: @max_red_inverse_select(
45 ; CHECK: icmp slt <2 x i32>
46 ; CHECK: select <2 x i1>
48 ; CHECK: icmp sgt <2 x i32>
51 define i32 @max_red_inverse_select(i32 %max) {
56 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
57 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
58 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
59 %0 = load i32* %arrayidx, align 4
60 %cmp3 = icmp slt i32 %max.red.08, %0
61 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
62 %indvars.iv.next = add i64 %indvars.iv, 1
63 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
64 %exitcond = icmp eq i32 %lftr.wideiv, 1024
65 br i1 %exitcond, label %for.end, label %for.body
71 ; Turn this into a min reduction.
72 ; CHECK-LABEL: @min_red(
73 ; CHECK: icmp slt <2 x i32>
74 ; CHECK: select <2 x i1>
76 ; CHECK: icmp slt <2 x i32>
79 define i32 @min_red(i32 %max) {
84 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
85 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
86 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
87 %0 = load i32* %arrayidx, align 4
88 %cmp3 = icmp slt i32 %0, %max.red.08
89 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
90 %indvars.iv.next = add i64 %indvars.iv, 1
91 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
92 %exitcond = icmp eq i32 %lftr.wideiv, 1024
93 br i1 %exitcond, label %for.end, label %for.body
99 ; Turn this into a min reduction. The select has its inputs reversed therefore
100 ; this is a min reduction.
101 ; CHECK-LABEL: @min_red_inverse_select(
102 ; CHECK: icmp sgt <2 x i32>
103 ; CHECK: select <2 x i1>
104 ; CHECK: middle.block
105 ; CHECK: icmp slt <2 x i32>
108 define i32 @min_red_inverse_select(i32 %max) {
113 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
114 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
115 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
116 %0 = load i32* %arrayidx, align 4
117 %cmp3 = icmp sgt i32 %max.red.08, %0
118 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
119 %indvars.iv.next = add i64 %indvars.iv, 1
120 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
121 %exitcond = icmp eq i32 %lftr.wideiv, 1024
122 br i1 %exitcond, label %for.end, label %for.body
130 ; Turn this into a max reduction.
131 ; CHECK-LABEL: @umax_red(
132 ; CHECK: icmp ugt <2 x i32>
133 ; CHECK: select <2 x i1>
134 ; CHECK: middle.block
135 ; CHECK: icmp ugt <2 x i32>
138 define i32 @umax_red(i32 %max) {
143 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
144 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
145 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
146 %0 = load i32* %arrayidx, align 4
147 %cmp3 = icmp ugt i32 %0, %max.red.08
148 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
149 %indvars.iv.next = add i64 %indvars.iv, 1
150 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
151 %exitcond = icmp eq i32 %lftr.wideiv, 1024
152 br i1 %exitcond, label %for.end, label %for.body
158 ; Turn this into a max reduction. The select has its inputs reversed therefore
159 ; this is a max reduction.
160 ; CHECK-LABEL: @umax_red_inverse_select(
161 ; CHECK: icmp ult <2 x i32>
162 ; CHECK: select <2 x i1>
163 ; CHECK: middle.block
164 ; CHECK: icmp ugt <2 x i32>
167 define i32 @umax_red_inverse_select(i32 %max) {
172 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
173 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
174 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
175 %0 = load i32* %arrayidx, align 4
176 %cmp3 = icmp ult i32 %max.red.08, %0
177 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
178 %indvars.iv.next = add i64 %indvars.iv, 1
179 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
180 %exitcond = icmp eq i32 %lftr.wideiv, 1024
181 br i1 %exitcond, label %for.end, label %for.body
187 ; Turn this into a min reduction.
188 ; CHECK-LABEL: @umin_red(
189 ; CHECK: icmp ult <2 x i32>
190 ; CHECK: select <2 x i1>
191 ; CHECK: middle.block
192 ; CHECK: icmp ult <2 x i32>
195 define i32 @umin_red(i32 %max) {
200 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
201 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
202 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
203 %0 = load i32* %arrayidx, align 4
204 %cmp3 = icmp ult i32 %0, %max.red.08
205 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
206 %indvars.iv.next = add i64 %indvars.iv, 1
207 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
208 %exitcond = icmp eq i32 %lftr.wideiv, 1024
209 br i1 %exitcond, label %for.end, label %for.body
215 ; Turn this into a min reduction. The select has its inputs reversed therefore
216 ; this is a min reduction.
217 ; CHECK-LABEL: @umin_red_inverse_select(
218 ; CHECK: icmp ugt <2 x i32>
219 ; CHECK: select <2 x i1>
220 ; CHECK: middle.block
221 ; CHECK: icmp ult <2 x i32>
224 define i32 @umin_red_inverse_select(i32 %max) {
229 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
230 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
231 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
232 %0 = load i32* %arrayidx, align 4
233 %cmp3 = icmp ugt i32 %max.red.08, %0
234 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
235 %indvars.iv.next = add i64 %indvars.iv, 1
236 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
237 %exitcond = icmp eq i32 %lftr.wideiv, 1024
238 br i1 %exitcond, label %for.end, label %for.body
245 ; Turn this into a min reduction (select inputs are reversed).
246 ; CHECK-LABEL: @sge_min_red(
247 ; CHECK: icmp sge <2 x i32>
248 ; CHECK: select <2 x i1>
249 ; CHECK: middle.block
250 ; CHECK: icmp slt <2 x i32>
253 define i32 @sge_min_red(i32 %max) {
258 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
259 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
260 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
261 %0 = load i32* %arrayidx, align 4
262 %cmp3 = icmp sge i32 %0, %max.red.08
263 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0
264 %indvars.iv.next = add i64 %indvars.iv, 1
265 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
266 %exitcond = icmp eq i32 %lftr.wideiv, 1024
267 br i1 %exitcond, label %for.end, label %for.body
274 ; Turn this into a max reduction (select inputs are reversed).
275 ; CHECK-LABEL: @sle_min_red(
276 ; CHECK: icmp sle <2 x i32>
277 ; CHECK: select <2 x i1>
278 ; CHECK: middle.block
279 ; CHECK: icmp sgt <2 x i32>
282 define i32 @sle_min_red(i32 %max) {
287 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
288 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
289 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
290 %0 = load i32* %arrayidx, align 4
291 %cmp3 = icmp sle i32 %0, %max.red.08
292 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0
293 %indvars.iv.next = add i64 %indvars.iv, 1
294 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
295 %exitcond = icmp eq i32 %lftr.wideiv, 1024
296 br i1 %exitcond, label %for.end, label %for.body
303 ; Turn this into a min reduction (select inputs are reversed).
304 ; CHECK-LABEL: @uge_min_red(
305 ; CHECK: icmp uge <2 x i32>
306 ; CHECK: select <2 x i1>
307 ; CHECK: middle.block
308 ; CHECK: icmp ult <2 x i32>
311 define i32 @uge_min_red(i32 %max) {
316 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
317 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
318 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
319 %0 = load i32* %arrayidx, align 4
320 %cmp3 = icmp uge i32 %0, %max.red.08
321 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0
322 %indvars.iv.next = add i64 %indvars.iv, 1
323 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
324 %exitcond = icmp eq i32 %lftr.wideiv, 1024
325 br i1 %exitcond, label %for.end, label %for.body
332 ; Turn this into a max reduction (select inputs are reversed).
333 ; CHECK-LABEL: @ule_min_red(
334 ; CHECK: icmp ule <2 x i32>
335 ; CHECK: select <2 x i1>
336 ; CHECK: middle.block
337 ; CHECK: icmp ugt <2 x i32>
340 define i32 @ule_min_red(i32 %max) {
345 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
346 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
347 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
348 %0 = load i32* %arrayidx, align 4
349 %cmp3 = icmp ule i32 %0, %max.red.08
350 %max.red.0 = select i1 %cmp3, i32 %max.red.08, i32 %0
351 %indvars.iv.next = add i64 %indvars.iv, 1
352 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
353 %exitcond = icmp eq i32 %lftr.wideiv, 1024
354 br i1 %exitcond, label %for.end, label %for.body
361 ; CHECK-LABEL: @no_red_1(
362 ; CHECK-NOT: icmp <2 x i32>
363 define i32 @no_red_1(i32 %max) {
368 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
369 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
370 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
371 %arrayidx1 = getelementptr inbounds [1024 x i32]* @A, i64 1, i64 %indvars.iv
372 %0 = load i32* %arrayidx, align 4
373 %1 = load i32* %arrayidx1, align 4
374 %cmp3 = icmp sgt i32 %0, %1
375 %max.red.0 = select i1 %cmp3, i32 %0, i32 %max.red.08
376 %indvars.iv.next = add i64 %indvars.iv, 1
377 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
378 %exitcond = icmp eq i32 %lftr.wideiv, 1024
379 br i1 %exitcond, label %for.end, label %for.body
385 ; CHECK-LABEL: @no_red_2(
386 ; CHECK-NOT: icmp <2 x i32>
387 define i32 @no_red_2(i32 %max) {
392 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
393 %max.red.08 = phi i32 [ %max, %entry ], [ %max.red.0, %for.body ]
394 %arrayidx = getelementptr inbounds [1024 x i32]* @A, i64 0, i64 %indvars.iv
395 %arrayidx1 = getelementptr inbounds [1024 x i32]* @A, i64 1, i64 %indvars.iv
396 %0 = load i32* %arrayidx, align 4
397 %1 = load i32* %arrayidx1, align 4
398 %cmp3 = icmp sgt i32 %0, %max.red.08
399 %max.red.0 = select i1 %cmp3, i32 %0, i32 %1
400 %indvars.iv.next = add i64 %indvars.iv, 1
401 %lftr.wideiv = trunc i64 %indvars.iv.next to i32
402 %exitcond = icmp eq i32 %lftr.wideiv, 1024
403 br i1 %exitcond, label %for.end, label %for.body
413 ; Turn this into a max reduction in the presence of a no-nans-fp-math attribute.
414 ; CHECK-LABEL: @max_red_float(
415 ; CHECK: fcmp ogt <2 x float>
416 ; CHECK: select <2 x i1>
417 ; CHECK: middle.block
418 ; CHECK: fcmp ogt <2 x float>
421 define float @max_red_float(float %max) #0 {
426 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
427 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
428 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
429 %0 = load float* %arrayidx, align 4
430 %cmp3 = fcmp ogt float %0, %max.red.08
431 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
432 %indvars.iv.next = add i64 %indvars.iv, 1
433 %exitcond = icmp eq i64 %indvars.iv.next, 1024
434 br i1 %exitcond, label %for.end, label %for.body
440 ; CHECK-LABEL: @max_red_float_ge(
441 ; CHECK: fcmp oge <2 x float>
442 ; CHECK: select <2 x i1>
443 ; CHECK: middle.block
444 ; CHECK: fcmp ogt <2 x float>
447 define float @max_red_float_ge(float %max) #0 {
452 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
453 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
454 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
455 %0 = load float* %arrayidx, align 4
456 %cmp3 = fcmp oge float %0, %max.red.08
457 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
458 %indvars.iv.next = add i64 %indvars.iv, 1
459 %exitcond = icmp eq i64 %indvars.iv.next, 1024
460 br i1 %exitcond, label %for.end, label %for.body
466 ; CHECK-LABEL: @inverted_max_red_float(
467 ; CHECK: fcmp olt <2 x float>
468 ; CHECK: select <2 x i1>
469 ; CHECK: middle.block
470 ; CHECK: fcmp ogt <2 x float>
473 define float @inverted_max_red_float(float %max) #0 {
478 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
479 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
480 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
481 %0 = load float* %arrayidx, align 4
482 %cmp3 = fcmp olt float %0, %max.red.08
483 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0
484 %indvars.iv.next = add i64 %indvars.iv, 1
485 %exitcond = icmp eq i64 %indvars.iv.next, 1024
486 br i1 %exitcond, label %for.end, label %for.body
492 ; CHECK-LABEL: @inverted_max_red_float_le(
493 ; CHECK: fcmp ole <2 x float>
494 ; CHECK: select <2 x i1>
495 ; CHECK: middle.block
496 ; CHECK: fcmp ogt <2 x float>
499 define float @inverted_max_red_float_le(float %max) #0 {
504 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
505 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
506 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
507 %0 = load float* %arrayidx, align 4
508 %cmp3 = fcmp ole float %0, %max.red.08
509 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0
510 %indvars.iv.next = add i64 %indvars.iv, 1
511 %exitcond = icmp eq i64 %indvars.iv.next, 1024
512 br i1 %exitcond, label %for.end, label %for.body
518 ; CHECK-LABEL: @unordered_max_red_float(
519 ; CHECK: fcmp ole <2 x float>
520 ; CHECK: select <2 x i1>
521 ; CHECK: middle.block
522 ; CHECK: fcmp ogt <2 x float>
525 define float @unordered_max_red_float(float %max) #0 {
530 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
531 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
532 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
533 %0 = load float* %arrayidx, align 4
534 %cmp3 = fcmp ugt float %0, %max.red.08
535 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
536 %indvars.iv.next = add i64 %indvars.iv, 1
537 %exitcond = icmp eq i64 %indvars.iv.next, 1024
538 br i1 %exitcond, label %for.end, label %for.body
544 ; CHECK-LABEL: @unordered_max_red_float_ge(
545 ; CHECK: fcmp olt <2 x float>
546 ; CHECK: select <2 x i1>
547 ; CHECK: middle.block
548 ; CHECK: fcmp ogt <2 x float>
551 define float @unordered_max_red_float_ge(float %max) #0 {
556 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
557 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
558 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
559 %0 = load float* %arrayidx, align 4
560 %cmp3 = fcmp uge float %0, %max.red.08
561 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
562 %indvars.iv.next = add i64 %indvars.iv, 1
563 %exitcond = icmp eq i64 %indvars.iv.next, 1024
564 br i1 %exitcond, label %for.end, label %for.body
570 ; CHECK-LABEL: @inverted_unordered_max_red_float(
571 ; CHECK: fcmp oge <2 x float>
572 ; CHECK: select <2 x i1>
573 ; CHECK: middle.block
574 ; CHECK: fcmp ogt <2 x float>
577 define float @inverted_unordered_max_red_float(float %max) #0 {
582 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
583 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
584 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
585 %0 = load float* %arrayidx, align 4
586 %cmp3 = fcmp ult float %0, %max.red.08
587 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0
588 %indvars.iv.next = add i64 %indvars.iv, 1
589 %exitcond = icmp eq i64 %indvars.iv.next, 1024
590 br i1 %exitcond, label %for.end, label %for.body
596 ; CHECK-LABEL: @inverted_unordered_max_red_float_le(
597 ; CHECK: fcmp ogt <2 x float>
598 ; CHECK: select <2 x i1>
599 ; CHECK: middle.block
600 ; CHECK: fcmp ogt <2 x float>
603 define float @inverted_unordered_max_red_float_le(float %max) #0 {
608 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
609 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
610 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
611 %0 = load float* %arrayidx, align 4
612 %cmp3 = fcmp ule float %0, %max.red.08
613 %max.red.0 = select i1 %cmp3, float %max.red.08, float %0
614 %indvars.iv.next = add i64 %indvars.iv, 1
615 %exitcond = icmp eq i64 %indvars.iv.next, 1024
616 br i1 %exitcond, label %for.end, label %for.body
624 ; Turn this into a min reduction in the presence of a no-nans-fp-math attribute.
625 ; CHECK-LABEL: @min_red_float(
626 ; CHECK: fcmp olt <2 x float>
627 ; CHECK: select <2 x i1>
628 ; CHECK: middle.block
629 ; CHECK: fcmp olt <2 x float>
632 define float @min_red_float(float %min) #0 {
637 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
638 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
639 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
640 %0 = load float* %arrayidx, align 4
641 %cmp3 = fcmp olt float %0, %min.red.08
642 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08
643 %indvars.iv.next = add i64 %indvars.iv, 1
644 %exitcond = icmp eq i64 %indvars.iv.next, 1024
645 br i1 %exitcond, label %for.end, label %for.body
651 ; CHECK-LABEL: @min_red_float_le(
652 ; CHECK: fcmp ole <2 x float>
653 ; CHECK: select <2 x i1>
654 ; CHECK: middle.block
655 ; CHECK: fcmp olt <2 x float>
658 define float @min_red_float_le(float %min) #0 {
663 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
664 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
665 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
666 %0 = load float* %arrayidx, align 4
667 %cmp3 = fcmp ole float %0, %min.red.08
668 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08
669 %indvars.iv.next = add i64 %indvars.iv, 1
670 %exitcond = icmp eq i64 %indvars.iv.next, 1024
671 br i1 %exitcond, label %for.end, label %for.body
677 ; CHECK-LABEL: @inverted_min_red_float(
678 ; CHECK: fcmp ogt <2 x float>
679 ; CHECK: select <2 x i1>
680 ; CHECK: middle.block
681 ; CHECK: fcmp olt <2 x float>
684 define float @inverted_min_red_float(float %min) #0 {
689 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
690 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
691 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
692 %0 = load float* %arrayidx, align 4
693 %cmp3 = fcmp ogt float %0, %min.red.08
694 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0
695 %indvars.iv.next = add i64 %indvars.iv, 1
696 %exitcond = icmp eq i64 %indvars.iv.next, 1024
697 br i1 %exitcond, label %for.end, label %for.body
703 ; CHECK-LABEL: @inverted_min_red_float_ge(
704 ; CHECK: fcmp oge <2 x float>
705 ; CHECK: select <2 x i1>
706 ; CHECK: middle.block
707 ; CHECK: fcmp olt <2 x float>
710 define float @inverted_min_red_float_ge(float %min) #0 {
715 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
716 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
717 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
718 %0 = load float* %arrayidx, align 4
719 %cmp3 = fcmp oge float %0, %min.red.08
720 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0
721 %indvars.iv.next = add i64 %indvars.iv, 1
722 %exitcond = icmp eq i64 %indvars.iv.next, 1024
723 br i1 %exitcond, label %for.end, label %for.body
729 ; CHECK-LABEL: @unordered_min_red_float(
730 ; CHECK: fcmp oge <2 x float>
731 ; CHECK: select <2 x i1>
732 ; CHECK: middle.block
733 ; CHECK: fcmp olt <2 x float>
736 define float @unordered_min_red_float(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]* @fA, i64 0, i64 %indvars.iv
744 %0 = load float* %arrayidx, align 4
745 %cmp3 = fcmp ult 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: @unordered_min_red_float_le(
756 ; CHECK: fcmp ogt <2 x float>
757 ; CHECK: select <2 x i1>
758 ; CHECK: middle.block
759 ; CHECK: fcmp olt <2 x float>
762 define float @unordered_min_red_float_le(float %min) #0 {
767 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
768 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
769 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
770 %0 = load float* %arrayidx, align 4
771 %cmp3 = fcmp ule float %0, %min.red.08
772 %min.red.0 = select i1 %cmp3, float %0, float %min.red.08
773 %indvars.iv.next = add i64 %indvars.iv, 1
774 %exitcond = icmp eq i64 %indvars.iv.next, 1024
775 br i1 %exitcond, label %for.end, label %for.body
781 ; CHECK-LABEL: @inverted_unordered_min_red_float(
782 ; CHECK: fcmp ole <2 x float>
783 ; CHECK: select <2 x i1>
784 ; CHECK: middle.block
785 ; CHECK: fcmp olt <2 x float>
788 define float @inverted_unordered_min_red_float(float %min) #0 {
793 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
794 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
795 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
796 %0 = load float* %arrayidx, align 4
797 %cmp3 = fcmp ugt float %0, %min.red.08
798 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0
799 %indvars.iv.next = add i64 %indvars.iv, 1
800 %exitcond = icmp eq i64 %indvars.iv.next, 1024
801 br i1 %exitcond, label %for.end, label %for.body
807 ; CHECK-LABEL: @inverted_unordered_min_red_float_ge(
808 ; CHECK: fcmp olt <2 x float>
809 ; CHECK: select <2 x i1>
810 ; CHECK: middle.block
811 ; CHECK: fcmp olt <2 x float>
814 define float @inverted_unordered_min_red_float_ge(float %min) #0 {
819 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
820 %min.red.08 = phi float [ %min, %entry ], [ %min.red.0, %for.body ]
821 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
822 %0 = load float* %arrayidx, align 4
823 %cmp3 = fcmp uge float %0, %min.red.08
824 %min.red.0 = select i1 %cmp3, float %min.red.08, float %0
825 %indvars.iv.next = add i64 %indvars.iv, 1
826 %exitcond = icmp eq i64 %indvars.iv.next, 1024
827 br i1 %exitcond, label %for.end, label %for.body
833 ; Make sure we handle doubles, too.
834 ; CHECK-LABEL: @min_red_double(
835 ; CHECK: fcmp olt <2 x double>
836 ; CHECK: select <2 x i1>
837 ; CHECK: middle.block
838 ; CHECK: fcmp olt <2 x double>
841 define double @min_red_double(double %min) #0 {
846 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
847 %min.red.08 = phi double [ %min, %entry ], [ %min.red.0, %for.body ]
848 %arrayidx = getelementptr inbounds [1024 x double]* @dA, i64 0, i64 %indvars.iv
849 %0 = load double* %arrayidx, align 4
850 %cmp3 = fcmp olt double %0, %min.red.08
851 %min.red.0 = select i1 %cmp3, double %0, double %min.red.08
852 %indvars.iv.next = add i64 %indvars.iv, 1
853 %exitcond = icmp eq i64 %indvars.iv.next, 1024
854 br i1 %exitcond, label %for.end, label %for.body
857 ret double %min.red.0
861 ; Don't this into a max reduction. The no-nans-fp-math attribute is missing
862 ; CHECK-LABEL: @max_red_float_nans(
863 ; CHECK-NOT: <2 x float>
865 define float @max_red_float_nans(float %max) {
870 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
871 %max.red.08 = phi float [ %max, %entry ], [ %max.red.0, %for.body ]
872 %arrayidx = getelementptr inbounds [1024 x float]* @fA, i64 0, i64 %indvars.iv
873 %0 = load float* %arrayidx, align 4
874 %cmp3 = fcmp ogt float %0, %max.red.08
875 %max.red.0 = select i1 %cmp3, float %0, float %max.red.08
876 %indvars.iv.next = add i64 %indvars.iv, 1
877 %exitcond = icmp eq i64 %indvars.iv.next, 1024
878 br i1 %exitcond, label %for.end, label %for.body
885 attributes #0 = { "no-nans-fp-math"="true" }