diff --git a/base/boot.jl b/base/boot.jl index 71152e6c116ae..3095da73e6c5d 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -152,7 +152,7 @@ export #checked_smul, checked_ssub, checked_uadd, checked_umul, checked_usub, #nan_dom_err, copysign_float, ctlz_int, ctpop_int, cttz_int, #div_float, eq_float, eq_int, eqfsi64, eqfui64, flipsign_int, select_value, - #fpext64, fpiseq, fpislt, fpsiround, fpuiround, fptosi, fptoui, + #sqrt_llvm, fpext64, fpiseq, fpislt, fpsiround, fpuiround, fptosi, fptoui, #fptrunc32, le_float, lefsi64, lefui64, lesif64, #leuif64, lshr_int, lt_float, ltfsi64, ltfui64, ltsif64, ltuif64, mul_float, #mul_int, ne_float, ne_int, neg_float, neg_int, not_int, or_int, rem_float, diff --git a/base/math.jl b/base/math.jl index bbbfc87b7b265..8bb798d42b017 100644 --- a/base/math.jl +++ b/base/math.jl @@ -22,7 +22,7 @@ import Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin, acos, atan, asinh, acosh, atanh, sqrt, log2, log10, max, min, minmax, ceil, floor, trunc, round, ^, exp2, exp10 -import Core.Intrinsics.nan_dom_err +import Core.Intrinsics: nan_dom_err, sqrt_llvm, box, unbox # non-type specific math functions @@ -272,7 +272,7 @@ exp10(x::Integer) = exp10(float(x)) # functions that return NaN on non-NaN argument for domain error for f in (:sin, :cos, :tan, :asin, :acos, :acosh, :atanh, :log, :log2, :log10, - :lgamma, :sqrt, :log1p) + :lgamma, :log1p) @eval begin ($f)(x::Float64) = nan_dom_err(ccall(($(string(f)),libm), Float64, (Float64,), x), x) ($f)(x::Float32) = nan_dom_err(ccall(($(string(f,"f")),libm), Float32, (Float32,), x), x) @@ -281,6 +281,11 @@ for f in (:sin, :cos, :tan, :asin, :acos, :acosh, :atanh, :log, :log2, :log10, end end +sqrt(x::Float64) = nan_dom_err(box(Float64,sqrt_llvm(unbox(Float64,x))), x) +sqrt(x::Float32) = nan_dom_err(box(Float32,sqrt_llvm(unbox(Float32,x))), x) +sqrt(x::Real) = sqrt(float(x)) +@vectorize_1arg Number sqrt + for f in (:ceil, :trunc, :significand) # :rint, :nearbyint @eval begin ($f)(x::Float64) = ccall(($(string(f)),libm), Float64, (Float64,), x) diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index 3001dbbdbbd84..60667097efd0e 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -34,6 +34,7 @@ namespace JL_I { nan_dom_err, // functions abs_float, copysign_float, flipsign_int, select_value, + sqrt_llvm, // pointer access pointerref, pointerset, pointertoref, // c interface @@ -1243,6 +1244,12 @@ static Value *emit_intrinsic(intrinsic f, jl_value_t **args, size_t nargs, HANDLE(jl_alloca,1) { return builder.CreateAlloca(IntegerType::get(jl_LLVMContext, 8),JL_INT(x)); } + HANDLE(sqrt_llvm,1) { + x = FP(x); + return builder.CreateCall(Intrinsic::getDeclaration(jl_Module, Intrinsic::sqrt, + ArrayRef(x->getType())), + x); + } default: assert(false); } @@ -1321,7 +1328,7 @@ extern "C" void jl_init_intrinsic_functions(void) ADD_I(uitofp); ADD_I(sitofp); ADD_I(fptrunc); ADD_I(fpext); ADD_I(abs_float); ADD_I(copysign_float); - ADD_I(flipsign_int); ADD_I(select_value); + ADD_I(flipsign_int); ADD_I(select_value); ADD_I(sqrt_llvm); ADD_I(pointerref); ADD_I(pointerset); ADD_I(pointertoref); ADD_I(checked_sadd); ADD_I(checked_uadd); ADD_I(checked_ssub); ADD_I(checked_usub);