From c96791b42733e79ea7ec77cbacfe6a4e3fbe61c0 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sun, 29 Mar 2026 17:07:18 -0400 Subject: [PATCH 1/3] use Base.assume_variant to disallow LLVM from simplifying the bench loop --- src/execution.jl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/execution.jl b/src/execution.jl index 3d1aa98e..1772d063 100644 --- a/src/execution.jl +++ b/src/execution.jl @@ -584,6 +584,16 @@ function generate_benchmark_definition( core_body = :($(core); $(returns)) end @static if isdefined(Base, :donotdelete) + if isdefined(Base, :assume_variant) + # Wrap each interpolated variable with assume_variant inside + # the corefunc body to prevent LLVM from hoisting + # loop-invariant pure calls out of the benchmark loop (LICM). + # We must barrier inside corefunc (on unboxed scalars) rather + # than outside (on tuple element pointers), because the tuple + # argument is marked readonly and LLVM won't reload it. + barrier_stmts = [:($(v) = Base.assume_variant($(v))) for v in quote_vars] + core_body = Expr(:block, barrier_stmts..., core_body) + end invocation = :( let x = $invocation Base.donotdelete(x) From 1bcbe6ce07238fe2ea14b070daebb5140c2faf5a Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Mon, 30 Mar 2026 12:33:58 -0400 Subject: [PATCH 2/3] update to blackbox --- src/execution.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/execution.jl b/src/execution.jl index 1772d063..aa8c2ed0 100644 --- a/src/execution.jl +++ b/src/execution.jl @@ -584,14 +584,14 @@ function generate_benchmark_definition( core_body = :($(core); $(returns)) end @static if isdefined(Base, :donotdelete) - if isdefined(Base, :assume_variant) - # Wrap each interpolated variable with assume_variant inside + if isdefined(Base, :blackbox) + # Wrap each interpolated variable with blackbox inside # the corefunc body to prevent LLVM from hoisting # loop-invariant pure calls out of the benchmark loop (LICM). # We must barrier inside corefunc (on unboxed scalars) rather # than outside (on tuple element pointers), because the tuple # argument is marked readonly and LLVM won't reload it. - barrier_stmts = [:($(v) = Base.assume_variant($(v))) for v in quote_vars] + barrier_stmts = [:($(v) = Base.blackbox($(v))) for v in quote_vars] core_body = Expr(:block, barrier_stmts..., core_body) end invocation = :( From 7f0facc90f7396d8477a8668591d5bffdf9f50a6 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 31 Mar 2026 11:43:25 -0400 Subject: [PATCH 3/3] Apply suggestion from @IanButterworth --- src/execution.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/execution.jl b/src/execution.jl index aa8c2ed0..57447827 100644 --- a/src/execution.jl +++ b/src/execution.jl @@ -588,9 +588,6 @@ function generate_benchmark_definition( # Wrap each interpolated variable with blackbox inside # the corefunc body to prevent LLVM from hoisting # loop-invariant pure calls out of the benchmark loop (LICM). - # We must barrier inside corefunc (on unboxed scalars) rather - # than outside (on tuple element pointers), because the tuple - # argument is marked readonly and LLVM won't reload it. barrier_stmts = [:($(v) = Base.blackbox($(v))) for v in quote_vars] core_body = Expr(:block, barrier_stmts..., core_body) end