1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \
3; RUN:   < %s -mtriple=powerpc64-unknown-linux -mcpu=pwr8 | FileCheck %s
4; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \
5; RUN:   < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 | FileCheck %s
6; RUN: llc -verify-machineinstrs -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \
7; RUN:   < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr8 -mattr=-vsx | \
8; RUN:   FileCheck %s -check-prefix=NOVSX
9
10declare i32 @llvm.experimental.constrained.fptosi.i32.f64(double, metadata)
11declare i64 @llvm.experimental.constrained.fptosi.i64.f64(double, metadata)
12declare i64 @llvm.experimental.constrained.fptoui.i64.f64(double, metadata)
13declare i32 @llvm.experimental.constrained.fptoui.i32.f64(double, metadata)
14
15declare i32 @llvm.experimental.constrained.fptosi.i32.f32(float, metadata)
16declare i64 @llvm.experimental.constrained.fptosi.i64.f32(float, metadata)
17declare i64 @llvm.experimental.constrained.fptoui.i64.f32(float, metadata)
18declare i32 @llvm.experimental.constrained.fptoui.i32.f32(float, metadata)
19
20declare double @llvm.experimental.constrained.sitofp.f64.i32(i32, metadata, metadata)
21declare double @llvm.experimental.constrained.sitofp.f64.i64(i64, metadata, metadata)
22declare double @llvm.experimental.constrained.uitofp.f64.i32(i32, metadata, metadata)
23declare double @llvm.experimental.constrained.uitofp.f64.i64(i64, metadata, metadata)
24
25declare float @llvm.experimental.constrained.sitofp.f32.i64(i64, metadata, metadata)
26declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata)
27declare float @llvm.experimental.constrained.uitofp.f32.i32(i32, metadata, metadata)
28declare float @llvm.experimental.constrained.uitofp.f32.i64(i64, metadata, metadata)
29
30define i32 @d_to_i32(double %m) #0 {
31; CHECK-LABEL: d_to_i32:
32; CHECK:       # %bb.0: # %entry
33; CHECK-NEXT:    xscvdpsxws f0, f1
34; CHECK-NEXT:    mffprwz r3, f0
35; CHECK-NEXT:    blr
36;
37; NOVSX-LABEL: d_to_i32:
38; NOVSX:       # %bb.0: # %entry
39; NOVSX-NEXT:    fctiwz f0, f1
40; NOVSX-NEXT:    addi r3, r1, -4
41; NOVSX-NEXT:    stfiwx f0, 0, r3
42; NOVSX-NEXT:    lwz r3, -4(r1)
43; NOVSX-NEXT:    blr
44entry:
45  %conv = call i32 @llvm.experimental.constrained.fptosi.i32.f64(double %m, metadata !"fpexcept.strict") #0
46  ret i32 %conv
47}
48
49define i64 @d_to_i64(double %m) #0 {
50; CHECK-LABEL: d_to_i64:
51; CHECK:       # %bb.0: # %entry
52; CHECK-NEXT:    xscvdpsxds f0, f1
53; CHECK-NEXT:    mffprd r3, f0
54; CHECK-NEXT:    blr
55;
56; NOVSX-LABEL: d_to_i64:
57; NOVSX:       # %bb.0: # %entry
58; NOVSX-NEXT:    fctidz f0, f1
59; NOVSX-NEXT:    stfd f0, -8(r1)
60; NOVSX-NEXT:    ld r3, -8(r1)
61; NOVSX-NEXT:    blr
62entry:
63  %conv = call i64 @llvm.experimental.constrained.fptosi.i64.f64(double %m, metadata !"fpexcept.strict") #0
64  ret i64 %conv
65}
66
67define i64 @d_to_u64(double %m) #0 {
68; CHECK-LABEL: d_to_u64:
69; CHECK:       # %bb.0: # %entry
70; CHECK-NEXT:    xscvdpuxds f0, f1
71; CHECK-NEXT:    mffprd r3, f0
72; CHECK-NEXT:    blr
73;
74; NOVSX-LABEL: d_to_u64:
75; NOVSX:       # %bb.0: # %entry
76; NOVSX-NEXT:    fctiduz f0, f1
77; NOVSX-NEXT:    stfd f0, -8(r1)
78; NOVSX-NEXT:    ld r3, -8(r1)
79; NOVSX-NEXT:    blr
80entry:
81  %conv = call i64 @llvm.experimental.constrained.fptoui.i64.f64(double %m, metadata !"fpexcept.strict") #0
82  ret i64 %conv
83}
84
85define zeroext i32 @d_to_u32(double %m) #0 {
86; CHECK-LABEL: d_to_u32:
87; CHECK:       # %bb.0: # %entry
88; CHECK-NEXT:    xscvdpuxws f0, f1
89; CHECK-NEXT:    mffprwz r3, f0
90; CHECK-NEXT:    clrldi r3, r3, 32
91; CHECK-NEXT:    blr
92;
93; NOVSX-LABEL: d_to_u32:
94; NOVSX:       # %bb.0: # %entry
95; NOVSX-NEXT:    fctiwuz f0, f1
96; NOVSX-NEXT:    addi r3, r1, -4
97; NOVSX-NEXT:    stfiwx f0, 0, r3
98; NOVSX-NEXT:    lwz r3, -4(r1)
99; NOVSX-NEXT:    blr
100entry:
101  %conv = call i32 @llvm.experimental.constrained.fptoui.i32.f64(double %m, metadata !"fpexcept.strict") #0
102  ret i32 %conv
103}
104
105define signext i32 @f_to_i32(float %m) #0 {
106; CHECK-LABEL: f_to_i32:
107; CHECK:       # %bb.0: # %entry
108; CHECK-NEXT:    xscvdpsxws f0, f1
109; CHECK-NEXT:    mffprwz r3, f0
110; CHECK-NEXT:    extsw r3, r3
111; CHECK-NEXT:    blr
112;
113; NOVSX-LABEL: f_to_i32:
114; NOVSX:       # %bb.0: # %entry
115; NOVSX-NEXT:    fctiwz f0, f1
116; NOVSX-NEXT:    addi r3, r1, -4
117; NOVSX-NEXT:    stfiwx f0, 0, r3
118; NOVSX-NEXT:    lwa r3, -4(r1)
119; NOVSX-NEXT:    blr
120entry:
121  %conv = call i32 @llvm.experimental.constrained.fptosi.i32.f32(float %m, metadata !"fpexcept.strict") #0
122  ret i32 %conv
123}
124
125define i64 @f_to_i64(float %m) #0 {
126; CHECK-LABEL: f_to_i64:
127; CHECK:       # %bb.0: # %entry
128; CHECK-NEXT:    xscvdpsxds f0, f1
129; CHECK-NEXT:    mffprd r3, f0
130; CHECK-NEXT:    blr
131;
132; NOVSX-LABEL: f_to_i64:
133; NOVSX:       # %bb.0: # %entry
134; NOVSX-NEXT:    fctidz f0, f1
135; NOVSX-NEXT:    stfd f0, -8(r1)
136; NOVSX-NEXT:    ld r3, -8(r1)
137; NOVSX-NEXT:    blr
138entry:
139  %conv = call i64 @llvm.experimental.constrained.fptosi.i64.f32(float %m, metadata !"fpexcept.strict") #0
140  ret i64 %conv
141}
142
143define i64 @f_to_u64(float %m) #0 {
144; CHECK-LABEL: f_to_u64:
145; CHECK:       # %bb.0: # %entry
146; CHECK-NEXT:    xscvdpuxds f0, f1
147; CHECK-NEXT:    mffprd r3, f0
148; CHECK-NEXT:    blr
149;
150; NOVSX-LABEL: f_to_u64:
151; NOVSX:       # %bb.0: # %entry
152; NOVSX-NEXT:    fctiduz f0, f1
153; NOVSX-NEXT:    stfd f0, -8(r1)
154; NOVSX-NEXT:    ld r3, -8(r1)
155; NOVSX-NEXT:    blr
156entry:
157  %conv = call i64 @llvm.experimental.constrained.fptoui.i64.f32(float %m, metadata !"fpexcept.strict") #0
158  ret i64 %conv
159}
160
161define zeroext i32 @f_to_u32(float %m) #0 {
162; CHECK-LABEL: f_to_u32:
163; CHECK:       # %bb.0: # %entry
164; CHECK-NEXT:    xscvdpuxws f0, f1
165; CHECK-NEXT:    mffprwz r3, f0
166; CHECK-NEXT:    clrldi r3, r3, 32
167; CHECK-NEXT:    blr
168;
169; NOVSX-LABEL: f_to_u32:
170; NOVSX:       # %bb.0: # %entry
171; NOVSX-NEXT:    fctiwuz f0, f1
172; NOVSX-NEXT:    addi r3, r1, -4
173; NOVSX-NEXT:    stfiwx f0, 0, r3
174; NOVSX-NEXT:    lwz r3, -4(r1)
175; NOVSX-NEXT:    blr
176entry:
177  %conv = call i32 @llvm.experimental.constrained.fptoui.i32.f32(float %m, metadata !"fpexcept.strict") #0
178  ret i32 %conv
179}
180
181define double @i32_to_d(i32 signext %m) #0 {
182; CHECK-LABEL: i32_to_d:
183; CHECK:       # %bb.0: # %entry
184; CHECK-NEXT:    mtfprwa f0, r3
185; CHECK-NEXT:    xscvsxddp f1, f0
186; CHECK-NEXT:    blr
187;
188; NOVSX-LABEL: i32_to_d:
189; NOVSX:       # %bb.0: # %entry
190; NOVSX-NEXT:    addi r4, r1, -4
191; NOVSX-NEXT:    stw r3, -4(r1)
192; NOVSX-NEXT:    lfiwax f0, 0, r4
193; NOVSX-NEXT:    fcfid f1, f0
194; NOVSX-NEXT:    blr
195entry:
196  %conv = tail call double @llvm.experimental.constrained.sitofp.f64.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
197  ret double %conv
198}
199
200define double @i64_to_d(i64 %m) #0 {
201; CHECK-LABEL: i64_to_d:
202; CHECK:       # %bb.0: # %entry
203; CHECK-NEXT:    mtfprd f0, r3
204; CHECK-NEXT:    xscvsxddp f1, f0
205; CHECK-NEXT:    blr
206;
207; NOVSX-LABEL: i64_to_d:
208; NOVSX:       # %bb.0: # %entry
209; NOVSX-NEXT:    std r3, -8(r1)
210; NOVSX-NEXT:    lfd f0, -8(r1)
211; NOVSX-NEXT:    fcfid f1, f0
212; NOVSX-NEXT:    blr
213entry:
214  %conv = tail call double @llvm.experimental.constrained.sitofp.f64.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
215  ret double %conv
216}
217
218define double @u32_to_d(i32 zeroext %m) #0 {
219; CHECK-LABEL: u32_to_d:
220; CHECK:       # %bb.0: # %entry
221; CHECK-NEXT:    mtfprwz f0, r3
222; CHECK-NEXT:    xscvuxddp f1, f0
223; CHECK-NEXT:    blr
224;
225; NOVSX-LABEL: u32_to_d:
226; NOVSX:       # %bb.0: # %entry
227; NOVSX-NEXT:    addi r4, r1, -4
228; NOVSX-NEXT:    stw r3, -4(r1)
229; NOVSX-NEXT:    lfiwzx f0, 0, r4
230; NOVSX-NEXT:    fcfidu f1, f0
231; NOVSX-NEXT:    blr
232entry:
233  %conv = tail call double @llvm.experimental.constrained.uitofp.f64.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
234  ret double %conv
235}
236
237define double @u64_to_d(i64 %m) #0 {
238; CHECK-LABEL: u64_to_d:
239; CHECK:       # %bb.0: # %entry
240; CHECK-NEXT:    mtfprd f0, r3
241; CHECK-NEXT:    xscvuxddp f1, f0
242; CHECK-NEXT:    blr
243;
244; NOVSX-LABEL: u64_to_d:
245; NOVSX:       # %bb.0: # %entry
246; NOVSX-NEXT:    std r3, -8(r1)
247; NOVSX-NEXT:    lfd f0, -8(r1)
248; NOVSX-NEXT:    fcfidu f1, f0
249; NOVSX-NEXT:    blr
250entry:
251  %conv = tail call double @llvm.experimental.constrained.uitofp.f64.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
252  ret double %conv
253}
254
255define float @i32_to_f(i32 signext %m) #0 {
256; CHECK-LABEL: i32_to_f:
257; CHECK:       # %bb.0: # %entry
258; CHECK-NEXT:    mtfprwa f0, r3
259; CHECK-NEXT:    xscvsxdsp f1, f0
260; CHECK-NEXT:    blr
261;
262; NOVSX-LABEL: i32_to_f:
263; NOVSX:       # %bb.0: # %entry
264; NOVSX-NEXT:    addi r4, r1, -4
265; NOVSX-NEXT:    stw r3, -4(r1)
266; NOVSX-NEXT:    lfiwax f0, 0, r4
267; NOVSX-NEXT:    fcfids f1, f0
268; NOVSX-NEXT:    blr
269entry:
270  %conv = tail call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
271  ret float %conv
272}
273
274define float @i64_to_f(i64 %m) #0 {
275; CHECK-LABEL: i64_to_f:
276; CHECK:       # %bb.0: # %entry
277; CHECK-NEXT:    mtfprd f0, r3
278; CHECK-NEXT:    xscvsxdsp f1, f0
279; CHECK-NEXT:    blr
280;
281; NOVSX-LABEL: i64_to_f:
282; NOVSX:       # %bb.0: # %entry
283; NOVSX-NEXT:    std r3, -8(r1)
284; NOVSX-NEXT:    lfd f0, -8(r1)
285; NOVSX-NEXT:    fcfids f1, f0
286; NOVSX-NEXT:    blr
287entry:
288  %conv = tail call float @llvm.experimental.constrained.sitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
289  ret float %conv
290}
291
292define float @u32_to_f(i32 zeroext %m) #0 {
293; CHECK-LABEL: u32_to_f:
294; CHECK:       # %bb.0: # %entry
295; CHECK-NEXT:    mtfprwz f0, r3
296; CHECK-NEXT:    xscvuxdsp f1, f0
297; CHECK-NEXT:    blr
298;
299; NOVSX-LABEL: u32_to_f:
300; NOVSX:       # %bb.0: # %entry
301; NOVSX-NEXT:    addi r4, r1, -4
302; NOVSX-NEXT:    stw r3, -4(r1)
303; NOVSX-NEXT:    lfiwzx f0, 0, r4
304; NOVSX-NEXT:    fcfidus f1, f0
305; NOVSX-NEXT:    blr
306entry:
307  %conv = tail call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
308  ret float %conv
309}
310
311define float @u64_to_f(i64 %m) #0 {
312; CHECK-LABEL: u64_to_f:
313; CHECK:       # %bb.0: # %entry
314; CHECK-NEXT:    mtfprd f0, r3
315; CHECK-NEXT:    xscvuxdsp f1, f0
316; CHECK-NEXT:    blr
317;
318; NOVSX-LABEL: u64_to_f:
319; NOVSX:       # %bb.0: # %entry
320; NOVSX-NEXT:    std r3, -8(r1)
321; NOVSX-NEXT:    lfd f0, -8(r1)
322; NOVSX-NEXT:    fcfidus f1, f0
323; NOVSX-NEXT:    blr
324entry:
325  %conv = tail call float @llvm.experimental.constrained.uitofp.f32.i64(i64 %m, metadata !"round.dynamic", metadata !"fpexcept.strict") #0
326  ret float %conv
327}
328
329attributes #0 = { strictfp }
330