Skip to content

ssa: canonicalize basic aliases in generic symbols - #2367

Merged
xushiwei merged 1 commit into
xgo-dev:mainfrom
cpunion:codex/canonicalize-generic-basic-aliases
Aug 20, 2026
Merged

ssa: canonicalize basic aliases in generic symbols#2367
xushiwei merged 1 commit into
xgo-dev:mainfrom
cpunion:codex/canonicalize-generic-basic-aliases

Conversation

@cpunion

@cpunion cpunion commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Extracted from #2234.

Canonicalizes basic aliases byte (uint8) and rune (int32) in generic ABI symbols (ssa/abi.typeArgString).

go/types may cache a generic instance using either spelling depending on which spelling was instantiated first. Canonicalizing byte and rune to uint8 and int32 ensures that generic ABI symbols do not depend on type instantiation order.

Validation

  • go test -v ./ssa/abi -count=1
  • go test -v ./cl -run '^TestRunAndTestFromTestgo/tpnamed$' -count=1
  • go test -v ./cl -run '^TestRunAndTestFromTestgo$' -count=1

@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: canonicalize generic basic aliases

The change is correct and well-targeted. typeArgString now maps byte->uint8 and rune->int32 so that generic ABI symbol names are stable regardless of which spelling go/types cached first for an instantiation. I verified against Go 1.25 go/types that this is real work, not dead code: types.Universe.Lookup("byte").Type() returns a *types.Basic whose .String() is "byte" (with Kind()==Byte), so without the new switch a byte type-argument would render as "byte" and diverge from a uint8 instantiation. The rationale comment is accurate.

Reviewed across correctness, performance, security, and documentation:

  • Performance — no concern; this is compile-time symbol generation, one Kind() read plus a small switch.
  • Security — no concern; operates on trusted go/types data with fixed canonical strings, and reduces (never introduces) symbol collisions since byte/uint8 are the identical type.
  • TestsTestTypeArgs_CanonicalizesBasicAliases and the updated in.go CHECK lines ([0]byte -> [0]uint8) match the new behavior.

Only minor, non-blocking notes below.

Comment thread ssa/abi/abi.go
return types.Typ[types.Uint8].String()
case types.Rune:
return types.Typ[types.Int32].String()
}

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.

Minor: this canonicalization now lives in four places in the package (typeArgString here, BasicName below at ~L311, and Str/reflectTypeArgBaseString in type.go), split between Kind()-based and Name()-based mappings. Consider a small shared helper (e.g. canonicalBasicName(*types.Basic) string) to keep the byte->uint8 / rune->int32 rule from drifting. Also, for consistency with BasicName you could return the literals "uint8"/"int32" instead of types.Typ[...].String(). Non-blocking.

Comment thread ssa/abi/abi.go
case *types.Basic:
// byte and rune are aliases for uint8 and int32. go/types may cache a
// generic instance using either spelling, so ABI symbols must not
// depend on which spelling was instantiated first.

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.

Nit: the switch is keyed on Kind(), and types.Byte/types.Rune are the same constants as types.Uint8/types.Int32. So these cases also match plain uint8/int32 arguments (harmless no-op here), and a future case types.Uint8:/case types.Int32: would be a duplicate-case compile error. A one-line note that the branch is keyed on kind (which can't distinguish the alias from the target) would prevent that foot-gun. Non-blocking.

@codecov

codecov Bot commented Aug 19, 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

c519de521756 | workflow run | long-term charts

Program measurements

Platform Workload File size vs base Build vs base Run vs base
Linux cprintf 19288 B 0 B / +0.0% 267.058 ms -34.23 ms / -11.4% (better) 1.078 ms +17.87 us / +1.7% (worse)
Linux fmtprintf 1859344 B +24 B / +0.001291% (worse) 2.073 s +25.27 ms / +1.2% (worse) 2.777 ms -38.49 us / -1.4% (better)
Linux println 68776 B 0 B / +0.0% 261.288 ms -445.6 us / -0.2% (better) 1.387 ms -90.06 us / -6.1% (better)
macOS cprintf 84672 B 0 B / +0.0% 342.933 ms -46.2 ms / -11.9% (better) 2.621 ms -467.2 us / -15.1% (better)
macOS fmtprintf 1892464 B +16 B / +0.0008455% (worse) 2.735 s -707 ms / -20.5% (better) 14.282 ms -4.632 ms / -24.5% (better)
macOS println 121360 B 0 B / +0.0% 352.837 ms -18.87 ms / -5.1% (better) 3.567 ms -762.3 us / -17.6% (better)
Core language and compiler benchmarks
Platform Benchmark ns/op vs base
Linux BenchmarkLookupPCRandom 9.538 ns/op -0.376 ns/op / -3.8% (better)
Linux BenchmarkMergeCompilerFlags 112.200 ns/op 0 ns/op / +0.0%
Linux BenchmarkMergeLinkerFlags 72.820 ns/op -0.32 ns/op / -0.4% (better)
Linux BenchmarkChannelBuffered 28.690 ns/op +0.55 ns/op / +2.0% (worse)
Linux BenchmarkChannelHandoff 19708 ns/op +299 ns/op / +1.5% (worse)
Linux BenchmarkDefer 34.480 ns/op -0.08 ns/op / -0.2% (better)
Linux BenchmarkDirectCall 1.363 ns/op -0.001 ns/op / -0.1% (better)
Linux BenchmarkGlobalRead 1.364 ns/op 0 ns/op / +0.0%
Linux BenchmarkGlobalWrite 2.176 ns/op -0.005 ns/op / -0.2% (better)
Linux BenchmarkGoroutine 25024 ns/op +90 ns/op / +0.4% (worse)
Linux BenchmarkInterfaceCall 6.547 ns/op -0.275 ns/op / -4.0% (better)
Linux BenchmarkRuntimeGetG 1.366 ns/op -0.273 ns/op / -16.7% (better)
macOS BenchmarkLookupPCRandom 11.890 ns/op -3.03 ns/op / -20.3% (better)
macOS BenchmarkMergeCompilerFlags 120.400 ns/op -23.3 ns/op / -16.2% (better)
macOS BenchmarkMergeLinkerFlags 74.890 ns/op -18.31 ns/op / -19.6% (better)
macOS BenchmarkChannelBuffered 22.730 ns/op -1.23 ns/op / -5.1% (better)
macOS BenchmarkChannelHandoff 8673 ns/op +1662 ns/op / +23.7% (worse)
macOS BenchmarkDefer 35.860 ns/op +1.55 ns/op / +4.5% (worse)
macOS BenchmarkDirectCall 1.155 ns/op +0.028 ns/op / +2.5% (worse)
macOS BenchmarkGlobalRead 1.143 ns/op -0.111 ns/op / -8.9% (better)
macOS BenchmarkGlobalWrite 1.248 ns/op -0.068 ns/op / -5.2% (better)
macOS BenchmarkGoroutine 40388 ns/op +11976 ns/op / +42.2% (worse)
macOS BenchmarkInterfaceCall 5.474 ns/op +0.263 ns/op / +5.0% (worse)
macOS BenchmarkRuntimeGetG 2.615 ns/op -0.051 ns/op / -1.9% (better)

Compared with cf91afb98fca measured in the same runner job.

@xushiwei
xushiwei merged commit f6b02f6 into xgo-dev:main Aug 20, 2026
65 of 83 checks passed
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.

2 participants