From 798a5f70df9a9f7f486a71152ddf6ee572e3d9cc Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 8 Nov 2016 11:53:26 +0000 Subject: [PATCH] Revert "runtime: remove some redundant libm functions copied inline." This reverts commit fee75bd50f9240b7b0377291718d7354498c9b62. LLVM does not have lround as a libcall and this inhibits LICM. --- .../compiler/transforms/llvm_ir_generator.py | 9 +++--- artiq/runtime.rs/libksupport/api.rs | 2 +- artiq/runtime/ksupport_glue.c | 29 +++++++++++++++++-- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/artiq/compiler/transforms/llvm_ir_generator.py b/artiq/compiler/transforms/llvm_ir_generator.py index e9643aa04..c86888a0f 100644 --- a/artiq/compiler/transforms/llvm_ir_generator.py +++ b/artiq/compiler/transforms/llvm_ir_generator.py @@ -323,6 +323,8 @@ class LLVMIRGenerator: llty = ll.FunctionType(llvoid, []) elif name == "llvm.floor.f64": llty = ll.FunctionType(lldouble, [lldouble]) + elif name == "llvm.round.f64": + llty = ll.FunctionType(lldouble, [lldouble]) elif name == "llvm.pow.f64": llty = ll.FunctionType(lldouble, [lldouble, lldouble]) elif name == "llvm.powi.f64": @@ -347,8 +349,6 @@ class LLVMIRGenerator: llty = ll.FunctionType(lli32, [llptr]) elif name == "strcmp": llty = ll.FunctionType(lli32, [llptr, llptr]) - elif name == "lround": - llty = ll.FunctionType(lli32, [lldouble]) elif name == "send_rpc": llty = ll.FunctionType(llvoid, [lli32, llptr, llptrptr]) elif name == "send_async_rpc": @@ -1044,8 +1044,9 @@ class LLVMIRGenerator: name=insn.name) elif insn.op == "round": llarg = self.map(insn.operands[0]) - return self.llbuilder.call(self.llbuiltin("lround"), [llarg], - name=insn.name) + llvalue = self.llbuilder.call(self.llbuiltin("llvm.round.f64"), [llarg]) + return self.llbuilder.fptosi(llvalue, self.llty_of_type(insn.type), + name=insn.name) elif insn.op == "globalenv": def get_outer(llenv, env_ty): if "$outer" in env_ty.params: diff --git a/artiq/runtime.rs/libksupport/api.rs b/artiq/runtime.rs/libksupport/api.rs index 81c4d75df..5f9d7f967 100644 --- a/artiq/runtime.rs/libksupport/api.rs +++ b/artiq/runtime.rs/libksupport/api.rs @@ -74,7 +74,7 @@ static mut API: &'static [(&'static str, *const ())] = &[ /* libm */ api!(sqrt), - api!(lround), + api!(round), /* exceptions */ api!(_Unwind_Resume), diff --git a/artiq/runtime/ksupport_glue.c b/artiq/runtime/ksupport_glue.c index 515635c94..f0d496dc3 100644 --- a/artiq/runtime/ksupport_glue.c +++ b/artiq/runtime/ksupport_glue.c @@ -70,10 +70,33 @@ int dl_iterate_phdr (int (*callback)(struct dl_phdr_info *, size_t, void *), voi } /* called by kernel */ -long lround(double x); -long lround(double x) +double round(double x); +double round(double x) { - return x < 0 ? floor(x) : ceil(x); + union {double f; uint64_t i;} u = {x}; + int e = u.i >> 52 & 0x7ff; + double y; + + if (e >= 0x3ff+52) + return x; + if (u.i >> 63) + x = -x; + if (e < 0x3ff-1) { + /* we don't do it in ARTIQ */ + /* raise inexact if x!=0 */ + // FORCE_EVAL(x + 0x1p52); + return 0*u.f; + } + y = (double)(x + 0x1p52) - 0x1p52 - x; + if (y > 0.5) + y = y + x - 1; + else if (y <= -0.5) + y = y + x + 1; + else + y = y + x; + if (u.i >> 63) + y = -y; + return y; } /* called by kernel */