Skip to content

Error in max_double implementation #57119

@eschnett

Description

@eschnett

I see this strange behaviour in Julia 1.12-dev (todays nightly build), first reported at MakieOrg/Makie.jl#4729:

julia> using IntervalSets

julia> f(x) = (iv=0.0..1.0; mod(x,iv))
f (generic function with 1 method)

julia> f(0.0)
NaN

The correct result is 0.0, and this works fine in Julia 1.11, and also when mod is called directly instead of in a function (mod(0.0, 0.0..1.0)).

I believe this is a bug in Julia's constant propagation mechanism. I have posted more details in the Makie.jl issue.

I see that Julia determines already at compile time that the call to mod will return NaN:

julia> @code_warntype f(0.0)
MethodInstance for f(::Float64)
  from f(x) @ Main REPL[1]:1
Arguments
  #self#::Core.Const(Main.f)
  x::Float64
Locals
  iv::ClosedInterval{Float64}
Body::Float64
1%1 = Main.:..::Core.Const(IntervalSets...)
│        (iv = (%1)(0.0, 1.0))
│   %3 = Main.mod::Core.Const(mod)
│   %4 = iv::Core.Const(0.0 .. 1.0)
│   %5 = (%3)(x, %4)::Core.Const(NaN)
└──      return %5

IntervalSets' mod function is

mod(x, i::TypedEndpointsInterval{:closed,:closed}) = mod(x - leftendpoint(i), width(i)) + leftendpoint(i)

and its width function is

function width(A::AbstractInterval)
    _width = rightendpoint(A) - leftendpoint(A)
    max(zero(_width), _width)   # this works when T is a Date
end

I find that removing the line calling max avoids the problem. It seems to me that this line somehow confuses Julia into assuming that the second argument to mod is 0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIndicates an unexpected problem or unintended behaviormathsMathematical functionsregression 1.12Regression in the 1.12 release

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions