Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

complete effect inference failure when repeating effect inference #56321

Open
nsajko opened this issue Oct 25, 2024 · 4 comments
Open

complete effect inference failure when repeating effect inference #56321

nsajko opened this issue Oct 25, 2024 · 4 comments
Labels
backport 1.10 Change should be backported to the 1.10 release compiler:effects effect analysis

Comments

@nsajko
Copy link
Contributor

nsajko commented Oct 25, 2024

Reproducer:

module Zeros
    export Zero
    struct Zero end
end

module PositiveIntegers
    module RecursiveStep
        using ...Zeros
        export recursive_step
        function recursive_step(@nospecialize t::Type)
            Union{Zero, t}
        end
    end
    module UpperBounds
        using ..RecursiveStep
        abstract type A end
        abstract type B{P <: recursive_step(A)} <: A    end
        abstract type C{P <: recursive_step(B)} <: B{P} end
    end
    const PositiveIntegerUpperBound = UpperBounds.A
    const PositiveIntegerUpperBoundTighter = UpperBounds.C
    using .RecursiveStep
    export
        natural_successor, natural_predecessor,
        NonnegativeInteger, NonnegativeIntegerUpperBound,
        PositiveInteger, PositiveIntegerUpperBound,
        type_assert_nonnegative_integer, type_assert_positive_integer
    struct PositiveInteger{
        Predecessor <: recursive_step(PositiveIntegerUpperBoundTighter),
    } <: PositiveIntegerUpperBoundTighter{Predecessor}
        predecessor::Predecessor
        global const NonnegativeInteger = recursive_step(PositiveInteger)
        global const NonnegativeIntegerUpperBound = recursive_step(PositiveIntegerUpperBound)
        global function natural_successor(p::P) where {P <: NonnegativeInteger}
            r = new{P}(p)
            type_assert_positive_integer(r)
        end
    end
    function type_assert_nonnegative_integer(@nospecialize x::NonnegativeInteger)
        x
    end
    function type_assert_positive_integer(@nospecialize x::PositiveInteger)
        x
    end
    function natural_predecessor(@nospecialize o::PositiveInteger)
        r = o.predecessor
        type_assert_nonnegative_integer(r)
    end
end

module IntegersGreaterThanOne
    using ..PositiveIntegers
    export IntegerGreaterThanOne, IntegerGreaterThanOneUpperBound
    const IntegerGreaterThanOne = let t = PositiveInteger
        t{P} where {P <: t}
    end
    const IntegerGreaterThanOneUpperBound = let t = PositiveIntegerUpperBound
        PositiveIntegers.UpperBounds.B{P} where {P <: t}
    end
end

module Utils
    using ..Zeros, ..PositiveIntegers, ..IntegersGreaterThanOne
    export minus_two, half_floor
    function minus_two(@nospecialize m::IntegerGreaterThanOne)
        natural_predecessor(natural_predecessor(m))
    end
    function half_floor(@nospecialize m::NonnegativeInteger)
        ret = if m isa IntegerGreaterThanOneUpperBound
            let n = minus_two(m), rec = @inline half_floor(n)
                type_assert_positive_integer(natural_successor(rec))
            end
        else
            Zero()
        end
        type_assert_nonnegative_integer(ret)
    end
end

V1.10 works fine, on v1.11 and v1.12 this happens:

julia> include("/home/nsajko/tuple_sorting/reproducer.jl")
Main.Utils

julia> Base.infer_effects(Utils.half_floor)  # OK
(+c,+e,!n,!t,+s,?m,+u,+o,+r)

julia> Base.infer_effects(Utils.half_floor)  # ?!??
(!c,!e,!n,!t,!s,!m,!u,!o,!r)

julia> versioninfo()
Julia Version 1.12.0-DEV.1466
Commit 73b85cfc04d (2024-10-23 01:12 UTC)
Build Info:
  Official https://julialang.org release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-18.1.7 (ORCJIT, znver2)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
Environment:
  JULIA_NUM_PRECOMPILE_TASKS = 4
  JULIA_PKG_PRECOMPILE_AUTO = 0
@nsajko nsajko added compiler:effects effect analysis regression 1.11 Regression in the 1.11 release regression 1.12 Regression in the 1.12 release bisect wanted labels Oct 25, 2024
@nsajko
Copy link
Contributor Author

nsajko commented Oct 25, 2024

Bisecting. It seems there are two different events of interest here:

  1. At some point the good effect inference of v1.10 turned bad.
  2. At some point after that, the effect inference became good again, but only for the first Base.infer_effects call, as shown above.

@nsajko
Copy link
Contributor Author

nsajko commented Oct 25, 2024

Bisected the first event to 631b5c3 #51092. cc @vtjnash

@vtjnash vtjnash added backport 1.10 Change should be backported to the 1.10 release and removed regression 1.11 Regression in the 1.11 release regression 1.12 Regression in the 1.12 release bisect wanted labels Oct 25, 2024
@nsajko
Copy link
Contributor Author

nsajko commented Oct 25, 2024

Bisected the second event to 65aeaf6 #54323. cc @aviatesk

Before:

julia> include("/tmp/reproducer.jl")
Main.Utils

julia> Base.infer_effects(Utils.half_floor)
(!c,!e,!n,!t,!s,!m,!u)′

julia> Base.infer_effects(Utils.half_floor)
(!c,!e,!n,!t,!s,!m,!u)′

julia> versioninfo()
Julia Version 1.12.0-DEV.654
Commit 583981fb43c (2024-06-05 00:17 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-17.0.6 (ORCJIT, znver2)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
Environment:
  JULIA_NUM_PRECOMPILE_TASKS = 4
  JULIA_PKG_PRECOMPILE_AUTO = 0

After:

julia> include("/tmp/reproducer.jl")
Main.Utils

julia> Base.infer_effects(Utils.half_floor)
(+c,+e,!n,!t,+s,?m,+u)

julia> Base.infer_effects(Utils.half_floor)
(!c,!e,!n,!t,!s,!m,!u)′

julia> versioninfo()
Julia Version 1.12.0-DEV.655
Commit 65aeaf6c652 (2024-06-05 01:11 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-17.0.6 (ORCJIT, znver2)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
Environment:
  JULIA_NUM_PRECOMPILE_TASKS = 4
  JULIA_PKG_PRECOMPILE_AUTO = 0

@nsajko
Copy link
Contributor Author

nsajko commented Oct 25, 2024

I guess it should be possible to somehow preserve the good effect inference result in subsequent effect inference queries, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport 1.10 Change should be backported to the 1.10 release compiler:effects effect analysis
Projects
None yet
Development

No branches or pull requests

2 participants