-
Notifications
You must be signed in to change notification settings - Fork 10
Open
Description
In the following MWE:
using Libtask
function g(y)
produce(y + 1)
end
Libtask.might_produce(::Type{Tuple{typeof(g),Int}}) = true
function f(x)
if x == 1
y = 2
end
# `g` must produce.
# Also, there must be at least two calls to `produce` in the function.
g(y)
g(y)
return 1
end
f(1)
t = TapedTask(nothing, f, 1)f(1) generates this IR:
2 1 ─ %1 = (_2 === 1)::Bool
└── goto #3 if not %1
2 ─ nothing::Nothing
5 3 ┄ %4 = φ (#2 => true, #1 => false)::Bool
│ $(Expr(:throw_undef_if_not, :y, :(%4)))::Any
│ invoke Main.produce(3::Int64)::Int64
6 │ $(Expr(:throw_undef_if_not, :y, :(%4)))::Any
│ invoke Main.produce(3::Int64)::Int64
7 └── return 1which Libtask transforms into this IR:
2 1 ─ %1 = (Libtask.resume_block_is)(_1, 14)::Any
│ %2 = (Libtask.resume_block_is)(_1, 11)::Any
└── nothing::Any
2 ─ goto #8 if not %1
3 ─ goto #9 if not %2
4 ─ goto #5
5 ─ %7 = (_3 === 1)::Bool
│ (Libtask.set_ref_at!)(_1, 1, %7)::Any
│ %9 = (Libtask.get_ref_at)(_1, 1)::Any
└── goto #7 if not %9
6 ─ nothing::Nothing
└── goto #7
7 ┄ %13 = φ (#6 => true, #5 => false)::Any
│ %14 = (Libtask.deref_phi)(_1, %13)::Any
│ (Libtask.set_ref_at!)(_1, 2, %14)::Any
5 │ $(Expr(:throw_undef_if_not, :y, :(%14)))::Any
2 │ (Libtask.set_resume_block!)(_1, 14)::Any
│ %18 = (Libtask.ProducedValue)(3)::Any
└── return %18
6 8 ─ $(Expr(:throw_undef_if_not, :y, :(%14)))::Any
2 │ (Libtask.set_resume_block!)(_1, 11)::Any
│ %22 = (Libtask.ProducedValue)(3)::Any
└── return %22
9 ─ (Libtask.set_resume_block!)(_1, -1)::Any
7 └── return 1which errors with
Basic Block 7 does not dominate block 8 (tried to use value %14 at %20)when constructing a TapedTask. The issue is that Libtask inserts resume points before the :throw_undef_if_not expressions, which means that if the function is resumed from one of these points, %14 isn't defined (because the check that defines it was run earlier).
This is the same issue as #200, but minimised to remove the Turing dep.
I'm opening a separate issue because there's an downstream fix for the Turing model at TuringLang/DynamicPPL.jl#1110, and I think that's easier to merge and release than a more general fix for this kind of thing.
Metadata
Metadata
Assignees
Labels
No labels