Skip to content

Commit 7ab26e0

Browse files
authored
Merge pull request #43797 from ianatol/ia/condfolding
Allow branch folding to look at type information, fix Conditional bug
2 parents 7b1cc4b + 35a5172 commit 7ab26e0

File tree

4 files changed

+36
-6
lines changed

4 files changed

+36
-6
lines changed

base/compiler/optimize.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,8 @@ function finish(interp::AbstractInterpreter, opt::OptimizationState,
402402
force_noinline = _any(@nospecialize(x) -> isexpr(x, :meta) && x.args[1] === :noinline, ir.meta)
403403

404404
# compute inlining and other related optimizations
405-
if (isa(result, Const) || isconstType(result))
405+
wresult = isa(result, InterConditional) ? widenconditional(result) : result
406+
if (isa(wresult, Const) || isconstType(wresult))
406407
proven_pure = false
407408
# must be proven pure to use constant calling convention;
408409
# otherwise we might skip throwing errors (issue #20704)
@@ -436,14 +437,14 @@ function finish(interp::AbstractInterpreter, opt::OptimizationState,
436437
# Still set pure flag to make sure `inference` tests pass
437438
# and to possibly enable more optimization in the future
438439
src.pure = true
439-
if isa(result, Const)
440-
val = result.val
440+
if isa(wresult, Const)
441+
val = wresult.val
441442
if is_inlineable_constant(val)
442443
analyzed = ConstAPI(val)
443444
end
444445
else
445-
@assert isconstType(result)
446-
analyzed = ConstAPI(result.parameters[1])
446+
@assert isconstType(wresult)
447+
analyzed = ConstAPI(wresult.parameters[1])
447448
end
448449
force_noinline || (src.inlineable = true)
449450
end

base/compiler/ssair/ir.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,13 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
10071007
stmt = renumber_ssa2!(stmt, ssa_rename, used_ssas, late_fixup, result_idx, do_rename_ssa)::GotoIfNot
10081008
result[result_idx][:inst] = stmt
10091009
cond = stmt.cond
1010-
if isa(cond, Bool) && compact.fold_constant_branches
1010+
if compact.fold_constant_branches
1011+
if !isa(cond, Bool)
1012+
condT = widenconditional(argextype(cond, compact))
1013+
isa(condT, Const) || @goto bail
1014+
cond = condT.val
1015+
isa(cond, Bool) || @goto bail
1016+
end
10111017
if cond
10121018
result[result_idx][:inst] = nothing
10131019
kill_edge!(compact, active_bb, active_bb, stmt.dest)
@@ -1018,6 +1024,7 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
10181024
result_idx += 1
10191025
end
10201026
else
1027+
@label bail
10211028
result[result_idx][:inst] = GotoIfNot(cond, compact.bb_rename_succ[stmt.dest])
10221029
result_idx += 1
10231030
end

test/compiler/inline.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,3 +884,10 @@ end
884884
# have_fma elimination inside ^
885885
f_pow() = ^(2.0, -1.0)
886886
@test fully_eliminated(f_pow, Tuple{})
887+
888+
# bug where Conditional wasn't being properly marked as ConstAPI
889+
let
890+
@noinline fcond(a, b) = a === b
891+
ftest(a) = (fcond(a, nothing); a)
892+
@test fully_eliminated(ftest, Tuple{Bool})
893+
end

test/compiler/irpasses.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,3 +758,18 @@ let # effect-freeness computation for array allocation
758758
nothing
759759
end
760760
end
761+
762+
# allow branch folding to look at type information
763+
let ci = code_typed1(optimize=false) do
764+
cond = 1 + 1 == 2
765+
if !cond
766+
gcd(24, 36)
767+
else
768+
gcd(64, 128)
769+
end
770+
end
771+
ir = Core.Compiler.inflate_ir(ci)
772+
@test count(@nospecialize(stmt)->isa(stmt, Core.GotoIfNot), ir.stmts.inst) == 1
773+
ir = Core.Compiler.compact!(ir, true)
774+
@test count(@nospecialize(stmt)->isa(stmt, Core.GotoIfNot), ir.stmts.inst) == 0
775+
end

0 commit comments

Comments
 (0)