Skip to content

Commit

Permalink
Use native fmin/fmax in aarch64 (#47814)
Browse files Browse the repository at this point in the history
* Use native fmin in aarch64

* Small cleanup + effects

* Cleanup

* Update base/math.jl

Co-authored-by: Valentin Churavy <[email protected]>

* Some more cleanup

Co-authored-by: Valentin Churavy <[email protected]>
  • Loading branch information
gbaraldi and vchuravy authored Jan 3, 2023
1 parent 4831361 commit 52af407
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -851,26 +851,45 @@ minmax(x::T, y::T) where {T<:AbstractFloat} = min(x, y), max(x, y)

_isless(x::Float16, y::Float16) = signbit(widen(x) - widen(y))

const has_native_fminmax = Sys.ARCH === :aarch64
@static if has_native_fminmax
@eval begin
Base.@assume_effects :total @inline llvm_min(x::Float64, y::Float64) = ccall("llvm.minimum.f64", llvmcall, Float64, (Float64, Float64), x, y)
Base.@assume_effects :total @inline llvm_min(x::Float32, y::Float32) = ccall("llvm.minimum.f32", llvmcall, Float32, (Float32, Float32), x, y)
Base.@assume_effects :total @inline llvm_max(x::Float64, y::Float64) = ccall("llvm.maximum.f64", llvmcall, Float64, (Float64, Float64), x, y)
Base.@assume_effects :total @inline llvm_max(x::Float32, y::Float32) = ccall("llvm.maximum.f32", llvmcall, Float32, (Float32, Float32), x, y)
end
end

function min(x::T, y::T) where {T<:Union{Float32,Float64}}
@static if has_native_fminmax
return llvm_min(x,y)
end
diff = x - y
argmin = ifelse(signbit(diff), x, y)
anynan = isnan(x)|isnan(y)
ifelse(anynan, diff, argmin)
return ifelse(anynan, diff, argmin)
end

function max(x::T, y::T) where {T<:Union{Float32,Float64}}
@static if has_native_fminmax
return llvm_max(x,y)
end
diff = x - y
argmax = ifelse(signbit(diff), y, x)
anynan = isnan(x)|isnan(y)
ifelse(anynan, diff, argmax)
return ifelse(anynan, diff, argmax)
end

function minmax(x::T, y::T) where {T<:Union{Float32,Float64}}
@static if has_native_fminmax
return llvm_min(x, y), llvm_max(x, y)
end
diff = x - y
sdiff = signbit(diff)
min, max = ifelse(sdiff, x, y), ifelse(sdiff, y, x)
anynan = isnan(x)|isnan(y)
ifelse(anynan, diff, min), ifelse(anynan, diff, max)
return ifelse(anynan, diff, min), ifelse(anynan, diff, max)
end

"""
Expand Down

0 comments on commit 52af407

Please sign in to comment.