Skip to content

ssa: check signed indexes with a single unsigned compare - #2606

Open
visualfc wants to merge 1 commit into
xgo-dev:mainfrom
visualfc:improve/index-unsigned-compare
Open

visualfc wants to merge 1 commit into
xgo-dev:mainfrom
visualfc:improve/index-unsigned-compare

Conversation

@visualfc

@visualfc visualfc commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Lower slice/array/string index bounds checks to a single unsigned idx >=u len compare.
  • Signed negatives already fail that compare because len/cap are non-negative, so the extra icmp slt / or on the fast path is redundant.
  • Keep PanicIndex vs PanicIndexU (and the 32-bit wide-index split) so panic text is unchanged.

This matches Go's IsInBounds lowering.

Tests

  • ssa.TestSignedIndexUsesUnsignedCompare checks signed indexes emit icmp uge without icmp slt.
  • Handwritten cl/_testgo/indexerr IR checks updated for the single compare.
  • Autogenerated concat / tprecur snapshots refreshed.

Performance

Isolated index-check microbenchmarks on darwin/arm64 (Apple M5, 1s × 6). These avoid LLGo's noinline []T stack-header ABI, so they compare only the bounds-check lowering.

Benchmark gc llgo baseline this PR this/baseline
IndexInlinedDynamic 0.266 0.340 0.282 0.83 (~17% faster)
IndexInlinedMasked 0.261 0.255 0.247 0.97 (same asm)
IndexGlobal 1.165 0.694 0.694 1.00
  • IndexInlinedDynamic: inlined s[idx] where idx is loaded, so LLVM cannot prove idx >= 0. Baseline keeps an extra tbnz; this PR is a single uge.
  • IndexInlinedMasked: inlined s[i&4095]. Both compilers already fold to one uge.
  • IndexGlobal: noinline data[i] with len loaded from a global (L1), not a caller stack store.

A noinline []T call can still look slower because LLGo passes the slice header on the stack; that is ABI/store-forwarding, not this compare.

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: single unsigned bounds compare

The change replaces the two-part bounds check (icmp slt idx, 0 OR icmp uge idx, max) with a single unsigned idx >=u max, backed by the invariant that max is a non-negative len/cap so signed negatives fail as large unsigned values.

I traced correctness across all paths and it holds:

  • Negative signed indexes are sign-extended by toNative/castInt before the compare, so they become large unsigned values and are rejected.
  • Extended 64-bit-index / 32-bit-word path still compares on the widened i64 operands (via boundsArg) and defers truncation until after the check, preventing an out-of-range uint64 from truncating into an apparently-valid index. TestWideIndexBoundsCheck386 still guards this.
  • Panic reporting stays correct: PanicIndex/PanicIndexU selection is preserved and the raw index is reported.
  • indexNeedsCheck only elides the check for a constant index provably in [0, max) against a constant max — every non-constant or unprovable case conservatively returns true.

Net effect is fewer IR instructions per bounds check (drops one icmp and one or i1 on the common path) with no correctness or performance regression. Fixture CHECK/CHECK-NOT directives and the new TestSignedIndexUsesUnsignedCompare accurately pin the new lowering.

Minor / optional (non-blocking):

  • ssa/datastruct.go — the checkIndex doc comment (the "single unsigned comparison idx >=u max" note) describes only the common path; the extended 64-bit/32-bit path below preserves the same invariant but isn't mentioned. A one-line note there would help future readers.

Two small suggestions are left inline. No blocking issues.

Comment thread ssa/datastruct.go
Comment thread ssa/bounds_checks_test.go
len/cap is non-negative, so idx >=u max already rejects signed negatives.
Drop the extra icmp slt / or on the index fast path to match Go.
@visualfc
visualfc force-pushed the improve/index-unsigned-compare branch from e39eae0 to 89fc757 Compare September 15, 2026 14:00
@codecov

codecov Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions

Copy link
Copy Markdown

LLGo baseline benchmarks

89fc757429c3 | workflow run | long-term charts

Program measurements

