Skip to content

Commit 91fe9c3

Browse files
KenoKristofferC
authored andcommitted
Fix use counts for mutable struct SROA
PR #28478 moved the computation of the use counts before the finish call. to fix #28444. However, the early parts of the finish call fixes up phi node arguments, which fail to get counted if we look at use counts before that fixup is performed. This causes #30594 where the only non-trivial use is on the backedge of the phi and would thus incorrectly fail to get accounted for. Fix that by taking the use count after phi fixup but before dce. (cherry picked from commit f8f2045)
1 parent d8e69b8 commit 91fe9c3

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

base/compiler/ssair/passes.jl

+7-3
Original file line numberDiff line numberDiff line change
@@ -688,10 +688,14 @@ function getfield_elim_pass!(ir::IRCode, domtree::DomTree)
688688
compact[idx] = val === nothing ? nothing : val.x
689689
end
690690

691-
# Copy the use count, `finish` may modify it and for our predicate
692-
# below we need it consistent with the state of the IR here.
691+
692+
non_dce_finish!(compact)
693+
# Copy the use count, `simple_dce!` may modify it and for our predicate
694+
# below we need it consistent with the state of the IR here (after tracking
695+
# phi node arguments, but before dce).
693696
used_ssas = copy(compact.used_ssas)
694-
ir = finish(compact)
697+
simple_dce!(compact)
698+
ir = complete(compact)
695699
# Now go through any mutable structs and see which ones we can eliminate
696700
for (idx, (intermediaries, defuse)) in defuses
697701
intermediaries = collect(intermediaries)

test/compiler/irpasses.jl

+26
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,29 @@ let m = Meta.@lower 1 + 1
3737
Core.Compiler.verify_ir(ir)
3838
@test isa(ir.stmts[3], Core.PhiNode) && length(ir.stmts[3].edges) == 1
3939
end
40+
41+
# Tests for SROA
42+
43+
mutable struct Foo30594; x::Float64; end
44+
Base.copy(x::Foo30594) = Foo30594(x.x)
45+
function add!(p::Foo30594, off::Foo30594)
46+
p.x += off.x
47+
return p
48+
end
49+
Base.:(+)(a::Foo30594, b::Foo30594) = add!(copy(a), b)
50+
51+
let results = Float64[]
52+
@noinline use30594(x) = push!(results, x.x); nothing
53+
function foo30594(cnt::Int, dx::Int)
54+
step = Foo30594(dx)
55+
curr = step + Foo30594(1)
56+
for i in 1:cnt
57+
use30594(curr)
58+
curr = curr + step
59+
end
60+
nothing
61+
end
62+
63+
foo30594(4, -1)
64+
@test results == [0.0, -1.0, -2.0, -3.0]
65+
end

0 commit comments

Comments
 (0)