diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index bf2e6d3aae17f7..9a0468e8e36ea4 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -372,10 +372,7 @@ function lift_leaves(compact::IncrementalCompact, lift_arg!(compact, leaf, cache_key, def, 1+field, lifted_leaves) continue elseif isexpr(def, :new) - typ = widenconst(types(compact)[leaf]) - if isa(typ, UnionAll) - typ = unwrap_unionall(typ) - end + typ = unwrap_unionall(widenconst(types(compact)[leaf])) (isa(typ, DataType) && !isabstracttype(typ)) || return nothing @assert !ismutabletype(typ) if length(def.args) < 1+field @@ -786,10 +783,7 @@ function sroa_pass!(ir::IRCode) push!(preserved, preserved_arg.id) continue elseif isexpr(def, :new) - typ = widenconst(argextype(SSAValue(defidx), compact)) - if isa(typ, UnionAll) - typ = unwrap_unionall(typ) - end + typ = unwrap_unionall(widenconst(argextype(SSAValue(defidx), compact))) if typ isa DataType && !ismutabletype(typ) record_immutable_preserve!(new_preserves, def, compact) push!(preserved, preserved_arg.id) @@ -948,10 +942,7 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse defexpr = ir[SSAValue(idx)][:inst] isexpr(defexpr, :new) || continue newidx = idx - typ = ir.stmts[newidx][:type] - if isa(typ, UnionAll) - typ = unwrap_unionall(typ) - end + typ = unwrap_unionall(ir.stmts[newidx][:type]) # Could still end up here if we tried to setfield! on an immutable, which would # error at runtime, but is not illegal to have in the IR. ismutabletype(typ) || continue @@ -1023,6 +1014,13 @@ function sroa_mutables!(ir::IRCode, defuses::IdDict{Int, Tuple{SPCSet, SSADefUse end has_safe_def(ir, get_domtree(), allblocks, du, newidx, use.idx) || @goto skip end + else # always have some definition at the allocation site + for i = 1:length(du.uses) + use = du.uses[i] + if use.kind === :isdefined + ir[SSAValue(use.idx)][:inst] = true + end + end end end # Everything accounted for. Go field by field and perform idf: diff --git a/test/compiler/irpasses.jl b/test/compiler/irpasses.jl index fedc622b911487..6c77891bede5a1 100644 --- a/test/compiler/irpasses.jl +++ b/test/compiler/irpasses.jl @@ -493,6 +493,31 @@ let src = code_typed1(isdefined_elim) end @test isdefined_elim() == Any[] +function abmult(r::Int, x0) + if r < 0 + r = -r + end + f = x -> x * r + return @inline f(x0) +end +let src = code_typed1(abmult, (Int,Int)) + @test is_scalar_replaced(src) +end +@test abmult(-3, 3) == 9 + +function abmult2(r0::Int, x0) + r::Int = r0 + if r < 0 + r = -r + end + f = x -> x * r + return f(x0) +end +let src = code_typed1(abmult2, (Int,Int)) + @test is_scalar_replaced(src) +end +@test abmult2(-3, 3) == 9 + # comparison lifting # ==================