Simple example:
function calc(x, y, z)
if z > 5
throw(ArgumentError("z ($z) must to be โค 5."))
end
x + y * z
end
function calc_z(n)
z = 0
try
while calc(0, 3, z) < n
z += 1
end
catch ex
if ex isa ArgumentError
# pass
else
rethrow()
end
end
z - 1
end
calc_z(10)
# => 3, expected
calc_z(20)
# => -1, unexpected, 5 is expected
Is this correct behavior on Julia v0.7?
(On Julia v0.6, calc_z(20) returns 5 as I expect)
versioninfo():
Julia Version 0.7.0-beta2.0
Commit b145832402* (2018-07-13 19:54 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin14.5.0)
CPU: Intel(R) Core(TM) i7-5557U CPU @ 3.10GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.0 (ORCJIT, broadwell)
see details: https://gist.github.com/antimon2/1dca9305e9aee13a4df642076e95c4c3
When the exception is caught, z is reverting to its pre-try-block value (0). @Keno seems to be ฯแถ-related.
MWE:
julia> @noinline make_error(n) = n == 5 ? error() : true
make_error (generic function with 1 method)
julia> function foo()
z = 0
try
while make_error(z)
z+=1
end
catch end
return z
end
foo (generic function with 1 method)
julia> foo()
0
Thanks, the bug in the MWE is very obvious:
julia> @code_typed foo()
CodeInfo(
1 โ nothing โ
3 2 โ :($(Expr(:enter, 4))) โ
4 3 โ %3 = ฯ (2 => 0, 3 => %6)::Int64 โ
โ %4 = ฯ (0)::Int64 โ
โ invoke Main.make_error(%3::Int64) โ
5 โ %6 = Base.add_int(%3, 1)::Int64 โโป +
โ %7 = ฯ (%6)::Int64 โ
โโโ goto 3 โ
4 โ %9 = ฯแถ (%4, %7)::Int64 โ
โโโ :($(Expr(:leave, 1))) โ
8 5 โ return %9 โ
6 โ goto 4 โ
) => Int64
The initial upsilon node is placed in the first BB after the enter, but that also happens to be the target of the backedge from the while loop, so the value of the phic gets reset. I'll see if we can insert an extra BB to break the critical edge. Alternatively, we may be able to add the initial Upsilon nodes in the :enter BB
@Keno If you have some time available, do you mind explaining what the problem was? What does " ฯแถ-related" mean?
ฯแถ nodes are one of the node types of the extended SSA representation of the new optimizer in Julia 0.7. See documentation here: https://github.com/JuliaLang/julia/blob/master/doc/src/devdocs/ssair.md#phic-nodes-and-upsilon-nodes
Most helpful comment
Thanks, the bug in the MWE is very obvious:
The initial upsilon node is placed in the first BB after the enter, but that also happens to be the target of the backedge from the while loop, so the value of the phic gets reset. I'll see if we can insert an extra BB to break the critical edge. Alternatively, we may be able to add the initial Upsilon nodes in the :enter BB