Skip to content

Commit c128d44

Browse files
committed
[WebAssembly] Add Support for Arc and Hyperbolic trig llvm intrinsics to WASM
1 parent 949bbdc commit c128d44

File tree

2 files changed

+314
-0
lines changed

2 files changed

+314
-0
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,24 @@ struct RuntimeLibcallSignatureTable {
204204
Table[RTLIB::TAN_F32] = f32_func_f32;
205205
Table[RTLIB::TAN_F64] = f64_func_f64;
206206
Table[RTLIB::TAN_F128] = i64_i64_func_i64_i64;
207+
Table[RTLIB::ASIN_F32] = f32_func_f32;
208+
Table[RTLIB::ASIN_F64] = f64_func_f64;
209+
Table[RTLIB::ASIN_F128] = i64_i64_func_i64_i64;
210+
Table[RTLIB::ACOS_F32] = f32_func_f32;
211+
Table[RTLIB::ACOS_F64] = f64_func_f64;
212+
Table[RTLIB::ACOS_F128] = i64_i64_func_i64_i64;
213+
Table[RTLIB::ATAN_F32] = f32_func_f32;
214+
Table[RTLIB::ATAN_F64] = f64_func_f64;
215+
Table[RTLIB::ATAN_F128] = i64_i64_func_i64_i64;
216+
Table[RTLIB::SINH_F32] = f32_func_f32;
217+
Table[RTLIB::SINH_F64] = f64_func_f64;
218+
Table[RTLIB::SINH_F128] = i64_i64_func_i64_i64;
219+
Table[RTLIB::COSH_F32] = f32_func_f32;
220+
Table[RTLIB::COSH_F64] = f64_func_f64;
221+
Table[RTLIB::COSH_F128] = i64_i64_func_i64_i64;
222+
Table[RTLIB::TANH_F32] = f32_func_f32;
223+
Table[RTLIB::TANH_F64] = f64_func_f64;
224+
Table[RTLIB::TANH_F128] = i64_i64_func_i64_i64;
207225
Table[RTLIB::SINCOS_F32] = func_f32_iPTR_iPTR;
208226
Table[RTLIB::SINCOS_F64] = func_f64_iPTR_iPTR;
209227
Table[RTLIB::SINCOS_F128] = func_i64_i64_iPTR_iPTR;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-keep-registers | FileCheck %s
3+
4+
; Test a subset of compiler-rt/libm libcalls expected to be emitted by the wasm backend
5+
6+
target triple = "wasm32-unknown-unknown"
7+
8+
declare fp128 @llvm.sin.f128(fp128)
9+
declare fp128 @llvm.cos.f128(fp128)
10+
declare fp128 @llvm.tan.f128(fp128)
11+
declare fp128 @llvm.asin.f128(fp128)
12+
declare fp128 @llvm.acos.f128(fp128)
13+
declare fp128 @llvm.atan.f128.i32(fp128)
14+
declare fp128 @llvm.sinh.f128(fp128)
15+
declare fp128 @llvm.cosh.f128(fp128)
16+
declare fp128 @llvm.tanh.f128(fp128)
17+
18+
declare double @llvm.sin.f64(double)
19+
declare double @llvm.cos.f64(double)
20+
declare double @llvm.tan.f64(double)
21+
declare double @llvm.asin.f64(double)
22+
declare double @llvm.acos.f64(double)
23+
declare double @llvm.atan.f64(double)
24+
declare double @llvm.sinh.f64(double)
25+
declare double @llvm.cosh.f64(double)
26+
declare double @llvm.tanh.f64(double)
27+
28+
declare float @llvm.sin.f32(float)
29+
declare float @llvm.cos.f32(float)
30+
declare float @llvm.tan.f32(float)
31+
declare float @llvm.asin.f32(float)
32+
declare float @llvm.acos.f32(float)
33+
declare float @llvm.atan.f32(float)
34+
declare float @llvm.sinh.f32(float)
35+
declare float @llvm.cosh.f32(float)
36+
declare float @llvm.tanh.f32(float)
37+
38+
39+
define fp128 @fp128libcalls(fp128 %x) {
40+
; compiler-rt call
41+
; CHECK-LABEL: fp128libcalls:
42+
; CHECK: .functype fp128libcalls (i32, i64, i64) -> ()
43+
; CHECK-NEXT: .local i32
44+
; CHECK-NEXT: # %bb.0:
45+
; CHECK-NEXT: global.get $push28=, __stack_pointer
46+
; CHECK-NEXT: i32.const $push29=, 144
47+
; CHECK-NEXT: i32.sub $push73=, $pop28, $pop29
48+
; CHECK-NEXT: local.tee $push72=, 3, $pop73
49+
; CHECK-NEXT: global.set __stack_pointer, $pop72
50+
; CHECK-NEXT: local.get $push74=, 3
51+
; CHECK-NEXT: i32.const $push62=, 128
52+
; CHECK-NEXT: i32.add $push63=, $pop74, $pop62
53+
; CHECK-NEXT: local.get $push76=, 1
54+
; CHECK-NEXT: local.get $push75=, 2
55+
; CHECK-NEXT: call sinl, $pop63, $pop76, $pop75
56+
; CHECK-NEXT: local.get $push77=, 3
57+
; CHECK-NEXT: i32.const $push58=, 112
58+
; CHECK-NEXT: i32.add $push59=, $pop77, $pop58
59+
; CHECK-NEXT: local.get $push78=, 3
60+
; CHECK-NEXT: i64.load $push3=, 128($pop78)
61+
; CHECK-NEXT: local.get $push79=, 3
62+
; CHECK-NEXT: i32.const $push60=, 128
63+
; CHECK-NEXT: i32.add $push61=, $pop79, $pop60
64+
; CHECK-NEXT: i32.const $push0=, 8
65+
; CHECK-NEXT: i32.add $push1=, $pop61, $pop0
66+
; CHECK-NEXT: i64.load $push2=, 0($pop1)
67+
; CHECK-NEXT: call cosl, $pop59, $pop3, $pop2
68+
; CHECK-NEXT: local.get $push80=, 3
69+
; CHECK-NEXT: i32.const $push54=, 96
70+
; CHECK-NEXT: i32.add $push55=, $pop80, $pop54
71+
; CHECK-NEXT: local.get $push81=, 3
72+
; CHECK-NEXT: i64.load $push6=, 112($pop81)
73+
; CHECK-NEXT: local.get $push82=, 3
74+
; CHECK-NEXT: i32.const $push56=, 112
75+
; CHECK-NEXT: i32.add $push57=, $pop82, $pop56
76+
; CHECK-NEXT: i32.const $push71=, 8
77+
; CHECK-NEXT: i32.add $push4=, $pop57, $pop71
78+
; CHECK-NEXT: i64.load $push5=, 0($pop4)
79+
; CHECK-NEXT: call tanl, $pop55, $pop6, $pop5
80+
; CHECK-NEXT: local.get $push83=, 3
81+
; CHECK-NEXT: i32.const $push50=, 80
82+
; CHECK-NEXT: i32.add $push51=, $pop83, $pop50
83+
; CHECK-NEXT: local.get $push84=, 3
84+
; CHECK-NEXT: i64.load $push9=, 96($pop84)
85+
; CHECK-NEXT: local.get $push85=, 3
86+
; CHECK-NEXT: i32.const $push52=, 96
87+
; CHECK-NEXT: i32.add $push53=, $pop85, $pop52
88+
; CHECK-NEXT: i32.const $push70=, 8
89+
; CHECK-NEXT: i32.add $push7=, $pop53, $pop70
90+
; CHECK-NEXT: i64.load $push8=, 0($pop7)
91+
; CHECK-NEXT: call asinl, $pop51, $pop9, $pop8
92+
; CHECK-NEXT: local.get $push86=, 3
93+
; CHECK-NEXT: i32.const $push46=, 64
94+
; CHECK-NEXT: i32.add $push47=, $pop86, $pop46
95+
; CHECK-NEXT: local.get $push87=, 3
96+
; CHECK-NEXT: i64.load $push12=, 80($pop87)
97+
; CHECK-NEXT: local.get $push88=, 3
98+
; CHECK-NEXT: i32.const $push48=, 80
99+
; CHECK-NEXT: i32.add $push49=, $pop88, $pop48
100+
; CHECK-NEXT: i32.const $push69=, 8
101+
; CHECK-NEXT: i32.add $push10=, $pop49, $pop69
102+
; CHECK-NEXT: i64.load $push11=, 0($pop10)
103+
; CHECK-NEXT: call acosl, $pop47, $pop12, $pop11
104+
; CHECK-NEXT: local.get $push89=, 3
105+
; CHECK-NEXT: i32.const $push42=, 48
106+
; CHECK-NEXT: i32.add $push43=, $pop89, $pop42
107+
; CHECK-NEXT: local.get $push90=, 3
108+
; CHECK-NEXT: i64.load $push15=, 64($pop90)
109+
; CHECK-NEXT: local.get $push91=, 3
110+
; CHECK-NEXT: i32.const $push44=, 64
111+
; CHECK-NEXT: i32.add $push45=, $pop91, $pop44
112+
; CHECK-NEXT: i32.const $push68=, 8
113+
; CHECK-NEXT: i32.add $push13=, $pop45, $pop68
114+
; CHECK-NEXT: i64.load $push14=, 0($pop13)
115+
; CHECK-NEXT: call atanl, $pop43, $pop15, $pop14
116+
; CHECK-NEXT: local.get $push92=, 3
117+
; CHECK-NEXT: i32.const $push38=, 32
118+
; CHECK-NEXT: i32.add $push39=, $pop92, $pop38
119+
; CHECK-NEXT: local.get $push93=, 3
120+
; CHECK-NEXT: i64.load $push18=, 48($pop93)
121+
; CHECK-NEXT: local.get $push94=, 3
122+
; CHECK-NEXT: i32.const $push40=, 48
123+
; CHECK-NEXT: i32.add $push41=, $pop94, $pop40
124+
; CHECK-NEXT: i32.const $push67=, 8
125+
; CHECK-NEXT: i32.add $push16=, $pop41, $pop67
126+
; CHECK-NEXT: i64.load $push17=, 0($pop16)
127+
; CHECK-NEXT: call sinhl, $pop39, $pop18, $pop17
128+
; CHECK-NEXT: local.get $push95=, 3
129+
; CHECK-NEXT: i32.const $push34=, 16
130+
; CHECK-NEXT: i32.add $push35=, $pop95, $pop34
131+
; CHECK-NEXT: local.get $push96=, 3
132+
; CHECK-NEXT: i64.load $push21=, 32($pop96)
133+
; CHECK-NEXT: local.get $push97=, 3
134+
; CHECK-NEXT: i32.const $push36=, 32
135+
; CHECK-NEXT: i32.add $push37=, $pop97, $pop36
136+
; CHECK-NEXT: i32.const $push66=, 8
137+
; CHECK-NEXT: i32.add $push19=, $pop37, $pop66
138+
; CHECK-NEXT: i64.load $push20=, 0($pop19)
139+
; CHECK-NEXT: call coshl, $pop35, $pop21, $pop20
140+
; CHECK-NEXT: local.get $push100=, 3
141+
; CHECK-NEXT: local.get $push98=, 3
142+
; CHECK-NEXT: i64.load $push24=, 16($pop98)
143+
; CHECK-NEXT: local.get $push99=, 3
144+
; CHECK-NEXT: i32.const $push32=, 16
145+
; CHECK-NEXT: i32.add $push33=, $pop99, $pop32
146+
; CHECK-NEXT: i32.const $push65=, 8
147+
; CHECK-NEXT: i32.add $push22=, $pop33, $pop65
148+
; CHECK-NEXT: i64.load $push23=, 0($pop22)
149+
; CHECK-NEXT: call tanhl, $pop100, $pop24, $pop23
150+
; CHECK-NEXT: local.get $push102=, 0
151+
; CHECK-NEXT: local.get $push101=, 3
152+
; CHECK-NEXT: i32.const $push64=, 8
153+
; CHECK-NEXT: i32.add $push25=, $pop101, $pop64
154+
; CHECK-NEXT: i64.load $push26=, 0($pop25)
155+
; CHECK-NEXT: i64.store 8($pop102), $pop26
156+
; CHECK-NEXT: local.get $push104=, 0
157+
; CHECK-NEXT: local.get $push103=, 3
158+
; CHECK-NEXT: i64.load $push27=, 0($pop103)
159+
; CHECK-NEXT: i64.store 0($pop104), $pop27
160+
; CHECK-NEXT: local.get $push105=, 3
161+
; CHECK-NEXT: i32.const $push30=, 144
162+
; CHECK-NEXT: i32.add $push31=, $pop105, $pop30
163+
; CHECK-NEXT: global.set __stack_pointer, $pop31
164+
; CHECK-NEXT: return
165+
; libm calls
166+
%d = call fp128 @llvm.sin.f128(fp128 %x)
167+
%e = call fp128 @llvm.cos.f128(fp128 %d)
168+
%f = call fp128 @llvm.tan.f128(fp128 %e)
169+
%g = call fp128 @llvm.asin.f128.i32(fp128 %f)
170+
%h = call fp128 @llvm.acos.f128(fp128 %g)
171+
%i = call fp128 @llvm.atan.f128(fp128 %h)
172+
%a = call fp128 @llvm.sinh.f128(fp128 %i)
173+
%b = call fp128 @llvm.cosh.f128(fp128 %a)
174+
%c = call fp128 @llvm.tanh.f128(fp128 %b)
175+
ret fp128 %c
176+
}
177+
178+
define i128 @i128libcalls(i128 %x, i128 %y) {
179+
; Basic ops should be expanded
180+
; CHECK-LABEL: i128libcalls:
181+
; CHECK: .functype i128libcalls (i32, i64, i64, i64, i64) -> ()
182+
; CHECK-NEXT: .local i32, i64
183+
; CHECK-NEXT: # %bb.0:
184+
; CHECK-NEXT: global.get $push11=, __stack_pointer
185+
; CHECK-NEXT: i32.const $push12=, 32
186+
; CHECK-NEXT: i32.sub $push23=, $pop11, $pop12
187+
; CHECK-NEXT: local.tee $push22=, 5, $pop23
188+
; CHECK-NEXT: global.set __stack_pointer, $pop22
189+
; CHECK-NEXT: local.get $push24=, 5
190+
; CHECK-NEXT: i32.const $push17=, 16
191+
; CHECK-NEXT: i32.add $push18=, $pop24, $pop17
192+
; CHECK-NEXT: local.get $push26=, 1
193+
; CHECK-NEXT: local.get $push25=, 3
194+
; CHECK-NEXT: i64.add $push21=, $pop26, $pop25
195+
; CHECK-NEXT: local.tee $push20=, 6, $pop21
196+
; CHECK-NEXT: local.get $push28=, 2
197+
; CHECK-NEXT: local.get $push27=, 4
198+
; CHECK-NEXT: i64.add $push0=, $pop28, $pop27
199+
; CHECK-NEXT: local.get $push30=, 6
200+
; CHECK-NEXT: local.get $push29=, 1
201+
; CHECK-NEXT: i64.lt_u $push1=, $pop30, $pop29
202+
; CHECK-NEXT: i64.extend_i32_u $push2=, $pop1
203+
; CHECK-NEXT: i64.add $push3=, $pop0, $pop2
204+
; CHECK-NEXT: local.get $push32=, 3
205+
; CHECK-NEXT: local.get $push31=, 4
206+
; CHECK-NEXT: call __multi3, $pop18, $pop20, $pop3, $pop32, $pop31
207+
; CHECK-NEXT: local.get $push37=, 5
208+
; CHECK-NEXT: local.get $push33=, 5
209+
; CHECK-NEXT: i64.load $push7=, 16($pop33)
210+
; CHECK-NEXT: local.get $push34=, 5
211+
; CHECK-NEXT: i32.const $push15=, 16
212+
; CHECK-NEXT: i32.add $push16=, $pop34, $pop15
213+
; CHECK-NEXT: i32.const $push4=, 8
214+
; CHECK-NEXT: i32.add $push5=, $pop16, $pop4
215+
; CHECK-NEXT: i64.load $push6=, 0($pop5)
216+
; CHECK-NEXT: local.get $push36=, 3
217+
; CHECK-NEXT: local.get $push35=, 4
218+
; CHECK-NEXT: call __umodti3, $pop37, $pop7, $pop6, $pop36, $pop35
219+
; CHECK-NEXT: local.get $push39=, 0
220+
; CHECK-NEXT: local.get $push38=, 5
221+
; CHECK-NEXT: i32.const $push19=, 8
222+
; CHECK-NEXT: i32.add $push8=, $pop38, $pop19
223+
; CHECK-NEXT: i64.load $push9=, 0($pop8)
224+
; CHECK-NEXT: i64.store 8($pop39), $pop9
225+
; CHECK-NEXT: local.get $push41=, 0
226+
; CHECK-NEXT: local.get $push40=, 5
227+
; CHECK-NEXT: i64.load $push10=, 0($pop40)
228+
; CHECK-NEXT: i64.store 0($pop41), $pop10
229+
; CHECK-NEXT: local.get $push42=, 5
230+
; CHECK-NEXT: i32.const $push13=, 32
231+
; CHECK-NEXT: i32.add $push14=, $pop42, $pop13
232+
; CHECK-NEXT: global.set __stack_pointer, $pop14
233+
; CHECK-NEXT: return
234+
%a = add i128 %x, %y
235+
%b = mul i128 %a, %y
236+
%c = urem i128 %b, %y
237+
ret i128 %c
238+
}
239+
240+
define double @f64libcalls(double %x) {
241+
; CHECK-LABEL: f64libcalls:
242+
; CHECK: .functype f64libcalls (f64) -> (f64)
243+
; CHECK-NEXT: # %bb.0:
244+
; CHECK-NEXT: local.get $push9=, 0
245+
; CHECK-NEXT: call $push0=, sin, $pop9
246+
; CHECK-NEXT: call $push1=, cos, $pop0
247+
; CHECK-NEXT: call $push2=, tan, $pop1
248+
; CHECK-NEXT: call $push3=, asin, $pop2
249+
; CHECK-NEXT: call $push4=, acos, $pop3
250+
; CHECK-NEXT: call $push5=, atan, $pop4
251+
; CHECK-NEXT: call $push6=, sinh, $pop5
252+
; CHECK-NEXT: call $push7=, cosh, $pop6
253+
; CHECK-NEXT: call $push8=, tanh, $pop7
254+
; CHECK-NEXT: return $pop8
255+
256+
257+
%k = call double @llvm.sin.f64(double %x)
258+
%a = call double @llvm.cos.f64(double %k)
259+
%b = call double @llvm.tan.f64(double %a)
260+
%c = call double @llvm.asin.f64(double %b)
261+
%d = call double @llvm.acos.f64(double %c)
262+
%e = call double @llvm.atan.f64(double %d)
263+
%f = call double @llvm.sinh.f64(double %e)
264+
%g = call double @llvm.cosh.f64(double %f)
265+
%h = call double @llvm.tanh.f64(double %g)
266+
ret double %h
267+
}
268+
269+
define float @f32libcalls(float %x) {
270+
; CHECK-LABEL: f32libcalls:
271+
; CHECK: .functype f32libcalls (f32) -> (f32)
272+
; CHECK-NEXT: # %bb.0:
273+
; CHECK-NEXT: local.get $push9=, 0
274+
; CHECK-NEXT: call $push0=, sinf, $pop9
275+
; CHECK-NEXT: call $push1=, cosf, $pop0
276+
; CHECK-NEXT: call $push2=, tanf, $pop1
277+
; CHECK-NEXT: call $push3=, asinf, $pop2
278+
; CHECK-NEXT: call $push4=, acosf, $pop3
279+
; CHECK-NEXT: call $push5=, atanf, $pop4
280+
; CHECK-NEXT: call $push6=, sinhf, $pop5
281+
; CHECK-NEXT: call $push7=, coshf, $pop6
282+
; CHECK-NEXT: call $push8=, tanhf, $pop7
283+
; CHECK-NEXT: return $pop8
284+
285+
286+
%k = call float @llvm.sin.f32(float %x)
287+
%a = call float @llvm.cos.f32(float %k)
288+
%b = call float @llvm.tan.f32(float %a)
289+
%c = call float @llvm.asin.f32(float %b)
290+
%d = call float @llvm.acos.f32(float %c)
291+
%e = call float @llvm.atan.f32(float %d)
292+
%f = call float @llvm.sinh.f32(float %e)
293+
%g = call float @llvm.cosh.f32(float %f)
294+
%h = call float @llvm.tanh.f32(float %g)
295+
ret float %h
296+
}

0 commit comments

Comments
 (0)