From fdbae11e31bbe8edb9620ddba82c6747b9ddc9f3 Mon Sep 17 00:00:00 2001
From: oscarddssmith <oscar.smith@juliacomputing.com>
Date: Thu, 21 Oct 2021 13:56:38 -0400
Subject: [PATCH 1/3] fix overflow and undeflow for @fastmath exp

---
 base/special/exp.jl | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/base/special/exp.jl b/base/special/exp.jl
index 7e7f9b100b439..83b8e1b15e480 100644
--- a/base/special/exp.jl
+++ b/base/special/exp.jl
@@ -253,6 +253,8 @@ end
     return reinterpret(T, twopk + reinterpret(Int64, small_part))
 end
 @inline function exp_impl_fast(x::Float64, base)
+    x >= MAX_EXP(base, T) && return Inf
+    x <= -SUBNORM_EXP(base, T) && return 0.0
     T = Float64
     N_float = muladd(x, LogBo256INV(base, T), MAGIC_ROUND_CONST(T))
     N = reinterpret(UInt64, N_float) % Int32
@@ -287,6 +289,8 @@ end
 end
 
 @inline function exp_impl_fast(x::Float32, base)
+    x >= MAX_EXP(base, T) && return Inf32
+    x <= -SUBNORM_EXP(base, T) && return 0f0
     T = Float32
     N_float = round(x*LogBINV(base, T))
     N = unsafe_trunc(Int32, N_float)

From 6c9e2b98a774f5dbd0cf86815e798d26b077551c Mon Sep 17 00:00:00 2001
From: oscarddssmith <oscar.smith@juliacomputing.com>
Date: Thu, 21 Oct 2021 14:09:51 -0400
Subject: [PATCH 2/3] fixed

---
 base/special/exp.jl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/base/special/exp.jl b/base/special/exp.jl
index 83b8e1b15e480..d9afd4c7134c9 100644
--- a/base/special/exp.jl
+++ b/base/special/exp.jl
@@ -253,9 +253,9 @@ end
     return reinterpret(T, twopk + reinterpret(Int64, small_part))
 end
 @inline function exp_impl_fast(x::Float64, base)
+    T = Float64
     x >= MAX_EXP(base, T) && return Inf
     x <= -SUBNORM_EXP(base, T) && return 0.0
-    T = Float64
     N_float = muladd(x, LogBo256INV(base, T), MAGIC_ROUND_CONST(T))
     N = reinterpret(UInt64, N_float) % Int32
     N_float -=  MAGIC_ROUND_CONST(T) #N_float now equals round(x*LogBo256INV(base, T))
@@ -289,9 +289,9 @@ end
 end
 
 @inline function exp_impl_fast(x::Float32, base)
+    T = Float32
     x >= MAX_EXP(base, T) && return Inf32
     x <= -SUBNORM_EXP(base, T) && return 0f0
-    T = Float32
     N_float = round(x*LogBINV(base, T))
     N = unsafe_trunc(Int32, N_float)
     r = muladd(N_float, LogBU(base, T), x)

From e8d5678be18370503a58d8a76917e942760210e5 Mon Sep 17 00:00:00 2001
From: Oscar Smith <oscardssmith@gmail.com>
Date: Thu, 21 Oct 2021 22:44:55 -0400
Subject: [PATCH 3/3] add tests

---
 test/fastmath.jl | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/test/fastmath.jl b/test/fastmath.jl
index edaab1c6eb0cf..e93fb93330b4f 100644
--- a/test/fastmath.jl
+++ b/test/fastmath.jl
@@ -249,3 +249,13 @@ end
     @test (@fastmath "a" * "b") == "ab"
     @test (@fastmath "a" ^ 2) == "aa"
 end
+
+
+@testset "exp overflow and underflow" begin
+    for T in (Float32,Float64)
+        for func in (@fastmath exp2,exp,exp10)
+            @test func(T(2000)) == T(Inf)
+            @test func(T(-2000)) == T(0)
+        end
+    end
+end