1; RUN: llc < %s -asm-verbose=false | FileCheck %s
2
3; Test that basic conversion operations assemble as expected.
4
5target datalayout = "e-p:32:32-i64:64-n32:64-S128"
6target triple = "wasm32-unknown-unknown"
7
8; CHECK-LABEL: i32_wrap_i64:
9; CHECK-NEXT: .param i64{{$}}
10; CHECK-NEXT: .result i32{{$}}
11; CHECK-NEXT: .local i64, i32{{$}}
12; CHECK-NEXT: get_local 0{{$}}
13; CHECK-NEXT: set_local 1, pop{{$}}
14; CHECK-NEXT: i32_wrap (get_local 1){{$}}
15; CHECK-NEXT: set_local 2, pop{{$}}
16; CHECK-NEXT: return (get_local 2){{$}}
17define i32 @i32_wrap_i64(i64 %x) {
18  %a = trunc i64 %x to i32
19  ret i32 %a
20}
21
22; CHECK-LABEL: i64_extend_s_i32:
23; CHECK-NEXT: .param i32
24; CHECK-NEXT: .result i64
25; CHECK-NEXT: .local i32, i64{{$}}
26; CHECK-NEXT: get_local 0{{$}}
27; CHECK-NEXT: set_local 1, pop{{$}}
28; CHECK-NEXT: i64_extend_s (get_local 1){{$}}
29; CHECK-NEXT: set_local 2, pop{{$}}
30; CHECK-NEXT: return (get_local 2){{$}}
31define i64 @i64_extend_s_i32(i32 %x) {
32  %a = sext i32 %x to i64
33  ret i64 %a
34}
35
36; CHECK-LABEL: i64_extend_u_i32:
37; CHECK-NEXT: .param i32
38; CHECK-NEXT: .result i64
39; CHECK-NEXT: .local i32, i64{{$}}
40; CHECK-NEXT: get_local 0{{$}}
41; CHECK-NEXT: set_local 1, pop{{$}}
42; CHECK-NEXT: i64_extend_u (get_local 1){{$}}
43; CHECK-NEXT: set_local 2, pop{{$}}
44; CHECK-NEXT: return (get_local 2){{$}}
45define i64 @i64_extend_u_i32(i32 %x) {
46  %a = zext i32 %x to i64
47  ret i64 %a
48}
49
50; CHECK-LABEL: i32_trunc_s_f32:
51; CHECK-NEXT: .param f32
52; CHECK-NEXT: .result i32
53; CHECK-NEXT: .local f32, i32{{$}}
54; CHECK-NEXT: get_local 0{{$}}
55; CHECK-NEXT: set_local 1, pop{{$}}
56; CHECK-NEXT: i32_trunc_s (get_local 1){{$}}
57; CHECK-NEXT: set_local 2, pop{{$}}
58; CHECK-NEXT: return (get_local 2){{$}}
59define i32 @i32_trunc_s_f32(float %x) {
60  %a = fptosi float %x to i32
61  ret i32 %a
62}
63
64; CHECK-LABEL: i32_trunc_u_f32:
65; CHECK-NEXT: .param f32
66; CHECK-NEXT: .result i32
67; CHECK-NEXT: .local f32, i32{{$}}
68; CHECK-NEXT: get_local 0{{$}}
69; CHECK-NEXT: set_local 1, pop{{$}}
70; CHECK-NEXT: i32_trunc_u (get_local 1){{$}}
71; CHECK-NEXT: set_local 2, pop{{$}}
72; CHECK-NEXT: return (get_local 2){{$}}
73define i32 @i32_trunc_u_f32(float %x) {
74  %a = fptoui float %x to i32
75  ret i32 %a
76}
77
78; CHECK-LABEL: i32_trunc_s_f64:
79; CHECK-NEXT: .param f64
80; CHECK-NEXT: .result i32
81; CHECK-NEXT: .local f64, i32{{$}}
82; CHECK-NEXT: get_local 0{{$}}
83; CHECK-NEXT: set_local 1, pop{{$}}
84; CHECK-NEXT: i32_trunc_s (get_local 1){{$}}
85; CHECK-NEXT: set_local 2, pop{{$}}
86; CHECK-NEXT: return (get_local 2){{$}}
87define i32 @i32_trunc_s_f64(double %x) {
88  %a = fptosi double %x to i32
89  ret i32 %a
90}
91
92; CHECK-LABEL: i32_trunc_u_f64:
93; CHECK-NEXT: .param f64
94; CHECK-NEXT: .result i32
95; CHECK-NEXT: .local f64, i32{{$}}
96; CHECK-NEXT: get_local 0{{$}}
97; CHECK-NEXT: set_local 1, pop{{$}}
98; CHECK-NEXT: i32_trunc_u (get_local 1){{$}}
99; CHECK-NEXT: set_local 2, pop{{$}}
100; CHECK-NEXT: return (get_local 2){{$}}
101define i32 @i32_trunc_u_f64(double %x) {
102  %a = fptoui double %x to i32
103  ret i32 %a
104}
105
106; CHECK-LABEL: i64_trunc_s_f32:
107; CHECK-NEXT: .param f32
108; CHECK-NEXT: .result i64
109; CHECK-NEXT: .local f32, i64{{$}}
110; CHECK-NEXT: get_local 0{{$}}
111; CHECK-NEXT: set_local 1, pop{{$}}
112; CHECK-NEXT: i64_trunc_s (get_local 1){{$}}
113; CHECK-NEXT: set_local 2, pop{{$}}
114; CHECK-NEXT: return (get_local 2){{$}}
115define i64 @i64_trunc_s_f32(float %x) {
116  %a = fptosi float %x to i64
117  ret i64 %a
118}
119
120; CHECK-LABEL: i64_trunc_u_f32:
121; CHECK-NEXT: .param f32
122; CHECK-NEXT: .result i64
123; CHECK-NEXT: .local f32, i64{{$}}
124; CHECK-NEXT: get_local 0{{$}}
125; CHECK-NEXT: set_local 1, pop{{$}}
126; CHECK-NEXT: i64_trunc_u (get_local 1){{$}}
127; CHECK-NEXT: set_local 2, pop{{$}}
128; CHECK-NEXT: return (get_local 2){{$}}
129define i64 @i64_trunc_u_f32(float %x) {
130  %a = fptoui float %x to i64
131  ret i64 %a
132}
133
134; CHECK-LABEL: i64_trunc_s_f64:
135; CHECK-NEXT: .param f64
136; CHECK-NEXT: .result i64
137; CHECK-NEXT: .local f64, i64{{$}}
138; CHECK-NEXT: get_local 0{{$}}
139; CHECK-NEXT: set_local 1, pop{{$}}
140; CHECK-NEXT: i64_trunc_s (get_local 1){{$}}
141; CHECK-NEXT: set_local 2, pop{{$}}
142; CHECK-NEXT: return (get_local 2){{$}}
143define i64 @i64_trunc_s_f64(double %x) {
144  %a = fptosi double %x to i64
145  ret i64 %a
146}
147
148; CHECK-LABEL: i64_trunc_u_f64:
149; CHECK-NEXT: .param f64
150; CHECK-NEXT: .result i64
151; CHECK-NEXT: .local f64, i64{{$}}
152; CHECK-NEXT: get_local 0{{$}}
153; CHECK-NEXT: set_local 1, pop{{$}}
154; CHECK-NEXT: i64_trunc_u (get_local 1){{$}}
155; CHECK-NEXT: set_local 2, pop{{$}}
156; CHECK-NEXT: return (get_local 2){{$}}
157define i64 @i64_trunc_u_f64(double %x) {
158  %a = fptoui double %x to i64
159  ret i64 %a
160}
161
162; CHECK-LABEL: f32_convert_s_i32:
163; CHECK-NEXT: .param i32
164; CHECK-NEXT: .result f32
165; CHECK-NEXT: .local i32, f32{{$}}
166; CHECK-NEXT: get_local 0{{$}}
167; CHECK-NEXT: set_local 1, pop{{$}}
168; CHECK-NEXT: f32_convert_s (get_local 1){{$}}
169; CHECK-NEXT: set_local 2, pop{{$}}
170; CHECK-NEXT: return (get_local 2){{$}}
171define float @f32_convert_s_i32(i32 %x) {
172  %a = sitofp i32 %x to float
173  ret float %a
174}
175
176; CHECK-LABEL: f32_convert_u_i32:
177; CHECK-NEXT: .param i32
178; CHECK-NEXT: .result f32
179; CHECK-NEXT: .local i32, f32{{$}}
180; CHECK-NEXT: get_local 0{{$}}
181; CHECK-NEXT: set_local 1, pop{{$}}
182; CHECK-NEXT: f32_convert_u (get_local 1){{$}}
183; CHECK-NEXT: set_local 2, pop{{$}}
184; CHECK-NEXT: return (get_local 2){{$}}
185define float @f32_convert_u_i32(i32 %x) {
186  %a = uitofp i32 %x to float
187  ret float %a
188}
189
190; CHECK-LABEL: f64_convert_s_i32:
191; CHECK-NEXT: .param i32
192; CHECK-NEXT: .result f64
193; CHECK-NEXT: .local i32, f64{{$}}
194; CHECK-NEXT: get_local 0{{$}}
195; CHECK-NEXT: set_local 1, pop{{$}}
196; CHECK-NEXT: f64_convert_s (get_local 1){{$}}
197; CHECK-NEXT: set_local 2, pop{{$}}
198; CHECK-NEXT: return (get_local 2){{$}}
199define double @f64_convert_s_i32(i32 %x) {
200  %a = sitofp i32 %x to double
201  ret double %a
202}
203
204; CHECK-LABEL: f64_convert_u_i32:
205; CHECK-NEXT: .param i32
206; CHECK-NEXT: .result f64
207; CHECK-NEXT: .local i32, f64{{$}}
208; CHECK-NEXT: get_local 0{{$}}
209; CHECK-NEXT: set_local 1, pop{{$}}
210; CHECK-NEXT: f64_convert_u (get_local 1){{$}}
211; CHECK-NEXT: set_local 2, pop{{$}}
212; CHECK-NEXT: return (get_local 2){{$}}
213define double @f64_convert_u_i32(i32 %x) {
214  %a = uitofp i32 %x to double
215  ret double %a
216}
217
218; CHECK-LABEL: f32_convert_s_i64:
219; CHECK-NEXT: .param i64
220; CHECK-NEXT: .result f32
221; CHECK-NEXT: .local i64, f32{{$}}
222; CHECK-NEXT: get_local 0{{$}}
223; CHECK-NEXT: set_local 1, pop{{$}}
224; CHECK-NEXT: f32_convert_s (get_local 1){{$}}
225; CHECK-NEXT: set_local 2, pop{{$}}
226; CHECK-NEXT: return (get_local 2){{$}}
227define float @f32_convert_s_i64(i64 %x) {
228  %a = sitofp i64 %x to float
229  ret float %a
230}
231
232; CHECK-LABEL: f32_convert_u_i64:
233; CHECK-NEXT: .param i64
234; CHECK-NEXT: .result f32
235; CHECK-NEXT: .local i64, f32{{$}}
236; CHECK-NEXT: get_local 0{{$}}
237; CHECK-NEXT: set_local 1, pop{{$}}
238; CHECK-NEXT: f32_convert_u (get_local 1){{$}}
239; CHECK-NEXT: set_local 2, pop{{$}}
240; CHECK-NEXT: return (get_local 2){{$}}
241define float @f32_convert_u_i64(i64 %x) {
242  %a = uitofp i64 %x to float
243  ret float %a
244}
245
246; CHECK-LABEL: f64_convert_s_i64:
247; CHECK-NEXT: .param i64
248; CHECK-NEXT: .result f64
249; CHECK-NEXT: .local i64, f64{{$}}
250; CHECK-NEXT: get_local 0{{$}}
251; CHECK-NEXT: set_local 1, pop{{$}}
252; CHECK-NEXT: f64_convert_s (get_local 1){{$}}
253; CHECK-NEXT: set_local 2, pop{{$}}
254; CHECK-NEXT: return (get_local 2){{$}}
255define double @f64_convert_s_i64(i64 %x) {
256  %a = sitofp i64 %x to double
257  ret double %a
258}
259
260; CHECK-LABEL: f64_convert_u_i64:
261; CHECK-NEXT: .param i64
262; CHECK-NEXT: .result f64
263; CHECK-NEXT: .local i64, f64{{$}}
264; CHECK-NEXT: get_local 0{{$}}
265; CHECK-NEXT: set_local 1, pop{{$}}
266; CHECK-NEXT: f64_convert_u (get_local 1){{$}}
267; CHECK-NEXT: set_local 2, pop{{$}}
268; CHECK-NEXT: return (get_local 2){{$}}
269define double @f64_convert_u_i64(i64 %x) {
270  %a = uitofp i64 %x to double
271  ret double %a
272}
273
274; CHECK-LABEL: f64_promote_f32:
275; CHECK-NEXT: .param f32
276; CHECK-NEXT: .result f64
277; CHECK-NEXT: .local f32, f64{{$}}
278; CHECK-NEXT: get_local 0{{$}}
279; CHECK-NEXT: set_local 1, pop{{$}}
280; CHECK-NEXT: f64_promote (get_local 1){{$}}
281; CHECK-NEXT: set_local 2, pop{{$}}
282; CHECK-NEXT: return (get_local 2){{$}}
283define double @f64_promote_f32(float %x) {
284  %a = fpext float %x to double
285  ret double %a
286}
287
288; CHECK-LABEL: f32_demote_f64:
289; CHECK-NEXT: .param f64
290; CHECK-NEXT: .result f32
291; CHECK-NEXT: .local f64, f32{{$}}
292; CHECK-NEXT: get_local 0{{$}}
293; CHECK-NEXT: set_local 1, pop{{$}}
294; CHECK-NEXT: f32_demote (get_local 1){{$}}
295; CHECK-NEXT: set_local 2, pop{{$}}
296; CHECK-NEXT: return (get_local 2){{$}}
297define float @f32_demote_f64(double %x) {
298  %a = fptrunc double %x to float
299  ret float %a
300}
301