Skip to content

Commit ecc050c

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

File tree

2 files changed

+252
-0
lines changed

2 files changed

+252
-0
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp

Lines changed: 18 additions & 0 deletions
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;
Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
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 double @f64libcalls(double %x) {
179+
; CHECK-LABEL: f64libcalls:
180+
; CHECK: .functype f64libcalls (f64) -> (f64)
181+
; CHECK-NEXT: # %bb.0:
182+
; CHECK-NEXT: local.get $push9=, 0
183+
; CHECK-NEXT: call $push0=, sin, $pop9
184+
; CHECK-NEXT: call $push1=, cos, $pop0
185+
; CHECK-NEXT: call $push2=, tan, $pop1
186+
; CHECK-NEXT: call $push3=, asin, $pop2
187+
; CHECK-NEXT: call $push4=, acos, $pop3
188+
; CHECK-NEXT: call $push5=, atan, $pop4
189+
; CHECK-NEXT: call $push6=, sinh, $pop5
190+
; CHECK-NEXT: call $push7=, cosh, $pop6
191+
; CHECK-NEXT: call $push8=, tanh, $pop7
192+
; CHECK-NEXT: return $pop8
193+
194+
195+
%k = call double @llvm.sin.f64(double %x)
196+
%a = call double @llvm.cos.f64(double %k)
197+
%b = call double @llvm.tan.f64(double %a)
198+
%c = call double @llvm.asin.f64(double %b)
199+
%d = call double @llvm.acos.f64(double %c)
200+
%e = call double @llvm.atan.f64(double %d)
201+
%f = call double @llvm.sinh.f64(double %e)
202+
%g = call double @llvm.cosh.f64(double %f)
203+
%h = call double @llvm.tanh.f64(double %g)
204+
ret double %h
205+
}
206+
207+
define float @f32libcalls(float %x) {
208+
; CHECK-LABEL: f32libcalls:
209+
; CHECK: .functype f32libcalls (f32) -> (f32)
210+
; CHECK-NEXT: # %bb.0:
211+
; CHECK-NEXT: local.get $push9=, 0
212+
; CHECK-NEXT: call $push0=, sinf, $pop9
213+
; CHECK-NEXT: call $push1=, cosf, $pop0
214+
; CHECK-NEXT: call $push2=, tanf, $pop1
215+
; CHECK-NEXT: call $push3=, asinf, $pop2
216+
; CHECK-NEXT: call $push4=, acosf, $pop3
217+
; CHECK-NEXT: call $push5=, atanf, $pop4
218+
; CHECK-NEXT: call $push6=, sinhf, $pop5
219+
; CHECK-NEXT: call $push7=, coshf, $pop6
220+
; CHECK-NEXT: call $push8=, tanhf, $pop7
221+
; CHECK-NEXT: return $pop8
222+
223+
224+
%k = call float @llvm.sin.f32(float %x)
225+
%a = call float @llvm.cos.f32(float %k)
226+
%b = call float @llvm.tan.f32(float %a)
227+
%c = call float @llvm.asin.f32(float %b)
228+
%d = call float @llvm.acos.f32(float %c)
229+
%e = call float @llvm.atan.f32(float %d)
230+
%f = call float @llvm.sinh.f32(float %e)
231+
%g = call float @llvm.cosh.f32(float %f)
232+
%h = call float @llvm.tanh.f32(float %g)
233+
ret float %h
234+
}

0 commit comments

Comments
 (0)