Source

ocaml-llvm-phantom / examples / sqrt_intr.ml

Full commit
(* sqrt using via intrinsics *)

let (&) = (@@) 

open Llvm_phantom.Std
module P = Phantom

let context = Llvm.global_context () 

include Create(struct let context = context end)
open Type
(* open Value *)

include CreateModule(struct
  let name = "mymodule"
  let opt = true
end)

(* Declare "sqrt" with its type double(double) *)
let sqrt = External.declare "llvm.sqrt.f64" double (Phantom.c1 double)

let () = Value.dump sqrt

let () = assert (Llvm.is_intrinsic !<sqrt)

(* I do not know why but unlike C external function sqrt in sqrt.ml,
   LLVM intrinsics cannot be called as a function. We must use it in another function,
   or we get an error:

   LLVM ERROR: Program used external function 'llvm.sqrt.f64' which could not be resolved!

   The following is such a failure example:

    let run_sqrt = ExecutionEngine.run_function1 sqrt
    
    let run_sqrt_ocaml x = Genvalue.as_float double (run_sqrt (Genvalue.of_float double x))
    
    let () = Printf.eprintf "sqrt(3.0)=%f\n" (run_sqrt_ocaml 3.0)
*)

let main = build & func1 "main" ~dump:true 
  double (* return type *)
  ("param", double) (* the parameter *)
  & fun _self x -> call sqrt (P.c1 x)
  
let run = ExecutionEngine.run_function1 main

let run_ocaml x = Genvalue.as_float double (run (Genvalue.of_float double x))

let () = Printf.eprintf "sqrt(3.0)=%f\n" (run_ocaml 3.0)