diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index f2ef2e9d47ee1..1d5ddac833fff 100644 --- a/base/compiler/ssair/passes.jl +++ b/base/compiler/ssair/passes.jl @@ -767,6 +767,11 @@ function perform_lifting!(compact::IncrementalCompact, else_result = lifted_value(compact, old_node_ssa, else_result, lifted_philikes, lifted_leaves, reverse_mapping) + # In cases where the Core.ifelse condition is statically-known, e.g., thanks + # to a PiNode from a guarding conditional, we replace with the other branch. + then_result === SKIP_TOKEN && (then_result = else_result) + else_result === SKIP_TOKEN && (else_result = then_result) + @assert then_result !== SKIP_TOKEN && then_result !== UNDEF_TOKEN @assert else_result !== SKIP_TOKEN && else_result !== UNDEF_TOKEN diff --git a/test/compiler/irpasses.jl b/test/compiler/irpasses.jl index f27961c526559..6db6fe837285a 100644 --- a/test/compiler/irpasses.jl +++ b/test/compiler/irpasses.jl @@ -742,6 +742,58 @@ let m = Meta.@lower 1 + 1 @test Core.Compiler.verify_ir(ir) === nothing end +# A lifted Core.ifelse with an eliminated branch (#50276) +let m = Meta.@lower 1 + 1 + @assert Meta.isexpr(m, :thunk) + src = m.args[1]::CodeInfo + src.code = Any[ + # block 1 + #= %1: =# Core.Argument(2), + # block 2 + #= %2: =# Expr(:call, Core.ifelse, SSAValue(1), true, missing), + #= %3: =# GotoIfNot(SSAValue(2), 11), + # block 3 + #= %4: =# PiNode(SSAValue(2), Bool), # <-- This PiNode is the trigger of the bug, since it + # means that only one branch of the Core.ifelse + # is lifted. + #= %5: =# GotoIfNot(false, 8), + # block 2 + #= %6: =# nothing, + #= %7: =# GotoNode(8), + # block 4 + #= %8: =# PhiNode(Int32[5, 7], Any[SSAValue(4), SSAValue(6)]), + # ^-- N.B. This PhiNode also needs to have a Union{ ... } type in order + # for lifting to be performed (it is skipped for e.g. `Bool`) + # + #= %9: =# Expr(:call, isa, SSAValue(8), Missing), + #= %10: =# ReturnNode(SSAValue(9)), + # block 5 + #= %11: =# ReturnNode(false), + ] + src.ssavaluetypes = Any[ + Any, + Union{Missing, Bool}, + Any, + Bool, + Any, + Missing, + Any, + Union{Nothing, Bool}, + Bool, + Any, + Any + ] + nstmts = length(src.code) + src.codelocs = fill(one(Int32), nstmts) + src.ssaflags = fill(one(Int32), nstmts) + src.slotflags = fill(zero(UInt8), 3) + ir = Core.Compiler.inflate_ir(src) + Main.Base.IRShow.show_ir(stdout, ir) + @test Core.Compiler.verify_ir(ir) === nothing + ir = @test_nowarn Core.Compiler.sroa_pass!(ir) + @test Core.Compiler.verify_ir(ir) === nothing +end + # Issue #31546 - missing widenconst in SROA function f_31546(x) (a, b) = x == "r" ? (false, false) :