llvm-hs / llvm-hs-examples

Examples for Haskell bindings to LLVM
MIT License
70 stars 20 forks source link

Llvm 12 updates #14

Closed jrp2014 closed 3 years ago

jrp2014 commented 3 years ago

This PR updates the examples for llvm-12.

The only example that doesn't fully work is arith, which segfaults when the JIT'd function f is evaluated. Not clear why, but presumably because the external references to sin etc are not properly resolved. Suggestions welcome.

jrp2014 commented 3 years ago

OK, so the good news is that this works on linux, but doesn't work on MacOS, with ghc 8.10.4. The only resource I have been able to find is https://purelyfunctional.org/posts/2018-04-02-llvm-hs-jit-external-function.html but that applies to linux, so far as I can see. Suggestions welcome.

$ cabal run arith
Up to date
*** Codegen ***
; ModuleID = 'arith.ll'

declare external ccc  double @llvm.sin.f64(double)    

declare external ccc  double @llvm.sqrt.f64(double)    

define external ccc  double @f(double  %x_0)    {
  %x_1 = fmul        double 3.141593e0, %x_0 
  %x_2 = fdiv        double %x_1, 2.000000e0 
  %x_3 =  call ccc  double  @llvm.sin.f64(double  %x_2)  
  %x_4 =  call ccc  double  @llvm.sqrt.f64(double  %x_0)  
  %x_5 = fadd        double 1.000000e0, %x_4 
  %x_6 =  call ccc  double  @llvm.sqrt.f64(double  %x_0)  
  %x_7 = fadd        double 1.000000e0, %x_6 
  %x_8 = fmul        double %x_5, %x_7 
  %x_9 = fmul        double %x_3, %x_8 
  ret double %x_9 
}
*** Expression ***

\x -> sin(3.141592653589793 * x / 2.0) * (1.0 + sqrt(x)) * (1.0 + sqrt(x))

*** LLVM IR ***

; ModuleID = 'arith.ll'
source_filename = "<string>"

declare double @llvm.sin.f64(double)

declare double @llvm.sqrt.f64(double)

define double @f(double %x_0) {
  %x_1 = fmul double 0x400921FB54442D18, %x_0
  %x_2 = fdiv double %x_1, 2.000000e+00
  %x_3 = call double @llvm.sin.f64(double %x_2)
  %x_4 = call double @llvm.sqrt.f64(double %x_0)
  %x_5 = fadd double 1.000000e+00, %x_4
  %x_6 = call double @llvm.sqrt.f64(double %x_0)
  %x_7 = fadd double 1.000000e+00, %x_6
  %x_8 = fmul double %x_5, %x_7
  %x_9 = fmul double %x_3, %x_8
  ret double %x_9
}

*** Optimized ***

*** LLVM IR ***

; ModuleID = 'arith.ll'
source_filename = "<string>"

declare double @llvm.sin.f64(double)

declare double @llvm.sqrt.f64(double)

define double @f(double %x_0) local_unnamed_addr {
  %x_1 = fmul double %x_0, 0x400921FB54442D18
  %x_2 = fmul double %x_1, 5.000000e-01
  %x_3 = tail call double @llvm.sin.f64(double %x_2)
  %x_4 = tail call double @llvm.sqrt.f64(double %x_0)
  %x_5 = fadd double %x_4, 1.000000e+00
  %x_6 = tail call double @llvm.sqrt.f64(double %x_0)
  %x_7 = fadd double %x_6, 1.000000e+00
  %x_8 = fmul double %x_5, %x_7
  %x_9 = fmul double %x_3, %x_8
  ret double %x_9
}

*** Result ***

results match
[0.0,4.0,7.137764622384033e-16,-7.464101615137754,-2.204364238465236e-15,10.47213595499958,4.3716141420356565e-15,-13.291502622129181,-7.179787856884051e-15,16.0,1.0608230609850833e-14]