Platform Workload File size vs base Text size vs base Build vs base Run vs base
Linux cprintf 19832 B 0 B / +0.0% 387 B 0 B / +0.0% 478.787 ms -4.931 ms / -1.0% (better) 1.276 ms -11.33 us / -0.9% (better)
Linux cprintf-lto 19584 B 0 B / +0.0% 368 B 0 B / +0.0% 493.748 ms +17.73 ms / +3.7% (worse) 1.310 ms +52.18 us / +4.1% (worse)
Linux fmtprintf 1632216 B -3360 B / -0.2% (better) 483198 B -2826 B / -0.6% (better) 3.778 s +5.572 ms / +0.1% (worse) 3.107 ms +46.2 us / +1.5% (worse)
Linux fmtprintf-lto 1473832 B -1112 B / -0.1% (better) 421173 B -676 B / -0.2% (better) 10.799 s -98.25 ms / -0.9% (better) 3.091 ms +207.5 us / +7.2% (worse)
Linux println 61168 B -800 B / -1.3% (better) 14192 B -476 B / -3.2% (better) 459.650 ms -35.63 ms / -7.2% (better) 1.606 ms +74.28 us / +4.8% (worse)
Linux println-lto 53944 B -96 B / -0.2% (better) 12073 B -42 B / -0.3% (better) 668.760 ms -4.76 ms / -0.7% (better) 1.576 ms +49.12 us / +3.2% (worse)
macOS cprintf 84480 B 0 B / +0.0% 17101 B 0 B / +0.0% 541.670 ms -368.4 ms / -40.5% (better) 2.625 ms -1.627 ms / -38.3% (better)
macOS cprintf-lto 84288 B 0 B / +0.0% 12865 B 0 B / +0.0% 578.292 ms -373.3 ms / -39.2% (better) 2.940 ms -819.9 us / -21.8% (better)
macOS fmtprintf 1483376 B -32 B / -0.002157% (better) 856988 B -2220 B / -0.3% (better) 2.770 s -1.6 s / -36.6% (better) 5.086 ms -7.787 ms / -60.5% (better)
macOS fmtprintf-lto 1175808 B 0 B / +0.0% 829912 B -572 B / -0.1% (better) 7.929 s -2.495 s / -23.9% (better) 11.009 ms +5.216 ms / +90.0% (worse)
macOS println 114512 B -160 B / -0.1% (better) 34116 B -552 B / -1.6% (better) 1.001 s +284.5 ms / +39.7% (worse) 4.083 ms -670.6 us / -14.1% (better)
macOS println-lto 118720 B 0 B / +0.0% 32100 B -12 B / -0.03737% (better) 842.019 ms -149.9 ms / -15.1% (better) 3.988 ms -1.177 ms / -22.8% (better)
Windows MinGW cprintf 19456 B 0 B / +0.0% 4550 B 0 B / +0.0% 1.143 s -74.46 ms / -6.1% (better) 3.705 ms -787.4 us / -17.5% (better)
Windows MinGW cprintf-lto 17920 B 0 B / +0.0% 4486 B 0 B / +0.0% 1.174 s -54.26 ms / -4.4% (better) 3.418 ms -848.7 us / -19.9% (better)
Windows MinGW fmtprintf 1906176 B -3072 B / -0.2% (better) 584854 B -3280 B / -0.6% (better) 4.161 s -15.59 ms / -0.4% (better) 8.221 ms -846.3 us / -9.3% (better)
Windows MinGW fmtprintf-lto 1928704 B -1536 B / -0.1% (better) 533750 B -656 B / -0.1% (better) 10.080 s -236.2 ms / -2.3% (better) 7.914 ms -978.6 us / -11.0% (better)
Windows MinGW println 70656 B -512 B / -0.7% (better) 23078 B -640 B / -2.7% (better) 1.141 s -45.79 ms / -3.9% (better) 6.625 ms -1.115 ms / -14.4% (better)
Windows MinGW println-lto 65024 B 0 B / +0.0% 20358 B -48 B / -0.2% (better) 1.358 s +3.528 ms / +0.3% (worse) 6.403 ms -612.3 us / -8.7% (better)
Windows MinGW 386 cprintf 42496 B 0 B / +0.0% 5326 B 0 B / +0.0% 1.039 s -33.81 ms / -3.2% (better) 5.310 ms -385.8 us / -6.8% (better)
Windows MinGW 386 cprintf-lto 20992 B 0 B / +0.0% 5094 B 0 B / +0.0% 1.073 s -45.97 ms / -4.1% (better) 5.167 ms -168.3 us / -3.2% (better)
Windows MinGW 386 fmtprintf 1870848 B -1024 B / -0.1% (better) 461742 B -720 B / -0.2% (better) 3.860 s -205.4 ms / -5.1% (better) 10.926 ms -492.8 us / -4.3% (better)
Windows MinGW 386 fmtprintf-lto 2147840 B -1024 B / -0.04765% (better) 439610 B -532 B / -0.1% (better) 9.073 s -370.3 ms / -3.9% (better) 11.385 ms -215.9 us / -1.9% (better)
Windows MinGW 386 println 90624 B 0 B / +0.0% 19830 B 0 B / +0.0% 1.029 s -45.58 ms / -4.2% (better) 9.685 ms +231.5 us / +2.4% (worse)
Windows MinGW 386 println-lto 69120 B 0 B / +0.0% 17726 B -16 B / -0.1% (better) 1.234 s -30.75 ms / -2.4% (better) 9.778 ms +697 us / +7.7% (worse)
Windows MinGW ARM64 cprintf 18944 B 0 B / +0.0% 4408 B 0 B / +0.0% 1.345 s -31.41 ms / -2.3% (better) 6.366 ms +124.8 us / +2.0% (worse)
Windows MinGW ARM64 cprintf-lto 17920 B 0 B / +0.0% 4340 B 0 B / +0.0% 1.347 s -23.4 ms / -1.7% (better) 6.085 ms -226 us / -3.6% (better)
Windows MinGW ARM64 fmtprintf 1793536 B -3584 B / -0.2% (better) 497888 B -2788 B / -0.6% (better) 4.278 s +238.7 ms / +5.9% (worse) 13.378 ms +1.378 ms / +11.5% (worse)
Windows MinGW ARM64 fmtprintf-lto 1852928 B -1536 B / -0.1% (better) 464380 B -840 B / -0.2% (better) 9.247 s +109.4 ms / +1.2% (worse) 12.737 ms +585.1 us / +4.8% (worse)
Windows MinGW ARM64 println 67072 B -1024 B / -1.5% (better) 21816 B -560 B / -2.5% (better) 1.359 s +18.89 ms / +1.4% (worse) 10.257 ms -445.9 us / -4.2% (better)
Windows MinGW ARM64 println-lto 63488 B 0 B / +0.0% 19436 B -8 B / -0.04114% (better) 1.557 s +32.41 ms / +2.1% (worse) 10.954 ms +668 us / +6.5% (worse)
Windows MSVC cprintf 120320 B 0 B / +0.0% 65782 B 0 B / +0.0% 997.276 ms -47.44 ms / -4.5% (better) 3.426 ms -56.1 us / -1.6% (better)
Windows MSVC cprintf-lto 119808 B 0 B / +0.0% 65718 B 0 B / +0.0% 1.004 s +12.18 ms / +1.2% (worse) 3.802 ms -111.9 us / -2.9% (better)
Windows MSVC fmtprintf 1620480 B -3584 B / -0.2% (better) 680374 B -3280 B / -0.5% (better) 3.924 s +27.17 ms / +0.7% (worse) 10.425 ms +1.474 ms / +16.5% (worse)
Windows MSVC fmtprintf-lto 1612800 B -1024 B / -0.1% (better) 633958 B -1088 B / -0.2% (better) 9.416 s -143.1 ms / -1.5% (better) 10.603 ms +1.463 ms / +16.0% (worse)
Windows MSVC println 192000 B -512 B / -0.3% (better) 118502 B -640 B / -0.5% (better) 990.392 ms +41.14 ms / +4.3% (worse) 7.747 ms +444 us / +6.1% (worse)
Windows MSVC println-lto 189952 B 0 B / +0.0% 116326 B -48 B / -0.04125% (better) 1.159 s -20.09 ms / -1.7% (better) 8.028 ms +124.6 us / +1.6% (worse)
Windows MSVC 386 cprintf 9728 B 0 B / +0.0% 3931 B 0 B / +0.0% 1.004 s -8.944 ms / -0.9% (better) 5.568 ms -469 us / -7.8% (better)
Windows MSVC 386 cprintf-lto 9216 B 0 B / +0.0% 3853 B 0 B / +0.0% 971.197 ms +2.317 ms / +0.2% (worse) 5.576 ms +200.4 us / +3.7% (worse)
Windows MSVC 386 fmtprintf 1185792 B -512 B / -0.04316% (better) 445125 B -704 B / -0.2% (better) 3.908 s +82.84 ms / +2.2% (worse) 12.321 ms +1.105 ms / +9.9% (worse)
Windows MSVC 386 fmtprintf-lto 1220608 B -1024 B / -0.1% (better) 416073 B -768 B / -0.2% (better) 9.016 s +305.2 ms / +3.5% (worse) 12.896 ms +934.7 us / +7.8% (worse)
Windows MSVC 386 println 34304 B 0 B / +0.0% 18673 B 0 B / +0.0% 968.483 ms +41.12 ms / +4.4% (worse) 9.889 ms +869.9 us / +9.6% (worse)
Windows MSVC 386 println-lto 32256 B 0 B / +0.0% 16839 B -16 B / -0.1% (better) 1.134 s +15.31 ms / +1.4% (worse) 9.668 ms +246 us / +2.6% (worse)
Windows MSVC ARM64 cprintf 11264 B 0 B / +0.0% 3976 B 0 B / +0.0% 2.054 s -22.66 ms / -1.1% (better) 6.587 ms -774.9 us / -10.5% (better)
Windows MSVC ARM64 cprintf-lto 10752 B 0 B / +0.0% 3868 B 0 B / +0.0% 2.047 s -152.2 us / -0.007435% (better) 6.563 ms +39.6 us / +0.6% (worse)
Windows MSVC ARM64 fmtprintf 1370624 B -1024 B / -0.1% (better) 501044 B -576 B / -0.1% (better) 6.457 s +51.02 ms / +0.8% (worse) 14.747 ms +1.847 ms / +14.3% (worse)
Windows MSVC ARM64 fmtprintf-lto 1387008 B -1024 B / -0.1% (better) 467028 B -1104 B / -0.2% (better) 14.998 s +114.4 ms / +0.8% (worse) 15.961 ms +614.1 us / +4.0% (worse)
Windows MSVC ARM64 println 41472 B 0 B / +0.0% 21608 B -16 B / -0.1% (better) 2.008 s -39.42 ms / -1.9% (better) 12.471 ms +626.3 us / +5.3% (worse)
Windows MSVC ARM64 println-lto 39424 B 0 B / +0.0% 19340 B -32 B / -0.2% (better) 2.307 s +7.3 ms / +0.3% (worse) 12.401 ms +772.8 us / +6.6% (worse)
Core language and compiler benchmarks
Platform Benchmark ns/op vs base
Linux BenchmarkLookupPCRandom 14.700 ns/op +0.13 ns/op / +0.9% (worse)
Linux BenchmarkMergeCompilerFlags 195.500 ns/op -3.4 ns/op / -1.7% (better)
Linux BenchmarkMergeLinkerFlags 125.100 ns/op -7.1 ns/op / -5.4% (better)
Linux BenchmarkChannelBuffered 55.700 ns/op +0.59 ns/op / +1.1% (worse)
Linux BenchmarkChannelHandoff 18751 ns/op +3208 ns/op / +20.6% (worse)
Linux BenchmarkDefer 47.750 ns/op -0.3 ns/op / -0.6% (better)
Linux BenchmarkDirectCall 1.167 ns/op +0.003 ns/op / +0.3% (worse)
Linux BenchmarkGlobalRead 1.166 ns/op +0.002 ns/op / +0.2% (worse)
Linux BenchmarkGlobalWrite 7.761 ns/op -0.005 ns/op / -0.1% (better)
Linux BenchmarkGoroutine 30112 ns/op +7870 ns/op / +35.4% (worse)
Linux BenchmarkInterfaceCall 5.820 ns/op -0.102 ns/op / -1.7% (better)
Linux BenchmarkRuntimeGetG 2.433 ns/op +0.002 ns/op / +0.1% (worse)
macOS BenchmarkLookupPCRandom 12.570 ns/op -2.86 ns/op / -18.5% (better)
macOS BenchmarkMergeCompilerFlags 112.200 ns/op -16.8 ns/op / -13.0% (better)
macOS BenchmarkMergeLinkerFlags 79.690 ns/op -9.83 ns/op / -11.0% (better)
macOS BenchmarkChannelBuffered 24.960 ns/op -11.1 ns/op / -30.8% (better)
macOS BenchmarkChannelHandoff 7536 ns/op -6317 ns/op / -45.6% (better)
macOS BenchmarkDefer 33.070 ns/op -10.05 ns/op / -23.3% (better)
macOS BenchmarkDirectCall 1.055 ns/op -0.105 ns/op / -9.1% (better)
macOS BenchmarkGlobalRead 1.125 ns/op -0.364 ns/op / -24.4% (better)
macOS BenchmarkGlobalWrite 1.057 ns/op -0.577 ns/op / -35.3% (better)
macOS BenchmarkGoroutine 45193 ns/op -7079 ns/op / -13.5% (better)
macOS BenchmarkInterfaceCall 3.895 ns/op -0.889 ns/op / -18.6% (better)
macOS BenchmarkRuntimeGetG 2.077 ns/op -0.862 ns/op / -29.3% (better)
Windows MinGW BenchmarkLookupPCRandom 13.170 ns/op +0.12 ns/op / +0.9% (worse)
Windows MinGW BenchmarkMergeCompilerFlags 621.800 ns/op -9 ns/op / -1.4% (better)
Windows MinGW BenchmarkMergeLinkerFlags 532.800 ns/op -13.3 ns/op / -2.4% (better)
Windows MinGW BenchmarkChannelBuffered 30.700 ns/op -0.29 ns/op / -0.9% (better)
Windows MinGW BenchmarkChannelHandoff 1031 ns/op +85.2 ns/op / +9.0% (worse)
Windows MinGW BenchmarkDefer 56.630 ns/op -1.16 ns/op / -2.0% (better)
Windows MinGW BenchmarkDirectCall 1.548 ns/op -0.001 ns/op / -0.1% (better)
Windows MinGW BenchmarkGlobalRead 1.551 ns/op +0.002 ns/op / +0.1% (worse)
Windows MinGW BenchmarkGlobalWrite 2.471 ns/op +0.002 ns/op / +0.1% (worse)
Windows MinGW BenchmarkGoroutine 83305 ns/op -22925 ns/op / -21.6% (better)
Windows MinGW BenchmarkInterfaceCall 8.370 ns/op -0.317 ns/op / -3.6% (better)
Windows MinGW BenchmarkRuntimeGetG 1.860 ns/op -0.005 ns/op / -0.3% (better)
Windows MinGW 386 BenchmarkLookupPCRandom 64.820 ns/op +0.11 ns/op / +0.2% (worse)
Windows MinGW 386 BenchmarkMergeCompilerFlags 700.800 ns/op +36.2 ns/op / +5.4% (worse)
Windows MinGW 386 BenchmarkMergeLinkerFlags 648.700 ns/op -14.2 ns/op / -2.1% (better)
Windows MinGW 386 BenchmarkChannelBuffered 50.450 ns/op -2.27 ns/op / -4.3% (better)
Windows MinGW 386 BenchmarkChannelHandoff 1226 ns/op -176 ns/op / -12.6% (better)
Windows MinGW 386 BenchmarkDefer 46.350 ns/op -0.34 ns/op / -0.7% (better)
Windows MinGW 386 BenchmarkDirectCall 0.924 ns/op -0.1189 ns/op / -11.4% (better)
Windows MinGW 386 BenchmarkGlobalRead 0.944 ns/op -0.2693 ns/op / -22.2% (better)
Windows MinGW 386 BenchmarkGlobalWrite 16.210 ns/op -0.1 ns/op / -0.6% (better)
Windows MinGW 386 BenchmarkGoroutine 76391 ns/op -1205 ns/op / -1.6% (better)
Windows MinGW 386 BenchmarkInterfaceCall 5.424 ns/op +0.146 ns/op / +2.8% (worse)
Windows MinGW 386 BenchmarkRuntimeGetG 1.221 ns/op -0.025 ns/op / -2.0% (better)
Windows MinGW ARM64 BenchmarkLookupPCRandom 12.030 ns/op +0.09 ns/op / +0.8% (worse)
Windows MinGW ARM64 BenchmarkMergeCompilerFlags 573.900 ns/op -62.4 ns/op / -9.8% (better)
Windows MinGW ARM64 BenchmarkMergeLinkerFlags 533.100 ns/op -52.6 ns/op / -9.0% (better)
Windows MinGW ARM64 BenchmarkChannelBuffered 39.550 ns/op +0.9 ns/op / +2.3% (worse)
Windows MinGW ARM64 BenchmarkChannelHandoff 1944 ns/op +14 ns/op / +0.7% (worse)
Windows MinGW ARM64 BenchmarkDefer 52.810 ns/op +0.57 ns/op / +1.1% (worse)
Windows MinGW ARM64 BenchmarkDirectCall 0.590 ns/op -0.0001 ns/op / -0.01696% (better)
Windows MinGW ARM64 BenchmarkGlobalRead 0.663 ns/op -0.0736 ns/op / -10.0% (better)
Windows MinGW ARM64 BenchmarkGlobalWrite 0.663 ns/op +0.0004 ns/op / +0.1% (worse)
Windows MinGW ARM64 BenchmarkGoroutine 56821 ns/op -2040 ns/op / -3.5% (better)
Windows MinGW ARM64 BenchmarkInterfaceCall 4.136 ns/op -0.199 ns/op / -4.6% (better)
Windows MinGW ARM64 BenchmarkRuntimeGetG 1.806 ns/op +0.036 ns/op / +2.0% (worse)
Windows MSVC BenchmarkLookupPCRandom 13.200 ns/op +0.18 ns/op / +1.4% (worse)
Windows MSVC BenchmarkMergeCompilerFlags 614.100 ns/op +22.5 ns/op / +3.8% (worse)
Windows MSVC BenchmarkMergeLinkerFlags 533 ns/op -2.5 ns/op / -0.5% (better)
Windows MSVC BenchmarkChannelBuffered 28.920 ns/op +0.34 ns/op / +1.2% (worse)
Windows MSVC BenchmarkChannelHandoff 1034 ns/op -72 ns/op / -6.5% (better)
Windows MSVC BenchmarkDefer 54.470 ns/op -1.38 ns/op / -2.5% (better)
Windows MSVC BenchmarkDirectCall 1.549 ns/op +0.002 ns/op / +0.1% (worse)
Windows MSVC BenchmarkGlobalRead 1.551 ns/op -0.311 ns/op / -16.7% (better)
Windows MSVC BenchmarkGlobalWrite 2.457 ns/op +0.001 ns/op / +0.04072% (worse)
Windows MSVC BenchmarkGoroutine 79896 ns/op -5098 ns/op / -6.0% (better)
Windows MSVC BenchmarkInterfaceCall 8.689 ns/op -0.002 ns/op / -0.02301% (better)
Windows MSVC BenchmarkRuntimeGetG 1.860 ns/op +0.004 ns/op / +0.2% (worse)
Windows MSVC 386 BenchmarkLookupPCRandom 26.550 ns/op 0 ns/op / +0.0%
Windows MSVC 386 BenchmarkMergeCompilerFlags 737.100 ns/op +27.2 ns/op / +3.8% (worse)
Windows MSVC 386 BenchmarkMergeLinkerFlags 678.100 ns/op +12.6 ns/op / +1.9% (worse)
Windows MSVC 386 BenchmarkChannelBuffered 39.550 ns/op -0.87 ns/op / -2.2% (better)
Windows MSVC 386 BenchmarkChannelHandoff 826.200 ns/op -10.2 ns/op / -1.2% (better)
Windows MSVC 386 BenchmarkDefer 44.960 ns/op -4.29 ns/op / -8.7% (better)
Windows MSVC 386 BenchmarkDirectCall 1.550 ns/op +0.001 ns/op / +0.1% (worse)
Windows MSVC 386 BenchmarkGlobalRead 1.862 ns/op 0 ns/op / +0.0%
Windows MSVC 386 BenchmarkGlobalWrite 7.794 ns/op +0.017 ns/op / +0.2% (worse)
Windows MSVC 386 BenchmarkGoroutine 85983 ns/op +557 ns/op / +0.7% (worse)
Windows MSVC 386 BenchmarkInterfaceCall 8.405 ns/op +0.342 ns/op / +4.2% (worse)
Windows MSVC 386 BenchmarkRuntimeGetG 1.928 ns/op -0.247 ns/op / -11.4% (better)
Windows MSVC ARM64 BenchmarkLookupPCRandom 12.430 ns/op +0.24 ns/op / +2.0% (worse)
Windows MSVC ARM64 BenchmarkMergeCompilerFlags 645.400 ns/op +72 ns/op / +12.6% (worse)
Windows MSVC ARM64 BenchmarkMergeLinkerFlags 580.600 ns/op +53.1 ns/op / +10.1% (worse)
Windows MSVC ARM64 BenchmarkChannelBuffered 39.170 ns/op -0.37 ns/op / -0.9% (better)
Windows MSVC ARM64 BenchmarkChannelHandoff 1831 ns/op -146 ns/op / -7.4% (better)
Windows MSVC ARM64 BenchmarkDefer 75.710 ns/op +9.13 ns/op / +13.7% (worse)
Windows MSVC ARM64 BenchmarkDirectCall 0.591 ns/op -0.0023 ns/op / -0.4% (better)
Windows MSVC ARM64 BenchmarkGlobalRead 0.592 ns/op -0.077 ns/op / -11.5% (better)
Windows MSVC ARM64 BenchmarkGlobalWrite 3.853 ns/op +0.087 ns/op / +2.3% (worse)
Windows MSVC ARM64 BenchmarkGoroutine 54318 ns/op -3820 ns/op / -6.6% (better)
Windows MSVC ARM64 BenchmarkInterfaceCall 4.180 ns/op -0.038 ns/op / -0.9% (better)
Windows MSVC ARM64 BenchmarkRuntimeGetG 2.189 ns/op -0.05 ns/op / -2.2% (better)

