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