Skip to content

cl: fold constant comparisons before lowering - #2257

Open
cpunion wants to merge 3 commits into
xgo-dev:mainfrom
cpunion:codex/goroot-unreachable-bodyless-20260801
Open

cl: fold constant comparisons before lowering#2257
cpunion wants to merge 3 commits into
xgo-dev:mainfrom
cpunion:codex/goroot-unreachable-bodyless-20260801

Conversation

@cpunion

@cpunion cpunion commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • fold SSA comparisons whose operands are both Go constants before LLVM lowering
  • preserve nil and non-constant comparisons on the existing lowering path
  • add the fixedbugs/issue9608 counterexample and remove its Go 1.26 xfail

This keeps the fix generic: constant string comparisons no longer become runtime StringEqual calls, so ordinary LLVM optimization can eliminate their unreachable branches and bodyless references.

Testing

  • go test ./cl -run "^(TestFoldConstComparison|TestCompileFoldsConstStringComparison|TestCompileNilBinOpAndHelpers|TestCompileGenericNilSwitchAndCompare)$" -count=1
  • go test ./internal/build -run "^(TestDoAllowsMissingFunctionBodies|TestDoOptimizesUnreachableBodylessCalls)$" -count=1
  • fixedbugs/issue9608.go with an empty xfail list on Go 1.24.11, Go 1.25.0, and Go 1.26.5
  • targeted cl coverage: foldConstComparison 100%
  • go test ./test/goroot -count=1

A combined full cl/internal/build run reached the standard 10-minute package timeout while still progressing through unrelated generated-program and PCLN integration cases; no related assertion failure was observed.

@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@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 summary

Clean, well-scoped change. The new foldConstComparison helper folds constant-operand comparisons to a boolean at IR-generation time, which lets LLVM prove the dead branch and drop the reference to the bodyless @main.fail, resolving the removed issue9608 xfail. Correctness looks sound:

  • Only the six comparison operators are folded; arithmetic/bitwise ops fall through unchanged.
  • Both operands must be *ssa.Const with non-nil Value, so typed and untyped nil comparisons are correctly excluded (verified by TestFoldConstComparison) and still take the existing nil path.
  • constant.Compare matches Go semantics for every constant kind a non-nil *ssa.Const.Value can hold. Ordering ops on bool/complex (which would panic in constant.Compare) are rejected upstream by Go's type checker, so they can't reach here. NaN is not representable as a Go constant, so no float divergence.

No security or performance concerns; the fold reduces emitted IR and downstream optimizer work.

Findings below are minor/optional — nothing blocking.

Minor

  • cl/compile.go:1595foldConstComparison returns (bool, bool) where the first is the result and the second is the "folded" flag. Two unnamed bools where order matters is easy to misread. Consider named returns (result, folded bool) and/or a one-line doc comment noting that nil constants are intentionally skipped (so a future refactor doesn't accidentally fold typed/untyped nil through go/constant). Consistent with the terse local style, so optional.

Comment thread internal/build/testdata/unreachablebodyless/main.go
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

LLGo baseline benchmarks

e0921289471d | workflow run | long-term charts

Program measurements

Platform Workload File size vs main Build vs main Run vs main
Linux cprintf 18544 B new 337.478 ms new 1.264 ms new
Linux fmtprintf 2215856 B new 3.234 s new 2.414 ms new
Linux println 71504 B new 337.991 ms new 1.571 ms new
macOS cprintf 84672 B new 307.308 ms new 2.587 ms new
macOS fmtprintf 2361520 B new 2.446 s new 16.663 ms new
macOS println 125712 B new 306.019 ms new 3.921 ms new
Core language and compiler benchmarks
Platform Benchmark ns/op vs main
Linux BenchmarkLookupPCRandom 13.220 ns/op new
Linux BenchmarkMergeCompilerFlags 153.200 ns/op new
Linux BenchmarkMergeLinkerFlags 98.750 ns/op new
Linux BenchmarkChannelBuffered 33.960 ns/op new
Linux BenchmarkChannelHandoff 30823 ns/op new
Linux BenchmarkDefer 43.640 ns/op new
Linux BenchmarkDirectCall 1.560 ns/op new
Linux BenchmarkGlobalRead 1.868 ns/op new
Linux BenchmarkGlobalWrite 2.487 ns/op new
Linux BenchmarkGoroutine 29006 ns/op new
Linux BenchmarkInterfaceCall 8.098 ns/op new
Linux BenchmarkRuntimeGetG 1.868 ns/op new
macOS BenchmarkLookupPCRandom 12.900 ns/op new
macOS BenchmarkMergeCompilerFlags 125.500 ns/op new
macOS BenchmarkMergeLinkerFlags 101 ns/op new
macOS BenchmarkChannelBuffered 20.920 ns/op new
macOS BenchmarkChannelHandoff 6735 ns/op new
macOS BenchmarkDefer 25.950 ns/op new
macOS BenchmarkDirectCall 0.975 ns/op new
macOS BenchmarkGlobalRead 0.985 ns/op new
macOS BenchmarkGlobalWrite 0.962 ns/op new
macOS BenchmarkGoroutine 20833 ns/op new
macOS BenchmarkInterfaceCall 4.158 ns/op new
macOS BenchmarkRuntimeGetG 1.920 ns/op new

No main baseline exists yet; all metrics are marked new.

Warning

  • The rendered benchmark data could not be pushed.

@cpunion

cpunion commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator Author

The Ubuntu failure was a stale cl/_testrt/builtin FileCheck block caused by this PR intentionally folding the seven constant string comparisons. e09212894 updates only the affected constants and comparison output; the Go source body is unchanged. The focused cl and ssa builtin snapshot tests now pass locally.

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