Timer runtime benchmarks

Platform Operation and runtime ns/op vs base
Linux AfterFuncZeroDelivery/Go 898.800 ns/op -8.5 ns/op / -0.9% (better)
Linux AfterFuncZeroDelivery/LLGo 37664 ns/op +6367 ns/op / +20.3% (worse)
Linux CreateStop/Go 290.600 ns/op -2.4 ns/op / -0.8% (better)
Linux CreateStop/LLGo 1790 ns/op -123 ns/op / -6.4% (better)
Linux RearmStopped/Go 115.800 ns/op -0.2 ns/op / -0.2% (better)
Linux RearmStopped/LLGo 1378 ns/op +187 ns/op / +15.7% (worse)
Linux ResetActive/Go 68.650 ns/op +0.05 ns/op / +0.1% (worse)
Linux ResetActive/LLGo 827.100 ns/op +210.2 ns/op / +34.1% (worse)
Linux ResetHeap1024/Go 67.080 ns/op -0.22 ns/op / -0.3% (better)
Linux ResetHeap1024/LLGo 179.900 ns/op -0.5 ns/op / -0.3% (better)
macOS AfterFuncZeroDelivery/Go 478.600 ns/op -13.6 ns/op / -2.8% (better)
macOS AfterFuncZeroDelivery/LLGo 69990 ns/op -38373 ns/op / -35.4% (better)
macOS CreateStop/Go 143.100 ns/op -36.6 ns/op / -20.4% (better)
macOS CreateStop/LLGo 467.600 ns/op -458.1 ns/op / -49.5% (better)
macOS RearmStopped/Go 63.590 ns/op -15.93 ns/op / -20.0% (better)
macOS RearmStopped/LLGo 349.100 ns/op -181.8 ns/op / -34.2% (better)
macOS ResetActive/Go 43.860 ns/op -8.99 ns/op / -17.0% (better)
macOS ResetActive/LLGo 199.400 ns/op -74.1 ns/op / -27.1% (better)
macOS ResetHeap1024/Go 43.140 ns/op -8.2 ns/op / -16.0% (better)
macOS ResetHeap1024/LLGo 102.900 ns/op +2.1 ns/op / +2.1% (worse)
Windows MinGW AfterFuncZeroDelivery/Go 554 ns/op -16.7 ns/op / -2.9% (better)
Windows MinGW AfterFuncZeroDelivery/LLGo 163328 ns/op -1585 ns/op / -1.0% (better)
Windows MinGW CreateStop/Go 115.700 ns/op -0.4 ns/op / -0.3% (better)
Windows MinGW CreateStop/LLGo 437 ns/op -3.9 ns/op / -0.9% (better)
Windows MinGW RearmStopped/Go 31.620 ns/op +0.02 ns/op / +0.1% (worse)
Windows MinGW RearmStopped/LLGo 271.500 ns/op -15.9 ns/op / -5.5% (better)
Windows MinGW ResetActive/Go 20.440 ns/op +0.33 ns/op / +1.6% (worse)
Windows MinGW ResetActive/LLGo 164.900 ns/op +7.4 ns/op / +4.7% (worse)
Windows MinGW ResetHeap1024/Go 20.420 ns/op -0.04 ns/op / -0.2% (better)
Windows MinGW ResetHeap1024/LLGo 126.700 ns/op -4.2 ns/op / -3.2% (better)
Windows MinGW 386 AfterFuncZeroDelivery/Go 951.500 ns/op -2.5 ns/op / -0.3% (better)
Windows MinGW 386 AfterFuncZeroDelivery/LLGo 160767 ns/op +4420 ns/op / +2.8% (worse)
Windows MinGW 386 CreateStop/Go 239.600 ns/op +0.8 ns/op / +0.3% (worse)
Windows MinGW 386 CreateStop/LLGo 833.800 ns/op +230.5 ns/op / +38.2% (worse)
Windows MinGW 386 RearmStopped/Go 86.950 ns/op -0.56 ns/op / -0.6% (better)
Windows MinGW 386 RearmStopped/LLGo 469.100 ns/op +106.9 ns/op / +29.5% (worse)
Windows MinGW 386 ResetActive/Go 41.600 ns/op +0.16 ns/op / +0.4% (worse)
Windows MinGW 386 ResetActive/LLGo 304.400 ns/op +8.4 ns/op / +2.8% (worse)
Windows MinGW 386 ResetHeap1024/Go 42.310 ns/op +0.2 ns/op / +0.5% (worse)
Windows MinGW 386 ResetHeap1024/LLGo 166.900 ns/op +6.9 ns/op / +4.3% (worse)
Windows MinGW ARM64 AfterFuncZeroDelivery/Go 672.400 ns/op -4.3 ns/op / -0.6% (better)
Windows MinGW ARM64 AfterFuncZeroDelivery/LLGo 136522 ns/op +3979 ns/op / +3.0% (worse)
Windows MinGW ARM64 CreateStop/Go 198.900 ns/op +7.1 ns/op / +3.7% (worse)
Windows MinGW ARM64 CreateStop/LLGo 414.400 ns/op -6 ns/op / -1.4% (better)
Windows MinGW ARM64 RearmStopped/Go 70.580 ns/op 0 ns/op / +0.0%
Windows MinGW ARM64 RearmStopped/LLGo 261.200 ns/op +0.9 ns/op / +0.3% (worse)
Windows MinGW ARM64 ResetActive/Go 30.860 ns/op -0.13 ns/op / -0.4% (better)
Windows MinGW ARM64 ResetActive/LLGo 141.300 ns/op -1.3 ns/op / -0.9% (better)
Windows MinGW ARM64 ResetHeap1024/Go 31.100 ns/op +0.08 ns/op / +0.3% (worse)
Windows MinGW ARM64 ResetHeap1024/LLGo 127.200 ns/op +0.7 ns/op / +0.6% (worse)
Windows MSVC AfterFuncZeroDelivery/Go 578.600 ns/op +6.2 ns/op / +1.1% (worse)
Windows MSVC AfterFuncZeroDelivery/LLGo 155987 ns/op -2309 ns/op / -1.5% (better)
Windows MSVC CreateStop/Go 116.600 ns/op -2.2 ns/op / -1.9% (better)
Windows MSVC CreateStop/LLGo 421.400 ns/op -39.9 ns/op / -8.6% (better)
Windows MSVC RearmStopped/Go 31.430 ns/op -0.11 ns/op / -0.3% (better)
Windows MSVC RearmStopped/LLGo 267.800 ns/op -9.1 ns/op / -3.3% (better)
Windows MSVC ResetActive/Go 20.340 ns/op +0.15 ns/op / +0.7% (worse)
Windows MSVC ResetActive/LLGo 136 ns/op -11.9 ns/op / -8.0% (better)
Windows MSVC ResetHeap1024/Go 20.500 ns/op -0.04 ns/op / -0.2% (better)
Windows MSVC ResetHeap1024/LLGo 128 ns/op +5.1 ns/op / +4.1% (worse)
Windows MSVC 386 AfterFuncZeroDelivery/Go 971.600 ns/op +19.3 ns/op / +2.0% (worse)
Windows MSVC 386 AfterFuncZeroDelivery/LLGo 186294 ns/op -743 ns/op / -0.4% (better)
Windows MSVC 386 CreateStop/Go 191.300 ns/op -2.1 ns/op / -1.1% (better)
Windows MSVC 386 CreateStop/LLGo 462.700 ns/op +2.9 ns/op / +0.6% (worse)
Windows MSVC 386 RearmStopped/Go 63.540 ns/op -0.17 ns/op / -0.3% (better)
Windows MSVC 386 RearmStopped/LLGo 331.300 ns/op +8.4 ns/op / +2.6% (worse)
Windows MSVC 386 ResetActive/Go 39.050 ns/op +0.09 ns/op / +0.2% (worse)
Windows MSVC 386 ResetActive/LLGo 911.500 ns/op +73.6 ns/op / +8.8% (worse)
Windows MSVC 386 ResetHeap1024/Go 39.500 ns/op -0.05 ns/op / -0.1% (better)
Windows MSVC 386 ResetHeap1024/LLGo 170.700 ns/op -2.9 ns/op / -1.7% (better)
Windows MSVC ARM64 AfterFuncZeroDelivery/Go 683.500 ns/op +3.8 ns/op / +0.6% (worse)
Windows MSVC ARM64 AfterFuncZeroDelivery/LLGo 130133 ns/op -3841 ns/op / -2.9% (better)
Windows MSVC ARM64 CreateStop/Go 197.700 ns/op -2.3 ns/op / -1.2% (better)
Windows MSVC ARM64 CreateStop/LLGo 463.500 ns/op +18.1 ns/op / +4.1% (worse)
Windows MSVC ARM64 RearmStopped/Go 71.040 ns/op -0.28 ns/op / -0.4% (better)
Windows MSVC ARM64 RearmStopped/LLGo 297.400 ns/op +12.6 ns/op / +4.4% (worse)
Windows MSVC ARM64 ResetActive/Go 31.340 ns/op -0.17 ns/op / -0.5% (better)
Windows MSVC ARM64 ResetActive/LLGo 150.700 ns/op -5.5 ns/op / -3.5% (better)
Windows MSVC ARM64 ResetHeap1024/Go 31.460 ns/op +0.25 ns/op / +0.8% (worse)
Windows MSVC ARM64 ResetHeap1024/LLGo 139.600 ns/op -0.3 ns/op / -0.2% (better)

