ITADN

Equivalent CodeInstance query (`jl_get_ci_equiv`) only checks ABI-equivalence before replacement

#62021Opentopolarity 创建于 2026-06-05
bugcompiler:inferenceinvalidcorrectness bug ⚠
T
topolaritycommented
Noticed this while working on TypedCallable. We use this equivalence predicate to check whether an invokee CodeInstance can be swapped out for another in the cache before codegen: https://github.com/JuliaLang/julia/blob/f89b5396b713101b2be0a2c47a45de4e16b441f4/Compiler/src/typeinfer.jl#L1723-L1731 and then to support invoking the cached "equivalent" CI, our AOT / JIT codegen has a very similar notion of "equivalence" to choose a target CI: https://github.com/JuliaLang/julia/blob/f89b5396b713101b2be0a2c47a45de4e16b441f4/src/jitlayers.cpp#L2331-L2334 but notably this does not replace the CodeInstance in the `:invoke` or `.edges` of the CI. IPO-safety guarantees us that this replacement is sound even if the `exct`, `ipo_purity_bits`, etc. from the new CodeInstance are wide compared to the CI originally inferred against, but this guarantee only applies point-wise in world age - it requires that we continue to respect the world / invalidation bounds for the invoked CI. My concern is that if later the "equivalent" CI is invalidated but your original CI in your `.edges` was not, it seems that this can become a stale invalidation bug. Even before then, it appears that the world bounds for the produced CI can be invalid if the "equivalent" CI has a more narrow world range. If reachable this bug is quite hard to hit in practice, since it relies on two different runs for the same `MethodInstance` yielding appreciably different inference results, which for the time being ~usually only happens due to cache effects, etc. I put Claude 🤖 on reproducing, but we've gotten sidetracked after discovering other missing edges.
2 条评论