This directory contains scripts for running LLGo locally and inside reusable Linux dev containers.
- Docker installed and running
- Docker Compose v2 (
docker compose, notdocker-compose)
Start an interactive shell (pick one):
./dev/docker.sh amd64
./dev/docker.sh arm64
./dev/docker.sh i386Notes:
amd64uses thepydepsimage target (includes extra Python demo deps likenumpy/torch).arm64andi386use the smallerbasetarget (no extra Python ML deps).
Inside the container, run tests/builds using the repo scripts:
./dev/llgo.sh test ./...
./dev/llgo.sh test ./test
# WASI/WASM (wasip1/wasm)
./dev/llgo_wasm.sh build ./...Notes:
dev/docker.shstarts in the same repo subdirectory you launched it from.dev/llgo.shanddev/llgo_wasm.shmust be run from withinLLGO_ROOT(the repo) and will error otherwise.
./dev/docker.sh amd64 bash -lc './dev/llgo.sh test ./test'From anywhere inside the repo:
./dev/llgo.sh test ./test
./dev/llgo_wasm.sh build ./..../dev/local_ci.shThis script creates a temporary workspace, runs formatting/build/tests, runs llgo test, and then runs demo checks.
You can control demo parallelism via LLGO_DEMO_JOBS (defaults to up to 4 jobs).
dev/docker.sh is a thin wrapper around docker compose:
./dev/docker.sh <arch> [command...]<arch>must beamd64,arm64, ori386.- If
[command...]is omitted, it starts an interactivebash. - If
[command...]is provided, it runs that command and exits. - You must run it from within the repo (within
LLGO_ROOT), and it will start in the matching repo subdirectory inside the container.
LLGo currently has two different golden-test refresh flows:
gentestsfor directory-based golden files such asout.llandexpect.txtlitgenfor the curated set of 40 source-embedded, autogenerated// LITTESTFileCheck snapshots
Run:
go run ./chore/gentestsBehavior:
- Refreshes
out.llfor the built-in test suites undercl/_testlibc,cl/_testlibgo,cl/_testrt,cl/_testgo,cl/_testpy, andcl/_testdata. - Refreshes
expect.txtfor the same directories using the existing runtime execution flow. - Preserves the existing skip convention where
out.llorexpect.txtcontaining only;means "do not refresh". - New behavior: if a test case directory contains a non-test Go source file whose first line is exactly
// LITTEST,gentestsskipsllgenfor that directory and does not regenerateout.llthere.
Use gentests when the test still stores LLVM IR in out.ll.
Autogenerated checks stay in the Go source file. A test opts in with an
autogenerated note immediately after // LITTEST; the note also records the
arguments required to reproduce the checks:
// LITTEST
// NOTE: Assertions have been autogenerated by chore/litgen UTC_ARGS: --function=run --check-globals=smartCreate or replace an autogenerated region explicitly:
go run ./chore/litgen --function=run --check-globals=smart path/to/in.goRefresh existing autogenerated tests recursively, using the arguments recorded in each source file:
go run ./chore/litgen -u clCheck that committed autogenerated checks are current without modifying files:
go run ./chore/litgen -u --check clBehavior:
- Accepts one or more paths.
- If the path is a
.gofile, it refreshes only that file. The file must start with// LITTEST. - If the path is a directory, it walks that directory recursively and processes marked source files in a stable order.
-u/--update-onlyupdates only tests that already carry the autogenerated note. Handwritten checks are never silently replaced.--checkreports stale autogenerated checks and does not write files.--functionis repeatable and selects functions by regular expression. Use--all-functionsonly when the entire generated module is genuinely the test contract.--check-globals=none|smart|allcontrols global checks.smartkeeps globals referenced by selected functions.- Generated checks abstract numeric LLVM SSA values, block suffixes, numeric globals, and generated cgo symbol hashes to reduce irrelevant churn.
- Does not update
expect.txtand does not writeout.ll.
Use litgen only when a test intentionally checks a broad IR shape. Prefer
short, handwritten FileCheck assertions for a single lowering or ABI property.
Runtime output does not replace focused IR checks; it only removes the need for
a second full-output snapshot.
Use 100 FileCheck directive lines as an audit threshold rather than a size cap.
For a larger handwritten fixture, every group should correspond to an explicit
semantic contract. Convert long contiguous IR-shape checks to an opted-in
litgen snapshot instead.
Source-embedded IR checks are enabled by putting this marker on the first line of the source file:
// LITTESTThe generated directives are consumed by the existing littest/FileCheck path in the compiler tests.
Example:
- cl/_testrt/litdemo/in.go is a minimal
_testrtcase that demonstrateslitgenoutput.