Compared with 2db247e43848 measured in the same runner job.

@github-actions

Copy link
Copy Markdown

LLGo WebAssembly build benchmarks

89fc757429c3 | workflow run | long-term charts

WebAssembly output sizes

Profile and compiler Wasm module vs base Generated JS glue vs base
ec32/LLGo 112677 B -228 B / -0.2% (better) 70736 B 0 B / +0.0%
ec64/LLGo 118380 B -287 B / -0.2% (better) 74033 B 0 B / +0.0%
js/Go 1895533 B 0 B / +0.0% 0 B 0 B / 0.0%
js/LLGo 66362 B -30 B / -0.04519% (better) 68511 B 0 B / +0.0%
wasip1/Go 1909947 B 0 B / +0.0% 0 B 0 B / 0.0%
wasip1/LLGo 72646 B -43 B / -0.1% (better) 0 B 0 B / 0.0%
wc32/LLGo 116752 B -255 B / -0.2% (better) 0 B 0 B / 0.0%

LLGo WebAssembly build measurements

Profile Build vs base
ec32 5.361 s -54.94 ms / -1.0% (better)
ec64 4.941 s +369.7 us / +0.007483% (worse)
js 4.455 s -10.48 ms / -0.2% (better)
wasip1 2.974 s -17.11 ms / -0.6% (better)
wc32 3.713 s -3.47 ms / -0.1% (better)

Compared with 2db247e43848 measured in the same runner job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant