You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Capture LLVM IR of `f(::types...)` and return the lines containing actual operations: drop preamble (`define`/`declare`), labels, braces, comments, blank lines, and the trailing `ret` (which is bookkeeping, not an operation — when the caller inlines `f`, only the operation lines remain).
532
+
# Capture LLVM IR of `f(::types...)` and return the lines containing actual operations: drop preamble (`define`/`declare`), labels, braces, comments, blank lines, the trailing `ret` (bookkeeping, not an operation — when the caller inlines `f`, only the operation lines remain), and `--code-coverage` counter increments (`atomicrmw add` into a fixed pointer) so the count is the same with or without coverage instrumentation.
# A `call` instruction targeting an LLVM intrinsic (`@llvm.ctpop`, `@llvm.abs`, …) is a single native instruction, not a runtime dispatch. Only flag calls into Julia runtime functions (`@j_*`, `@julia_*`, `@ijl_*`, `@jl_*`).
# `>>>` with a runtime shift amount lowers to ~13 IR lines (mask, branch, mod), but the typical hot-path use is a constant shift; wrap it in a helper so the constant folds into the body.
547
551
shr1(x::UInt3) = x >>>1
548
552
549
-
# `(label, f, types, exact_ops)`. Counts are exact on Julia 1.11+ with default codegen options (calibrated on 1.11.9 and 1.13.0-rc1; both produce identical IR for these methods). Coverage instrumentation and `--check-bounds=yes` both inflate counts (CI runs with both), and 1.10's codegen differs, so the exact-count check is gated below.
553
+
# `(label, f, types, exact_ops)`. Counts are exact on Julia 1.11+ (calibrated on 1.11.9 and 1.13.0-rc1; both produce identical IR for these methods); 1.10's codegen differs, so the exact-count check is gated to 1.11+ below.
# Exact counts only hold for clean codegen: Julia 1.11+, no coverage instrumentation, and `--check-bounds` at its default (0 = default, 1 = yes, 2 = no). The `runtime_calls == 0` invariant remains the important one and runs unconditionally.
568
-
counts_calibrated =VERSION>=v"1.11"&&
569
-
Base.JLOptions().code_coverage ==0&&
570
-
Base.JLOptions().check_bounds ==0
571
-
572
571
for (label, f, types, exact_ops) in cases
573
572
ops =llvm_ops(f, types)
574
573
# No dispatch into runtime helpers — every operation must lower to native instructions or LLVM intrinsics. Also rules out allocations, which would surface as `@jl_gc_*` calls.
575
574
@testruntime_calls(ops) ==0
576
575
# Exact op count — any drift (up or down) signals a codegen change worth a look.
0 commit comments