Skip to content

Commit 8bfc73a

Browse files
authored
Fix legality check in SROA (#28478)
The legality check was using use counts after `finish(compact)` got to delete, which made them inaccurate. Instead, take a copy of the use counts before. Additionally, ignore any uses that got deleted during `finish(compact)`. Fixes #28444.
1 parent e3bc48d commit 8bfc73a

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

base/compiler/ssair/passes.jl

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,9 @@ 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.
693+
used_ssas = copy(compact.used_ssas)
691694
ir = finish(compact)
692695
# Now go through any mutable structs and see which ones we can eliminate
693696
for (idx, (intermediaries, defuse)) in defuses
@@ -699,9 +702,9 @@ function getfield_elim_pass!(ir::IRCode, domtree::DomTree)
699702
nleaves = length(defuse.uses) + length(defuse.defs) + length(defuse.ccall_preserve_uses)
700703
nuses = 0
701704
for idx in intermediaries
702-
nuses += compact.used_ssas[idx]
705+
nuses += used_ssas[idx]
703706
end
704-
nuses_total = compact.used_ssas[idx] + nuses - length(intermediaries)
707+
nuses_total = used_ssas[idx] + nuses - length(intermediaries)
705708
nleaves == nuses_total || continue
706709
# Find the type for this allocation
707710
defexpr = ir[SSAValue(idx)]
@@ -717,7 +720,13 @@ function getfield_elim_pass!(ir::IRCode, domtree::DomTree)
717720
fielddefuse = SSADefUse[SSADefUse() for _ = 1:fieldcount(typ)]
718721
ok = true
719722
for use in defuse.uses
720-
field = try_compute_fieldidx_expr(typ, ir[SSAValue(use)])
723+
stmt = ir[SSAValue(use)]
724+
# We may have discovered above that this use is dead
725+
# after the getfield elim of immutables. In that case,
726+
# it would have been deleted. That's fine, just ignore
727+
# the use in that case.
728+
stmt === nothing && continue
729+
field = try_compute_fieldidx_expr(typ, stmt)
721730
field === nothing && (ok = false; break)
722731
push!(fielddefuse[field].uses, use)
723732
end

test/compiler/compiler.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,3 +1950,16 @@ end
19501950
h28356() = f28356(Any[Float64][1])
19511951

19521952
@test h28356() isa S28356{Float64}
1953+
1954+
# Issue #28444
1955+
mutable struct foo28444
1956+
a::Int
1957+
b::Int
1958+
end
1959+
function bar28444()
1960+
a = foo28444(1, 2)
1961+
c, d = a.a, a.b
1962+
e = (c, d)
1963+
e[1]
1964+
end
1965+
@test bar28444() == 1

0 commit comments

Comments
 (0)