1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc --mtriple=loongarch32 --mattr=+d < %s | FileCheck %s --check-prefix=LA32
3; RUN: llc --mtriple=loongarch64 --mattr=+d < %s | FileCheck %s --check-prefix=LA64
4
5define float @convert_double_to_float(double %a) nounwind {
6; LA32-LABEL: convert_double_to_float:
7; LA32:       # %bb.0:
8; LA32-NEXT:    fcvt.s.d $fa0, $fa0
9; LA32-NEXT:    jirl $zero, $ra, 0
10;
11; LA64-LABEL: convert_double_to_float:
12; LA64:       # %bb.0:
13; LA64-NEXT:    fcvt.s.d $fa0, $fa0
14; LA64-NEXT:    jirl $zero, $ra, 0
15  %1 = fptrunc double %a to float
16  ret float %1
17}
18
19define double @convert_float_to_double(float %a) nounwind {
20; LA32-LABEL: convert_float_to_double:
21; LA32:       # %bb.0:
22; LA32-NEXT:    fcvt.d.s $fa0, $fa0
23; LA32-NEXT:    jirl $zero, $ra, 0
24;
25; LA64-LABEL: convert_float_to_double:
26; LA64:       # %bb.0:
27; LA64-NEXT:    fcvt.d.s $fa0, $fa0
28; LA64-NEXT:    jirl $zero, $ra, 0
29  %1 = fpext float %a to double
30  ret double %1
31}
32
33define double @convert_i8_to_double(i8 signext %a) nounwind {
34; LA32-LABEL: convert_i8_to_double:
35; LA32:       # %bb.0:
36; LA32-NEXT:    movgr2fr.w $fa0, $a0
37; LA32-NEXT:    ffint.d.w $fa0, $fa0
38; LA32-NEXT:    jirl $zero, $ra, 0
39;
40; LA64-LABEL: convert_i8_to_double:
41; LA64:       # %bb.0:
42; LA64-NEXT:    movgr2fr.w $fa0, $a0
43; LA64-NEXT:    ffint.d.w $fa0, $fa0
44; LA64-NEXT:    jirl $zero, $ra, 0
45  %1 = sitofp i8 %a to double
46  ret double %1
47}
48
49define double @convert_i16_to_double(i16 signext %a) nounwind {
50; LA32-LABEL: convert_i16_to_double:
51; LA32:       # %bb.0:
52; LA32-NEXT:    movgr2fr.w $fa0, $a0
53; LA32-NEXT:    ffint.d.w $fa0, $fa0
54; LA32-NEXT:    jirl $zero, $ra, 0
55;
56; LA64-LABEL: convert_i16_to_double:
57; LA64:       # %bb.0:
58; LA64-NEXT:    movgr2fr.w $fa0, $a0
59; LA64-NEXT:    ffint.d.w $fa0, $fa0
60; LA64-NEXT:    jirl $zero, $ra, 0
61  %1 = sitofp i16 %a to double
62  ret double %1
63}
64
65define double @convert_i32_to_double(i32 %a) nounwind {
66; LA32-LABEL: convert_i32_to_double:
67; LA32:       # %bb.0:
68; LA32-NEXT:    movgr2fr.w $fa0, $a0
69; LA32-NEXT:    ffint.d.w $fa0, $fa0
70; LA32-NEXT:    jirl $zero, $ra, 0
71;
72; LA64-LABEL: convert_i32_to_double:
73; LA64:       # %bb.0:
74; LA64-NEXT:    movgr2fr.w $fa0, $a0
75; LA64-NEXT:    ffint.d.w $fa0, $fa0
76; LA64-NEXT:    jirl $zero, $ra, 0
77  %1 = sitofp i32 %a to double
78  ret double %1
79}
80
81define double @convert_i64_to_double(i64 %a) nounwind {
82; LA32-LABEL: convert_i64_to_double:
83; LA32:       # %bb.0:
84; LA32-NEXT:    addi.w $sp, $sp, -16
85; LA32-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
86; LA32-NEXT:    bl __floatdidf
87; LA32-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
88; LA32-NEXT:    addi.w $sp, $sp, 16
89; LA32-NEXT:    jirl $zero, $ra, 0
90;
91; LA64-LABEL: convert_i64_to_double:
92; LA64:       # %bb.0:
93; LA64-NEXT:    movgr2fr.d $fa0, $a0
94; LA64-NEXT:    ffint.d.l $fa0, $fa0
95; LA64-NEXT:    jirl $zero, $ra, 0
96  %1 = sitofp i64 %a to double
97  ret double %1
98}
99
100define i32 @convert_double_to_i32(double %a) nounwind {
101; LA32-LABEL: convert_double_to_i32:
102; LA32:       # %bb.0:
103; LA32-NEXT:    ftintrz.w.d $fa0, $fa0
104; LA32-NEXT:    movfr2gr.s $a0, $fa0
105; LA32-NEXT:    jirl $zero, $ra, 0
106;
107; LA64-LABEL: convert_double_to_i32:
108; LA64:       # %bb.0:
109; LA64-NEXT:    ftintrz.w.d $fa0, $fa0
110; LA64-NEXT:    movfr2gr.s $a0, $fa0
111; LA64-NEXT:    jirl $zero, $ra, 0
112  %1 = fptosi double %a to i32
113  ret i32 %1
114}
115
116define i32 @convert_double_to_u32(double %a) nounwind {
117; LA32-LABEL: convert_double_to_u32:
118; LA32:       # %bb.0:
119; LA32-NEXT:    pcalau12i $a0, .LCPI7_0
120; LA32-NEXT:    addi.w $a0, $a0, .LCPI7_0
121; LA32-NEXT:    fld.d $fa1, $a0, 0
122; LA32-NEXT:    fsub.d $fa2, $fa0, $fa1
123; LA32-NEXT:    ftintrz.w.d $fa2, $fa2
124; LA32-NEXT:    movfr2gr.s $a0, $fa2
125; LA32-NEXT:    lu12i.w $a1, -524288
126; LA32-NEXT:    xor $a0, $a0, $a1
127; LA32-NEXT:    fcmp.clt.d $fcc0, $fa0, $fa1
128; LA32-NEXT:    movcf2gr $a1, $fcc0
129; LA32-NEXT:    masknez $a0, $a0, $a1
130; LA32-NEXT:    ftintrz.w.d $fa0, $fa0
131; LA32-NEXT:    movfr2gr.s $a2, $fa0
132; LA32-NEXT:    maskeqz $a1, $a2, $a1
133; LA32-NEXT:    or $a0, $a1, $a0
134; LA32-NEXT:    jirl $zero, $ra, 0
135;
136; LA64-LABEL: convert_double_to_u32:
137; LA64:       # %bb.0:
138; LA64-NEXT:    ftintrz.l.d $fa0, $fa0
139; LA64-NEXT:    movfr2gr.d $a0, $fa0
140; LA64-NEXT:    jirl $zero, $ra, 0
141  %1 = fptoui double %a to i32
142  ret i32 %1
143}
144
145define i64 @convert_double_to_i64(double %a) nounwind {
146; LA32-LABEL: convert_double_to_i64:
147; LA32:       # %bb.0:
148; LA32-NEXT:    addi.w $sp, $sp, -16
149; LA32-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
150; LA32-NEXT:    bl __fixdfdi
151; LA32-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
152; LA32-NEXT:    addi.w $sp, $sp, 16
153; LA32-NEXT:    jirl $zero, $ra, 0
154;
155; LA64-LABEL: convert_double_to_i64:
156; LA64:       # %bb.0:
157; LA64-NEXT:    ftintrz.l.d $fa0, $fa0
158; LA64-NEXT:    movfr2gr.d $a0, $fa0
159; LA64-NEXT:    jirl $zero, $ra, 0
160  %1 = fptosi double %a to i64
161  ret i64 %1
162}
163
164define i64 @convert_double_to_u64(double %a) nounwind {
165; LA32-LABEL: convert_double_to_u64:
166; LA32:       # %bb.0:
167; LA32-NEXT:    addi.w $sp, $sp, -16
168; LA32-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
169; LA32-NEXT:    bl __fixunsdfdi
170; LA32-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
171; LA32-NEXT:    addi.w $sp, $sp, 16
172; LA32-NEXT:    jirl $zero, $ra, 0
173;
174; LA64-LABEL: convert_double_to_u64:
175; LA64:       # %bb.0:
176; LA64-NEXT:    pcalau12i $a0, .LCPI9_0
177; LA64-NEXT:    addi.d $a0, $a0, .LCPI9_0
178; LA64-NEXT:    fld.d $fa1, $a0, 0
179; LA64-NEXT:    fsub.d $fa2, $fa0, $fa1
180; LA64-NEXT:    ftintrz.l.d $fa2, $fa2
181; LA64-NEXT:    movfr2gr.d $a0, $fa2
182; LA64-NEXT:    lu52i.d $a1, $zero, -2048
183; LA64-NEXT:    xor $a0, $a0, $a1
184; LA64-NEXT:    fcmp.clt.d $fcc0, $fa0, $fa1
185; LA64-NEXT:    movcf2gr $a1, $fcc0
186; LA64-NEXT:    masknez $a0, $a0, $a1
187; LA64-NEXT:    ftintrz.l.d $fa0, $fa0
188; LA64-NEXT:    movfr2gr.d $a2, $fa0
189; LA64-NEXT:    maskeqz $a1, $a2, $a1
190; LA64-NEXT:    or $a0, $a1, $a0
191; LA64-NEXT:    jirl $zero, $ra, 0
192  %1 = fptoui double %a to i64
193  ret i64 %1
194}
195
196define double @convert_u8_to_double(i8 zeroext %a) nounwind {
197; LA32-LABEL: convert_u8_to_double:
198; LA32:       # %bb.0:
199; LA32-NEXT:    movgr2fr.w $fa0, $a0
200; LA32-NEXT:    ffint.d.w $fa0, $fa0
201; LA32-NEXT:    jirl $zero, $ra, 0
202;
203; LA64-LABEL: convert_u8_to_double:
204; LA64:       # %bb.0:
205; LA64-NEXT:    movgr2fr.w $fa0, $a0
206; LA64-NEXT:    ffint.d.w $fa0, $fa0
207; LA64-NEXT:    jirl $zero, $ra, 0
208  %1 = uitofp i8 %a to double
209  ret double %1
210}
211
212define double @convert_u16_to_double(i16 zeroext %a) nounwind {
213; LA32-LABEL: convert_u16_to_double:
214; LA32:       # %bb.0:
215; LA32-NEXT:    movgr2fr.w $fa0, $a0
216; LA32-NEXT:    ffint.d.w $fa0, $fa0
217; LA32-NEXT:    jirl $zero, $ra, 0
218;
219; LA64-LABEL: convert_u16_to_double:
220; LA64:       # %bb.0:
221; LA64-NEXT:    movgr2fr.w $fa0, $a0
222; LA64-NEXT:    ffint.d.w $fa0, $fa0
223; LA64-NEXT:    jirl $zero, $ra, 0
224  %1 = uitofp i16 %a to double
225  ret double %1
226}
227
228define double @convert_u32_to_double(i32 %a) nounwind {
229; LA32-LABEL: convert_u32_to_double:
230; LA32:       # %bb.0:
231; LA32-NEXT:    addi.w $sp, $sp, -16
232; LA32-NEXT:    addi.w $a1, $sp, 8
233; LA32-NEXT:    ori $a1, $a1, 4
234; LA32-NEXT:    lu12i.w $a2, 275200
235; LA32-NEXT:    st.w $a2, $a1, 0
236; LA32-NEXT:    st.w $a0, $sp, 8
237; LA32-NEXT:    pcalau12i $a0, .LCPI12_0
238; LA32-NEXT:    addi.w $a0, $a0, .LCPI12_0
239; LA32-NEXT:    fld.d $fa0, $a0, 0
240; LA32-NEXT:    fld.d $fa1, $sp, 8
241; LA32-NEXT:    fsub.d $fa0, $fa1, $fa0
242; LA32-NEXT:    addi.w $sp, $sp, 16
243; LA32-NEXT:    jirl $zero, $ra, 0
244;
245; LA64-LABEL: convert_u32_to_double:
246; LA64:       # %bb.0:
247; LA64-NEXT:    lu52i.d $a1, $zero, 1107
248; LA64-NEXT:    movgr2fr.d $fa0, $a1
249; LA64-NEXT:    pcalau12i $a1, .LCPI12_0
250; LA64-NEXT:    addi.d $a1, $a1, .LCPI12_0
251; LA64-NEXT:    fld.d $fa1, $a1, 0
252; LA64-NEXT:    fsub.d $fa0, $fa0, $fa1
253; LA64-NEXT:    lu12i.w $a1, 275200
254; LA64-NEXT:    bstrins.d $a0, $a1, 63, 32
255; LA64-NEXT:    movgr2fr.d $fa1, $a0
256; LA64-NEXT:    fadd.d $fa0, $fa1, $fa0
257; LA64-NEXT:    jirl $zero, $ra, 0
258  %1 = uitofp i32 %a to double
259  ret double %1
260}
261
262define double @convert_u64_to_double(i64 %a) nounwind {
263; LA32-LABEL: convert_u64_to_double:
264; LA32:       # %bb.0:
265; LA32-NEXT:    addi.w $sp, $sp, -16
266; LA32-NEXT:    st.w $ra, $sp, 12 # 4-byte Folded Spill
267; LA32-NEXT:    bl __floatundidf
268; LA32-NEXT:    ld.w $ra, $sp, 12 # 4-byte Folded Reload
269; LA32-NEXT:    addi.w $sp, $sp, 16
270; LA32-NEXT:    jirl $zero, $ra, 0
271;
272; LA64-LABEL: convert_u64_to_double:
273; LA64:       # %bb.0:
274; LA64-NEXT:    srli.d $a1, $a0, 32
275; LA64-NEXT:    lu52i.d $a2, $zero, 1107
276; LA64-NEXT:    or $a1, $a1, $a2
277; LA64-NEXT:    movgr2fr.d $fa0, $a1
278; LA64-NEXT:    pcalau12i $a1, .LCPI13_0
279; LA64-NEXT:    addi.d $a1, $a1, .LCPI13_0
280; LA64-NEXT:    fld.d $fa1, $a1, 0
281; LA64-NEXT:    fsub.d $fa0, $fa0, $fa1
282; LA64-NEXT:    lu12i.w $a1, 275200
283; LA64-NEXT:    bstrins.d $a0, $a1, 63, 32
284; LA64-NEXT:    movgr2fr.d $fa1, $a0
285; LA64-NEXT:    fadd.d $fa0, $fa1, $fa0
286; LA64-NEXT:    jirl $zero, $ra, 0
287  %1 = uitofp i64 %a to double
288  ret double %1
289}
290
291define double @bitcast_i64_to_double(i64 %a, i64 %b) nounwind {
292; LA32-LABEL: bitcast_i64_to_double:
293; LA32:       # %bb.0:
294; LA32-NEXT:    addi.w $sp, $sp, -16
295; LA32-NEXT:    addi.w $a2, $sp, 8
296; LA32-NEXT:    ori $a2, $a2, 4
297; LA32-NEXT:    st.w $a1, $a2, 0
298; LA32-NEXT:    st.w $a0, $sp, 8
299; LA32-NEXT:    fld.d $fa0, $sp, 8
300; LA32-NEXT:    addi.w $sp, $sp, 16
301; LA32-NEXT:    jirl $zero, $ra, 0
302;
303; LA64-LABEL: bitcast_i64_to_double:
304; LA64:       # %bb.0:
305; LA64-NEXT:    movgr2fr.d $fa0, $a0
306; LA64-NEXT:    jirl $zero, $ra, 0
307  %1 = bitcast i64 %a to double
308  ret double %1
309}
310
311define i64 @bitcast_double_to_i64(double %a) nounwind {
312; LA32-LABEL: bitcast_double_to_i64:
313; LA32:       # %bb.0:
314; LA32-NEXT:    addi.w $sp, $sp, -16
315; LA32-NEXT:    fst.d $fa0, $sp, 8
316; LA32-NEXT:    addi.w $a0, $sp, 8
317; LA32-NEXT:    ori $a0, $a0, 4
318; LA32-NEXT:    ld.w $a1, $a0, 0
319; LA32-NEXT:    ld.w $a0, $sp, 8
320; LA32-NEXT:    addi.w $sp, $sp, 16
321; LA32-NEXT:    jirl $zero, $ra, 0
322;
323; LA64-LABEL: bitcast_double_to_i64:
324; LA64:       # %bb.0:
325; LA64-NEXT:    movfr2gr.d $a0, $fa0
326; LA64-NEXT:    jirl $zero, $ra, 0
327  %1 = bitcast double %a to i64
328  ret i64 %1
329}
330