1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux \
3; RUN:   -mcpu=pwr8 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr  | FileCheck \
4; RUN:   --check-prefix=P8 %s
5; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux \
6; RUN:   -mcpu=pwr9 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr | FileCheck \
7; RUN:   --check-prefix=P9 %s
8
9; FIXME: Constrained fpext would fail if VSX feature disabled. Add no-vsx
10
11declare float @llvm.experimental.constrained.ceil.f32(float, metadata)
12declare double @llvm.experimental.constrained.ceil.f64(double, metadata)
13declare <4 x float> @llvm.experimental.constrained.ceil.v4f32(<4 x float>, metadata)
14declare <2 x double> @llvm.experimental.constrained.ceil.v2f64(<2 x double>, metadata)
15
16declare float @llvm.experimental.constrained.floor.f32(float, metadata)
17declare double @llvm.experimental.constrained.floor.f64(double, metadata)
18declare <4 x float> @llvm.experimental.constrained.floor.v4f32(<4 x float>, metadata)
19declare <2 x double> @llvm.experimental.constrained.floor.v2f64(<2 x double>, metadata)
20
21declare double @llvm.experimental.constrained.nearbyint.f64(double, metadata, metadata)
22declare <4 x float> @llvm.experimental.constrained.nearbyint.v4f32(<4 x float>, metadata, metadata)
23declare <2 x double> @llvm.experimental.constrained.nearbyint.v2f64(<2 x double>, metadata, metadata)
24
25declare <4 x double> @llvm.experimental.constrained.fpext.v4f64.v4f32(<4 x float>, metadata)
26declare <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f32(<2 x float>, metadata)
27
28declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata)
29declare <4 x float> @llvm.experimental.constrained.fptrunc.v4f32.v4f64(<4 x double>, metadata, metadata)
30declare <2 x float> @llvm.experimental.constrained.fptrunc.v2f32.v2f64(<2 x double>, metadata, metadata)
31
32declare float @llvm.experimental.constrained.round.f32(float, metadata)
33declare double @llvm.experimental.constrained.round.f64(double, metadata)
34declare <4 x float> @llvm.experimental.constrained.round.v4f32(<4 x float>, metadata)
35declare <2 x double> @llvm.experimental.constrained.round.v2f64(<2 x double>, metadata)
36
37declare float @llvm.experimental.constrained.trunc.f32(float, metadata)
38declare double @llvm.experimental.constrained.trunc.f64(double, metadata)
39declare <4 x float> @llvm.experimental.constrained.trunc.v4f32(<4 x float>, metadata)
40declare <2 x double> @llvm.experimental.constrained.trunc.v2f64(<2 x double>, metadata)
41
42define float @ceil_f32(float %f1) {
43; P8-LABEL: ceil_f32:
44; P8:       # %bb.0:
45; P8-NEXT:    xsrdpip f1, f1
46; P8-NEXT:    blr
47;
48; P9-LABEL: ceil_f32:
49; P9:       # %bb.0:
50; P9-NEXT:    xsrdpip f1, f1
51; P9-NEXT:    blr
52  %res = call float @llvm.experimental.constrained.ceil.f32(
53                        float %f1,
54                        metadata !"fpexcept.strict")
55  ret float %res
56}
57
58define double @ceil_f64(double %f1) {
59; P8-LABEL: ceil_f64:
60; P8:       # %bb.0:
61; P8-NEXT:    xsrdpip f1, f1
62; P8-NEXT:    blr
63;
64; P9-LABEL: ceil_f64:
65; P9:       # %bb.0:
66; P9-NEXT:    xsrdpip f1, f1
67; P9-NEXT:    blr
68  %res = call double @llvm.experimental.constrained.ceil.f64(
69                        double %f1,
70                        metadata !"fpexcept.strict")
71  ret double %res
72}
73
74define <4 x float> @ceil_v4f32(<4 x float> %vf1) {
75; P8-LABEL: ceil_v4f32:
76; P8:       # %bb.0:
77; P8-NEXT:    xvrspip v2, v2
78; P8-NEXT:    blr
79;
80; P9-LABEL: ceil_v4f32:
81; P9:       # %bb.0:
82; P9-NEXT:    xvrspip v2, v2
83; P9-NEXT:    blr
84  %res = call <4 x float> @llvm.experimental.constrained.ceil.v4f32(
85                        <4 x float> %vf1,
86                        metadata !"fpexcept.strict")
87  ret <4 x float> %res
88}
89
90define <2 x double> @ceil_v2f64(<2 x double> %vf1) {
91; P8-LABEL: ceil_v2f64:
92; P8:       # %bb.0:
93; P8-NEXT:    xvrdpip v2, v2
94; P8-NEXT:    blr
95;
96; P9-LABEL: ceil_v2f64:
97; P9:       # %bb.0:
98; P9-NEXT:    xvrdpip v2, v2
99; P9-NEXT:    blr
100  %res = call <2 x double> @llvm.experimental.constrained.ceil.v2f64(
101                        <2 x double> %vf1,
102                        metadata !"fpexcept.strict")
103  ret <2 x double> %res
104}
105
106define float @floor_f32(float %f1) {
107; P8-LABEL: floor_f32:
108; P8:       # %bb.0:
109; P8-NEXT:    xsrdpim f1, f1
110; P8-NEXT:    blr
111;
112; P9-LABEL: floor_f32:
113; P9:       # %bb.0:
114; P9-NEXT:    xsrdpim f1, f1
115; P9-NEXT:    blr
116  %res = call float @llvm.experimental.constrained.floor.f32(
117                        float %f1,
118                        metadata !"fpexcept.strict")
119  ret float %res
120}
121
122define double @floor_f64(double %f1) {
123; P8-LABEL: floor_f64:
124; P8:       # %bb.0:
125; P8-NEXT:    xsrdpim f1, f1
126; P8-NEXT:    blr
127;
128; P9-LABEL: floor_f64:
129; P9:       # %bb.0:
130; P9-NEXT:    xsrdpim f1, f1
131; P9-NEXT:    blr
132  %res = call double @llvm.experimental.constrained.floor.f64(
133                        double %f1,
134                        metadata !"fpexcept.strict")
135  ret double %res;
136}
137
138define <4 x float> @floor_v4f32(<4 x float> %vf1) {
139; P8-LABEL: floor_v4f32:
140; P8:       # %bb.0:
141; P8-NEXT:    xvrspim v2, v2
142; P8-NEXT:    blr
143;
144; P9-LABEL: floor_v4f32:
145; P9:       # %bb.0:
146; P9-NEXT:    xvrspim v2, v2
147; P9-NEXT:    blr
148  %res = call <4 x float> @llvm.experimental.constrained.floor.v4f32(
149                        <4 x float> %vf1,
150                        metadata !"fpexcept.strict")
151  ret <4 x float> %res;
152}
153
154define <2 x double> @floor_v2f64(<2 x double> %vf1) {
155; P8-LABEL: floor_v2f64:
156; P8:       # %bb.0:
157; P8-NEXT:    xvrdpim v2, v2
158; P8-NEXT:    blr
159;
160; P9-LABEL: floor_v2f64:
161; P9:       # %bb.0:
162; P9-NEXT:    xvrdpim v2, v2
163; P9-NEXT:    blr
164  %res = call <2 x double> @llvm.experimental.constrained.floor.v2f64(
165                        <2 x double> %vf1,
166                        metadata !"fpexcept.strict")
167  ret <2 x double> %res;
168}
169
170define double @nearbyint_f64(double %f1, double %f2) {
171; P8-LABEL: nearbyint_f64:
172; P8:       # %bb.0:
173; P8-NEXT:    xsrdpic f1, f1
174; P8-NEXT:    blr
175;
176; P9-LABEL: nearbyint_f64:
177; P9:       # %bb.0:
178; P9-NEXT:    xsrdpic f1, f1
179; P9-NEXT:    blr
180  %res = call double @llvm.experimental.constrained.nearbyint.f64(
181                        double %f1,
182                        metadata !"round.dynamic",
183                        metadata !"fpexcept.strict")
184  ret double %res
185}
186
187define <4 x float> @nearbyint_v4f32(<4 x float> %vf1, <4 x float> %vf2) {
188; P8-LABEL: nearbyint_v4f32:
189; P8:       # %bb.0:
190; P8-NEXT:    xvrspic v2, v2
191; P8-NEXT:    blr
192;
193; P9-LABEL: nearbyint_v4f32:
194; P9:       # %bb.0:
195; P9-NEXT:    xvrspic v2, v2
196; P9-NEXT:    blr
197  %res = call <4 x float> @llvm.experimental.constrained.nearbyint.v4f32(
198                        <4 x float> %vf1,
199                        metadata !"round.dynamic",
200                        metadata !"fpexcept.strict")
201  ret <4 x float> %res
202}
203
204define <2 x double> @nearbyint_v2f64(<2 x double> %vf1, <2 x double> %vf2) {
205; P8-LABEL: nearbyint_v2f64:
206; P8:       # %bb.0:
207; P8-NEXT:    xvrdpic v2, v2
208; P8-NEXT:    blr
209;
210; P9-LABEL: nearbyint_v2f64:
211; P9:       # %bb.0:
212; P9-NEXT:    xvrdpic v2, v2
213; P9-NEXT:    blr
214  %res = call <2 x double> @llvm.experimental.constrained.nearbyint.v2f64(
215                        <2 x double> %vf1,
216                        metadata !"round.dynamic",
217                        metadata !"fpexcept.strict")
218  ret <2 x double> %res
219}
220
221define <4 x double> @fpext_v4f64_v4f32(<4 x float> %vf1) {
222; P8-LABEL: fpext_v4f64_v4f32:
223; P8:       # %bb.0:
224; P8-NEXT:    xxsldwi vs0, v2, v2, 1
225; P8-NEXT:    xxsldwi vs1, v2, v2, 3
226; P8-NEXT:    xxswapd vs3, v2
227; P8-NEXT:    xscvspdpn f2, v2
228; P8-NEXT:    xscvspdpn f0, vs0
229; P8-NEXT:    xscvspdpn f1, vs1
230; P8-NEXT:    xscvspdpn f3, vs3
231; P8-NEXT:    xxmrghd v2, vs2, vs0
232; P8-NEXT:    xxmrghd v3, vs3, vs1
233; P8-NEXT:    blr
234;
235; P9-LABEL: fpext_v4f64_v4f32:
236; P9:       # %bb.0:
237; P9-NEXT:    xxsldwi vs0, v2, v2, 3
238; P9-NEXT:    xxswapd vs1, v2
239; P9-NEXT:    xscvspdpn f0, vs0
240; P9-NEXT:    xscvspdpn f1, vs1
241; P9-NEXT:    xxsldwi vs2, v2, v2, 1
242; P9-NEXT:    xscvspdpn f2, vs2
243; P9-NEXT:    xxmrghd vs0, vs1, vs0
244; P9-NEXT:    xscvspdpn f1, v2
245; P9-NEXT:    xxmrghd v3, vs1, vs2
246; P9-NEXT:    xxlor v2, vs0, vs0
247; P9-NEXT:    blr
248  %res = call <4 x double> @llvm.experimental.constrained.fpext.v4f64.v4f32(
249                        <4 x float> %vf1,
250                        metadata !"fpexcept.strict")
251  ret <4 x double> %res
252}
253
254define <2 x double> @fpext_v2f64_v2f32(<2 x float> %vf1) {
255; P8-LABEL: fpext_v2f64_v2f32:
256; P8:       # %bb.0:
257; P8-NEXT:    xxsldwi vs0, v2, v2, 1
258; P8-NEXT:    xscvspdpn f1, v2
259; P8-NEXT:    xscvspdpn f0, vs0
260; P8-NEXT:    xxmrghd v2, vs1, vs0
261; P8-NEXT:    blr
262;
263; P9-LABEL: fpext_v2f64_v2f32:
264; P9:       # %bb.0:
265; P9-NEXT:    xxsldwi vs0, v2, v2, 3
266; P9-NEXT:    xxswapd vs1, v2
267; P9-NEXT:    xscvspdpn f0, vs0
268; P9-NEXT:    xscvspdpn f1, vs1
269; P9-NEXT:    xxmrghd v2, vs1, vs0
270; P9-NEXT:    blr
271  %res = call <2 x double> @llvm.experimental.constrained.fpext.v2f64.v2f32(
272                        <2 x float> %vf1,
273                        metadata !"fpexcept.strict")
274  ret <2 x double> %res
275}
276
277define float @fptrunc_f32_f64(double %f1) {
278; P8-LABEL: fptrunc_f32_f64:
279; P8:       # %bb.0:
280; P8-NEXT:    xsrsp f1, f1
281; P8-NEXT:    blr
282;
283; P9-LABEL: fptrunc_f32_f64:
284; P9:       # %bb.0:
285; P9-NEXT:    xsrsp f1, f1
286; P9-NEXT:    blr
287  %res = call float @llvm.experimental.constrained.fptrunc.f32.f64(
288                        double %f1,
289                        metadata !"round.dynamic",
290                        metadata !"fpexcept.strict")
291  ret float %res;
292}
293
294define <4 x float> @fptrunc_v4f32_v4f64(<4 x double> %vf1) {
295; P8-LABEL: fptrunc_v4f32_v4f64:
296; P8:       # %bb.0:
297; P8-NEXT:    xxmrgld vs0, v2, v3
298; P8-NEXT:    xxmrghd vs1, v2, v3
299; P8-NEXT:    xvcvdpsp v2, vs0
300; P8-NEXT:    xvcvdpsp v3, vs1
301; P8-NEXT:    vmrgew v2, v3, v2
302; P8-NEXT:    blr
303;
304; P9-LABEL: fptrunc_v4f32_v4f64:
305; P9:       # %bb.0:
306; P9-NEXT:    xxmrgld vs0, v3, v2
307; P9-NEXT:    xvcvdpsp v4, vs0
308; P9-NEXT:    xxmrghd vs0, v3, v2
309; P9-NEXT:    xvcvdpsp v2, vs0
310; P9-NEXT:    vmrgew v2, v2, v4
311; P9-NEXT:    blr
312  %res = call <4 x float> @llvm.experimental.constrained.fptrunc.v4f32.v4f64(
313                        <4 x double> %vf1,
314                        metadata !"round.dynamic",
315                        metadata !"fpexcept.strict")
316  ret <4 x float> %res
317}
318
319define <2 x float> @fptrunc_v2f32_v2f64(<2 x double> %vf1) {
320; P8-LABEL: fptrunc_v2f32_v2f64:
321; P8:       # %bb.0:
322; P8-NEXT:    xxswapd vs0, v2
323; P8-NEXT:    xsrsp f1, v2
324; P8-NEXT:    xsrsp f0, f0
325; P8-NEXT:    xscvdpspn v2, f1
326; P8-NEXT:    xscvdpspn v3, f0
327; P8-NEXT:    vmrghw v2, v2, v3
328; P8-NEXT:    blr
329;
330; P9-LABEL: fptrunc_v2f32_v2f64:
331; P9:       # %bb.0:
332; P9-NEXT:    xsrsp f0, v2
333; P9-NEXT:    xscvdpspn vs0, f0
334; P9-NEXT:    xxsldwi v3, vs0, vs0, 3
335; P9-NEXT:    xxswapd vs0, v2
336; P9-NEXT:    xsrsp f0, f0
337; P9-NEXT:    xscvdpspn vs0, f0
338; P9-NEXT:    xxsldwi v2, vs0, vs0, 3
339; P9-NEXT:    vmrghw v2, v3, v2
340; P9-NEXT:    blr
341  %res = call <2 x float> @llvm.experimental.constrained.fptrunc.v2f32.v2f64(
342                        <2 x double> %vf1,
343                        metadata !"round.dynamic",
344                        metadata !"fpexcept.strict")
345  ret <2 x float> %res
346}
347
348define float @round_f32(float %f1) {
349; P8-LABEL: round_f32:
350; P8:       # %bb.0:
351; P8-NEXT:    xsrdpi f1, f1
352; P8-NEXT:    blr
353;
354; P9-LABEL: round_f32:
355; P9:       # %bb.0:
356; P9-NEXT:    xsrdpi f1, f1
357; P9-NEXT:    blr
358  %res = call float @llvm.experimental.constrained.round.f32(
359                        float %f1,
360                        metadata !"fpexcept.strict")
361  ret float %res
362}
363
364define double @round_f64(double %f1) {
365; P8-LABEL: round_f64:
366; P8:       # %bb.0:
367; P8-NEXT:    xsrdpi f1, f1
368; P8-NEXT:    blr
369;
370; P9-LABEL: round_f64:
371; P9:       # %bb.0:
372; P9-NEXT:    xsrdpi f1, f1
373; P9-NEXT:    blr
374  %res = call double @llvm.experimental.constrained.round.f64(
375                        double %f1,
376                        metadata !"fpexcept.strict")
377  ret double %res
378}
379
380define <4 x float> @round_v4f32(<4 x float> %vf1) {
381; P8-LABEL: round_v4f32:
382; P8:       # %bb.0:
383; P8-NEXT:    xvrspi v2, v2
384; P8-NEXT:    blr
385;
386; P9-LABEL: round_v4f32:
387; P9:       # %bb.0:
388; P9-NEXT:    xvrspi v2, v2
389; P9-NEXT:    blr
390  %res = call <4 x float> @llvm.experimental.constrained.round.v4f32(
391                        <4 x float> %vf1,
392                        metadata !"fpexcept.strict")
393  ret <4 x float> %res
394}
395
396define <2 x double> @round_v2f64(<2 x double> %vf1) {
397; P8-LABEL: round_v2f64:
398; P8:       # %bb.0:
399; P8-NEXT:    xvrdpi v2, v2
400; P8-NEXT:    blr
401;
402; P9-LABEL: round_v2f64:
403; P9:       # %bb.0:
404; P9-NEXT:    xvrdpi v2, v2
405; P9-NEXT:    blr
406  %res = call <2 x double> @llvm.experimental.constrained.round.v2f64(
407                        <2 x double> %vf1,
408                        metadata !"fpexcept.strict")
409  ret <2 x double> %res
410}
411
412define float @trunc_f32(float %f1) {
413; P8-LABEL: trunc_f32:
414; P8:       # %bb.0:
415; P8-NEXT:    xsrdpiz f1, f1
416; P8-NEXT:    blr
417;
418; P9-LABEL: trunc_f32:
419; P9:       # %bb.0:
420; P9-NEXT:    xsrdpiz f1, f1
421; P9-NEXT:    blr
422  %res = call float @llvm.experimental.constrained.trunc.f32(
423                        float %f1,
424                        metadata !"fpexcept.strict")
425  ret float %res
426}
427
428define double @trunc_f64(double %f1) {
429; P8-LABEL: trunc_f64:
430; P8:       # %bb.0:
431; P8-NEXT:    xsrdpiz f1, f1
432; P8-NEXT:    blr
433;
434; P9-LABEL: trunc_f64:
435; P9:       # %bb.0:
436; P9-NEXT:    xsrdpiz f1, f1
437; P9-NEXT:    blr
438  %res = call double @llvm.experimental.constrained.trunc.f64(
439                        double %f1,
440                        metadata !"fpexcept.strict")
441  ret double %res
442}
443
444define <4 x float> @trunc_v4f32(<4 x float> %vf1) {
445; P8-LABEL: trunc_v4f32:
446; P8:       # %bb.0:
447; P8-NEXT:    xvrspiz v2, v2
448; P8-NEXT:    blr
449;
450; P9-LABEL: trunc_v4f32:
451; P9:       # %bb.0:
452; P9-NEXT:    xvrspiz v2, v2
453; P9-NEXT:    blr
454  %res = call <4 x float> @llvm.experimental.constrained.trunc.v4f32(
455                        <4 x float> %vf1,
456                        metadata !"fpexcept.strict")
457  ret <4 x float> %res
458}
459
460define <2 x double> @trunc_v2f64(<2 x double> %vf1) {
461; P8-LABEL: trunc_v2f64:
462; P8:       # %bb.0:
463; P8-NEXT:    xvrdpiz v2, v2
464; P8-NEXT:    blr
465;
466; P9-LABEL: trunc_v2f64:
467; P9:       # %bb.0:
468; P9-NEXT:    xvrdpiz v2, v2
469; P9-NEXT:    blr
470  %res = call <2 x double> @llvm.experimental.constrained.trunc.v2f64(
471                        <2 x double> %vf1,
472                        metadata !"fpexcept.strict")
473  ret <2 x double> %res
474}
475