@@ -166,13 +166,24 @@ func (b *builder) createMachineKeepAliveImpl() {
166166}
167167
168168var mathToLLVMMapping = map [string ]string {
169- "math.Ceil" : "llvm.ceil.f64" ,
170- "math.Exp" : "llvm.exp.f64" ,
171- "math.Exp2" : "llvm.exp2.f64" ,
172- "math.Floor" : "llvm.floor.f64" ,
173- "math.Log" : "llvm.log.f64" ,
174- "math.Sqrt" : "llvm.sqrt.f64" ,
175- "math.Trunc" : "llvm.trunc.f64" ,
169+ "math.Acos" : "llvm.acos.f64" ,
170+ "math.Asin" : "llvm.asin.f64" ,
171+ "math.Atan" : "llvm.atan.f64" ,
172+ "math.Atan2" : "llvm.atan2.f64" ,
173+ "math.Ceil" : "llvm.ceil.f64" ,
174+ "math.Cos" : "llvm.cos.f64" ,
175+ "math.Cosh" : "llvm.cosh.f64" ,
176+ "math.Exp" : "llvm.exp.f64" ,
177+ "math.Exp2" : "llvm.exp2.f64" ,
178+ "math.Floor" : "llvm.floor.f64" ,
179+ "math.Log" : "llvm.log.f64" ,
180+ "math.Sin" : "llvm.sin.f64" ,
181+ "math.Sincos" : "llvm.sincos.f64" ,
182+ "math.Sinh" : "llvm.sinh.f64" ,
183+ "math.Sqrt" : "llvm.sqrt.f64" ,
184+ "math.Tan" : "llvm.tan.f64" ,
185+ "math.Tanh" : "llvm.tanh.f64" ,
186+ "math.Trunc" : "llvm.trunc.f64" ,
176187}
177188
178189// defineMathOp defines a math function body as a call to a LLVM intrinsic,
@@ -185,18 +196,39 @@ var mathToLLVMMapping = map[string]string{
185196// float32(math.Sqrt(float64(v))) to a 32-bit floating point operation, which is
186197// beneficial on architectures where 64-bit floating point operations are (much)
187198// more expensive than 32-bit ones.
188- func (b * builder ) defineMathOp () {
189- b .createFunctionStart (true )
190- llvmName := mathToLLVMMapping [b .fn .RelString (nil )]
191- if llvmName == "" {
192- panic ("unreachable: unknown math operation" ) // sanity check
199+ func (b * builder ) defineMathOp () bool {
200+ llvmName , ok := mathToLLVMMapping [b .fn .RelString (nil )]
201+ if ! ok {
202+ return false
203+ }
204+ if strings .HasSuffix (b .Triple , "-wasi" ) {
205+ // We don't have a real libc for wasip2. Until that is fixed, we need to
206+ // limit math intrinsics on WASI to a subset supported natively in
207+ // WebAssembly.
208+ // Also, since we don't know the specific libc we will target, disallow
209+ // these for all WASI targets.
210+ switch b .fn .Name () {
211+ case "Ceil" , "Exp" , "Exp2" , "Floor" , "Log" , "Sqrt" , "Trunc" :
212+ default :
213+ return false
214+ }
193215 }
216+ b .createFunctionStart (true )
194217 llvmFn := b .mod .NamedFunction (llvmName )
195218 if llvmFn .IsNil () {
196219 // The intrinsic doesn't exist yet, so declare it.
197- // At the moment, all supported intrinsics have the form "double
198- // foo(double %x)" so we can hardcode the signature here.
199- llvmType := llvm .FunctionType (b .ctx .DoubleType (), []llvm.Type {b .ctx .DoubleType ()}, false )
220+ var llvmType llvm.Type
221+ switch b .fn .Name () {
222+ case "Atan2" :
223+ // double atan2(double %y, double %x)
224+ llvmType = llvm .FunctionType (b .ctx .DoubleType (), []llvm.Type {b .ctx .DoubleType (), b .ctx .DoubleType ()}, false )
225+ case "Sincos" :
226+ // {double, double} sincos(double %x)
227+ llvmType = llvm .FunctionType (b .ctx .StructType ([]llvm.Type {b .ctx .DoubleType (), b .ctx .DoubleType ()}, false ), []llvm.Type {b .ctx .DoubleType ()}, false )
228+ default :
229+ // double foo(double %x)
230+ llvmType = llvm .FunctionType (b .ctx .DoubleType (), []llvm.Type {b .ctx .DoubleType ()}, false )
231+ }
200232 llvmFn = llvm .AddFunction (b .mod , llvmName , llvmType )
201233 }
202234 // Create a call to the intrinsic.
@@ -206,6 +238,7 @@ func (b *builder) defineMathOp() {
206238 }
207239 result := b .CreateCall (llvmFn .GlobalValueType (), llvmFn , args , "" )
208240 b .CreateRet (result )
241+ return true
209242}
210243
211244func (b * builder ) defineCryptoIntrinsic () bool {
0 commit comments