From 36969687fb9bbd936b3adc0baa6cf0a408d2ccb7 Mon Sep 17 00:00:00 2001 From: Stefan Karpinski Date: Fri, 25 Apr 2014 10:33:06 -0400 Subject: [PATCH] Work around LLVM's dickish undefined constant folding behavior. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LLVM's fptosi intrinsic is undefined for NaN, so LLVM obnoxiously and pointlessly does different things when it gets NaN as a run-time value than as a compile-time value. To avoid this shitty, pointless trap, we have to avoid calling fptosi on NaN by introducing a branch into the hashing function – even though for hashing, we don't care *what* value is produced, just as long as it's consistent. Unfortunately, this affects the performance of Float64 hashing pretty badly. I was not able to figure out any way to recover this lost performance. LLVM really needs to stop doing this. --- base/hashing.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/hashing.jl b/base/hashing.jl index 0da7bbbce9ab9..53fd24305c45f 100644 --- a/base/hashing.jl +++ b/base/hashing.jl @@ -30,10 +30,11 @@ end ## hashing small, built-in numeric types ## hx(a::Uint64, b::Float64, h::Uint) = hash_uint((3a + reinterpret(Uint64,b)) - h) +const hx_NaN = hx(uint(0), NaN, uint(0)) hash(x::Uint64, h::Uint) = hx(x, float64(x), h) hash(x::Int64, h::Uint) = hx(reinterpret(Uint64,x), float64(x), h) -hash(x::Float64, h::Uint) = hx(box(Uint64,fptosi(unbox(Float64,x))), ifelse(isnan(x), NaN, x), h) +hash(x::Float64, h::Uint) = isnan(x) ? (hx_NaN $ h) : hx(box(Uint64,fptosi(unbox(Float64,x))), x, h) hash(x::Union(Int8,Uint8,Int16,Uint16,Int32,Uint32), h::Uint) = hash(int64(x), h) hash(x::Float32, h::Uint) = hash(float64(x), h)