xref: /llvm-project/llvm/test/CodeGen/AArch64/vecreduce-fminimum.ll (revision 1b12974ccba6478b27d7ba13ceead2864ab4be20)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOFP --check-prefix=CHECK-NOFP-SD
3; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon,+fullfp16 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP --check-prefix=CHECK-FP-SD
4; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOFP --check-prefix=CHECK-NOFP-GI
5; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -mattr=+neon,+fullfp16 -global-isel -global-isel-abort=2 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP --check-prefix=CHECK-FP-GI
6
7; CHECK-NOFP-GI:       warning: Instruction selection used fallback path for test_v11f16
8; CHECK-NOFP-GI-NEXT:  warning: Instruction selection used fallback path for test_v3f32
9; CHECK-NOFP-GI-NEXT:  warning: Instruction selection used fallback path for test_v3f32_ninf
10;
11; CHECK-FP-GI:       warning: Instruction selection used fallback path for test_v11f16
12; CHECK-FP-GI-NEXT:  warning: Instruction selection used fallback path for test_v3f32
13; CHECK-FP-GI-NEXT:  warning: Instruction selection used fallback path for test_v3f32_ninf
14
15declare half @llvm.vector.reduce.fminimum.v1f16(<1 x half> %a)
16declare float @llvm.vector.reduce.fminimum.v1f32(<1 x float> %a)
17declare double @llvm.vector.reduce.fminimum.v1f64(<1 x double> %a)
18declare fp128 @llvm.vector.reduce.fminimum.v1f128(<1 x fp128> %a)
19
20declare half @llvm.vector.reduce.fminimum.v4f16(<4 x half> %a)
21declare half @llvm.vector.reduce.fminimum.v8f16(<8 x half> %a)
22declare half @llvm.vector.reduce.fminimum.v16f16(<16 x half> %a)
23declare float @llvm.vector.reduce.fminimum.v2f32(<2 x float> %a)
24declare float @llvm.vector.reduce.fminimum.v4f32(<4 x float> %a)
25declare float @llvm.vector.reduce.fminimum.v8f32(<8 x float> %a)
26declare float @llvm.vector.reduce.fminimum.v16f32(<16 x float> %a)
27declare double @llvm.vector.reduce.fminimum.v2f64(<2 x double> %a)
28declare double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %a)
29
30declare half @llvm.vector.reduce.fminimum.v11f16(<11 x half> %a)
31declare float @llvm.vector.reduce.fminimum.v3f32(<3 x float> %a)
32declare fp128 @llvm.vector.reduce.fminimum.v2f128(<2 x fp128> %a)
33
34define half @test_v1f16(<1 x half> %a) nounwind {
35; CHECK-LABEL: test_v1f16:
36; CHECK:       // %bb.0:
37; CHECK-NEXT:    ret
38  %b = call half @llvm.vector.reduce.fminimum.v1f16(<1 x half> %a)
39  ret half %b
40}
41
42define float @test_v1f32(<1 x float> %a) nounwind {
43; CHECK-NOFP-SD-LABEL: test_v1f32:
44; CHECK-NOFP-SD:       // %bb.0:
45; CHECK-NOFP-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
46; CHECK-NOFP-SD-NEXT:    // kill: def $s0 killed $s0 killed $q0
47; CHECK-NOFP-SD-NEXT:    ret
48;
49; CHECK-FP-SD-LABEL: test_v1f32:
50; CHECK-FP-SD:       // %bb.0:
51; CHECK-FP-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
52; CHECK-FP-SD-NEXT:    // kill: def $s0 killed $s0 killed $q0
53; CHECK-FP-SD-NEXT:    ret
54;
55; CHECK-NOFP-GI-LABEL: test_v1f32:
56; CHECK-NOFP-GI:       // %bb.0:
57; CHECK-NOFP-GI-NEXT:    // kill: def $s0 killed $s0 killed $d0
58; CHECK-NOFP-GI-NEXT:    ret
59;
60; CHECK-FP-GI-LABEL: test_v1f32:
61; CHECK-FP-GI:       // %bb.0:
62; CHECK-FP-GI-NEXT:    // kill: def $s0 killed $s0 killed $d0
63; CHECK-FP-GI-NEXT:    ret
64  %b = call float @llvm.vector.reduce.fminimum.v1f32(<1 x float> %a)
65  ret float %b
66}
67
68define double @test_v1f64(<1 x double> %a) nounwind {
69; CHECK-LABEL: test_v1f64:
70; CHECK:       // %bb.0:
71; CHECK-NEXT:    ret
72  %b = call double @llvm.vector.reduce.fminimum.v1f64(<1 x double> %a)
73  ret double %b
74}
75
76define fp128 @test_v1f128(<1 x fp128> %a) nounwind {
77; CHECK-LABEL: test_v1f128:
78; CHECK:       // %bb.0:
79; CHECK-NEXT:    ret
80  %b = call fp128 @llvm.vector.reduce.fminimum.v1f128(<1 x fp128> %a)
81  ret fp128 %b
82}
83
84define half @test_v4f16(<4 x half> %a) nounwind {
85; CHECK-NOFP-SD-LABEL: test_v4f16:
86; CHECK-NOFP-SD:       // %bb.0:
87; CHECK-NOFP-SD-NEXT:    // kill: def $d0 killed $d0 def $q0
88; CHECK-NOFP-SD-NEXT:    mov h1, v0.h[1]
89; CHECK-NOFP-SD-NEXT:    fcvt s2, h0
90; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
91; CHECK-NOFP-SD-NEXT:    fmin s1, s2, s1
92; CHECK-NOFP-SD-NEXT:    mov h2, v0.h[2]
93; CHECK-NOFP-SD-NEXT:    mov h0, v0.h[3]
94; CHECK-NOFP-SD-NEXT:    fcvt h1, s1
95; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
96; CHECK-NOFP-SD-NEXT:    fcvt s0, h0
97; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
98; CHECK-NOFP-SD-NEXT:    fmin s1, s1, s2
99; CHECK-NOFP-SD-NEXT:    fcvt h1, s1
100; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
101; CHECK-NOFP-SD-NEXT:    fmin s0, s1, s0
102; CHECK-NOFP-SD-NEXT:    fcvt h0, s0
103; CHECK-NOFP-SD-NEXT:    ret
104;
105; CHECK-FP-LABEL: test_v4f16:
106; CHECK-FP:       // %bb.0:
107; CHECK-FP-NEXT:    fminv h0, v0.4h
108; CHECK-FP-NEXT:    ret
109;
110; CHECK-NOFP-GI-LABEL: test_v4f16:
111; CHECK-NOFP-GI:       // %bb.0:
112; CHECK-NOFP-GI-NEXT:    fcvtl v0.4s, v0.4h
113; CHECK-NOFP-GI-NEXT:    fminv s0, v0.4s
114; CHECK-NOFP-GI-NEXT:    fcvt h0, s0
115; CHECK-NOFP-GI-NEXT:    ret
116  %b = call half @llvm.vector.reduce.fminimum.v4f16(<4 x half> %a)
117  ret half %b
118}
119
120define half @test_v8f16(<8 x half> %a) nounwind {
121; CHECK-NOFP-SD-LABEL: test_v8f16:
122; CHECK-NOFP-SD:       // %bb.0:
123; CHECK-NOFP-SD-NEXT:    mov h1, v0.h[1]
124; CHECK-NOFP-SD-NEXT:    fcvt s2, h0
125; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
126; CHECK-NOFP-SD-NEXT:    fmin s1, s2, s1
127; CHECK-NOFP-SD-NEXT:    mov h2, v0.h[2]
128; CHECK-NOFP-SD-NEXT:    fcvt h1, s1
129; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
130; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
131; CHECK-NOFP-SD-NEXT:    fmin s1, s1, s2
132; CHECK-NOFP-SD-NEXT:    mov h2, v0.h[3]
133; CHECK-NOFP-SD-NEXT:    fcvt h1, s1
134; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
135; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
136; CHECK-NOFP-SD-NEXT:    fmin s1, s1, s2
137; CHECK-NOFP-SD-NEXT:    mov h2, v0.h[4]
138; CHECK-NOFP-SD-NEXT:    fcvt h1, s1
139; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
140; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
141; CHECK-NOFP-SD-NEXT:    fmin s1, s1, s2
142; CHECK-NOFP-SD-NEXT:    mov h2, v0.h[5]
143; CHECK-NOFP-SD-NEXT:    fcvt h1, s1
144; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
145; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
146; CHECK-NOFP-SD-NEXT:    fmin s1, s1, s2
147; CHECK-NOFP-SD-NEXT:    mov h2, v0.h[6]
148; CHECK-NOFP-SD-NEXT:    mov h0, v0.h[7]
149; CHECK-NOFP-SD-NEXT:    fcvt h1, s1
150; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
151; CHECK-NOFP-SD-NEXT:    fcvt s0, h0
152; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
153; CHECK-NOFP-SD-NEXT:    fmin s1, s1, s2
154; CHECK-NOFP-SD-NEXT:    fcvt h1, s1
155; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
156; CHECK-NOFP-SD-NEXT:    fmin s0, s1, s0
157; CHECK-NOFP-SD-NEXT:    fcvt h0, s0
158; CHECK-NOFP-SD-NEXT:    ret
159;
160; CHECK-FP-LABEL: test_v8f16:
161; CHECK-FP:       // %bb.0:
162; CHECK-FP-NEXT:    fminv h0, v0.8h
163; CHECK-FP-NEXT:    ret
164;
165; CHECK-NOFP-GI-LABEL: test_v8f16:
166; CHECK-NOFP-GI:       // %bb.0:
167; CHECK-NOFP-GI-NEXT:    fcvtl v1.4s, v0.4h
168; CHECK-NOFP-GI-NEXT:    fcvtl2 v0.4s, v0.8h
169; CHECK-NOFP-GI-NEXT:    fmin v0.4s, v1.4s, v0.4s
170; CHECK-NOFP-GI-NEXT:    fminv s0, v0.4s
171; CHECK-NOFP-GI-NEXT:    fcvt h0, s0
172; CHECK-NOFP-GI-NEXT:    ret
173  %b = call nnan half @llvm.vector.reduce.fminimum.v8f16(<8 x half> %a)
174  ret half %b
175}
176
177define half @test_v16f16(<16 x half> %a) nounwind {
178; CHECK-NOFP-SD-LABEL: test_v16f16:
179; CHECK-NOFP-SD:       // %bb.0:
180; CHECK-NOFP-SD-NEXT:    mov h2, v1.h[1]
181; CHECK-NOFP-SD-NEXT:    mov h3, v0.h[1]
182; CHECK-NOFP-SD-NEXT:    fcvt s4, h1
183; CHECK-NOFP-SD-NEXT:    fcvt s5, h0
184; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
185; CHECK-NOFP-SD-NEXT:    fcvt s3, h3
186; CHECK-NOFP-SD-NEXT:    fmin s4, s5, s4
187; CHECK-NOFP-SD-NEXT:    mov h5, v0.h[2]
188; CHECK-NOFP-SD-NEXT:    fmin s2, s3, s2
189; CHECK-NOFP-SD-NEXT:    mov h3, v1.h[2]
190; CHECK-NOFP-SD-NEXT:    fcvt h4, s4
191; CHECK-NOFP-SD-NEXT:    fcvt s5, h5
192; CHECK-NOFP-SD-NEXT:    fcvt h2, s2
193; CHECK-NOFP-SD-NEXT:    fcvt s3, h3
194; CHECK-NOFP-SD-NEXT:    fcvt s4, h4
195; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
196; CHECK-NOFP-SD-NEXT:    fmin s3, s5, s3
197; CHECK-NOFP-SD-NEXT:    mov h5, v0.h[3]
198; CHECK-NOFP-SD-NEXT:    fmin s2, s4, s2
199; CHECK-NOFP-SD-NEXT:    mov h4, v1.h[3]
200; CHECK-NOFP-SD-NEXT:    fcvt h3, s3
201; CHECK-NOFP-SD-NEXT:    fcvt s5, h5
202; CHECK-NOFP-SD-NEXT:    fcvt h2, s2
203; CHECK-NOFP-SD-NEXT:    fcvt s4, h4
204; CHECK-NOFP-SD-NEXT:    fcvt s3, h3
205; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
206; CHECK-NOFP-SD-NEXT:    fmin s4, s5, s4
207; CHECK-NOFP-SD-NEXT:    mov h5, v0.h[4]
208; CHECK-NOFP-SD-NEXT:    fmin s2, s2, s3
209; CHECK-NOFP-SD-NEXT:    mov h3, v1.h[4]
210; CHECK-NOFP-SD-NEXT:    fcvt h4, s4
211; CHECK-NOFP-SD-NEXT:    fcvt s5, h5
212; CHECK-NOFP-SD-NEXT:    fcvt h2, s2
213; CHECK-NOFP-SD-NEXT:    fcvt s3, h3
214; CHECK-NOFP-SD-NEXT:    fcvt s4, h4
215; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
216; CHECK-NOFP-SD-NEXT:    fmin s3, s5, s3
217; CHECK-NOFP-SD-NEXT:    mov h5, v0.h[5]
218; CHECK-NOFP-SD-NEXT:    fmin s2, s2, s4
219; CHECK-NOFP-SD-NEXT:    mov h4, v1.h[5]
220; CHECK-NOFP-SD-NEXT:    fcvt h3, s3
221; CHECK-NOFP-SD-NEXT:    fcvt s5, h5
222; CHECK-NOFP-SD-NEXT:    fcvt h2, s2
223; CHECK-NOFP-SD-NEXT:    fcvt s4, h4
224; CHECK-NOFP-SD-NEXT:    fcvt s3, h3
225; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
226; CHECK-NOFP-SD-NEXT:    fmin s4, s5, s4
227; CHECK-NOFP-SD-NEXT:    mov h5, v0.h[6]
228; CHECK-NOFP-SD-NEXT:    mov h0, v0.h[7]
229; CHECK-NOFP-SD-NEXT:    fmin s2, s2, s3
230; CHECK-NOFP-SD-NEXT:    fcvt h3, s4
231; CHECK-NOFP-SD-NEXT:    mov h4, v1.h[6]
232; CHECK-NOFP-SD-NEXT:    fcvt s5, h5
233; CHECK-NOFP-SD-NEXT:    mov h1, v1.h[7]
234; CHECK-NOFP-SD-NEXT:    fcvt s0, h0
235; CHECK-NOFP-SD-NEXT:    fcvt h2, s2
236; CHECK-NOFP-SD-NEXT:    fcvt s3, h3
237; CHECK-NOFP-SD-NEXT:    fcvt s4, h4
238; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
239; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
240; CHECK-NOFP-SD-NEXT:    fmin s0, s0, s1
241; CHECK-NOFP-SD-NEXT:    fmin s2, s2, s3
242; CHECK-NOFP-SD-NEXT:    fmin s3, s5, s4
243; CHECK-NOFP-SD-NEXT:    fcvt h0, s0
244; CHECK-NOFP-SD-NEXT:    fcvt h2, s2
245; CHECK-NOFP-SD-NEXT:    fcvt h3, s3
246; CHECK-NOFP-SD-NEXT:    fcvt s0, h0
247; CHECK-NOFP-SD-NEXT:    fcvt s2, h2
248; CHECK-NOFP-SD-NEXT:    fcvt s3, h3
249; CHECK-NOFP-SD-NEXT:    fmin s2, s2, s3
250; CHECK-NOFP-SD-NEXT:    fcvt h1, s2
251; CHECK-NOFP-SD-NEXT:    fcvt s1, h1
252; CHECK-NOFP-SD-NEXT:    fmin s0, s1, s0
253; CHECK-NOFP-SD-NEXT:    fcvt h0, s0
254; CHECK-NOFP-SD-NEXT:    ret
255;
256; CHECK-FP-LABEL: test_v16f16:
257; CHECK-FP:       // %bb.0:
258; CHECK-FP-NEXT:    fmin v0.8h, v0.8h, v1.8h
259; CHECK-FP-NEXT:    fminv h0, v0.8h
260; CHECK-FP-NEXT:    ret
261;
262; CHECK-NOFP-GI-LABEL: test_v16f16:
263; CHECK-NOFP-GI:       // %bb.0:
264; CHECK-NOFP-GI-NEXT:    fcvtl v2.4s, v0.4h
265; CHECK-NOFP-GI-NEXT:    fcvtl2 v0.4s, v0.8h
266; CHECK-NOFP-GI-NEXT:    fcvtl v3.4s, v1.4h
267; CHECK-NOFP-GI-NEXT:    fcvtl2 v1.4s, v1.8h
268; CHECK-NOFP-GI-NEXT:    fmin v0.4s, v2.4s, v0.4s
269; CHECK-NOFP-GI-NEXT:    fmin v1.4s, v3.4s, v1.4s
270; CHECK-NOFP-GI-NEXT:    fmin v0.4s, v0.4s, v1.4s
271; CHECK-NOFP-GI-NEXT:    fminv s0, v0.4s
272; CHECK-NOFP-GI-NEXT:    fcvt h0, s0
273; CHECK-NOFP-GI-NEXT:    ret
274  %b = call nnan half @llvm.vector.reduce.fminimum.v16f16(<16 x half> %a)
275  ret half %b
276}
277
278define float @test_v2f32(<2 x float> %a) nounwind {
279; CHECK-LABEL: test_v2f32:
280; CHECK:       // %bb.0:
281; CHECK-NEXT:    fminp s0, v0.2s
282; CHECK-NEXT:    ret
283  %b = call nnan float @llvm.vector.reduce.fminimum.v2f32(<2 x float> %a)
284  ret float %b
285}
286
287define float @test_v4f32(<4 x float> %a) nounwind {
288; CHECK-LABEL: test_v4f32:
289; CHECK:       // %bb.0:
290; CHECK-NEXT:    fminv s0, v0.4s
291; CHECK-NEXT:    ret
292  %b = call nnan float @llvm.vector.reduce.fminimum.v4f32(<4 x float> %a)
293  ret float %b
294}
295
296define float @test_v8f32(<8 x float> %a) nounwind {
297; CHECK-LABEL: test_v8f32:
298; CHECK:       // %bb.0:
299; CHECK-NEXT:    fmin v0.4s, v0.4s, v1.4s
300; CHECK-NEXT:    fminv s0, v0.4s
301; CHECK-NEXT:    ret
302  %b = call nnan float @llvm.vector.reduce.fminimum.v8f32(<8 x float> %a)
303  ret float %b
304}
305
306define float @test_v16f32(<16 x float> %a) nounwind {
307; CHECK-NOFP-SD-LABEL: test_v16f32:
308; CHECK-NOFP-SD:       // %bb.0:
309; CHECK-NOFP-SD-NEXT:    fmin v1.4s, v1.4s, v3.4s
310; CHECK-NOFP-SD-NEXT:    fmin v0.4s, v0.4s, v2.4s
311; CHECK-NOFP-SD-NEXT:    fmin v0.4s, v0.4s, v1.4s
312; CHECK-NOFP-SD-NEXT:    fminv s0, v0.4s
313; CHECK-NOFP-SD-NEXT:    ret
314;
315; CHECK-FP-SD-LABEL: test_v16f32:
316; CHECK-FP-SD:       // %bb.0:
317; CHECK-FP-SD-NEXT:    fmin v1.4s, v1.4s, v3.4s
318; CHECK-FP-SD-NEXT:    fmin v0.4s, v0.4s, v2.4s
319; CHECK-FP-SD-NEXT:    fmin v0.4s, v0.4s, v1.4s
320; CHECK-FP-SD-NEXT:    fminv s0, v0.4s
321; CHECK-FP-SD-NEXT:    ret
322;
323; CHECK-NOFP-GI-LABEL: test_v16f32:
324; CHECK-NOFP-GI:       // %bb.0:
325; CHECK-NOFP-GI-NEXT:    fmin v0.4s, v0.4s, v1.4s
326; CHECK-NOFP-GI-NEXT:    fmin v1.4s, v2.4s, v3.4s
327; CHECK-NOFP-GI-NEXT:    fmin v0.4s, v0.4s, v1.4s
328; CHECK-NOFP-GI-NEXT:    fminv s0, v0.4s
329; CHECK-NOFP-GI-NEXT:    ret
330;
331; CHECK-FP-GI-LABEL: test_v16f32:
332; CHECK-FP-GI:       // %bb.0:
333; CHECK-FP-GI-NEXT:    fmin v0.4s, v0.4s, v1.4s
334; CHECK-FP-GI-NEXT:    fmin v1.4s, v2.4s, v3.4s
335; CHECK-FP-GI-NEXT:    fmin v0.4s, v0.4s, v1.4s
336; CHECK-FP-GI-NEXT:    fminv s0, v0.4s
337; CHECK-FP-GI-NEXT:    ret
338  %b = call nnan float @llvm.vector.reduce.fminimum.v16f32(<16 x float> %a)
339  ret float %b
340}
341
342define double @test_v2f64(<2 x double> %a) nounwind {
343; CHECK-LABEL: test_v2f64:
344; CHECK:       // %bb.0:
345; CHECK-NEXT:    fminp d0, v0.2d
346; CHECK-NEXT:    ret
347  %b = call double @llvm.vector.reduce.fminimum.v2f64(<2 x double> %a)
348  ret double %b
349}
350
351define double @test_v4f64(<4 x double> %a) nounwind {
352; CHECK-LABEL: test_v4f64:
353; CHECK:       // %bb.0:
354; CHECK-NEXT:    fmin v0.2d, v0.2d, v1.2d
355; CHECK-NEXT:    fminp d0, v0.2d
356; CHECK-NEXT:    ret
357  %b = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> %a)
358  ret double %b
359}
360
361define half @test_v11f16(<11 x half> %a) nounwind {
362; CHECK-NOFP-LABEL: test_v11f16:
363; CHECK-NOFP:       // %bb.0:
364; CHECK-NOFP-NEXT:    ldr h16, [sp, #8]
365; CHECK-NOFP-NEXT:    ldr h17, [sp]
366; CHECK-NOFP-NEXT:    fcvt s1, h1
367; CHECK-NOFP-NEXT:    fcvt s0, h0
368; CHECK-NOFP-NEXT:    fcvt s2, h2
369; CHECK-NOFP-NEXT:    fcvt s16, h16
370; CHECK-NOFP-NEXT:    fcvt s17, h17
371; CHECK-NOFP-NEXT:    fmin s1, s1, s16
372; CHECK-NOFP-NEXT:    fmin s0, s0, s17
373; CHECK-NOFP-NEXT:    ldr h16, [sp, #16]
374; CHECK-NOFP-NEXT:    fcvt s16, h16
375; CHECK-NOFP-NEXT:    fcvt h1, s1
376; CHECK-NOFP-NEXT:    fcvt h0, s0
377; CHECK-NOFP-NEXT:    fcvt s1, h1
378; CHECK-NOFP-NEXT:    fcvt s0, h0
379; CHECK-NOFP-NEXT:    fmin s0, s0, s1
380; CHECK-NOFP-NEXT:    fmin s1, s2, s16
381; CHECK-NOFP-NEXT:    fcvt h0, s0
382; CHECK-NOFP-NEXT:    fcvt h1, s1
383; CHECK-NOFP-NEXT:    fcvt s0, h0
384; CHECK-NOFP-NEXT:    fcvt s1, h1
385; CHECK-NOFP-NEXT:    fmin s0, s0, s1
386; CHECK-NOFP-NEXT:    fcvt s1, h3
387; CHECK-NOFP-NEXT:    fcvt h0, s0
388; CHECK-NOFP-NEXT:    fcvt s0, h0
389; CHECK-NOFP-NEXT:    fmin s0, s0, s1
390; CHECK-NOFP-NEXT:    fcvt s1, h4
391; CHECK-NOFP-NEXT:    fcvt h0, s0
392; CHECK-NOFP-NEXT:    fcvt s0, h0
393; CHECK-NOFP-NEXT:    fmin s0, s0, s1
394; CHECK-NOFP-NEXT:    fcvt s1, h5
395; CHECK-NOFP-NEXT:    fcvt h0, s0
396; CHECK-NOFP-NEXT:    fcvt s0, h0
397; CHECK-NOFP-NEXT:    fmin s0, s0, s1
398; CHECK-NOFP-NEXT:    fcvt s1, h6
399; CHECK-NOFP-NEXT:    fcvt h0, s0
400; CHECK-NOFP-NEXT:    fcvt s0, h0
401; CHECK-NOFP-NEXT:    fmin s0, s0, s1
402; CHECK-NOFP-NEXT:    fcvt s1, h7
403; CHECK-NOFP-NEXT:    fcvt h0, s0
404; CHECK-NOFP-NEXT:    fcvt s0, h0
405; CHECK-NOFP-NEXT:    fmin s0, s0, s1
406; CHECK-NOFP-NEXT:    fcvt h0, s0
407; CHECK-NOFP-NEXT:    ret
408;
409; CHECK-FP-LABEL: test_v11f16:
410; CHECK-FP:       // %bb.0:
411; CHECK-FP-NEXT:    // kill: def $h0 killed $h0 def $q0
412; CHECK-FP-NEXT:    // kill: def $h1 killed $h1 def $q1
413; CHECK-FP-NEXT:    // kill: def $h2 killed $h2 def $q2
414; CHECK-FP-NEXT:    // kill: def $h3 killed $h3 def $q3
415; CHECK-FP-NEXT:    // kill: def $h4 killed $h4 def $q4
416; CHECK-FP-NEXT:    // kill: def $h5 killed $h5 def $q5
417; CHECK-FP-NEXT:    mov x8, sp
418; CHECK-FP-NEXT:    // kill: def $h6 killed $h6 def $q6
419; CHECK-FP-NEXT:    // kill: def $h7 killed $h7 def $q7
420; CHECK-FP-NEXT:    mov v0.h[1], v1.h[0]
421; CHECK-FP-NEXT:    movi v1.8h, #124, lsl #8
422; CHECK-FP-NEXT:    mov v0.h[2], v2.h[0]
423; CHECK-FP-NEXT:    ld1 { v1.h }[0], [x8]
424; CHECK-FP-NEXT:    add x8, sp, #8
425; CHECK-FP-NEXT:    ld1 { v1.h }[1], [x8]
426; CHECK-FP-NEXT:    add x8, sp, #16
427; CHECK-FP-NEXT:    mov v0.h[3], v3.h[0]
428; CHECK-FP-NEXT:    ld1 { v1.h }[2], [x8]
429; CHECK-FP-NEXT:    mov v0.h[4], v4.h[0]
430; CHECK-FP-NEXT:    mov v0.h[5], v5.h[0]
431; CHECK-FP-NEXT:    mov v0.h[6], v6.h[0]
432; CHECK-FP-NEXT:    mov v0.h[7], v7.h[0]
433; CHECK-FP-NEXT:    fmin v0.8h, v0.8h, v1.8h
434; CHECK-FP-NEXT:    fminv h0, v0.8h
435; CHECK-FP-NEXT:    ret
436  %b = call half @llvm.vector.reduce.fminimum.v11f16(<11 x half> %a)
437  ret half %b
438}
439
440; Neutral element is negative infinity which is chosen for padding the widened
441; vector.
442define float @test_v3f32(<3 x float> %a) nounwind {
443; CHECK-LABEL: test_v3f32:
444; CHECK:       // %bb.0:
445; CHECK-NEXT:    mov w8, #2139095040 // =0x7f800000
446; CHECK-NEXT:    fmov s1, w8
447; CHECK-NEXT:    mov v0.s[3], v1.s[0]
448; CHECK-NEXT:    fminv s0, v0.4s
449; CHECK-NEXT:    ret
450  %b = call float @llvm.vector.reduce.fminimum.v3f32(<3 x float> %a)
451  ret float %b
452}
453
454; Neutral element chosen for padding the widened vector is not negative infinity.
455define float @test_v3f32_ninf(<3 x float> %a) nounwind {
456; CHECK-LABEL: test_v3f32_ninf:
457; CHECK:       // %bb.0:
458; CHECK-NEXT:    mov w8, #2139095039 // =0x7f7fffff
459; CHECK-NEXT:    fmov s1, w8
460; CHECK-NEXT:    mov v0.s[3], v1.s[0]
461; CHECK-NEXT:    fminv s0, v0.4s
462; CHECK-NEXT:    ret
463  %b = call ninf float @llvm.vector.reduce.fminimum.v3f32(<3 x float> %a)
464  ret float %b
465}
466
467; Cannot legalize f128. See PR63267 - The underlying fminimum has no default
468; expansion and no libcalls.
469;define fp128 @test_v2f128(<2 x fp128> %a) nounwind {
470;  %b = call fp128 @llvm.vector.reduce.fminimum.v2f128(<2 x fp128> %a)
471;  ret fp128 %b
472;}
473