Skip to content

Commit f4bf8a7

Browse files
Implement missing math functions in LLVM backend (#739)
Implement cos, sin, atan, tan, log, log1p, _pi, exp & pow. All functions use the LLVM intrinsics except tan & atan. They do not exist in the version of LLVM we are using. Fixes #608
1 parent b977830 commit f4bf8a7

File tree

4 files changed

+38
-0
lines changed

4 files changed

+38
-0
lines changed

examples/pos/math.check

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
1
2+
0
3+
0
4+
0
5+
1
6+
32
7+
0
8+
0
9+
1

examples/pos/math.effekt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
def main() = {
2+
println(cos(0.0))
3+
println(sin(0.0))
4+
println(log(1.0))
5+
println(log1p(0.0))
6+
println(exp(0.0))
7+
println(pow(2.0, 5.0))
8+
println(tan(0.0))
9+
println(atan(0.0))
10+
println(sin(PI / 2.0))
11+
}

libraries/common/effekt.effekt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,21 +344,25 @@ extern pure def cos(x: Double): Double =
344344
js "Math.cos(${x})"
345345
chez "(cos ${x})"
346346
vm "effekt::cos(Double)"
347+
llvm "%z = call %Double @llvm.cos.f64(double ${x}) ret %Double %z"
347348

348349
extern pure def sin(x: Double): Double =
349350
js "Math.sin(${x})"
350351
chez "(sin ${x})"
351352
vm "effekt::sin(Double)"
353+
llvm "%z = call %Double @llvm.sin.f64(double ${x}) ret %Double %z"
352354

353355
extern pure def atan(x: Double): Double =
354356
js "Math.atan(${x})"
355357
chez "(atan ${x})"
356358
vm "effekt::atan(Double)"
359+
llvm "%z = call %Double @atan(double ${x}) ret %Double %z"
357360

358361
extern pure def tan(x: Double): Double =
359362
js "Math.tan(${x})"
360363
chez "(tan ${x})"
361364
vm "effekt::tan(Double)"
365+
llvm "%z = call %Double @tan(double ${x}) ret %Double %z"
362366

363367
extern pure def sqrt(x: Double): Double =
364368
js "Math.sqrt(${x})"
@@ -381,15 +385,18 @@ extern pure def log(x: Double): Double =
381385
js "Math.log(${x})"
382386
chez "(log ${x})"
383387
vm "effekt::log(Double)"
388+
llvm "%z = call %Double @llvm.log.f64(double ${x}) ret %Double %z"
384389

385390
extern pure def log1p(x: Double): Double =
386391
js "Math.log1p(${x})"
387392
chez "(log (+ ${x} 1))"
393+
llvm "%z = call %Double @log1p(double ${x}) ret %Double %z"
388394

389395
extern pure def exp(x: Double): Double =
390396
js "Math.exp(${x})"
391397
chez "(exp ${x})"
392398
vm "effekt::exp(Double)"
399+
llvm "%z = call %Double @llvm.exp.f64(double ${x}) ret %Double %z"
393400

394401
def pow(base: Double, exponent: Int): Double = {
395402
def loop(base: Double, exponent: Int, acc: Double): Double = {
@@ -408,12 +415,14 @@ extern pure def pow(base: Double, exponent: Double): Double =
408415
js "Math.pow(${base}, ${exponent})"
409416
chez "(expt ${base} ${exponent})"
410417
vm "effekt::pow(Double, Double)"
418+
llvm "%z = call %Double @llvm.pow.f64(double ${base}, double ${exponent}) ret %Double %z"
411419

412420
// since we do not have "extern val", yet
413421
extern pure def _pi(): Double =
414422
js "Math.PI"
415423
chez "(* 4 (atan 1))"
416424
vm "effekt::pi()"
425+
llvm "ret double 3.14159265358979323846264338327950288419716939937510582097494459"
417426

418427
val PI: Double = _pi()
419428

libraries/llvm/rts.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ declare double @llvm.sqrt.f64(double)
109109
declare double @llvm.round.f64(double)
110110
declare double @llvm.ceil.f64(double)
111111
declare double @llvm.floor.f64(double)
112+
declare double @llvm.cos.f64(double)
113+
declare double @llvm.sin.f64(double)
114+
declare double @llvm.log.f64(double)
115+
declare double @llvm.exp.f64(double)
116+
declare double @llvm.pow.f64(double, double)
117+
declare double @log1p(double)
118+
; Intrinsic versions of the following two only added in LLVM 19
119+
declare double @atan(double)
120+
declare double @tan(double)
112121
declare void @print(i64)
113122
declare void @exit(i64)
114123
declare void @llvm.assume(i1)

0 commit comments

Comments
 (0)