Skip to content

Commit 61df653

Browse files
committed
fix evalpoly type instability and 0-length case
1 parent 0741f9b commit 61df653

File tree

2 files changed

+17
-9
lines changed

2 files changed

+17
-9
lines changed

base/math.jl

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import .Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin,
2323
using .Base: sign_mask, exponent_mask, exponent_one,
2424
exponent_half, uinttype, significand_mask,
2525
significand_bits, exponent_bits, exponent_bias,
26-
exponent_max, exponent_raw_max, clamp, clamp!
26+
exponent_max, exponent_raw_max, clamp, clamp!, reduce_empty_iter
2727

2828
using Core.Intrinsics: sqrt_llvm
2929

@@ -103,17 +103,20 @@ function evalpoly(x, p::Tuple)
103103
_evalpoly(x, p)
104104
end
105105
end
106+
evalpoly(x, ::Tuple{}) = zero(one(x)) # dimensionless zero, i.e. 0 * x^0
106107

107108
evalpoly(x, p::AbstractVector) = _evalpoly(x, p)
108109

109110
function _evalpoly(x, p)
110111
Base.require_one_based_indexing(p)
111112
N = length(p)
112-
ex = p[end]
113+
@inbounds p0 = N == 0 ? reduce_empty_iter(+, p) : p[N]
114+
s = oftype(one(x) * p0, p0)
115+
N <= 1 && return s
113116
for i in N-1:-1:1
114-
ex = muladd(x, ex, p[i])
117+
@inbounds s = muladd(x, s, p[i])
115118
end
116-
ex
119+
return s
117120
end
118121

119122
function evalpoly(z::Complex, p::Tuple)
@@ -142,16 +145,17 @@ function evalpoly(z::Complex, p::Tuple)
142145
end
143146
end
144147
evalpoly(z::Complex, p::Tuple{<:Any}) = p[1]
145-
148+
evalpoly(z::Complex, ::Tuple{}) = zero(one(z)) # dimensionless zero, i.e. 0 * z^0
146149

147150
evalpoly(z::Complex, p::AbstractVector) = _evalpoly(z, p)
148151

149152
function _evalpoly(z::Complex, p)
150153
Base.require_one_based_indexing(p)
151-
length(p) == 1 && return p[1]
152154
N = length(p)
153-
a = p[end]
154-
b = p[end-1]
155+
@inbounds p0 = N == 0 ? reduce_empty_iter(+, p) : p[N]
156+
N <= 1 && return oftype(one(z) * p0, p0)
157+
a = p0
158+
@inbounds b = p[N-1]
155159

156160
x = real(z)
157161
y = imag(z)
@@ -160,7 +164,7 @@ function _evalpoly(z::Complex, p)
160164
for i in N-2:-1:1
161165
ai = a
162166
a = muladd(r, ai, b)
163-
b = muladd(-s, ai, p[i])
167+
@inbounds b = muladd(-s, ai, p[i])
164168
end
165169
ai = a
166170
muladd(ai, z, b)

test/math.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,8 @@ end
715715
@test evalpoly(x, (p1, p2, p3)) == evpm
716716
@test evalpoly(x, [p1, p2, p3]) == evpm
717717
end
718+
@test evalpoly(1.0f0, ()) === 0.0f0 # issue #56699
719+
@test @inferred(evalpoly(1.0f0, [2])) === 2.0f0 # type-stability
718720
end
719721

720722
@testset "evalpoly complex" begin
@@ -726,6 +728,8 @@ end
726728
end
727729
@test evalpoly(1+im, (2,)) == 2
728730
@test evalpoly(1+im, [2,]) == 2
731+
@test evalpoly(1.0f0+im, ()) === 0.0f0+0im # issue #56699
732+
@test @inferred(evalpoly(1.0f0+im, [2])) === 2.0f0+0im # type-stability
729733
end
730734

731735
@testset "cis" begin

0 commit comments

Comments
 (0)