xref: /llvm-project/llvm/test/CodeGen/ARM/fp-intrinsics.ll (revision 5c2a133b1342881dc4f42a896e7e5f4b85d20508)
1; RUN: llc -mtriple=armv8a-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP,CHECK-SP-V8,CHECK-DP-V8
2; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOSP,CHECK-NODP
3; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - -mattr=fp-armv8 | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP,CHECK-SP-V8,CHECK-DP-V8
4; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - -mattr=fp-armv8sp | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-NODP,CHECK-SP-V8
5; RUN: llc -mtriple=armv7a-none-eabi %s -o - -mattr=vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP,CHECK-SP-NOV8,CHECK-DP-NOV8
6; RUN: llc -mtriple=thumbv7m-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-NOSP,CHECK-NODP
7; RUN: llc -mtriple=thumbv7m-none-eabi %s -o - -mattr=vfp4 | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-DP,CHECK-SP-NOV8,CHECK-DP-NOV8
8; RUN: llc -mtriple=thumbv7m-none-eabi %s -o - -mattr=vfp4sp | FileCheck %s --check-prefixes=CHECK,CHECK-SP,CHECK-NODP,CHECK-SP-NOV8
9
10; Check that constrained fp intrinsics are correctly lowered. In particular
11; check that the valid combinations of single-precision and double-precision
12; hardware being present or absent work as expected (i.e. we get an instruction
13; when one is available, otherwise a libcall).
14
15; FIXME: We're not generating the right instructions for some of these
16; operations (see further FIXMEs down below).
17
18; Single-precision intrinsics
19
20; CHECK-LABEL: add_f32:
21; CHECK-NOSP: bl __aeabi_fadd
22; CHECK-SP: vadd.f32
23define float @add_f32(float %x, float %y) #0 {
24  %val = call float @llvm.experimental.constrained.fadd.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
25  ret float %val
26}
27
28; CHECK-LABEL: sub_f32:
29; CHECK-NOSP: bl __aeabi_fsub
30; CHECK-SP: vsub.f32
31define float @sub_f32(float %x, float %y) #0 {
32  %val = call float @llvm.experimental.constrained.fsub.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
33  ret float %val
34}
35
36; CHECK-LABEL: mul_f32:
37; CHECK-NOSP: bl __aeabi_fmul
38; CHECK-SP: vmul.f32
39define float @mul_f32(float %x, float %y) #0 {
40  %val = call float @llvm.experimental.constrained.fmul.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
41  ret float %val
42}
43
44; CHECK-LABEL: div_f32:
45; CHECK-NOSP: bl __aeabi_fdiv
46; CHECK-SP: vdiv.f32
47define float @div_f32(float %x, float %y) #0 {
48  %val = call float @llvm.experimental.constrained.fdiv.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
49  ret float %val
50}
51
52; CHECK-LABEL: frem_f32:
53; CHECK: bl fmodf
54define float @frem_f32(float %x, float %y) #0 {
55  %val = call float @llvm.experimental.constrained.frem.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
56  ret float %val
57}
58
59; CHECK-LABEL: fma_f32:
60; CHECK-NOSP: bl fmaf
61; CHECK-SP: vfma.f32
62define float @fma_f32(float %x, float %y, float %z) #0 {
63  %val = call float @llvm.experimental.constrained.fma.f32(float %x, float %y, float %z, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
64  ret float %val
65}
66
67; CHECK-LABEL: fptosi_f32:
68; CHECK-NOSP: bl __aeabi_f2iz
69; CHECK-SP: vcvt.s32.f32
70define i32 @fptosi_f32(float %x) #0 {
71  %val = call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %x, metadata !"fpexcept.strict") #0
72  ret i32 %val
73}
74
75; CHECK-LABEL: fptosi_f32_twice:
76; CHECK-NOSP: bl __aeabi_f2iz
77; CHECK-NOSP: bl __aeabi_f2iz
78; CHECK-SP: vcvt.s32.f32
79; FIXME-CHECK-SP: vcvt.s32.f32
80define void @fptosi_f32_twice(float %arg, ptr %ptr) #0 {
81entry:
82  %conv = call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %arg, metadata !"fpexcept.strict") #0
83  store i32 %conv, ptr %ptr, align 4
84  %conv1 = call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %arg, metadata !"fpexcept.strict") #0
85  %idx = getelementptr inbounds i32, ptr %ptr, i32 1
86  store i32 %conv1, ptr %idx, align 4
87  ret void
88}
89
90; CHECK-LABEL: fptoui_f32:
91; CHECK-NOSP: bl __aeabi_f2uiz
92; FIXME-CHECK-SP: vcvt.u32.f32
93define i32 @fptoui_f32(float %x) #0 {
94  %val = call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %x, metadata !"fpexcept.strict") #0
95  ret i32 %val
96}
97
98; CHECK-LABEL: fptoui_f32_twice:
99; CHECK-NOSP: bl __aeabi_f2uiz
100; CHECK-NOSP: bl __aeabi_f2uiz
101; FIXME-CHECK-SP: vcvt.u32.f32
102; FIXME-CHECK-SP: vcvt.u32.f32
103define void @fptoui_f32_twice(float %arg, ptr %ptr) #0 {
104entry:
105  %conv = call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %arg, metadata !"fpexcept.strict") #0
106  store i32 %conv, ptr %ptr, align 4
107  %conv1 = call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %arg, metadata !"fpexcept.strict") #0
108  %idx = getelementptr inbounds i32, ptr %ptr, i32 1
109  store i32 %conv1, ptr %idx, align 4
110  ret void
111}
112
113; CHECK-LABEL: sqrt_f32:
114; CHECK-NOSP: bl sqrtf
115; CHECK-SP: vsqrt.f32
116define float @sqrt_f32(float %x) #0 {
117  %val = call float @llvm.experimental.constrained.sqrt.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
118  ret float %val
119}
120
121; CHECK-LABEL: powi_f32:
122; CHECK: bl __powisf2
123define float @powi_f32(float %x, i32 %y) #0 {
124  %val = call float @llvm.experimental.constrained.powi.f32(float %x, i32 %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
125  ret float %val
126}
127
128; CHECK-LABEL: sin_f32:
129; CHECK: bl sinf
130define float @sin_f32(float %x) #0 {
131  %val = call float @llvm.experimental.constrained.sin.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
132  ret float %val
133}
134
135; CHECK-LABEL: cos_f32:
136; CHECK: bl cosf
137define float @cos_f32(float %x) #0 {
138  %val = call float @llvm.experimental.constrained.cos.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
139  ret float %val
140}
141
142; CHECK-LABEL: tan_f32:
143; CHECK: bl tanf
144define float @tan_f32(float %x) #0 {
145  %val = call float @llvm.experimental.constrained.tan.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
146  ret float %val
147}
148
149; CHECK-LABEL: atan2_f32:
150; CHECK: bl atan2f
151define float @atan2_f32(float %x, float %y) #0 {
152  %val = call float @llvm.experimental.constrained.atan2.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
153  ret float %val
154}
155
156; CHECK-LABEL: pow_f32:
157; CHECK: bl powf
158define float @pow_f32(float %x, float %y) #0 {
159  %val = call float @llvm.experimental.constrained.pow.f32(float %x, float %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
160  ret float %val
161}
162
163; CHECK-LABEL: log_f32:
164; CHECK: bl logf
165define float @log_f32(float %x) #0 {
166  %val = call float @llvm.experimental.constrained.log.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
167  ret float %val
168}
169
170; CHECK-LABEL: log10_f32:
171; CHECK: bl log10f
172define float @log10_f32(float %x) #0 {
173  %val = call float @llvm.experimental.constrained.log10.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
174  ret float %val
175}
176
177; CHECK-LABEL: log2_f32:
178; CHECK: bl log2f
179define float @log2_f32(float %x) #0 {
180  %val = call float @llvm.experimental.constrained.log2.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
181  ret float %val
182}
183
184; CHECK-LABEL: exp_f32:
185; CHECK: bl expf
186define float @exp_f32(float %x) #0 {
187  %val = call float @llvm.experimental.constrained.exp.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
188  ret float %val
189}
190
191; CHECK-LABEL: exp2_f32:
192; CHECK: bl exp2f
193define float @exp2_f32(float %x) #0 {
194  %val = call float @llvm.experimental.constrained.exp2.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
195  ret float %val
196}
197
198; CHECK-LABEL: rint_f32:
199; CHECK-NOSP: bl rintf
200; CHECK-SP-NOV8: bl rintf
201; CHECK-SP-V8: vrintx.f32
202define float @rint_f32(float %x) #0 {
203  %val = call float @llvm.experimental.constrained.rint.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
204  ret float %val
205}
206
207; CHECK-LABEL: nearbyint_f32:
208; CHECK-NOSP: bl nearbyintf
209; CHECK-SP-NOV8: bl nearbyintf
210; CHECK-SP-V8: vrintr.f32
211define float @nearbyint_f32(float %x) #0 {
212  %val = call float @llvm.experimental.constrained.nearbyint.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
213  ret float %val
214}
215
216; CHECK-LABEL: lrint_f32:
217; CHECK: bl lrintf
218define i32 @lrint_f32(float %x) #0 {
219  %val = call i32 @llvm.experimental.constrained.lrint.i32.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
220  ret i32 %val
221}
222
223; CHECK-LABEL: llrint_f32:
224; CHECK: bl llrintf
225define i32 @llrint_f32(float %x) #0 {
226  %val = call i32 @llvm.experimental.constrained.llrint.i32.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
227  ret i32 %val
228}
229
230; CHECK-LABEL: maxnum_f32:
231; CHECK-NOSP: bl fmaxf
232; CHECK-SP-NOV8: bl fmaxf
233; CHECK-SP-V8: vmaxnm.f32
234define float @maxnum_f32(float %x, float %y) #0 {
235  %val = call float @llvm.experimental.constrained.maxnum.f32(float %x, float %y, metadata !"fpexcept.strict") #0
236  ret float %val
237}
238
239; CHECK-LABEL: minnum_f32:
240; CHECK-NOSP: bl fminf
241; CHECK-SP-NOV8: bl fminf
242; CHECK-SP-V8: vminnm.f32
243define float @minnum_f32(float %x, float %y) #0 {
244  %val = call float @llvm.experimental.constrained.minnum.f32(float %x, float %y, metadata !"fpexcept.strict") #0
245  ret float %val
246}
247
248; CHECK-LABEL: ceil_f32:
249; CHECK-NOSP: bl ceilf
250; CHECK-SP-NOV8: bl ceilf
251; CHECK-SP-V8: vrintp.f32
252define float @ceil_f32(float %x) #0 {
253  %val = call float @llvm.experimental.constrained.ceil.f32(float %x, metadata !"fpexcept.strict") #0
254  ret float %val
255}
256
257; CHECK-LABEL: floor_f32:
258; CHECK-NOSP: bl floorf
259; CHECK-SP-NOV8: bl floorf
260; CHECK-SP-V8: vrintm.f32
261define float @floor_f32(float %x) #0 {
262  %val = call float @llvm.experimental.constrained.floor.f32(float %x, metadata !"fpexcept.strict") #0
263  ret float %val
264}
265
266; CHECK-LABEL: lround_f32:
267; CHECK: bl lroundf
268define i32 @lround_f32(float %x) #0 {
269  %val = call i32 @llvm.experimental.constrained.lround.i32.f32(float %x, metadata !"fpexcept.strict") #0
270  ret i32 %val
271}
272
273; CHECK-LABEL: llround_f32:
274; CHECK: bl llroundf
275define i32 @llround_f32(float %x) #0 {
276  %val = call i32 @llvm.experimental.constrained.llround.i32.f32(float %x, metadata !"fpexcept.strict") #0
277  ret i32 %val
278}
279
280; CHECK-LABEL: round_f32:
281; CHECK-NOSP: bl roundf
282; CHECK-SP-NOV8: bl roundf
283; CHECK-SP-V8: vrinta.f32
284define float @round_f32(float %x) #0 {
285  %val = call float @llvm.experimental.constrained.round.f32(float %x, metadata !"fpexcept.strict") #0
286  ret float %val
287}
288
289; CHECK-LABEL: trunc_f32:
290; CHECK-NOSP: bl truncf
291; CHECK-SP-NOV8: bl truncf
292; CHECK-SP-V8: vrintz.f32
293define float @trunc_f32(float %x) #0 {
294  %val = call float @llvm.experimental.constrained.trunc.f32(float %x, metadata !"fpexcept.strict") #0
295  ret float %val
296}
297
298; CHECK-LABEL: fcmp_olt_f32:
299; CHECK-NOSP: bl __aeabi_fcmplt
300; CHECK-SP: vcmp.f32
301define i32 @fcmp_olt_f32(float %a, float %b) #0 {
302  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"olt", metadata !"fpexcept.strict") #0
303  %conv = zext i1 %cmp to i32
304  ret i32 %conv
305}
306
307; CHECK-LABEL: fcmp_ole_f32:
308; CHECK-NOSP: bl __aeabi_fcmple
309; CHECK-SP: vcmp.f32
310define i32 @fcmp_ole_f32(float %a, float %b) #0 {
311  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ole", metadata !"fpexcept.strict") #0
312  %conv = zext i1 %cmp to i32
313  ret i32 %conv
314}
315
316; CHECK-LABEL: fcmp_ogt_f32:
317; CHECK-NOSP: bl __aeabi_fcmpgt
318; CHECK-SP: vcmp.f32
319define i32 @fcmp_ogt_f32(float %a, float %b) #0 {
320  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ogt", metadata !"fpexcept.strict") #0
321  %conv = zext i1 %cmp to i32
322  ret i32 %conv
323}
324
325; CHECK-LABEL: fcmp_oge_f32:
326; CHECK-NOSP: bl __aeabi_fcmpge
327; CHECK-SP: vcmp.f32
328define i32 @fcmp_oge_f32(float %a, float %b) #0 {
329  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"oge", metadata !"fpexcept.strict") #0
330  %conv = zext i1 %cmp to i32
331  ret i32 %conv
332}
333
334; CHECK-LABEL: fcmp_oeq_f32:
335; CHECK-NOSP: bl __aeabi_fcmpeq
336; CHECK-SP: vcmp.f32
337define i32 @fcmp_oeq_f32(float %a, float %b) #0 {
338  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"oeq", metadata !"fpexcept.strict") #0
339  %conv = zext i1 %cmp to i32
340  ret i32 %conv
341}
342
343; CHECK-LABEL: fcmp_one_f32:
344; CHECK-NOSP: bl __aeabi_fcmpeq
345; CHECK-NOSP: bl __aeabi_fcmpun
346; CHECK-SP: vcmp.f32
347define i32 @fcmp_one_f32(float %a, float %b) #0 {
348  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"one", metadata !"fpexcept.strict") #0
349  %conv = zext i1 %cmp to i32
350  ret i32 %conv
351}
352
353; CHECK-LABEL: fcmp_ult_f32:
354; CHECK-NOSP: bl __aeabi_fcmpge
355; CHECK-SP: vcmp.f32
356define i32 @fcmp_ult_f32(float %a, float %b) #0 {
357  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ult", metadata !"fpexcept.strict") #0
358  %conv = zext i1 %cmp to i32
359  ret i32 %conv
360}
361
362; CHECK-LABEL: fcmp_ule_f32:
363; CHECK-NOSP: bl __aeabi_fcmpgt
364; CHECK-SP: vcmp.f32
365define i32 @fcmp_ule_f32(float %a, float %b) #0 {
366  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ule", metadata !"fpexcept.strict") #0
367  %conv = zext i1 %cmp to i32
368  ret i32 %conv
369}
370
371; CHECK-LABEL: fcmp_ugt_f32:
372; CHECK-NOSP: bl __aeabi_fcmple
373; CHECK-SP: vcmp.f32
374define i32 @fcmp_ugt_f32(float %a, float %b) #0 {
375  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ugt", metadata !"fpexcept.strict") #0
376  %conv = zext i1 %cmp to i32
377  ret i32 %conv
378}
379
380; CHECK-LABEL: fcmp_uge_f32:
381; CHECK-NOSP: bl __aeabi_fcmplt
382; CHECK-SP: vcmp.f32
383define i32 @fcmp_uge_f32(float %a, float %b) #0 {
384  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"uge", metadata !"fpexcept.strict") #0
385  %conv = zext i1 %cmp to i32
386  ret i32 %conv
387}
388
389; CHECK-LABEL: fcmp_ueq_f32:
390; CHECK-NOSP: bl __aeabi_fcmpeq
391; CHECK-NOSP: bl __aeabi_fcmpun
392; CHECK-SP: vcmp.f32
393define i32 @fcmp_ueq_f32(float %a, float %b) #0 {
394  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"ueq", metadata !"fpexcept.strict") #0
395  %conv = zext i1 %cmp to i32
396  ret i32 %conv
397}
398
399; CHECK-LABEL: fcmp_une_f32:
400; CHECK-NOSP: bl __aeabi_fcmpeq
401; CHECK-SP: vcmp.f32
402define i32 @fcmp_une_f32(float %a, float %b) #0 {
403  %cmp = call i1 @llvm.experimental.constrained.fcmp.f32(float %a, float %b, metadata !"une", metadata !"fpexcept.strict") #0
404  %conv = zext i1 %cmp to i32
405  ret i32 %conv
406}
407
408; CHECK-LABEL: fcmps_olt_f32:
409; CHECK-NOSP: bl __aeabi_fcmplt
410; CHECK-SP: vcmpe.f32
411define i32 @fcmps_olt_f32(float %a, float %b) #0 {
412  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"olt", metadata !"fpexcept.strict") #0
413  %conv = zext i1 %cmp to i32
414  ret i32 %conv
415}
416
417; CHECK-LABEL: fcmps_ole_f32:
418; CHECK-NOSP: bl __aeabi_fcmple
419; CHECK-SP: vcmpe.f32
420define i32 @fcmps_ole_f32(float %a, float %b) #0 {
421  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ole", metadata !"fpexcept.strict") #0
422  %conv = zext i1 %cmp to i32
423  ret i32 %conv
424}
425
426; CHECK-LABEL: fcmps_ogt_f32:
427; CHECK-NOSP: bl __aeabi_fcmpgt
428; CHECK-SP: vcmpe.f32
429define i32 @fcmps_ogt_f32(float %a, float %b) #0 {
430  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ogt", metadata !"fpexcept.strict") #0
431  %conv = zext i1 %cmp to i32
432  ret i32 %conv
433}
434
435; CHECK-LABEL: fcmps_oge_f32:
436; CHECK-NOSP: bl __aeabi_fcmpge
437; CHECK-SP: vcmpe.f32
438define i32 @fcmps_oge_f32(float %a, float %b) #0 {
439  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"oge", metadata !"fpexcept.strict") #0
440  %conv = zext i1 %cmp to i32
441  ret i32 %conv
442}
443
444; CHECK-LABEL: fcmps_oeq_f32:
445; CHECK-NOSP: bl __aeabi_fcmpeq
446; CHECK-SP: vcmpe.f32
447define i32 @fcmps_oeq_f32(float %a, float %b) #0 {
448  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"oeq", metadata !"fpexcept.strict") #0
449  %conv = zext i1 %cmp to i32
450  ret i32 %conv
451}
452
453; CHECK-LABEL: fcmps_one_f32:
454; CHECK-NOSP: bl __aeabi_fcmpeq
455; CHECK-NOSP: bl __aeabi_fcmpun
456; CHECK-SP: vcmpe.f32
457define i32 @fcmps_one_f32(float %a, float %b) #0 {
458  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"one", metadata !"fpexcept.strict") #0
459  %conv = zext i1 %cmp to i32
460  ret i32 %conv
461}
462
463; CHECK-LABEL: fcmps_ult_f32:
464; CHECK-NOSP: bl __aeabi_fcmpge
465; CHECK-SP: vcmpe.f32
466define i32 @fcmps_ult_f32(float %a, float %b) #0 {
467  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ult", metadata !"fpexcept.strict") #0
468  %conv = zext i1 %cmp to i32
469  ret i32 %conv
470}
471
472; CHECK-LABEL: fcmps_ule_f32:
473; CHECK-NOSP: bl __aeabi_fcmpgt
474; CHECK-SP: vcmpe.f32
475define i32 @fcmps_ule_f32(float %a, float %b) #0 {
476  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ule", metadata !"fpexcept.strict") #0
477  %conv = zext i1 %cmp to i32
478  ret i32 %conv
479}
480
481; CHECK-LABEL: fcmps_ugt_f32:
482; CHECK-NOSP: bl __aeabi_fcmple
483; CHECK-SP: vcmpe.f32
484define i32 @fcmps_ugt_f32(float %a, float %b) #0 {
485  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ugt", metadata !"fpexcept.strict") #0
486  %conv = zext i1 %cmp to i32
487  ret i32 %conv
488}
489
490; CHECK-LABEL: fcmps_uge_f32:
491; CHECK-NOSP: bl __aeabi_fcmplt
492; CHECK-SP: vcmpe.f32
493define i32 @fcmps_uge_f32(float %a, float %b) #0 {
494  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"uge", metadata !"fpexcept.strict") #0
495  %conv = zext i1 %cmp to i32
496  ret i32 %conv
497}
498
499; CHECK-LABEL: fcmps_ueq_f32:
500; CHECK-NOSP: bl __aeabi_fcmpeq
501; CHECK-NOSP: bl __aeabi_fcmpun
502; CHECK-SP: vcmpe.f32
503define i32 @fcmps_ueq_f32(float %a, float %b) #0 {
504  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"ueq", metadata !"fpexcept.strict") #0
505  %conv = zext i1 %cmp to i32
506  ret i32 %conv
507}
508
509; CHECK-LABEL: fcmps_une_f32:
510; CHECK-NOSP: bl __aeabi_fcmpeq
511; CHECK-SP: vcmpe.f32
512define i32 @fcmps_une_f32(float %a, float %b) #0 {
513  %cmp = call i1 @llvm.experimental.constrained.fcmps.f32(float %a, float %b, metadata !"une", metadata !"fpexcept.strict") #0
514  %conv = zext i1 %cmp to i32
515  ret i32 %conv
516}
517
518
519; Double-precision intrinsics
520
521; CHECK-LABEL: add_f64:
522; CHECK-NODP: bl __aeabi_dadd
523; CHECK-DP: vadd.f64
524define double @add_f64(double %x, double %y) #0 {
525  %val = call double @llvm.experimental.constrained.fadd.f64(double %x, double %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
526  ret double %val
527}
528
529; CHECK-LABEL: sub_f64:
530; CHECK-NODP: bl __aeabi_dsub
531; CHECK-DP: vsub.f64
532define double @sub_f64(double %x, double %y) #0 {
533  %val = call double @llvm.experimental.constrained.fsub.f64(double %x, double %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
534  ret double %val
535}
536
537; CHECK-LABEL: mul_f64:
538; CHECK-NODP: bl __aeabi_dmul
539; CHECK-DP: vmul.f64
540define double @mul_f64(double %x, double %y) #0 {
541  %val = call double @llvm.experimental.constrained.fmul.f64(double %x, double %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
542  ret double %val
543}
544
545; CHECK-LABEL: div_f64:
546; CHECK-NODP: bl __aeabi_ddiv
547; CHECK-DP: vdiv.f64
548define double @div_f64(double %x, double %y) #0 {
549  %val = call double @llvm.experimental.constrained.fdiv.f64(double %x, double %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
550  ret double %val
551}
552
553; CHECK-LABEL: frem_f64:
554; CHECK: bl fmod
555define double @frem_f64(double %x, double %y) #0 {
556  %val = call double @llvm.experimental.constrained.frem.f64(double %x, double %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
557  ret double %val
558}
559
560; CHECK-LABEL: fma_f64:
561; CHECK-NODP: bl fma
562; CHECK-DP: vfma.f64
563define double @fma_f64(double %x, double %y, double %z) #0 {
564  %val = call double @llvm.experimental.constrained.fma.f64(double %x, double %y, double %z, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
565  ret double %val
566}
567
568; CHECK-LABEL: fptosi_f64:
569; CHECK-NODP: bl __aeabi_d2iz
570; CHECK-DP: vcvt.s32.f64
571define i32 @fptosi_f64(double %x) #0 {
572  %val = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %x, metadata !"fpexcept.strict") #0
573  ret i32 %val
574}
575
576; CHECK-LABEL: fptoui_f64:
577; CHECK-NODP: bl __aeabi_d2uiz
578; FIXME-CHECK-DP: vcvt.u32.f64
579define i32 @fptoui_f64(double %x) #0 {
580  %val = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %x, metadata !"fpexcept.strict") #0
581  ret i32 %val
582}
583
584; CHECK-LABEL: sqrt_f64:
585; CHECK-NODP: bl sqrt
586; CHECK-DP: vsqrt.f64
587define double @sqrt_f64(double %x) #0 {
588  %val = call double @llvm.experimental.constrained.sqrt.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
589  ret double %val
590}
591
592; CHECK-LABEL: powi_f64:
593; CHECK: bl __powidf2
594define double @powi_f64(double %x, i32 %y) #0 {
595  %val = call double @llvm.experimental.constrained.powi.f64(double %x, i32 %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
596  ret double %val
597}
598
599; CHECK-LABEL: sin_f64:
600; CHECK: bl sin
601define double @sin_f64(double %x) #0 {
602  %val = call double @llvm.experimental.constrained.sin.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
603  ret double %val
604}
605
606; CHECK-LABEL: cos_f64:
607; CHECK: bl cos
608define double @cos_f64(double %x) #0 {
609  %val = call double @llvm.experimental.constrained.cos.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
610  ret double %val
611}
612
613; CHECK-LABEL: tan_f64:
614; CHECK: bl tan
615define double @tan_f64(double %x) #0 {
616  %val = call double @llvm.experimental.constrained.tan.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
617  ret double %val
618}
619
620; CHECK-LABEL: atan2_f64:
621; CHECK: bl atan2
622define double @atan2_f64(double %x, double %y) #0 {
623  %val = call double @llvm.experimental.constrained.atan2.f64(double %x, double %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
624  ret double %val
625}
626
627; CHECK-LABEL: pow_f64:
628; CHECK: bl pow
629define double @pow_f64(double %x, double %y) #0 {
630  %val = call double @llvm.experimental.constrained.pow.f64(double %x, double %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
631  ret double %val
632}
633
634; CHECK-LABEL: log_f64:
635; CHECK: bl log
636define double @log_f64(double %x) #0 {
637  %val = call double @llvm.experimental.constrained.log.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
638  ret double %val
639}
640
641; CHECK-LABEL: log10_f64:
642; CHECK: bl log10
643define double @log10_f64(double %x) #0 {
644  %val = call double @llvm.experimental.constrained.log10.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
645  ret double %val
646}
647
648; CHECK-LABEL: log2_f64:
649; CHECK: bl log2
650define double @log2_f64(double %x) #0 {
651  %val = call double @llvm.experimental.constrained.log2.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
652  ret double %val
653}
654
655; CHECK-LABEL: exp_f64:
656; CHECK: bl exp
657define double @exp_f64(double %x) #0 {
658  %val = call double @llvm.experimental.constrained.exp.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
659  ret double %val
660}
661
662; CHECK-LABEL: exp2_f64:
663; CHECK: bl exp2
664define double @exp2_f64(double %x) #0 {
665  %val = call double @llvm.experimental.constrained.exp2.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
666  ret double %val
667}
668
669; CHECK-LABEL: rint_f64:
670; CHECK-NODP: bl rint
671; CHECK-DP-NOV8: bl rint
672; CHECK-DP-V8: vrintx.f64
673define double @rint_f64(double %x) #0 {
674  %val = call double @llvm.experimental.constrained.rint.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
675  ret double %val
676}
677
678; CHECK-LABEL: nearbyint_f64:
679; CHECK-NODP: bl nearbyint
680; CHECK-DP-NOV8: bl nearbyint
681; CHECK-DP-V8: vrintr.f64
682define double @nearbyint_f64(double %x) #0 {
683  %val = call double @llvm.experimental.constrained.nearbyint.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
684  ret double %val
685}
686
687; CHECK-LABEL: lrint_f64:
688; CHECK: bl lrint
689define i32 @lrint_f64(double %x) #0 {
690  %val = call i32 @llvm.experimental.constrained.lrint.i32.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
691  ret i32 %val
692}
693
694; CHECK-LABEL: llrint_f64:
695; CHECK: bl llrint
696define i32 @llrint_f64(double %x) #0 {
697  %val = call i32 @llvm.experimental.constrained.llrint.i32.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
698  ret i32 %val
699}
700
701; CHECK-LABEL: maxnum_f64:
702; CHECK-NODP: bl fmax
703; CHECK-DP-NOV8: bl fmax
704; CHECK-DP-V8: vmaxnm.f64
705define double @maxnum_f64(double %x, double %y) #0 {
706  %val = call double @llvm.experimental.constrained.maxnum.f64(double %x, double %y, metadata !"fpexcept.strict") #0
707  ret double %val
708}
709
710; CHECK-LABEL: minnum_f64:
711; CHECK-NODP: bl fmin
712; CHECK-DP-NOV8: bl fmin
713; CHECK-DP-V8: vminnm.f64
714define double @minnum_f64(double %x, double %y) #0 {
715  %val = call double @llvm.experimental.constrained.minnum.f64(double %x, double %y, metadata !"fpexcept.strict") #0
716  ret double %val
717}
718
719; CHECK-LABEL: ceil_f64:
720; CHECK-NODP: bl ceil
721; CHECK-DP-NOV8: bl ceil
722; CHECK-DP-V8: vrintp.f64
723define double @ceil_f64(double %x) #0 {
724  %val = call double @llvm.experimental.constrained.ceil.f64(double %x, metadata !"fpexcept.strict") #0
725  ret double %val
726}
727
728; CHECK-LABEL: floor_f64:
729; CHECK-NODP: bl floor
730; CHECK-DP-NOV8: bl floor
731; CHECK-DP-V8: vrintm.f64
732define double @floor_f64(double %x) #0 {
733  %val = call double @llvm.experimental.constrained.floor.f64(double %x, metadata !"fpexcept.strict") #0
734  ret double %val
735}
736
737; CHECK-LABEL: lround_f64:
738; CHECK: bl lround
739define i32 @lround_f64(double %x) #0 {
740  %val = call i32 @llvm.experimental.constrained.lround.i32.f64(double %x, metadata !"fpexcept.strict") #0
741  ret i32 %val
742}
743
744; CHECK-LABEL: llround_f64:
745; CHECK: bl llround
746define i32 @llround_f64(double %x) #0 {
747  %val = call i32 @llvm.experimental.constrained.llround.i32.f64(double %x, metadata !"fpexcept.strict") #0
748  ret i32 %val
749}
750
751; CHECK-LABEL: round_f64:
752; CHECK-NODP: bl round
753; CHECK-DP-NOV8: bl round
754; CHECK-DP-V8: vrinta.f64
755define double @round_f64(double %x) #0 {
756  %val = call double @llvm.experimental.constrained.round.f64(double %x, metadata !"fpexcept.strict") #0
757  ret double %val
758}
759
760; CHECK-LABEL: trunc_f64:
761; CHECK-NODP: bl trunc
762; CHECK-DP-NOV8: bl trunc
763; CHECK-DP-V8: vrintz.f64
764define double @trunc_f64(double %x) #0 {
765  %val = call double @llvm.experimental.constrained.trunc.f64(double %x, metadata !"fpexcept.strict") #0
766  ret double %val
767}
768
769; CHECK-LABEL: fcmp_olt_f64:
770; CHECK-NODP: bl __aeabi_dcmplt
771; CHECK-DP: vcmp.f64
772define i32 @fcmp_olt_f64(double %a, double %b) #0 {
773  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"olt", metadata !"fpexcept.strict") #0
774  %conv = zext i1 %cmp to i32
775  ret i32 %conv
776}
777
778; CHECK-LABEL: fcmp_ole_f64:
779; CHECK-NODP: bl __aeabi_dcmple
780; CHECK-DP: vcmp.f64
781define i32 @fcmp_ole_f64(double %a, double %b) #0 {
782  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ole", metadata !"fpexcept.strict") #0
783  %conv = zext i1 %cmp to i32
784  ret i32 %conv
785}
786
787; CHECK-LABEL: fcmp_ogt_f64:
788; CHECK-NODP: bl __aeabi_dcmpgt
789; CHECK-DP: vcmp.f64
790define i32 @fcmp_ogt_f64(double %a, double %b) #0 {
791  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ogt", metadata !"fpexcept.strict") #0
792  %conv = zext i1 %cmp to i32
793  ret i32 %conv
794}
795
796; CHECK-LABEL: fcmp_oge_f64:
797; CHECK-NODP: bl __aeabi_dcmpge
798; CHECK-DP: vcmp.f64
799define i32 @fcmp_oge_f64(double %a, double %b) #0 {
800  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oge", metadata !"fpexcept.strict") #0
801  %conv = zext i1 %cmp to i32
802  ret i32 %conv
803}
804
805; CHECK-LABEL: fcmp_oeq_f64:
806; CHECK-NODP: bl __aeabi_dcmpeq
807; CHECK-DP: vcmp.f64
808define i32 @fcmp_oeq_f64(double %a, double %b) #0 {
809  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") #0
810  %conv = zext i1 %cmp to i32
811  ret i32 %conv
812}
813
814; CHECK-LABEL: fcmp_one_f64:
815; CHECK-NODP-DAG: bl __aeabi_dcmpeq
816; CHECK-NODP-DAG: bl __aeabi_dcmpun
817; CHECK-DP: vcmp.f64
818define i32 @fcmp_one_f64(double %a, double %b) #0 {
819  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"one", metadata !"fpexcept.strict") #0
820  %conv = zext i1 %cmp to i32
821  ret i32 %conv
822}
823
824; CHECK-LABEL: fcmp_ult_f64:
825; CHECK-NODP: bl __aeabi_dcmpge
826; CHECK-DP: vcmp.f64
827define i32 @fcmp_ult_f64(double %a, double %b) #0 {
828  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ult", metadata !"fpexcept.strict") #0
829  %conv = zext i1 %cmp to i32
830  ret i32 %conv
831}
832
833; CHECK-LABEL: fcmp_ule_f64:
834; CHECK-NODP: bl __aeabi_dcmpgt
835; CHECK-DP: vcmp.f64
836define i32 @fcmp_ule_f64(double %a, double %b) #0 {
837  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ule", metadata !"fpexcept.strict") #0
838  %conv = zext i1 %cmp to i32
839  ret i32 %conv
840}
841
842; CHECK-LABEL: fcmp_ugt_f64:
843; CHECK-NODP: bl __aeabi_dcmple
844; CHECK-DP: vcmp.f64
845define i32 @fcmp_ugt_f64(double %a, double %b) #0 {
846  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ugt", metadata !"fpexcept.strict") #0
847  %conv = zext i1 %cmp to i32
848  ret i32 %conv
849}
850
851; CHECK-LABEL: fcmp_uge_f64:
852; CHECK-NODP: bl __aeabi_dcmplt
853; CHECK-DP: vcmp.f64
854define i32 @fcmp_uge_f64(double %a, double %b) #0 {
855  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"uge", metadata !"fpexcept.strict") #0
856  %conv = zext i1 %cmp to i32
857  ret i32 %conv
858}
859
860; CHECK-LABEL: fcmp_ueq_f64:
861; CHECK-NODP-DAG: bl __aeabi_dcmpeq
862; CHECK-NODP-DAG: bl __aeabi_dcmpun
863; CHECK-DP: vcmp.f64
864define i32 @fcmp_ueq_f64(double %a, double %b) #0 {
865  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"ueq", metadata !"fpexcept.strict") #0
866  %conv = zext i1 %cmp to i32
867  ret i32 %conv
868}
869
870; CHECK-LABEL: fcmp_une_f64:
871; CHECK-NODP: bl __aeabi_dcmpeq
872; CHECK-DP: vcmp.f64
873define i32 @fcmp_une_f64(double %a, double %b) #0 {
874  %cmp = call i1 @llvm.experimental.constrained.fcmp.f64(double %a, double %b, metadata !"une", metadata !"fpexcept.strict") #0
875  %conv = zext i1 %cmp to i32
876  ret i32 %conv
877}
878
879; CHECK-LABEL: fcmps_olt_f64:
880; CHECK-NODP: bl __aeabi_dcmplt
881; CHECK-DP: vcmpe.f64
882define i32 @fcmps_olt_f64(double %a, double %b) #0 {
883  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"olt", metadata !"fpexcept.strict") #0
884  %conv = zext i1 %cmp to i32
885  ret i32 %conv
886}
887
888; CHECK-LABEL: fcmps_ole_f64:
889; CHECK-NODP: bl __aeabi_dcmple
890; CHECK-DP: vcmpe.f64
891define i32 @fcmps_ole_f64(double %a, double %b) #0 {
892  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ole", metadata !"fpexcept.strict") #0
893  %conv = zext i1 %cmp to i32
894  ret i32 %conv
895}
896
897; CHECK-LABEL: fcmps_ogt_f64:
898; CHECK-NODP: bl __aeabi_dcmpgt
899; CHECK-DP: vcmpe.f64
900define i32 @fcmps_ogt_f64(double %a, double %b) #0 {
901  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ogt", metadata !"fpexcept.strict") #0
902  %conv = zext i1 %cmp to i32
903  ret i32 %conv
904}
905
906; CHECK-LABEL: fcmps_oge_f64:
907; CHECK-NODP: bl __aeabi_dcmpge
908; CHECK-DP: vcmpe.f64
909define i32 @fcmps_oge_f64(double %a, double %b) #0 {
910  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"oge", metadata !"fpexcept.strict") #0
911  %conv = zext i1 %cmp to i32
912  ret i32 %conv
913}
914
915; CHECK-LABEL: fcmps_oeq_f64:
916; CHECK-NODP: bl __aeabi_dcmpeq
917; CHECK-DP: vcmpe.f64
918define i32 @fcmps_oeq_f64(double %a, double %b) #0 {
919  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"oeq", metadata !"fpexcept.strict") #0
920  %conv = zext i1 %cmp to i32
921  ret i32 %conv
922}
923
924; CHECK-LABEL: fcmps_one_f64:
925; CHECK-NODP-DAG: bl __aeabi_dcmpeq
926; CHECK-NODP-DAG: bl __aeabi_dcmpun
927; CHECK-DP: vcmpe.f64
928define i32 @fcmps_one_f64(double %a, double %b) #0 {
929  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"one", metadata !"fpexcept.strict") #0
930  %conv = zext i1 %cmp to i32
931  ret i32 %conv
932}
933
934; CHECK-LABEL: fcmps_ult_f64:
935; CHECK-NODP: bl __aeabi_dcmpge
936; CHECK-DP: vcmpe.f64
937define i32 @fcmps_ult_f64(double %a, double %b) #0 {
938  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ult", metadata !"fpexcept.strict") #0
939  %conv = zext i1 %cmp to i32
940  ret i32 %conv
941}
942
943; CHECK-LABEL: fcmps_ule_f64:
944; CHECK-NODP: bl __aeabi_dcmpgt
945; CHECK-DP: vcmpe.f64
946define i32 @fcmps_ule_f64(double %a, double %b) #0 {
947  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ule", metadata !"fpexcept.strict") #0
948  %conv = zext i1 %cmp to i32
949  ret i32 %conv
950}
951
952; CHECK-LABEL: fcmps_ugt_f64:
953; CHECK-NODP: bl __aeabi_dcmple
954; CHECK-DP: vcmpe.f64
955define i32 @fcmps_ugt_f64(double %a, double %b) #0 {
956  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ugt", metadata !"fpexcept.strict") #0
957  %conv = zext i1 %cmp to i32
958  ret i32 %conv
959}
960
961; CHECK-LABEL: fcmps_uge_f64:
962; CHECK-NODP: bl __aeabi_dcmplt
963; CHECK-DP: vcmpe.f64
964define i32 @fcmps_uge_f64(double %a, double %b) #0 {
965  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"uge", metadata !"fpexcept.strict") #0
966  %conv = zext i1 %cmp to i32
967  ret i32 %conv
968}
969
970; CHECK-LABEL: fcmps_ueq_f64:
971; CHECK-NODP-DAG: bl __aeabi_dcmpeq
972; CHECK-NODP-DAG: bl __aeabi_dcmpun
973; CHECK-DP: vcmpe.f64
974define i32 @fcmps_ueq_f64(double %a, double %b) #0 {
975  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"ueq", metadata !"fpexcept.strict") #0
976  %conv = zext i1 %cmp to i32
977  ret i32 %conv
978}
979
980; CHECK-LABEL: fcmps_une_f64:
981; CHECK-NODP: bl __aeabi_dcmpeq
982; CHECK-DP: vcmpe.f64
983define i32 @fcmps_une_f64(double %a, double %b) #0 {
984  %cmp = call i1 @llvm.experimental.constrained.fcmps.f64(double %a, double %b, metadata !"une", metadata !"fpexcept.strict") #0
985  %conv = zext i1 %cmp to i32
986  ret i32 %conv
987}
988
989
990; Single/Double conversion intrinsics
991
992; CHECK-LABEL: fptrunc_f32:
993; CHECK-NODP: bl __aeabi_d2f
994; CHECK-DP: vcvt.f32.f64
995define float @fptrunc_f32(double %x) #0 {
996  %val = call float @llvm.experimental.constrained.fptrunc.f32.f64(double %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
997  ret float %val
998}
999
1000; CHECK-LABEL: fpext_f32:
1001; CHECK-NODP: bl __aeabi_f2d
1002; CHECK-DP: vcvt.f64.f32
1003define double @fpext_f32(float %x) #0 {
1004  %val = call double @llvm.experimental.constrained.fpext.f64.f32(float %x, metadata !"fpexcept.strict") #0
1005  ret double %val
1006}
1007
1008; CHECK-LABEL: fpext_f32_twice:
1009; CHECK-NODP: bl __aeabi_f2d
1010; CHECK-NODP: bl __aeabi_f2d
1011; CHECK-DP: vcvt.f64.f32
1012; FIXME-CHECK-DP: vcvt.f64.f32
1013define void @fpext_f32_twice(float %arg, ptr %ptr) #0 {
1014entry:
1015  %conv1 = call double @llvm.experimental.constrained.fpext.f64.f32(float %arg, metadata !"fpexcept.strict") #0
1016  store double %conv1, ptr %ptr, align 8
1017  %conv2 = call double @llvm.experimental.constrained.fpext.f64.f32(float %arg, metadata !"fpexcept.strict") #0
1018  %idx = getelementptr inbounds double, ptr %ptr, i32 1
1019  store double %conv2, ptr %idx, align 8
1020  ret void
1021}
1022
1023; CHECK-LABEL: sitofp_f32_i32:
1024; CHECK-NOSP: bl __aeabi_i2f
1025; FIXME-CHECK-SP: vcvt.f32.s32
1026define float @sitofp_f32_i32(i32 %x) #0 {
1027  %val = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
1028  ret float %val
1029}
1030
1031; CHECK-LABEL: sitofp_f64_i32:
1032; FIXME-CHECK-NODP: bl __aeabi_i2d
1033; FIXME-CHECK-DP: vcvt.f64.s32
1034define double @sitofp_f64_i32(i32 %x) #0 {
1035  %val = call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
1036  ret double %val
1037}
1038
1039
1040attributes #0 = { strictfp }
1041
1042declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)
1043declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata)
1044declare float @llvm.experimental.constrained.fmul.f32(float, float, metadata, metadata)
1045declare float @llvm.experimental.constrained.fdiv.f32(float, float, metadata, metadata)
1046declare float @llvm.experimental.constrained.frem.f32(float, float, metadata, metadata)
1047declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata)
1048declare i32 @llvm.experimental.constrained.fptosi.i32.f32(float, metadata)
1049declare i32 @llvm.experimental.constrained.fptoui.i32.f32(float, metadata)
1050declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata)
1051declare float @llvm.experimental.constrained.powi.f32(float, i32, metadata, metadata)
1052declare float @llvm.experimental.constrained.sin.f32(float, metadata, metadata)
1053declare float @llvm.experimental.constrained.cos.f32(float, metadata, metadata)
1054declare float @llvm.experimental.constrained.tan.f32(float, metadata, metadata)
1055declare float @llvm.experimental.constrained.atan2.f32(float, float, metadata, metadata)
1056declare float @llvm.experimental.constrained.pow.f32(float, float, metadata, metadata)
1057declare float @llvm.experimental.constrained.log.f32(float, metadata, metadata)
1058declare float @llvm.experimental.constrained.log10.f32(float, metadata, metadata)
1059declare float @llvm.experimental.constrained.log2.f32(float, metadata, metadata)
1060declare float @llvm.experimental.constrained.exp.f32(float, metadata, metadata)
1061declare float @llvm.experimental.constrained.exp2.f32(float, metadata, metadata)
1062declare float @llvm.experimental.constrained.rint.f32(float, metadata, metadata)
1063declare float @llvm.experimental.constrained.nearbyint.f32(float, metadata, metadata)
1064declare i32 @llvm.experimental.constrained.lrint.i32.f32(float, metadata, metadata)
1065declare i32 @llvm.experimental.constrained.llrint.i32.f32(float, metadata, metadata)
1066declare float @llvm.experimental.constrained.maxnum.f32(float, float, metadata)
1067declare float @llvm.experimental.constrained.minnum.f32(float, float, metadata)
1068declare float @llvm.experimental.constrained.ceil.f32(float, metadata)
1069declare float @llvm.experimental.constrained.floor.f32(float, metadata)
1070declare i32 @llvm.experimental.constrained.lround.i32.f32(float, metadata)
1071declare i32 @llvm.experimental.constrained.llround.i32.f32(float, metadata)
1072declare float @llvm.experimental.constrained.round.f32(float, metadata)
1073declare float @llvm.experimental.constrained.trunc.f32(float, metadata)
1074declare i1 @llvm.experimental.constrained.fcmps.f32(float, float, metadata, metadata)
1075declare i1 @llvm.experimental.constrained.fcmp.f32(float, float, metadata, metadata)
1076
1077declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
1078declare double @llvm.experimental.constrained.fsub.f64(double, double, metadata, metadata)
1079declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)
1080declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
1081declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata)
1082declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata)
1083declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
1084declare i32 @llvm.experimental.constrained.fptoui.i32.f64(double, metadata)
1085declare double @llvm.experimental.constrained.sqrt.f64(double, metadata, metadata)
1086declare double @llvm.experimental.constrained.powi.f64(double, i32, metadata, metadata)
1087declare double @llvm.experimental.constrained.sin.f64(double, metadata, metadata)
1088declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata)
1089declare double @llvm.experimental.constrained.tan.f64(double, metadata, metadata)
1090declare double @llvm.experimental.constrained.atan2.f64(double, double, metadata, metadata)
1091declare double @llvm.experimental.constrained.pow.f64(double, double, metadata, metadata)
1092declare double @llvm.experimental.constrained.log.f64(double, metadata, metadata)
1093declare double @llvm.experimental.constrained.log10.f64(double, metadata, metadata)
1094declare double @llvm.experimental.constrained.log2.f64(double, metadata, metadata)
1095declare double @llvm.experimental.constrained.exp.f64(double, metadata, metadata)
1096declare double @llvm.experimental.constrained.exp2.f64(double, metadata, metadata)
1097declare double @llvm.experimental.constrained.rint.f64(double, metadata, metadata)
1098declare double @llvm.experimental.constrained.nearbyint.f64(double, metadata, metadata)
1099declare i32 @llvm.experimental.constrained.lrint.i32.f64(double, metadata, metadata)
1100declare i32 @llvm.experimental.constrained.llrint.i32.f64(double, metadata, metadata)
1101declare double @llvm.experimental.constrained.maxnum.f64(double, double, metadata)
1102declare double @llvm.experimental.constrained.minnum.f64(double, double, metadata)
1103declare double @llvm.experimental.constrained.ceil.f64(double, metadata)
1104declare double @llvm.experimental.constrained.floor.f64(double, metadata)
1105declare i32 @llvm.experimental.constrained.lround.i32.f64(double, metadata)
1106declare i32 @llvm.experimental.constrained.llround.i32.f64(double, metadata)
1107declare double @llvm.experimental.constrained.round.f64(double, metadata)
1108declare double @llvm.experimental.constrained.trunc.f64(double, metadata)
1109declare i1 @llvm.experimental.constrained.fcmps.f64(double, double, metadata, metadata)
1110declare i1 @llvm.experimental.constrained.fcmp.f64(double, double, metadata, metadata)
1111
1112declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata)
1113declare double @llvm.experimental.constrained.fpext.f64.f32(float, metadata)
1114declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata)
1115declare double @llvm.experimental.constrained.sitofp.f64.i32(i32, metadata, metadata)
1116