From ed47b3e7351014eaa2c045e7053bbe67bad22df3 Mon Sep 17 00:00:00 2001 From: Cody Tapscott Date: Tue, 27 Jun 2023 14:01:31 -0400 Subject: [PATCH] optimize: Handle path-excluded `Core.ifelse` arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's possible for PiNodes to effectively imply statically the condition of a Core.ifelse. For example: ```julia 23 ─ %60 = Core.ifelse(%47, false, true)::Bool │ %61 = Core.ifelse(%47, %58, false)::Union{Missing, Bool} 25 ─ goto #27 if not %60 26 ─ %65 = π (%61, Bool) └─── ... ``` In basic block #26, the PiNode gives us enough information to conclude that `%47 === false` if control flow reaches that point. The previous code incorrectly assumed that this kind of pruning would only be done for PhiNodes. Resolves #50276. --- base/compiler/ssair/passes.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/base/compiler/ssair/passes.jl b/base/compiler/ssair/passes.jl index f2ef2e9d47ee15..1d5ddac833fffe 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