Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / minmax_reduction.ll
blob85a90f2e04c5e23a1484c44ce76d8b565a72f3aa
1 ; RUN: opt -S -passes=loop-vectorize,dce -force-vector-width=2 -force-vector-interleave=2  < %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
9 ; Signed tests.
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, i64 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>
18 ; CHECK: middle.block
19 ; CHECK: call i32 @llvm.vector.reduce.smax.v2i32
21 define i32 @max_red(i32 %max) {
22 entry:
23   br label %for.body
25 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
29   %0 = load i32, ptr %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
37 for.end:
38   ret i32 %max.red.0
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>
46 ; CHECK: middle.block
47 ; CHECK: call i32 @llvm.vector.reduce.smax.v2i32
49 define i32 @max_red_inverse_select(i32 %max) {
50 entry:
51   br label %for.body
53 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
57   %0 = load i32, ptr %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
65 for.end:
66   ret i32 %max.red.0
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>
73 ; CHECK: middle.block
74 ; CHECK: call i32 @llvm.vector.reduce.smin.v2i32
76 define i32 @min_red(i32 %max) {
77 entry:
78   br label %for.body
80 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
84   %0 = load i32, ptr %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
92 for.end:
93   ret i32 %max.red.0
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) {
105 entry:
106   br label %for.body
108 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
112   %0 = load i32, ptr %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
120 for.end:
121   ret i32 %max.red.0
124 ; Unsigned tests.
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) {
134 entry:
135   br label %for.body
137 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
141   %0 = load i32, ptr %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
149 for.end:
150   ret i32 %max.red.0
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) {
162 entry:
163   br label %for.body
165 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
169   %0 = load i32, ptr %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
177 for.end:
178   ret i32 %max.red.0
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) {
189 entry:
190   br label %for.body
192 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
196   %0 = load i32, ptr %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
204 for.end:
205   ret i32 %max.red.0
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) {
217 entry:
218   br label %for.body
220 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
224   %0 = load i32, ptr %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
232 for.end:
233   ret i32 %max.red.0
236 ; SGE -> SLT
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) {
245 entry:
246   br label %for.body
248 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
252   %0 = load i32, ptr %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
260 for.end:
261   ret i32 %max.red.0
264 ; SLE -> SGT
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) {
273 entry:
274   br label %for.body
276 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
280   %0 = load i32, ptr %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
288 for.end:
289   ret i32 %max.red.0
292 ; UGE -> ULT
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) {
301 entry:
302   br label %for.body
304 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
308   %0 = load i32, ptr %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
316 for.end:
317   ret i32 %max.red.0
320 ; ULE -> UGT
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) {
329 entry:
330   br label %for.body
332 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
336   %0 = load i32, ptr %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
344 for.end:
345   ret i32 %max.red.0
348 ; No reduction.
349 ; CHECK-LABEL: @no_red_1(
350 ; CHECK-NOT: icmp <2 x i32>
351 define i32 @no_red_1(i32 %max) {
352 entry:
353   br label %for.body
355 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
359   %arrayidx1 = getelementptr inbounds [1024 x i32], ptr @A, i64 1, i64 %indvars.iv
360   %0 = load i32, ptr %arrayidx, align 4
361   %1 = load i32, ptr %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
369 for.end:
370   ret i32 %max.red.0
373 ; CHECK-LABEL: @no_red_2(
374 ; CHECK-NOT: icmp <2 x i32>
375 define i32 @no_red_2(i32 %max) {
376 entry:
377   br label %for.body
379 for.body:
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], ptr @A, i64 0, i64 %indvars.iv
383   %arrayidx1 = getelementptr inbounds [1024 x i32], ptr @A, i64 1, i64 %indvars.iv
384   %0 = load i32, ptr %arrayidx, align 4
385   %1 = load i32, ptr %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
393 for.end:
394   ret i32 %max.red.0
397 ; Float tests.
399 ; Maximum.
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 {
409 entry:
410   br label %for.body
412 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
416   %0 = load float, ptr %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
423 for.end:
424   ret float %max.red.0
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 {
434 entry:
435   br label %for.body
437 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
441   %0 = load float, ptr %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
448 for.end:
449   ret float %max.red.0
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 {
459 entry:
460   br label %for.body
462 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
466   %0 = load float, ptr %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
473 for.end:
474   ret float %max.red.0
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 {
484 entry:
485   br label %for.body
487 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
491   %0 = load float, ptr %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
498 for.end:
499   ret float %max.red.0
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 {
509 entry:
510   br label %for.body
512 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
516   %0 = load float, ptr %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
523 for.end:
524   ret float %max.red.0
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 {
534 entry:
535   br label %for.body
537 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
541   %0 = load float, ptr %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
548 for.end:
549   ret float %max.red.0
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 {
559 entry:
560   br label %for.body
562 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
566   %0 = load float, ptr %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
573 for.end:
574   ret float %max.red.0
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 {
584 entry:
585   br label %for.body
587 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
591   %0 = load float, ptr %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
598 for.end:
599   ret float %max.red.0
602 ; Minimum.
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 {
612 entry:
613   br label %for.body
615 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
619   %0 = load float, ptr %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
626 for.end:
627   ret float %min.red.0
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 {
637 entry:
638   br label %for.body
640 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
644   %0 = load float, ptr %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
651 for.end:
652   ret float %min.red.0
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 {
662 entry:
663   br label %for.body
665 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
669   %0 = load float, ptr %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
676 for.end:
677   ret float %min.red.0
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 {
687 entry:
688   br label %for.body
690 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
694   %0 = load float, ptr %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
701 for.end:
702   ret float %min.red.0
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 {
712 entry:
713   br label %for.body
715 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
719   %0 = load float, ptr %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
726 for.end:
727   ret float %min.red.0
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 {
737 entry:
738   br label %for.body
740 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
744   %0 = load float, ptr %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
751 for.end:
752   ret float %min.red.0
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 {
762 entry:
763   br label %for.body
765 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
769   %0 = load float, ptr %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
776 for.end:
777   ret float %min.red.0
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 {
787 entry:
788   br label %for.body
790 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
794   %0 = load float, ptr %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
801 for.end:
802   ret float %min.red.0
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 {
813 entry:
814   br label %for.body
816 for.body:
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], ptr @dA, i64 0, i64 %indvars.iv
820   %0 = load double, ptr %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
827 for.end:
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) {
837 entry:
838   br label %for.body
840 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
844   %0 = load float, ptr %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
851 for.end:
852   ret float %max.red.0
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 {
860 entry:
861   br label %for.body
863 for.body:
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], ptr @fA, i64 0, i64 %indvars.iv
867   %0 = load float, ptr %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
874 for.end:
875   ret float %max.red.0
878 ; CHECK-LABEL: @smin_intrinsic(
879 ; CHECK: <2 x i32> @llvm.smin.v2i32
880 ; CHECK: i32 @llvm.vector.reduce.smin.v2i32
881 define i32 @smin_intrinsic(ptr nocapture readonly %x) {
882 entry:
883   br label %for.body
885 for.body:                                         ; preds = %entry, %for.body
886   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
887   %s.011 = phi i32 [ 100, %entry ], [ %1, %for.body ]
888   %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.012
889   %0 = load i32, ptr %arrayidx, align 4
890   %1 = tail call i32 @llvm.smin.i32(i32 %s.011, i32 %0)
891   %inc = add nuw nsw i32 %i.012, 1
892   %exitcond.not = icmp eq i32 %inc, 1024
893   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
895 for.cond.cleanup:                                 ; preds = %for.body
896   ret i32 %1
899 ; CHECK-LABEL: @smax_intrinsic(
900 ; CHECK: <2 x i32> @llvm.smax.v2i32
901 ; CHECK: i32 @llvm.vector.reduce.smax.v2i32
902 define i32 @smax_intrinsic(ptr nocapture readonly %x) {
903 entry:
904   br label %for.body
906 for.body:                                         ; preds = %entry, %for.body
907   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
908   %s.011 = phi i32 [ 100, %entry ], [ %1, %for.body ]
909   %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.012
910   %0 = load i32, ptr %arrayidx, align 4
911   %1 = tail call i32 @llvm.smax.i32(i32 %s.011, i32 %0)
912   %inc = add nuw nsw i32 %i.012, 1
913   %exitcond.not = icmp eq i32 %inc, 1024
914   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
916 for.cond.cleanup:                                 ; preds = %for.body
917   ret i32 %1
920 ; CHECK-LABEL: @umin_intrinsic(
921 ; CHECK: <2 x i32> @llvm.umin.v2i32
922 ; CHECK: i32 @llvm.vector.reduce.umin.v2i32
923 define i32 @umin_intrinsic(ptr nocapture readonly %x) {
924 entry:
925   br label %for.body
927 for.body:                                         ; preds = %entry, %for.body
928   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
929   %s.011 = phi i32 [ 100, %entry ], [ %1, %for.body ]
930   %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.012
931   %0 = load i32, ptr %arrayidx, align 4
932   %1 = tail call i32 @llvm.umin.i32(i32 %s.011, i32 %0)
933   %inc = add nuw nsw i32 %i.012, 1
934   %exitcond.not = icmp eq i32 %inc, 1024
935   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
937 for.cond.cleanup:                                 ; preds = %for.body
938   ret i32 %1
941 ; CHECK-LABEL: @umax_intrinsic(
942 ; CHECK: <2 x i32> @llvm.umax.v2i32
943 ; CHECK: i32 @llvm.vector.reduce.umax.v2i32
944 define i32 @umax_intrinsic(ptr nocapture readonly %x) {
945 entry:
946   br label %for.body
948 for.body:                                         ; preds = %entry, %for.body
949   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
950   %s.011 = phi i32 [ 100, %entry ], [ %1, %for.body ]
951   %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.012
952   %0 = load i32, ptr %arrayidx, align 4
953   %1 = tail call i32 @llvm.umax.i32(i32 %s.011, i32 %0)
954   %inc = add nuw nsw i32 %i.012, 1
955   %exitcond.not = icmp eq i32 %inc, 1024
956   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
958 for.cond.cleanup:                                 ; preds = %for.body
959   ret i32 %1
962 ; CHECK-LABEL: @fmin_intrinsic(
963 ; CHECK: nnan nsz <2 x float> @llvm.minnum.v2f32
964 ; CHECK: nnan nsz float @llvm.vector.reduce.fmin.v2f32
965 define float @fmin_intrinsic(ptr nocapture readonly %x) {
966 entry:
967   br label %for.body
969 for.cond.cleanup:                                 ; preds = %for.body
970   ret float %1
972 for.body:                                         ; preds = %entry, %for.body
973   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
974   %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ]
975   %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012
976   %0 = load float, ptr %arrayidx, align 4
977   %1 = tail call nnan nsz float @llvm.minnum.f32(float %s.011, float %0)
978   %inc = add nuw nsw i32 %i.012, 1
979   %exitcond.not = icmp eq i32 %inc, 1024
980   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
983 ; CHECK-LABEL: @fmax_intrinsic(
984 ; CHECK: fast <2 x float> @llvm.maxnum.v2f32
985 ; CHECK: fast float @llvm.vector.reduce.fmax.v2f32
986 define float @fmax_intrinsic(ptr nocapture readonly %x) {
987 entry:
988   br label %for.body
990 for.cond.cleanup:                                 ; preds = %for.body
991   ret float %1
993 for.body:                                         ; preds = %entry, %for.body
994   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
995   %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ]
996   %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012
997   %0 = load float, ptr %arrayidx, align 4
998   %1 = tail call fast float @llvm.maxnum.f32(float %s.011, float %0)
999   %inc = add nuw nsw i32 %i.012, 1
1000   %exitcond.not = icmp eq i32 %inc, 1024
1001   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1004 ; CHECK-LABEL: @fmin_intrinsic_nofast(
1005 ; CHECK-NOT: <2 x float> @llvm.minnum.v2f32
1006 define float @fmin_intrinsic_nofast(ptr nocapture readonly %x) {
1007 entry:
1008   br label %for.body
1010 for.cond.cleanup:                                 ; preds = %for.body
1011   ret float %1
1013 for.body:                                         ; preds = %entry, %for.body
1014   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1015   %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ]
1016   %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012
1017   %0 = load float, ptr %arrayidx, align 4
1018   %1 = tail call float @llvm.minnum.f32(float %s.011, float %0)
1019   %inc = add nuw nsw i32 %i.012, 1
1020   %exitcond.not = icmp eq i32 %inc, 1024
1021   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1024 ; CHECK-LABEL: @fmax_intrinsic_nofast(
1025 ; CHECK-NOT: <2 x float> @llvm.maxnum.v2f32
1026 define float @fmax_intrinsic_nofast(ptr nocapture readonly %x) {
1027 entry:
1028   br label %for.body
1030 for.cond.cleanup:                                 ; preds = %for.body
1031   ret float %1
1033 for.body:                                         ; preds = %entry, %for.body
1034   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1035   %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ]
1036   %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012
1037   %0 = load float, ptr %arrayidx, align 4
1038   %1 = tail call float @llvm.maxnum.f32(float %s.011, float %0)
1039   %inc = add nuw nsw i32 %i.012, 1
1040   %exitcond.not = icmp eq i32 %inc, 1024
1041   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1044 ; CHECK-LABEL: @sminmax(
1045 ; Min and max intrinsics - don't vectorize
1046 ; CHECK-NOT: <2 x i32>
1047 define i32 @sminmax(ptr nocapture readonly %x, ptr nocapture readonly %y) {
1048 entry:
1049   br label %for.body
1051 for.cond.cleanup:                                 ; preds = %for.body
1052   ret i32 %cond9
1054 for.body:                                         ; preds = %entry, %for.body
1055   %i.025 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1056   %s.024 = phi i32 [ 0, %entry ], [ %cond9, %for.body ]
1057   %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.025
1058   %0 = load i32, ptr %arrayidx, align 4
1059   %s.0. = tail call i32 @llvm.smin.i32(i32 %s.024, i32 %0)
1060   %arrayidx3 = getelementptr inbounds i32, ptr %y, i32 %i.025
1061   %1 = load i32, ptr %arrayidx3, align 4
1062   %cond9 = tail call i32 @llvm.smax.i32(i32 %s.0., i32 %1)
1063   %inc = add nuw nsw i32 %i.025, 1
1064   %exitcond.not = icmp eq i32 %inc, 1024
1065   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1068 ; CHECK-LABEL: @sminmin(
1069 ; CHECK: <2 x i32> @llvm.smin.v2i32
1070 ; CHECK: <2 x i32> @llvm.smin.v2i32
1071 ; CHECK: i32 @llvm.vector.reduce.smin.v2i32
1072 define i32 @sminmin(ptr nocapture readonly %x, ptr nocapture readonly %y) {
1073 entry:
1074   br label %for.body
1076 for.cond.cleanup:                                 ; preds = %for.body
1077   ret i32 %cond9
1079 for.body:                                         ; preds = %entry, %for.body
1080   %i.025 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1081   %s.024 = phi i32 [ 0, %entry ], [ %cond9, %for.body ]
1082   %arrayidx = getelementptr inbounds i32, ptr %x, i32 %i.025
1083   %0 = load i32, ptr %arrayidx, align 4
1084   %s.0. = tail call i32 @llvm.smin.i32(i32 %s.024, i32 %0)
1085   %arrayidx3 = getelementptr inbounds i32, ptr %y, i32 %i.025
1086   %1 = load i32, ptr %arrayidx3, align 4
1087   %cond9 = tail call i32 @llvm.smin.i32(i32 %s.0., i32 %1)
1088   %inc = add nuw nsw i32 %i.025, 1
1089   %exitcond.not = icmp eq i32 %inc, 1024
1090   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1093 ; CHECK-LABEL: fmaximum_intrinsic
1094 ; CHECK-LABEL: vector.body:
1095 ; CHECK: call <2 x float> @llvm.maximum.v2f32
1096 ; CHECK: call <2 x float> @llvm.maximum.v2f32
1098 ; CHECK-LABEL: middle.block:
1099 ; CHECK: call <2 x float> @llvm.maximum.v2f32
1100 ; CHECK: call float @llvm.vector.reduce.fmaximum.v2f32
1101 define float @fmaximum_intrinsic(ptr nocapture readonly %x) {
1102 entry:
1103   br label %for.body
1105 for.cond.cleanup:                                 ; preds = %for.body
1106   ret float %1
1108 for.body:                                         ; preds = %entry, %for.body
1109   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1110   %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ]
1111   %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012
1112   %0 = load float, ptr %arrayidx, align 4
1113   %1 = tail call float @llvm.maximum.f32(float %s.011, float %0)
1114   %inc = add nuw nsw i32 %i.012, 1
1115   %exitcond.not = icmp eq i32 %inc, 1024
1116   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1119 ; CHECK-LABEL: fminimum_intrinsic
1120 ; CHECK-LABEL: vector.body:
1121 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1122 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1124 ; CHECK-LABEL: middle.block:
1125 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1126 ; CHECK: call float @llvm.vector.reduce.fminimum.v2f32
1127 define float @fminimum_intrinsic(ptr nocapture readonly %x) {
1128 entry:
1129   br label %for.body
1131 for.cond.cleanup:                                 ; preds = %for.body
1132   ret float %1
1134 for.body:                                         ; preds = %entry, %for.body
1135   %i.012 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1136   %s.011 = phi float [ 0.000000e+00, %entry ], [ %1, %for.body ]
1137   %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.012
1138   %0 = load float, ptr %arrayidx, align 4
1139   %1 = tail call float @llvm.minimum.f32(float %s.011, float %0)
1140   %inc = add nuw nsw i32 %i.012, 1
1141   %exitcond.not = icmp eq i32 %inc, 1024
1142   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1145 ; CHECK-LABEL: fminimum_fminimum
1146 ; CHECK-LABEL: vector.body:
1147 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1148 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1149 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1150 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1152 ; CHECK-LABEL: middle.block:
1153 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1154 ; CHECK: call float @llvm.vector.reduce.fminimum.v2f32
1155 define float @fminimum_fminimum(ptr nocapture readonly %x, ptr nocapture readonly %y) {
1156 entry:
1157   br label %for.body
1159 for.cond.cleanup:                                 ; preds = %for.body
1160   ret float %cond9
1162 for.body:                                         ; preds = %entry, %for.body
1163   %i.025 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1164   %s.011 = phi float [ 0.000000e+00, %entry ], [ %cond9, %for.body ]
1165   %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.025
1166   %0 = load float, ptr %arrayidx, align 4
1167   %s.0. = tail call float @llvm.minimum.f32(float %s.011, float %0)
1168   %arrayidx3 = getelementptr inbounds float, ptr %y, i32 %i.025
1169   %1 = load float, ptr %arrayidx3, align 4
1170   %cond9 = tail call float @llvm.minimum.f32(float %s.0., float %1)
1171   %inc = add nuw nsw i32 %i.025, 1
1172   %exitcond.not = icmp eq i32 %inc, 1024
1173   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1176 ; CHECK-LABEL: fminimum_fminimum_one_with_flags
1177 ; CHECK-LABEL: vector.body:
1178 ; CHECK: call nnan nsz <2 x float> @llvm.minimum.v2f32
1179 ; CHECK: call nnan nsz <2 x float> @llvm.minimum.v2f32
1180 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1181 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1183 ; CHECK-LABEL: middle.block:
1184 ; CHECK: call <2 x float> @llvm.minimum.v2f32
1185 ; CHECK: call float @llvm.vector.reduce.fminimum.v2f32
1186 define float @fminimum_fminimum_one_with_flags(ptr nocapture readonly %x, ptr nocapture readonly %y) {
1187 entry:
1188   br label %for.body
1190 for.cond.cleanup:                                 ; preds = %for.body
1191   ret float %cond9
1193 for.body:                                         ; preds = %entry, %for.body
1194   %i.025 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
1195   %s.011 = phi float [ 0.000000e+00, %entry ], [ %cond9, %for.body ]
1196   %arrayidx = getelementptr inbounds float, ptr %x, i32 %i.025
1197   %0 = load float, ptr %arrayidx, align 4
1198   %s.0. = tail call nnan nsz float @llvm.minimum.f32(float %s.011, float %0)
1199   %arrayidx3 = getelementptr inbounds float, ptr %y, i32 %i.025
1200   %1 = load float, ptr %arrayidx3, align 4
1201   %cond9 = tail call float @llvm.minimum.f32(float %s.0., float %1)
1202   %inc = add nuw nsw i32 %i.025, 1
1203   %exitcond.not = icmp eq i32 %inc, 1024
1204   br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
1207 ; Make sure any check-not directives are not triggered by function declarations.
1208 ; CHECK: declare
1210 declare i32 @llvm.smin.i32(i32, i32)
1211 declare i32 @llvm.smax.i32(i32, i32)
1212 declare i32 @llvm.umin.i32(i32, i32)
1213 declare i32 @llvm.umax.i32(i32, i32)
1214 declare float @llvm.minnum.f32(float, float)
1215 declare float @llvm.maxnum.f32(float, float)
1216 declare float @llvm.minimum.f32(float, float)
1217 declare float @llvm.maximum.f32(float, float)
1219 attributes #0 = { "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" }
1220 attributes #1 = { "no-nans-fp-math"="true" }