1; RUN: llc < %s -mtriple=armv8-eabi -mattr=+fullfp16 | FileCheck %s
2; RUN: llc < %s -mtriple thumbv7a -mattr=+fullfp16 | FileCheck %s
3
4; TODO: we can't pass half-precision arguments as "half" types yet. We do
5; that for the time being by passing "float %f.coerce" and the necessary
6; bitconverts/truncates. In these tests we pass i16 and use 1 bitconvert, which
7; is the shortest way to get a half type. But when we can pass half types, we
8; want to use that here.
9
10define half @fp16_vminnm_o(i16 signext %a, i16 signext %b) {
11; CHECK-LABEL: fp16_vminnm_o:
12; CHECK-NOT: vminnm.f16
13entry:
14  %0 = bitcast i16 %a to half
15  %1 = bitcast i16 %b to half
16  %cmp = fcmp olt half %0, %1
17  %cond = select i1 %cmp, half %0, half %1
18  ret half %cond
19}
20
21define half @fp16_vminnm_o_rev(i16 signext %a, i16 signext %b) {
22; CHECK-LABEL: fp16_vminnm_o_rev:
23; CHECK-NOT: vminnm.f16
24entry:
25  %0 = bitcast i16 %a to half
26  %1 = bitcast i16 %b to half
27  %cmp = fcmp ogt half %0, %1
28  %cond = select i1 %cmp, half %0, half %1
29  ret half %cond
30}
31
32define half @fp16_vminnm_u(i16 signext %a, i16 signext %b) {
33; CHECK-LABEL: fp16_vminnm_u:
34; CHECK-NOT: vminnm.f16
35entry:
36  %0 = bitcast i16 %a to half
37  %1 = bitcast i16 %b to half
38  %cmp = fcmp ult half %0, %1
39  %cond = select i1 %cmp, half %0, half %1
40  ret half %cond
41}
42
43define half @fp16_vminnm_ule(i16 signext %a, i16 signext %b) {
44; CHECK-LABEL: fp16_vminnm_ule:
45; CHECK-NOT: vminnm.f16
46entry:
47  %0 = bitcast i16 %a to half
48  %1 = bitcast i16 %b to half
49  %cmp = fcmp ule half %0, %1
50  %cond = select i1 %cmp, half %0, half %1
51  ret half %cond
52}
53
54define half @fp16_vminnm_u_rev(i16 signext %a, i16 signext %b) {
55; CHECK-LABEL: fp16_vminnm_u_rev:
56; CHECK-NOT: vminnm.f16
57entry:
58  %0 = bitcast i16 %a to half
59  %1 = bitcast i16 %b to half
60  %cmp = fcmp ugt half %0, %1
61  %cond = select i1 %cmp, half %1, half %0
62  ret half %cond
63}
64
65define half @fp16_vmaxnm_o(i16 signext %a, i16 signext %b) {
66; CHECK-LABEL: fp16_vmaxnm_o:
67; CHECK-NOT: vmaxnm.f16
68entry:
69  %0 = bitcast i16 %a to half
70  %1 = bitcast i16 %b to half
71  %cmp = fcmp ogt half %0, %1
72  %cond = select i1 %cmp, half %0, half %1
73  ret half %cond
74}
75
76define half @fp16_vmaxnm_oge(i16 signext %a, i16 signext %b) {
77; CHECK-LABEL: fp16_vmaxnm_oge:
78; CHECK-NOT: vmaxnm.f16
79entry:
80  %0 = bitcast i16 %a to half
81  %1 = bitcast i16 %b to half
82  %cmp = fcmp oge half %0, %1
83  %cond = select i1 %cmp, half %0, half %1
84  ret half %cond
85}
86
87define half @fp16_vmaxnm_o_rev(i16 signext %a, i16 signext %b) {
88; CHECK-LABEL: fp16_vmaxnm_o_rev:
89; CHECK-NOT: vmaxnm.f16
90entry:
91  %0 = bitcast i16 %a to half
92  %1 = bitcast i16 %b to half
93  %cmp = fcmp olt half %0, %1
94  %cond = select i1 %cmp, half %1, half %0
95  ret half %cond
96}
97
98define half @fp16_vmaxnm_ole_rev(i16 signext %a, i16 signext %b) {
99; CHECK-LABEL: fp16_vmaxnm_ole_rev:
100; CHECK-NOT: vmaxnm.f16
101entry:
102  %0 = bitcast i16 %a to half
103  %1 = bitcast i16 %b to half
104  %cmp = fcmp ole half %0, %1
105  %cond = select i1 %cmp, half %1, half %0
106  ret half %cond
107}
108
109define half @fp16_vmaxnm_u(i16 signext %a, i16 signext %b) {
110; CHECK-LABEL: fp16_vmaxnm_u:
111; CHECK-NOT: vmaxnm.f16
112entry:
113  %0 = bitcast i16 %a to half
114  %1 = bitcast i16 %b to half
115  %cmp = fcmp ugt half %0, %1
116  %cond = select i1 %cmp, half %0, half %1
117  ret half %cond
118}
119
120define half @fp16_vmaxnm_uge(i16 signext %a, i16 signext %b) {
121; CHECK-LABEL: fp16_vmaxnm_uge:
122; CHECK-NOT: vmaxnm.f16
123entry:
124  %0 = bitcast i16 %a to half
125  %1 = bitcast i16 %b to half
126  %cmp = fcmp uge half %0, %1
127  %cond = select i1 %cmp, half %0, half %1
128  ret half %cond
129}
130
131define half @fp16_vmaxnm_u_rev(i16 signext %a, i16 signext %b) {
132; CHECK-LABEL: fp16_vmaxnm_u_rev:
133; CHECK-NOT: vmaxnm.f16
134entry:
135  %0 = bitcast i16 %a to half
136  %1 = bitcast i16 %b to half
137  %cmp = fcmp ult half %0, %1
138  %cond = select i1 %cmp, half %1, half %0
139  ret half %cond
140}
141
142; known non-NaNs
143
144define half @fp16_vminnm_NNNo(i16 signext %a) {
145; CHECK-LABEL:  fp16_vminnm_NNNo:
146; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
147; CHECK:	vmov.f16	[[S2:s[0-9]]], #1.200000e+01
148; CHECK:	vmov.f16	[[S4:s[0-9]]], r{{.}}
149; CHECK:	vminnm.f16	s2, [[S4]], [[S2]]
150; CHECK:	vmin.f16	d0, d1, d0
151entry:
152  %0 = bitcast i16 %a to half
153  %cmp1 = fcmp olt half %0, 12.
154  %cond1 = select i1 %cmp1, half %0, half 12.
155  %cmp2 = fcmp olt half 34., %cond1
156  %cond2 = select i1 %cmp2, half 34., half %cond1
157  ret half %cond2
158}
159
160define half @fp16_vminnm_NNNo_rev(i16 signext %a) {
161; CHECK-LABEL:  fp16_vminnm_NNNo_rev:
162; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
163; CHECK:	vmov.f16	[[S2:s[0-9]]], r{{.}}
164; CHECK:	vmin.f16	d0, d1, d0
165; CHECK:	vldr.16	[[S2:s[0-9]]], .LCPI{{.*}}
166; CHECK:	vminnm.f16	s0, [[S0]], [[S2]]
167entry:
168  %0 = bitcast i16 %a to half
169  %cmp1 = fcmp ogt half %0, 56.
170  %cond1 = select i1 %cmp1, half 56., half %0
171  %cmp2 = fcmp ogt half 78., %cond1
172  %cond2 = select i1 %cmp2, half %cond1, half 78.
173  ret half %cond2
174}
175
176define half @fp16_vminnm_NNNu(i16 signext %b) {
177; CHECK-LABEL: fp16_vminnm_NNNu:
178; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
179; CHECK:	vmov.f16	[[S2:s[0-9]]], #1.200000e+01
180; CHECK:	vmov.f16	[[S4:s[0-9]]], r{{.}}
181; CHECK:	vminnm.f16	s2, [[S4]], [[S2]]
182; CHECK:	vmin.f16	d0, d1, d0
183entry:
184  %0 = bitcast i16 %b to half
185  %cmp1 = fcmp ult half 12., %0
186  %cond1 = select i1 %cmp1, half 12., half %0
187  %cmp2 = fcmp ult half %cond1, 34.
188  %cond2 = select i1 %cmp2, half %cond1, half 34.
189  ret half %cond2
190}
191
192define half @fp16_vminnm_NNNule(i16 signext %b) {
193; CHECK-LABEL:  fp16_vminnm_NNNule:
194; CHECK:	vldr.16	[[S2:s[0-9]]], .LCPI{{.*}}
195; CHECK:	vmov.f16	[[S4:s[0-9]]], r{{.}}
196; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
197; CHECK:	vminnm.f16	s2, [[S4]], [[S2]]
198; CHECK:	vmin.f16	d0, d1, d0
199
200entry:
201  %0 = bitcast i16 %b to half
202  %cmp1 = fcmp ule half 34., %0
203  %cond1 = select i1 %cmp1, half 34., half %0
204  %cmp2 = fcmp ule half %cond1, 56.
205  %cond2 = select i1 %cmp2, half %cond1, half 56.
206  ret half %cond2
207}
208
209define half @fp16_vminnm_NNNu_rev(i16 signext %b) {
210; CHECK-LABEL:  fp16_vminnm_NNNu_rev:
211
212; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
213; CHECK:	vmov.f16	[[S2:s[0-9]]], r{{.}}
214; CHECK:	vmin.f16	d0, d1, d0
215; CHECK:	vldr.16	[[S2:s[0-9]]], .LCPI{{.*}}
216; CHECK:	vminnm.f16	s0, [[S0]], [[S2]]
217
218entry:
219  %0 = bitcast i16 %b to half
220  %cmp1 = fcmp ugt half 56., %0
221  %cond1 = select i1 %cmp1, half %0, half 56.
222  %cmp2 = fcmp ugt half %cond1, 78.
223  %cond2 = select i1 %cmp2, half 78., half %cond1
224  ret half %cond2
225}
226
227define half @fp16_vmaxnm_NNNo(i16 signext %a) {
228; CHECK-LABEL:  fp16_vmaxnm_NNNo:
229; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
230; CHECK:	vmov.f16	[[S2:s[0-9]]], #1.200000e+01
231; CHECK:	vmov.f16	[[S4:s[0-9]]], r{{.}}
232; CHECK:	vmaxnm.f16	s2, [[S4]], [[S2]]
233; CHECK:	vmax.f16	d0, d1, d0
234entry:
235  %0 = bitcast i16 %a to half
236  %cmp1 = fcmp ogt half %0, 12.
237  %cond1 = select i1 %cmp1, half %0, half 12.
238  %cmp2 = fcmp ogt half 34., %cond1
239  %cond2 = select i1 %cmp2, half 34., half %cond1
240  ret half %cond2
241}
242
243define half @fp16_vmaxnm_NNNoge(i16 signext %a) {
244; CHECK-LABEL:  fp16_vmaxnm_NNNoge:
245; CHECK:	vldr.16	[[S2:s[0-9]]], .LCPI{{.*}}
246; CHECK:	vmov.f16	[[S4:s[0-9]]], r{{.}}
247; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
248; CHECK:	vmaxnm.f16	s2, [[S4]], [[S2]]
249; CHECK:	vmax.f16	d0, d1, d0
250entry:
251  %0 = bitcast i16 %a to half
252  %cmp1 = fcmp oge half %0, 34.
253  %cond1 = select i1 %cmp1, half %0, half 34.
254  %cmp2 = fcmp oge half 56., %cond1
255  %cond2 = select i1 %cmp2, half 56., half %cond1
256  ret half %cond2
257}
258
259define half @fp16_vmaxnm_NNNo_rev(i16 signext %a) {
260; CHECK-LABEL:  fp16_vmaxnm_NNNo_rev:
261; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
262; CHECK:	vmov.f16	[[S2:s[0-9]]], r{{.}}
263; CHECK:	vmax.f16	d0, d1, d0
264; CHECK:	vldr.16	[[S2:s[0-9]]], .LCPI{{.*}}
265; CHECK:	vmaxnm.f16	s0, [[S0]], [[S2]]
266entry:
267  %0 = bitcast i16 %a to half
268  %cmp1 = fcmp olt half %0, 56.
269  %cond1 = select i1 %cmp1, half 56., half %0
270  %cmp2 = fcmp olt half 78., %cond1
271  %cond2 = select i1 %cmp2, half %cond1, half 78.
272  ret half %cond2
273}
274
275define half @fp16_vmaxnm_NNNole_rev(i16 signext %a) {
276; CHECK-LABEL:  fp16_vmaxnm_NNNole_rev:
277; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
278; CHECK:	vmov.f16	[[S2:s[0-9]]], r{{.}}
279; CHECK:	vmax.f16	d0, d1, d0
280; CHECK:	vldr.16	[[S2:s[0-9]]], .LCPI{{.*}}
281; CHECK:	vmaxnm.f16	s0, [[S0]], [[S2]]
282entry:
283  %0 = bitcast i16 %a to half
284  %cmp1 = fcmp ole half %0, 78.
285  %cond1 = select i1 %cmp1, half 78., half %0
286  %cmp2 = fcmp ole half 90., %cond1
287  %cond2 = select i1 %cmp2, half %cond1, half 90.
288  ret half %cond2
289}
290
291define half @fp16_vmaxnm_NNNu(i16 signext %b) {
292; CHECK-LABEL:  fp16_vmaxnm_NNNu:
293; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
294; CHECK:	vmov.f16	[[S2:s[0-9]]], #1.200000e+01
295; CHECK:	vmov.f16	[[S4:s[0-9]]], r{{.}}
296; CHECK:	vmaxnm.f16	s2, [[S4]], [[S2]]
297; CHECK:	vmax.f16	d0, d1, d0
298entry:
299  %0 = bitcast i16 %b to half
300  %cmp1 = fcmp ugt half 12., %0
301  %cond1 = select i1 %cmp1, half 12., half %0
302  %cmp2 = fcmp ugt half %cond1, 34.
303  %cond2 = select i1 %cmp2, half %cond1, half 34.
304  ret half %cond2
305}
306
307define half @fp16_vmaxnm_NNNuge(i16 signext %b) {
308; CHECK-LABEL:  fp16_vmaxnm_NNNuge:
309; CHECK:	vldr.16	[[S2:s[0-9]]], .LCPI{{.*}}
310; CHECK:	vmov.f16	[[S4:s[0-9]]], r{{.}}
311; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
312; CHECK:	vmaxnm.f16	s2, [[S4]], [[S2]]
313; CHECK:	vmax.f16	d0, d1, d0
314entry:
315  %0 = bitcast i16 %b to half
316  %cmp1 = fcmp uge half 34., %0
317  %cond1 = select i1 %cmp1, half 34., half %0
318  %cmp2 = fcmp uge half %cond1, 56.
319  %cond2 = select i1 %cmp2, half %cond1, half 56.
320  ret half %cond2
321}
322
323define half @fp16_vminmaxnm_neg0(i16 signext %a) {
324; CHECK-LABEL:  fp16_vminmaxnm_neg0:
325; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
326; CHECK:	vmov.f16	[[S2:s[0-9]]], r{{.}}
327; CHECK:	vminnm.f16	s2, [[S2]], [[S0]]
328; CHECK:	vmax.f16	d0, d1, d0
329entry:
330  %0 = bitcast i16 %a to half
331  %cmp1 = fcmp olt half %0, -0.
332  %cond1 = select i1 %cmp1, half %0, half -0.
333  %cmp2 = fcmp ugt half %cond1, -0.
334  %cond2 = select i1 %cmp2, half %cond1, half -0.
335  ret half %cond2
336}
337
338define half @fp16_vminmaxnm_e_0(i16 signext %a) {
339; CHECK-LABEL:  fp16_vminmaxnm_e_0:
340; CHECK:	vldr.16	[[S2:s[0-9]]], .LCPI{{.*}}
341; CHECK:	vmov.f16	[[S0:s[0-9]]], r{{.}}
342; CHECK:	vmin.f16	d0, d0, d1
343; CHECK:	vmaxnm.f16	s0, [[S0]], [[S2]]
344entry:
345  %0 = bitcast i16 %a to half
346  %cmp1 = fcmp nsz ole half 0., %0
347  %cond1 = select i1 %cmp1, half 0., half %0
348  %cmp2 = fcmp nsz uge half 0., %cond1
349  %cond2 = select i1 %cmp2, half 0., half %cond1
350  ret half %cond2
351}
352
353define half @fp16_vminmaxnm_e_neg0(i16 signext %a) {
354; CHECK-LABEL:  fp16_vminmaxnm_e_neg0:
355; CHECK:	vldr.16	[[S0:s[0-9]]], .LCPI{{.*}}
356; CHECK:	vmov.f16	[[S2:s[0-9]]], r{{.}}
357; CHECK:	vminnm.f16	s2, [[S2]], [[S0]]
358; CHECK:	vmax.f16	d0, d1, d0
359entry:
360  %0 = bitcast i16 %a to half
361  %cmp1 = fcmp nsz ule half -0., %0
362  %cond1 = select i1 %cmp1, half -0., half %0
363  %cmp2 = fcmp nsz oge half -0., %cond1
364  %cond2 = select i1 %cmp2, half -0., half %cond1
365  ret half %cond2
366}
367