Skip to content

Commit 678fe46

Browse files
committed
post-opt: add more test cases for visit_conditional_successors (#53642)
This commit fixes the first problem that was found while digging into #53613. It turns out that the post-domtree constructed from regular `IRCode` doesn't work for visiting conditional successors for post-opt analysis in cases like: ```julia julia> let code = Any[ # block 1 GotoIfNot(Argument(2), 3), # block 2 ReturnNode(Argument(3)), # block 3 (we should visit this block) Expr(:call, throw, "potential throw"), ReturnNode(), # unreachable ] ir = make_ircode(code; slottypes=Any[Any,Bool,Bool]) visited = BitSet() @test !Core.Compiler.visit_conditional_successors(CC.LazyPostDomtree(ir), ir, #=bb=#1) do succ::Int push!(visited, succ) return false end @test 2 ∉ visited @test 3 ∈ visited end Test Failed at REPL[14]:16 Expression: 2 ∉ visited Evaluated: 2 ∉ BitSet([2]) ``` This might mean that we need to fix on the `postdominates` end, but for now, this commit tries to get around it by using the augmented post domtree in `visit_conditional_successors`. Since the augmented post domtree is enforced to have a single return, we can keep using the current `postdominates` to fix the issue. However, this commit isn't enough to fix the NeuralNetworkReachability segfault as reported in #53613, and we need to tackle the second issue reported there too (#53613 (comment)).
1 parent eb9c9b8 commit 678fe46

File tree

3 files changed

+67
-11
lines changed

3 files changed

+67
-11
lines changed

base/compiler/optimize.jl

+2
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,8 @@ function any_stmt_may_throw(ir::IRCode, bb::Int)
533533
return false
534534
end
535535

536+
visit_conditional_successors(callback, ir::IRCode, bb::Int) = # used for test
537+
visit_conditional_successors(callback, LazyPostDomtree(ir), ir, bb)
536538
function visit_conditional_successors(callback, lazypostdomtree::LazyPostDomtree, ir::IRCode, bb::Int)
537539
visited = BitSet((bb,))
538540
worklist = Int[bb]

test/compiler/effects.jl

+10
Original file line numberDiff line numberDiff line change
@@ -1387,3 +1387,13 @@ let; Base.Experimental.@force_compile; func52843(); end
13871387
# https://github.com/JuliaLang/julia/issues/53508
13881388
@test !Core.Compiler.is_consistent(Base.infer_effects(getindex, (UnitRange{Int},Int)))
13891389
@test !Core.Compiler.is_consistent(Base.infer_effects(getindex, (Base.OneTo{Int},Int)))
1390+
1391+
@noinline f53613() = @assert isdefined(@__MODULE__, :v53613)
1392+
g53613() = f53613()
1393+
@test !Core.Compiler.is_consistent(Base.infer_effects(f53613))
1394+
@test_broken !Core.Compiler.is_consistent(Base.infer_effects(g53613))
1395+
@test_throws AssertionError f53613()
1396+
@test_throws AssertionError g53613()
1397+
global v53613 = nothing
1398+
@test f53613() === nothing
1399+
@test g53613() === nothing

test/compiler/ssair.jl

+55-11
Original file line numberDiff line numberDiff line change
@@ -233,35 +233,79 @@ let code = Any[
233233
end
234234

235235
# issue #37919
236-
let ci = code_lowered(()->@isdefined(_not_def_37919_), ())[1]
236+
let ci = only(code_lowered(()->@isdefined(_not_def_37919_), ()))
237237
ir = Core.Compiler.inflate_ir(ci)
238238
@test Core.Compiler.verify_ir(ir) === nothing
239239
end
240240

241241
let code = Any[
242242
# block 1
243-
GotoIfNot(Argument(2), 4),
243+
GotoIfNot(Argument(2), 4)
244244
# block 2
245-
GotoNode(3),
245+
Expr(:call, throw, "potential throw")
246+
ReturnNode() # unreachable
246247
# block 3
247-
Expr(:call, throw, "potential throw"),
248+
ReturnNode(Argument(3))
249+
]
250+
ir = make_ircode(code; slottypes=Any[Any,Bool,Int])
251+
visited = BitSet()
252+
@test !Core.Compiler.visit_conditional_successors(ir, #=bb=#1) do succ::Int
253+
push!(visited, succ)
254+
return false
255+
end
256+
@test 2 visited
257+
@test 3 visited
258+
oc = Core.OpaqueClosure(ir)
259+
@test oc(false, 1) == 1
260+
@test_throws "potential throw" oc(true, 1)
261+
end
262+
263+
let code = Any[
264+
# block 1
265+
GotoIfNot(Argument(2), 3)
266+
# block 2
267+
ReturnNode(Argument(3))
268+
# block 3
269+
Expr(:call, throw, "potential throw")
270+
ReturnNode() # unreachable
271+
]
272+
ir = make_ircode(code; slottypes=Any[Any,Bool,Int])
273+
visited = BitSet()
274+
@test !Core.Compiler.visit_conditional_successors(ir, #=bb=#1) do succ::Int
275+
push!(visited, succ)
276+
return false
277+
end
278+
@test 2 visited
279+
@test 3 visited
280+
oc = Core.OpaqueClosure(ir)
281+
@test oc(true, 1) == 1
282+
@test_throws "potential throw" oc(false, 1)
283+
end
284+
285+
let code = Any[
286+
# block 1
287+
GotoIfNot(Argument(2), 5)
288+
# block 2
289+
GotoNode(3)
290+
# block 3
291+
Expr(:call, throw, "potential throw")
292+
ReturnNode()
248293
# block 4
249-
Expr(:call, Core.Intrinsics.add_int, Argument(3), Argument(4)),
250-
GotoNode(6),
294+
Expr(:call, Core.Intrinsics.add_int, Argument(3), Argument(4))
295+
GotoNode(7)
251296
# block 5
252-
ReturnNode(SSAValue(4))
297+
ReturnNode(SSAValue(5))
253298
]
254299
ir = make_ircode(code; slottypes=Any[Any,Bool,Int,Int])
255-
lazypostdomtree = Core.Compiler.LazyPostDomtree(ir)
256300
visited = BitSet()
257-
@test !Core.Compiler.visit_conditional_successors(lazypostdomtree, ir, #=bb=#1) do succ::Int
301+
@test !Core.Compiler.visit_conditional_successors(ir, #=bb=#1) do succ::Int
258302
push!(visited, succ)
259303
return false
260304
end
261305
@test 2 visited
262306
@test 3 visited
263-
@test 4 visited
264-
@test 5 visited
307+
@test 4 visited
308+
@test 5 visited
265309
oc = Core.OpaqueClosure(ir)
266310
@test oc(false, 1, 1) == 2
267311
@test_throws "potential throw" oc(true, 1, 1)

0 commit comments

Comments
 (0)