From 4494e75620feefe7b0df34b3dd62d66bc54e2bfa Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki Date: Sat, 8 Jun 2024 02:09:27 +0900 Subject: [PATCH] inlining: optimize `and_int(x, true)` and `or_int(x, false)` We need an additional inlining pass to optimize cases like `and_int(x, true)` and `or_int(x, false)` to `x`. --- base/compiler/ssair/inlining.jl | 20 ++++++++++++++++++-- test/compiler/inline.jl | 6 ++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index a77a67ab262def..5848324f1b57f6 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -1672,7 +1672,7 @@ function early_inline_special_case(ir::IRCode, stmt::Expr, flag::UInt32, @nospecialize(type), sig::Signature, state::InliningState) OptimizationParams(state.interp).inlining || return nothing (; f, ft, argtypes) = sig - + ⊑ = partialorder(optimizer_lattice(state.interp)) if isa(type, Const) # || isconstType(type) val = type.val is_inlineable_constant(val) || return nothing @@ -1714,9 +1714,25 @@ function early_inline_special_case(ir::IRCode, stmt::Expr, flag::UInt32, elseif cond.val === false return SomeCase(stmt.args[4]) end - elseif ⊑(optimizer_lattice(state.interp), cond, Bool) && stmt.args[3] === stmt.args[4] + elseif cond ⊑ Bool && stmt.args[3] === stmt.args[4] + return SomeCase(stmt.args[3]) + end + elseif f === and_int && length(argtypes) == 3 + argtype2, argtype3 = argtypes[2], argtypes[3] + if argtype2 isa Const && argtype2.val === true && argtype3 ⊑ Bool return SomeCase(stmt.args[3]) end + if argtype3 isa Const && argtype3.val === true && argtype2 ⊑ Bool + return SomeCase(stmt.args[2]) + end + elseif f === or_int && length(argtypes) == 3 + argtype2, argtype3 = argtypes[2], argtypes[3] + if argtype2 isa Const && argtype2.val === false && argtype3 ⊑ Bool + return SomeCase(stmt.args[3]) + end + if argtype3 isa Const && argtype3.val === false && argtype2 ⊑ Bool + return SomeCase(stmt.args[2]) + end end return nothing end diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index a8b5fd66dcd0d0..f44e6665b05fcc 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -2214,3 +2214,9 @@ let ir = Base.code_ircode((Issue52644,); optimize_until="Inlining") do t @test irfunc(Issue52644(Tuple{})) === :DataType @test_throws MethodError irfunc(Issue52644(Tuple{<:Integer})) end + +# inlining optimization for `and_int` and `or_int` +@test fully_eliminated(x->x&true, (Bool,); retval=Argument(2)) +@test fully_eliminated(x->true&x, (Bool,); retval=Argument(2)) +@test fully_eliminated(x->x|false, (Bool,); retval=Argument(2)) +@test fully_eliminated(x->false|x, (Bool,); retval=Argument(2))