PeepholeOptimizer: Ignore dead implicit defs
[oota-llvm.git] / test / CodeGen / WebAssembly / conv.ll
1 ; RUN: llc < %s -asm-verbose=false | FileCheck %s
2
3 ; Test that basic conversion operations assemble as expected.
4
5 target datalayout = "e-p:32:32-i64:64-n32:64-S128"
6 target triple = "wasm32-unknown-unknown"
7
8 ; CHECK-LABEL: i32_wrap_i64:
9 ; CHECK-NEXT: .param i64{{$}}
10 ; CHECK-NEXT: .result i32{{$}}
11 ; CHECK-NEXT: i32.wrap/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
12 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
13 define i32 @i32_wrap_i64(i64 %x) {
14   %a = trunc i64 %x to i32
15   ret i32 %a
16 }
17
18 ; CHECK-LABEL: i64_extend_s_i32:
19 ; CHECK-NEXT: .param i32{{$}}
20 ; CHECK-NEXT: .result i64{{$}}
21 ; CHECK-NEXT: i64.extend_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
22 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
23 define i64 @i64_extend_s_i32(i32 %x) {
24   %a = sext i32 %x to i64
25   ret i64 %a
26 }
27
28 ; CHECK-LABEL: i64_extend_u_i32:
29 ; CHECK-NEXT: .param i32{{$}}
30 ; CHECK-NEXT: .result i64{{$}}
31 ; CHECK-NEXT: i64.extend_u/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
32 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
33 define i64 @i64_extend_u_i32(i32 %x) {
34   %a = zext i32 %x to i64
35   ret i64 %a
36 }
37
38 ; CHECK-LABEL: i32_trunc_s_f32:
39 ; CHECK-NEXT: .param f32{{$}}
40 ; CHECK-NEXT: .result i32{{$}}
41 ; CHECK-NEXT: i32.trunc_s/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
42 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
43 define i32 @i32_trunc_s_f32(float %x) {
44   %a = fptosi float %x to i32
45   ret i32 %a
46 }
47
48 ; CHECK-LABEL: i32_trunc_u_f32:
49 ; CHECK-NEXT: .param f32{{$}}
50 ; CHECK-NEXT: .result i32{{$}}
51 ; CHECK-NEXT: i32.trunc_u/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
52 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
53 define i32 @i32_trunc_u_f32(float %x) {
54   %a = fptoui float %x to i32
55   ret i32 %a
56 }
57
58 ; CHECK-LABEL: i32_trunc_s_f64:
59 ; CHECK-NEXT: .param f64{{$}}
60 ; CHECK-NEXT: .result i32{{$}}
61 ; CHECK-NEXT: i32.trunc_s/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
62 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
63 define i32 @i32_trunc_s_f64(double %x) {
64   %a = fptosi double %x to i32
65   ret i32 %a
66 }
67
68 ; CHECK-LABEL: i32_trunc_u_f64:
69 ; CHECK-NEXT: .param f64{{$}}
70 ; CHECK-NEXT: .result i32{{$}}
71 ; CHECK-NEXT: i32.trunc_u/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
72 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
73 define i32 @i32_trunc_u_f64(double %x) {
74   %a = fptoui double %x to i32
75   ret i32 %a
76 }
77
78 ; CHECK-LABEL: i64_trunc_s_f32:
79 ; CHECK-NEXT: .param f32{{$}}
80 ; CHECK-NEXT: .result i64{{$}}
81 ; CHECK-NEXT: i64.trunc_s/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
82 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
83 define i64 @i64_trunc_s_f32(float %x) {
84   %a = fptosi float %x to i64
85   ret i64 %a
86 }
87
88 ; CHECK-LABEL: i64_trunc_u_f32:
89 ; CHECK-NEXT: .param f32{{$}}
90 ; CHECK-NEXT: .result i64{{$}}
91 ; CHECK-NEXT: i64.trunc_u/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
92 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
93 define i64 @i64_trunc_u_f32(float %x) {
94   %a = fptoui float %x to i64
95   ret i64 %a
96 }
97
98 ; CHECK-LABEL: i64_trunc_s_f64:
99 ; CHECK-NEXT: .param f64{{$}}
100 ; CHECK-NEXT: .result i64{{$}}
101 ; CHECK-NEXT: i64.trunc_s/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
102 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
103 define i64 @i64_trunc_s_f64(double %x) {
104   %a = fptosi double %x to i64
105   ret i64 %a
106 }
107
108 ; CHECK-LABEL: i64_trunc_u_f64:
109 ; CHECK-NEXT: .param f64{{$}}
110 ; CHECK-NEXT: .result i64{{$}}
111 ; CHECK-NEXT: i64.trunc_u/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
112 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
113 define i64 @i64_trunc_u_f64(double %x) {
114   %a = fptoui double %x to i64
115   ret i64 %a
116 }
117
118 ; CHECK-LABEL: f32_convert_s_i32:
119 ; CHECK-NEXT: .param i32{{$}}
120 ; CHECK-NEXT: .result f32{{$}}
121 ; CHECK-NEXT: f32.convert_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
122 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
123 define float @f32_convert_s_i32(i32 %x) {
124   %a = sitofp i32 %x to float
125   ret float %a
126 }
127
128 ; CHECK-LABEL: f32_convert_u_i32:
129 ; CHECK-NEXT: .param i32{{$}}
130 ; CHECK-NEXT: .result f32{{$}}
131 ; CHECK-NEXT: f32.convert_u/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
132 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
133 define float @f32_convert_u_i32(i32 %x) {
134   %a = uitofp i32 %x to float
135   ret float %a
136 }
137
138 ; CHECK-LABEL: f64_convert_s_i32:
139 ; CHECK-NEXT: .param i32{{$}}
140 ; CHECK-NEXT: .result f64{{$}}
141 ; CHECK-NEXT: f64.convert_s/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
142 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
143 define double @f64_convert_s_i32(i32 %x) {
144   %a = sitofp i32 %x to double
145   ret double %a
146 }
147
148 ; CHECK-LABEL: f64_convert_u_i32:
149 ; CHECK-NEXT: .param i32{{$}}
150 ; CHECK-NEXT: .result f64{{$}}
151 ; CHECK-NEXT: f64.convert_u/i32 $push[[NUM:[0-9]+]]=, $0{{$}}
152 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
153 define double @f64_convert_u_i32(i32 %x) {
154   %a = uitofp i32 %x to double
155   ret double %a
156 }
157
158 ; CHECK-LABEL: f32_convert_s_i64:
159 ; CHECK-NEXT: .param i64{{$}}
160 ; CHECK-NEXT: .result f32{{$}}
161 ; CHECK-NEXT: f32.convert_s/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
162 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
163 define float @f32_convert_s_i64(i64 %x) {
164   %a = sitofp i64 %x to float
165   ret float %a
166 }
167
168 ; CHECK-LABEL: f32_convert_u_i64:
169 ; CHECK-NEXT: .param i64{{$}}
170 ; CHECK-NEXT: .result f32{{$}}
171 ; CHECK-NEXT: f32.convert_u/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
172 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
173 define float @f32_convert_u_i64(i64 %x) {
174   %a = uitofp i64 %x to float
175   ret float %a
176 }
177
178 ; CHECK-LABEL: f64_convert_s_i64:
179 ; CHECK-NEXT: .param i64{{$}}
180 ; CHECK-NEXT: .result f64{{$}}
181 ; CHECK-NEXT: f64.convert_s/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
182 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
183 define double @f64_convert_s_i64(i64 %x) {
184   %a = sitofp i64 %x to double
185   ret double %a
186 }
187
188 ; CHECK-LABEL: f64_convert_u_i64:
189 ; CHECK-NEXT: .param i64{{$}}
190 ; CHECK-NEXT: .result f64{{$}}
191 ; CHECK-NEXT: f64.convert_u/i64 $push[[NUM:[0-9]+]]=, $0{{$}}
192 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
193 define double @f64_convert_u_i64(i64 %x) {
194   %a = uitofp i64 %x to double
195   ret double %a
196 }
197
198 ; CHECK-LABEL: f64_promote_f32:
199 ; CHECK-NEXT: .param f32{{$}}
200 ; CHECK-NEXT: .result f64{{$}}
201 ; CHECK-NEXT: f64.promote/f32 $push[[NUM:[0-9]+]]=, $0{{$}}
202 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
203 define double @f64_promote_f32(float %x) {
204   %a = fpext float %x to double
205   ret double %a
206 }
207
208 ; CHECK-LABEL: f32_demote_f64:
209 ; CHECK-NEXT: .param f64{{$}}
210 ; CHECK-NEXT: .result f32{{$}}
211 ; CHECK-NEXT: f32.demote/f64 $push[[NUM:[0-9]+]]=, $0{{$}}
212 ; CHECK-NEXT: return $pop[[NUM]]{{$}}
213 define float @f32_demote_f64(double %x) {
214   %a = fptrunc double %x to float
215   ret float %a
216 }
217
218 ; If the high its are unused, LLVM will optimize sext/zext into anyext, which
219 ; we need to patterm-match back to a specific instruction.
220
221 ; CHECK-LABEL: anyext:
222 ; CHECK: i64.extend_u/i32 $push0=, $0{{$}}
223 define i64 @anyext(i32 %x) {
224     %y = sext i32 %x to i64
225     %w = shl i64 %y, 32
226     ret i64 %w
227 }
228
229 ; CHECK-LABEL: bitcast_i32_to_float:
230 ; CHECK: f32.reinterpret/i32   $push0=, $0{{$}}
231 define float @bitcast_i32_to_float(i32 %a) {
232   %t = bitcast i32 %a to float
233   ret float %t
234 }
235
236 ; CHECK-LABEL: bitcast_float_to_i32:
237 ; CHECK: i32.reinterpret/f32   $push0=, $0{{$}}
238 define i32 @bitcast_float_to_i32(float %a) {
239   %t = bitcast float %a to i32
240   ret i32 %t
241 }
242
243 ; CHECK-LABEL: bitcast_i64_to_double:
244 ; CHECK: f64.reinterpret/i64   $push0=, $0{{$}}
245 define double @bitcast_i64_to_double(i64 %a) {
246   %t = bitcast i64 %a to double
247   ret double %t
248 }
249
250 ; CHECK-LABEL: bitcast_double_to_i64:
251 ; CHECK: i64.reinterpret/f64   $push0=, $0{{$}}
252 define i64 @bitcast_double_to_i64(double %a) {
253   %t = bitcast double %a to i64
254   ret i64 %t
255 }