xref: /llvm-project/llvm/test/CodeGen/WebAssembly/conv-trap.ll (revision 0807bc7e07f0430bd5b048d5c08f09442aab3b7d)
1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mcpu=mvp -mattr=-nontrapping-fptoint | FileCheck %s
2
3; Test that basic conversion operations assemble as expected using
4; the trapping opcodes and explicit code to suppress the trapping.
5
6target triple = "wasm32-unknown-unknown"
7
8; CHECK-LABEL: i32_trunc_s_f32:
9; CHECK-NEXT: .functype i32_trunc_s_f32 (f32) -> (i32){{$}}
10; CHECK-NEXT: block
11; CHECK-NEXT: f32.abs $push[[ABS:[0-9]+]]=, $0{{$}}
12; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p31{{$}}
13; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}}
14; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[LT]]
15; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}}
16; CHECK-NEXT: i32.trunc_f32_s $push[[NUM:[0-9]+]]=, $0{{$}}
17; CHECK-NEXT: return $pop[[NUM]]{{$}}
18; CHECK-NEXT: BB
19; CHECK-NEXT: end_block
20; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, -2147483648{{$}}
21; CHECK-NEXT: return $pop[[ALT]]{{$}}
22define i32 @i32_trunc_s_f32(float %x) {
23  %a = fptosi float %x to i32
24  ret i32 %a
25}
26
27; CHECK-LABEL: i32_trunc_u_f32:
28; CHECK-NEXT: .functype i32_trunc_u_f32 (f32) -> (i32){{$}}
29; CHECK-NEXT: block
30; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p32{{$}}
31; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}}
32; CHECK-NEXT: f32.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}}
33; CHECK-NEXT: f32.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}}
34; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}}
35; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[AND]]
36; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}}
37; CHECK-NEXT: i32.trunc_f32_u $push[[NUM:[0-9]+]]=, $0{{$}}
38; CHECK-NEXT: return $pop[[NUM]]{{$}}
39; CHECK-NEXT: BB
40; CHECK-NEXT: end_block
41; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, 0{{$}}
42; CHECK-NEXT: return $pop[[ALT]]{{$}}
43define i32 @i32_trunc_u_f32(float %x) {
44  %a = fptoui float %x to i32
45  ret i32 %a
46}
47
48; CHECK-LABEL: i32_trunc_s_f64:
49; CHECK-NEXT: .functype i32_trunc_s_f64 (f64) -> (i32){{$}}
50; CHECK-NEXT: block
51; CHECK-NEXT: f64.abs $push[[ABS:[0-9]+]]=, $0{{$}}
52; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p31{{$}}
53; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}}
54; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[LT]]
55; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}}
56; CHECK-NEXT: i32.trunc_f64_s $push[[NUM:[0-9]+]]=, $0{{$}}
57; CHECK-NEXT: return $pop[[NUM]]{{$}}
58; CHECK-NEXT: BB
59; CHECK-NEXT: end_block
60; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, -2147483648{{$}}
61; CHECK-NEXT: return $pop[[ALT]]{{$}}
62define i32 @i32_trunc_s_f64(double %x) {
63  %a = fptosi double %x to i32
64  ret i32 %a
65}
66
67; CHECK-LABEL: i32_trunc_u_f64:
68; CHECK-NEXT: .functype i32_trunc_u_f64 (f64) -> (i32){{$}}
69; CHECK-NEXT: block
70; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p32{{$}}
71; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}}
72; CHECK-NEXT: f64.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}}
73; CHECK-NEXT: f64.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}}
74; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}}
75; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[AND]]
76; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}}
77; CHECK-NEXT: i32.trunc_f64_u $push[[NUM:[0-9]+]]=, $0{{$}}
78; CHECK-NEXT: return $pop[[NUM]]{{$}}
79; CHECK-NEXT: BB
80; CHECK-NEXT: end_block
81; CHECK-NEXT: i32.const $push[[ALT:[0-9]+]]=, 0{{$}}
82; CHECK-NEXT: return $pop[[ALT]]{{$}}
83define i32 @i32_trunc_u_f64(double %x) {
84  %a = fptoui double %x to i32
85  ret i32 %a
86}
87
88; CHECK-LABEL: i64_trunc_s_f32:
89; CHECK-NEXT: .functype i64_trunc_s_f32 (f32) -> (i64){{$}}
90; CHECK-NEXT: block
91; CHECK-NEXT: f32.abs $push[[ABS:[0-9]+]]=, $0{{$}}
92; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p63{{$}}
93; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}}
94; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[LT]]
95; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}}
96; CHECK-NEXT: i64.trunc_f32_s $push[[NUM:[0-9]+]]=, $0{{$}}
97; CHECK-NEXT: return $pop[[NUM]]{{$}}
98; CHECK-NEXT: BB
99; CHECK-NEXT: end_block
100; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, -9223372036854775808{{$}}
101; CHECK-NEXT: return $pop[[ALT]]{{$}}
102define i64 @i64_trunc_s_f32(float %x) {
103  %a = fptosi float %x to i64
104  ret i64 %a
105}
106
107; CHECK-LABEL: i64_trunc_u_f32:
108; CHECK-NEXT: .functype i64_trunc_u_f32 (f32) -> (i64){{$}}
109; CHECK-NEXT: block
110; CHECK-NEXT: f32.const $push[[LIMIT:[0-9]+]]=, 0x1p64{{$}}
111; CHECK-NEXT: f32.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}}
112; CHECK-NEXT: f32.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}}
113; CHECK-NEXT: f32.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}}
114; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}}
115; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[AND]]
116; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}}
117; CHECK-NEXT: i64.trunc_f32_u $push[[NUM:[0-9]+]]=, $0{{$}}
118; CHECK-NEXT: return $pop[[NUM]]{{$}}
119; CHECK-NEXT: BB
120; CHECK-NEXT: end_block
121; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, 0{{$}}
122; CHECK-NEXT: return $pop[[ALT]]{{$}}
123define i64 @i64_trunc_u_f32(float %x) {
124  %a = fptoui float %x to i64
125  ret i64 %a
126}
127
128; CHECK-LABEL: i64_trunc_s_f64:
129; CHECK-NEXT: .functype i64_trunc_s_f64 (f64) -> (i64){{$}}
130; CHECK-NEXT: block
131; CHECK-NEXT: f64.abs $push[[ABS:[0-9]+]]=, $0{{$}}
132; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p63{{$}}
133; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $pop[[ABS]], $pop[[LIMIT]]{{$}}
134; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[LT]]
135; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}}
136; CHECK-NEXT: i64.trunc_f64_s $push[[NUM:[0-9]+]]=, $0{{$}}
137; CHECK-NEXT: return $pop[[NUM]]{{$}}
138; CHECK-NEXT: BB
139; CHECK-NEXT: end_block
140; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, -9223372036854775808{{$}}
141; CHECK-NEXT: return $pop[[ALT]]{{$}}
142define i64 @i64_trunc_s_f64(double %x) {
143  %a = fptosi double %x to i64
144  ret i64 %a
145}
146
147; CHECK-LABEL: i64_trunc_u_f64:
148; CHECK-NEXT: .functype i64_trunc_u_f64 (f64) -> (i64){{$}}
149; CHECK-NEXT: block
150; CHECK-NEXT: f64.const $push[[LIMIT:[0-9]+]]=, 0x1p64{{$}}
151; CHECK-NEXT: f64.lt $push[[LT:[0-9]+]]=, $0, $pop[[LIMIT]]{{$}}
152; CHECK-NEXT: f64.const $push[[ZERO:[0-9]+]]=, 0x0p0{{$}}
153; CHECK-NEXT: f64.ge $push[[GE:[0-9]+]]=, $0, $pop[[ZERO]]{{$}}
154; CHECK-NEXT: i32.and $push[[AND:[0-9]+]]=, $pop[[LT]], $pop[[GE]]{{$}}
155; CHECK-NEXT: i32.eqz $push[[EQZ:[0-9]+]]=, $pop[[AND]]
156; CHECK-NEXT: br_if 0, $pop[[EQZ]]{{$}}
157; CHECK-NEXT: i64.trunc_f64_u $push[[NUM:[0-9]+]]=, $0{{$}}
158; CHECK-NEXT: return $pop[[NUM]]{{$}}
159; CHECK-NEXT: BB
160; CHECK-NEXT: end_block
161; CHECK-NEXT: i64.const $push[[ALT:[0-9]+]]=, 0{{$}}
162; CHECK-NEXT: return $pop[[ALT]]{{$}}
163define i64 @i64_trunc_u_f64(double %x) {
164  %a = fptoui double %x to i64
165  ret i64 %a
166}
167
168; CHECK-LABEL: llvm_wasm_trunc_signed_i32_f32:
169; CHECK-NEXT: .functype llvm_wasm_trunc_signed_i32_f32 (f32) -> (i32)
170; CHECK-NEXT: i32.trunc_f32_s $push[[L0:[0-9]+]]=, $0{{$}}
171; CHECK-NEXT: return $pop[[L0]]{{$}}
172declare i32 @llvm.wasm.trunc.signed.i32.f32(float)
173define i32 @llvm_wasm_trunc_signed_i32_f32(float %f) {
174  %a = call i32 @llvm.wasm.trunc.signed.i32.f32(float %f)
175  ret i32 %a
176}
177
178; CHECK-LABEL: llvm_wasm_trunc_unsigned_i32_f32:
179; CHECK-NEXT: .functype llvm_wasm_trunc_unsigned_i32_f32 (f32) -> (i32)
180; CHECK-NEXT: i32.trunc_f32_u $push[[L0:[0-9]+]]=, $0{{$}}
181; CHECK-NEXT: return $pop[[L0]]{{$}}
182declare i32 @llvm.wasm.trunc.unsigned.i32.f32(float)
183define i32 @llvm_wasm_trunc_unsigned_i32_f32(float %f) {
184  %a = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float %f)
185  ret i32 %a
186}
187
188; CHECK-LABEL: llvm_wasm_trunc_signed_i32_f64:
189; CHECK-NEXT: .functype llvm_wasm_trunc_signed_i32_f64 (f64) -> (i32)
190; CHECK-NEXT: i32.trunc_f64_s $push[[L0:[0-9]+]]=, $0{{$}}
191; CHECK-NEXT: return $pop[[L0]]{{$}}
192declare i32 @llvm.wasm.trunc.signed.i32.f64(double)
193define i32 @llvm_wasm_trunc_signed_i32_f64(double %f) {
194  %a = call i32 @llvm.wasm.trunc.signed.i32.f64(double %f)
195  ret i32 %a
196}
197
198; CHECK-LABEL: llvm_wasm_trunc_unsigned_i32_f64:
199; CHECK-NEXT: .functype llvm_wasm_trunc_unsigned_i32_f64 (f64) -> (i32)
200; CHECK-NEXT: i32.trunc_f64_u $push[[L0:[0-9]+]]=, $0{{$}}
201; CHECK-NEXT: return $pop[[L0]]{{$}}
202declare i32 @llvm.wasm.trunc.unsigned.i32.f64(double)
203define i32 @llvm_wasm_trunc_unsigned_i32_f64(double %f) {
204  %a = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double %f)
205  ret i32 %a
206}
207
208; CHECK-LABEL: llvm_wasm_trunc_signed_i64_f32:
209; CHECK-NEXT: .functype llvm_wasm_trunc_signed_i64_f32 (f32) -> (i64)
210; CHECK-NEXT: i64.trunc_f32_s $push[[L0:[0-9]+]]=, $0{{$}}
211; CHECK-NEXT: return $pop[[L0]]{{$}}
212declare i64 @llvm.wasm.trunc.signed.i64.f32(float)
213define i64 @llvm_wasm_trunc_signed_i64_f32(float %f) {
214  %a = call i64 @llvm.wasm.trunc.signed.i64.f32(float %f)
215  ret i64 %a
216}
217
218; CHECK-LABEL: llvm_wasm_trunc_unsigned_i64_f32:
219; CHECK-NEXT: .functype llvm_wasm_trunc_unsigned_i64_f32 (f32) -> (i64)
220; CHECK-NEXT: i64.trunc_f32_u $push[[L0:[0-9]+]]=, $0{{$}}
221; CHECK-NEXT: return $pop[[L0]]{{$}}
222declare i64 @llvm.wasm.trunc.unsigned.i64.f32(float)
223define i64 @llvm_wasm_trunc_unsigned_i64_f32(float %f) {
224  %a = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float %f)
225  ret i64 %a
226}
227
228; CHECK-LABEL: llvm_wasm_trunc_signed_i64_f64:
229; CHECK-NEXT: .functype llvm_wasm_trunc_signed_i64_f64 (f64) -> (i64)
230; CHECK-NEXT: i64.trunc_f64_s $push[[L0:[0-9]+]]=, $0{{$}}
231; CHECK-NEXT: return $pop[[L0]]{{$}}
232declare i64 @llvm.wasm.trunc.signed.i64.f64(double)
233define i64 @llvm_wasm_trunc_signed_i64_f64(double %f) {
234  %a = call i64 @llvm.wasm.trunc.signed.i64.f64(double %f)
235  ret i64 %a
236}
237
238; CHECK-LABEL: llvm_wasm_trunc_unsigned_i64_f64:
239; CHECK-NEXT: .functype llvm_wasm_trunc_unsigned_i64_f64 (f64) -> (i64)
240; CHECK-NEXT: i64.trunc_f64_u $push[[L0:[0-9]+]]=, $0{{$}}
241; CHECK-NEXT: return $pop[[L0]]{{$}}
242declare i64 @llvm.wasm.trunc.unsigned.i64.f64(double)
243define i64 @llvm_wasm_trunc_unsigned_i64_f64(double %f) {
244  %a = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double %f)
245  ret i64 %a
246}
247