Revert 374373: [Codegen] Alter the default promotion for saturating adds and subs
[llvm-core.git] / test / CodeGen / AArch64 / fp16_intrinsic_scalar_2op.ll
blob04da29888e735b1e53049a80ad2eb9af574f361f
1 ; RUN: llc < %s -mtriple=aarch64-eabi -mattr=+v8.2a,+fullfp16  | FileCheck %s
3 declare half @llvm.aarch64.sisd.fabd.f16(half, half)
4 declare half @llvm.aarch64.neon.fmax.f16(half, half)
5 declare half @llvm.aarch64.neon.fmin.f16(half, half)
6 declare half @llvm.aarch64.neon.frsqrts.f16(half, half)
7 declare half @llvm.aarch64.neon.frecps.f16(half, half)
8 declare half @llvm.aarch64.neon.fmulx.f16(half, half)
9 declare half @llvm.fabs.f16(half)
10 declare i32 @llvm.aarch64.neon.facge.i32.f16(half, half)
11 declare i32 @llvm.aarch64.neon.facgt.i32.f16(half, half)
13 define dso_local half @t_vabdh_f16(half %a, half %b) {
14 ; CHECK-LABEL: t_vabdh_f16:
15 ; CHECK:         fabd h0, h0, h1
16 ; CHECK-NEXT:    ret
17 entry:
18   %vabdh_f16 = tail call half @llvm.aarch64.sisd.fabd.f16(half %a, half %b)
19   ret half %vabdh_f16
22 define dso_local half @t_vabdh_f16_from_fsub_fabs(half %a, half %b) {
23 ; CHECK-LABEL: t_vabdh_f16_from_fsub_fabs:
24 ; CHECK:         fabd h0, h0, h1
25 ; CHECK-NEXT:    ret
26 entry:
27   %sub = fsub half %a, %b
28   %abs = tail call half @llvm.fabs.f16(half %sub)
29   ret half %abs
32 define dso_local i16 @t_vceqh_f16(half %a, half %b) {
33 ; CHECK-LABEL: t_vceqh_f16:
34 ; CHECK:         fcmp h0, h1
35 ; CHECK-NEXT:    csetm w0, eq
36 ; CHECK-NEXT:    ret
37 entry:
38   %0 = fcmp oeq half %a, %b
39   %vcmpd = sext i1 %0 to i16
40   ret i16 %vcmpd
43 define dso_local i16 @t_vcgeh_f16(half %a, half %b) {
44 ; CHECK-LABEL: t_vcgeh_f16:
45 ; CHECK:         fcmp h0, h1
46 ; CHECK-NEXT:    csetm w0, ge
47 ; CHECK-NEXT:    ret
48 entry:
49   %0 = fcmp oge half %a, %b
50   %vcmpd = sext i1 %0 to i16
51   ret i16 %vcmpd
54 define dso_local i16 @t_vcgth_f16(half %a, half %b) {
55 ; CHECK-LABEL: t_vcgth_f16:
56 ; CHECK:         fcmp h0, h1
57 ; CHECK-NEXT:    csetm w0, gt
58 ; CHECK-NEXT:    ret
59 entry:
60   %0 = fcmp ogt half %a, %b
61   %vcmpd = sext i1 %0 to i16
62   ret i16 %vcmpd
65 define dso_local i16 @t_vcleh_f16(half %a, half %b) {
66 ; CHECK-LABEL: t_vcleh_f16:
67 ; CHECK:         fcmp h0, h1
68 ; CHECK-NEXT:    csetm w0, ls
69 ; CHECK-NEXT:    ret
70 entry:
71   %0 = fcmp ole half %a, %b
72   %vcmpd = sext i1 %0 to i16
73   ret i16 %vcmpd
76 define dso_local i16 @t_vclth_f16(half %a, half %b) {
77 ; CHECK-LABEL: t_vclth_f16:
78 ; CHECK:         fcmp h0, h1
79 ; CHECK-NEXT:    csetm w0, mi
80 ; CHECK-NEXT:    ret
81 entry:
82   %0 = fcmp olt half %a, %b
83   %vcmpd = sext i1 %0 to i16
84   ret i16 %vcmpd
87 define dso_local half @t_vmaxh_f16(half %a, half %b) {
88 ; CHECK-LABEL: t_vmaxh_f16:
89 ; CHECK:         fmax h0, h0, h1
90 ; CHECK-NEXT:    ret
91 entry:
92   %vmax = tail call half @llvm.aarch64.neon.fmax.f16(half %a, half %b)
93   ret half %vmax
96 define dso_local half @t_vminh_f16(half %a, half %b) {
97 ; CHECK-LABEL: t_vminh_f16:
98 ; CHECK:         fmin h0, h0, h1
99 ; CHECK-NEXT:    ret
100 entry:
101   %vmin = tail call half @llvm.aarch64.neon.fmin.f16(half %a, half %b)
102   ret half %vmin
105 define dso_local half @t_vmulxh_f16(half %a, half %b) {
106 ; CHECK-LABEL: t_vmulxh_f16:
107 ; CHECK:         fmulx h0, h0, h1
108 ; CHECK-NEXT:    ret
109 entry:
110   %vmulxh_f16 = tail call half @llvm.aarch64.neon.fmulx.f16(half %a, half %b)
111   ret half %vmulxh_f16
114 define dso_local half @t_vrecpsh_f16(half %a, half %b) {
115 ; CHECK-LABEL: t_vrecpsh_f16:
116 ; CHECK:         frecps h0, h0, h1
117 ; CHECK-NEXT:    ret
118 entry:
119   %vrecps = tail call half @llvm.aarch64.neon.frecps.f16(half %a, half %b)
120   ret half %vrecps
123 define dso_local half @t_vrsqrtsh_f16(half %a, half %b) {
124 ; CHECK-LABEL: t_vrsqrtsh_f16:
125 ; CHECK:         frsqrts h0, h0, h1
126 ; CHECK-NEXT:    ret
127 entry:
128   %vrsqrtsh_f16 = tail call half @llvm.aarch64.neon.frsqrts.f16(half %a, half %b)
129   ret half %vrsqrtsh_f16
132 declare half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32, i32) #1
133 declare half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64, i32) #1
134 declare i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half, i32) #1
135 declare i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half, i32) #1
136 declare half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32, i32) #1
137 declare i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half, i32) #1
139 define dso_local half @test_vcvth_n_f16_s16_1(i16 %a) {
140 ; CHECK-LABEL: test_vcvth_n_f16_s16_1:
141 ; CHECK:         fmov s0, w[[wReg:[0-9]+]]
142 ; CHECK-NEXT:    scvtf h0, h0, #1
143 ; CHECK-NEXT:    ret
144 entry:
145   %sext = sext i16 %a to i32
146   %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %sext, i32 1)
147   ret half %fcvth_n
150 define dso_local half @test_vcvth_n_f16_s16_16(i16 %a) {
151 ; CHECK-LABEL: test_vcvth_n_f16_s16_16:
152 ; CHECK:         fmov s0, w[[wReg:[0-9]+]]
153 ; CHECK-NEXT:    scvtf h0, h0, #16
154 ; CHECK-NEXT:    ret
155 entry:
156   %sext = sext i16 %a to i32
157   %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %sext, i32 16)
158   ret half %fcvth_n
161 define dso_local half @test_vcvth_n_f16_s32_1(i32 %a) {
162 ; CHECK-LABEL: test_vcvth_n_f16_s32_1:
163 ; CHECK:         fmov s0, w0
164 ; CHECK-NEXT:    scvtf h0, h0, #1
165 ; CHECK-NEXT:    ret
166 entry:
167   %vcvth_n_f16_s32 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 1)
168   ret half %vcvth_n_f16_s32
171 define dso_local half @test_vcvth_n_f16_s32_16(i32 %a) {
172 ; CHECK-LABEL: test_vcvth_n_f16_s32_16:
173 ; CHECK:         fmov s0, w0
174 ; CHECK-NEXT:    scvtf h0, h0, #16
175 ; CHECK-NEXT:    ret
176 entry:
177   %vcvth_n_f16_s32 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i32(i32 %a, i32 16)
178   ret half %vcvth_n_f16_s32
181 define dso_local i16 @test_vcvth_n_s16_f16_1(half %a) {
182 ; CHECK-LABEL: test_vcvth_n_s16_f16_1:
183 ; CHECK:         fcvtzs h0, h0, #1
184 ; CHECK-NEXT:    fmov w0, s0
185 ; CHECK-NEXT:    ret
186 entry:
187   %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
188   %0 = trunc i32 %fcvth_n to i16
189   ret i16 %0
192 define dso_local i16 @test_vcvth_n_s16_f16_16(half %a) {
193 ; CHECK-LABEL: test_vcvth_n_s16_f16_16:
194 ; CHECK:         fcvtzs h0, h0, #16
195 ; CHECK-NEXT:    fmov w0, s0
196 ; CHECK-NEXT:    ret
197 entry:
198   %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 16)
199   %0 = trunc i32 %fcvth_n to i16
200   ret i16 %0
203 define dso_local i32 @test_vcvth_n_s32_f16_1(half %a) {
204 ; CHECK-LABEL: test_vcvth_n_s32_f16_1:
205 ; CHECK:         fcvtzs h0, h0, #1
206 ; CHECK-NEXT:    fmov w0, s0
207 ; CHECK-NEXT:    ret
208 entry:
209   %vcvth_n_s32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 1)
210   ret i32 %vcvth_n_s32_f16
213 define dso_local i32 @test_vcvth_n_s32_f16_16(half %a) {
214 ; CHECK-LABEL: test_vcvth_n_s32_f16_16:
215 ; CHECK:         fcvtzs h0, h0, #16
216 ; CHECK-NEXT:    fmov w0, s0
217 ; CHECK-NEXT:    ret
218 entry:
219   %vcvth_n_s32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxs.i32.f16(half %a, i32 16)
220   ret i32 %vcvth_n_s32_f16
223 define dso_local i64 @test_vcvth_n_s64_f16_1(half %a) {
224 ; CHECK-LABEL: test_vcvth_n_s64_f16_1:
225 ; CHECK:         fcvtzs h0, h0, #1
226 ; CHECK-NEXT:    fmov x0, d0
227 ; CHECK-NEXT:    ret
228 entry:
229   %vcvth_n_s64_f16 = tail call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 1)
230   ret i64 %vcvth_n_s64_f16
233 define dso_local i64 @test_vcvth_n_s64_f16_32(half %a) {
234 ; CHECK-LABEL: test_vcvth_n_s64_f16_32:
235 ; CHECK:         fcvtzs h0, h0, #32
236 ; CHECK-NEXT:    fmov x0, d0
237 ; CHECK-NEXT:    ret
238 entry:
239   %vcvth_n_s64_f16 = tail call i64 @llvm.aarch64.neon.vcvtfp2fxs.i64.f16(half %a, i32 32)
240   ret i64 %vcvth_n_s64_f16
243 define dso_local half @test_vcvth_n_f16_u16_1(i16 %a) {
244 ; CHECK-LABEL: test_vcvth_n_f16_u16_1:
245 ; CHECK:         ucvtf h0, h0, #1
246 ; CHECK-NEXT:    ret
247 entry:
248   %0 = zext i16 %a to i32
249   %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %0, i32 1)
250   ret half %fcvth_n
253 define dso_local half @test_vcvth_n_f16_u16_16(i16 %a) {
254 ; CHECK-LABEL: test_vcvth_n_f16_u16_16:
255 ; CHECK:         ucvtf h0, h0, #16
256 ; CHECK-NEXT:    ret
257 entry:
258   %0 = zext i16 %a to i32
259   %fcvth_n = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %0, i32 16)
260   ret half %fcvth_n
263 define dso_local half @test_vcvth_n_f16_u32_1(i32 %a) {
264 ; CHECK-LABEL: test_vcvth_n_f16_u32_1:
265 ; CHECK:         fmov s0, w0
266 ; CHECK-NEXT:    ucvtf h0, h0, #1
267 ; CHECK-NEXT:    ret
268 entry:
269   %vcvth_n_f16_u32 = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 1)
270   ret half %vcvth_n_f16_u32
273 define dso_local half @test_vcvth_n_f16_u32_16(i32 %a) {
274 ; CHECK-LABEL: test_vcvth_n_f16_u32_16:
275 ; CHECK:         ucvtf h0, h0, #16
276 ; CHECK-NEXT:    ret
277 entry:
278   %vcvth_n_f16_u32 = tail call half @llvm.aarch64.neon.vcvtfxu2fp.f16.i32(i32 %a, i32 16)
279   ret half %vcvth_n_f16_u32
282 define dso_local i16 @test_vcvth_n_u16_f16_1(half %a) {
283 ; CHECK-LABEL: test_vcvth_n_u16_f16_1:
284 ; CHECK:         fcvtzu h0, h0, #1
285 ; CHECK-NEXT:    fmov w0, s0
286 ; CHECK-NEXT:    ret
287 entry:
288   %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
289   %0 = trunc i32 %fcvth_n to i16
290   ret i16 %0
293 define dso_local i16 @test_vcvth_n_u16_f16_16(half %a) {
294 ; CHECK-LABEL: test_vcvth_n_u16_f16_16:
295 ; CHECK:         fcvtzu h0, h0, #16
296 ; CHECK-NEXT:    fmov w0, s0
297 ; CHECK-NEXT:    ret
298 entry:
299   %fcvth_n = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 16)
300   %0 = trunc i32 %fcvth_n to i16
301   ret i16 %0
304 define dso_local i32 @test_vcvth_n_u32_f16_1(half %a) {
305 ; CHECK-LABEL: test_vcvth_n_u32_f16_1:
306 ; CHECK:         fcvtzu h0, h0, #1
307 ; CHECK-NEXT:    fmov w0, s0
308 ; CHECK-NEXT:    ret
309 entry:
310   %vcvth_n_u32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 1)
311   ret i32 %vcvth_n_u32_f16
314 define dso_local i32 @test_vcvth_n_u32_f16_16(half %a) {
315 ; CHECK-LABEL: test_vcvth_n_u32_f16_16:
316 ; CHECK:         fcvtzu h0, h0, #16
317 ; CHECK-NEXT:    fmov w0, s0
318 ; CHECK-NEXT:    ret
319 entry:
320   %vcvth_n_u32_f16 = tail call i32 @llvm.aarch64.neon.vcvtfp2fxu.i32.f16(half %a, i32 16)
321   ret i32 %vcvth_n_u32_f16
324 define dso_local i16 @vcageh_f16_test(half %a, half %b) {
325 ; CHECK-LABEL: vcageh_f16_test:
326 ; CHECK:        facge   h0, h0, h1
327 ; CHECK-NEXT:   fmov    w0, s0
328 ; CHECK-NEXT:   ret
329 entry:
330   %facg = tail call i32 @llvm.aarch64.neon.facge.i32.f16(half %a, half %b)
331   %0 = trunc i32 %facg to i16
332   ret i16 %0
335 define dso_local i16 @vcagth_f16_test(half %a, half %b) {
336 ; CHECK-LABEL: vcagth_f16_test:
337 ; CHECK:        facgt   h0, h0, h1
338 ; CHECK-NEXT:   fmov    w0, s0
339 ; CHECK-NEXT:   ret
340 entry:
341   %facg = tail call i32 @llvm.aarch64.neon.facgt.i32.f16(half %a, half %b)
342   %0 = trunc i32 %facg to i16
343   ret i16 %0
346 define dso_local half @vcvth_n_f16_s64_test(i64 %a) {
347 ; CHECK-LABEL: vcvth_n_f16_s64_test:
348 ; CHECK:       fmov    d0, x0
349 ; CHECK-NEXT:  scvtf   h0, h0, #16
350 ; CHECK-NEXT:  ret
351 entry:
352   %vcvth_n_f16_s64 = tail call half @llvm.aarch64.neon.vcvtfxs2fp.f16.i64(i64 %a, i32 16)
353   ret half %vcvth_n_f16_s64