Skip to content
88 changes: 38 additions & 50 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,55 +51,44 @@ go test ./...

**Important:** The `LLGO_ROOT` environment variable must be set to the repository root when running llgo commands during development.

### Update out.ll files after modifying compiler IR generation

**CRITICAL:** When you modify the compiler's IR generation logic (especially in `ssa/` or `cl/` packages), you MUST update all out.ll test files under the `cl/` directory.

#### Understanding out.ll files

The `out.ll` files under the `cl/` directory are comparison IR files that serve as reference outputs for the test suite:
- They are generated by `llgen` from the corresponding `in.go` files in the same directory
- They reflect the current compiler's LLVM IR representation of the Go source code
- They are used by tests to verify that the compiler generates correct and consistent IR output

#### Required steps after modifying IR generation logic

1. **Reinstall the tools** to apply your compiler changes:
```bash
go install -v ./chore/gentests
go install -v ./chore/llgen
```

2. **Regenerate out.ll files**:

**For batch updates (recommended)** - Use `gentests` to regenerate all test files:
```bash
gentests
```
This will automatically regenerate all out.ll files in these directories:
- `cl/_testlibc`
- `cl/_testlibgo`
- `cl/_testrt`
- `cl/_testgo`
- `cl/_testpy`
- `cl/_testdata`

**For individual test inspection** - Use `llgen` to regenerate specific test directories:
```bash
llgen cl/_testgo/interface
llgen cl/_testrt/tpmethod
```

3. **Verify the changes** make sense by reviewing the diff in the out.ll files

4. **Commit the updated out.ll files** along with your compiler changes

#### Why this matters

This process ensures that:
- The test suite reflects the current compiler behavior
- Changes to IR generation are properly documented and reviewed
- Future regressions can be detected by comparing against the reference output
### Maintain LLVM IR checks by test intent

Do not refresh every FileCheck assertion after an IR change. First identify the
single compiler property a test is intended to protect, then keep the smallest
handwritten assertions that prove that property. Runtime output and focused IR
checks protect different contracts; avoid only the redundant full IR snapshot.

Treat 100 FileCheck directive lines as a review threshold, not a hard limit.
Above that threshold, verify that each handwritten group protects a distinct,
named semantic contract. If the test instead needs a long contiguous IR shape,
make that region reproducible with `litgen`.

The repository keeps a curated set of 40 source-embedded autogenerated checks
for cases where a broad function or module shape is itself the contract. They
remain in the Go source and carry a reproducible `UTC_ARGS` note:

```go
// LITTEST
// NOTE: Assertions have been autogenerated by chore/litgen UTC_ARGS: --function=run --check-globals=smart
```

Refresh and verify all opted-in snapshots with:

```bash
go run ./chore/litgen -u cl
go run ./chore/litgen -u --check cl
```

`litgen` will not replace a handwritten test during update-only operation. When
creating an autogenerated test, pass one or more `--function` expressions; use
`--all-functions` only for a deliberate whole-module contract. See
`dev/README.md` for the complete options and marker conventions.

IR checks observe the module after aggregate and target ABI lowering and before
the LLVM optimization pipeline. Keep portable assertions under `CHECK`; use
`DARWIN`, `LINUX`, `ARM64`, `AMD64`, or a combined prefix such as
`LINUX-AMD64` only for genuine target differences. Compiler fixtures no longer
use separate literal `out.ll` golden files.

## Code Quality

Expand Down Expand Up @@ -179,4 +168,3 @@ LLGO_ROOT=/path/to/llgo llgo run .
3. **Defer in Loops:** LLGo now supports `defer` within loops, matching Go's semantics of executing defers in LIFO order for every iteration. Be mindful of loop-heavy defer usage as it allocates per iteration.
4. **C Ecosystem Integration:** LLGo uses `go:linkname` directive to link external symbols through ABI
5. **Python Integration:** Third-party Python libraries require separate installation of library files

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,10 @@ Here are the Go packages that can be imported correctly:
- [LLVM 18](https://llvm.org)
- [Clang 18](https://clang.llvm.org)
- [LLD 18](https://lld.llvm.org)
- [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/)
- [pkg-config 0.29+](https://gitlab.freedesktop.org/pkg-config/pkg-config)
- [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/)
- [OpenSSL 3.0+](https://www.openssl.org/)
- [zlib 1.2+](https://www.zlib.net)
- [zlib 1.2+](https://github.com/madler/zlib)
- [Python 3.12+](https://www.python.org) (optional, for [github.com/goplus/lib/py](https://pkg.go.dev/github.com/goplus/lib/py))

## How to install
Expand Down Expand Up @@ -423,8 +423,8 @@ cd llgo
* [pysigfetch](https://github.com/goplus/hdq/tree/main/chore/pysigfetch): It generates symbol information by extracting information from Python's documentation site. This tool is not part of the `llgo` project, but we depend on it.
* [llpyg](chore/llpyg): It is used to automatically convert Python libraries into Go packages that `llgo` can import. It depends on `pydump` and `pysigfetch` to accomplish the task.
* [llgen](chore/llgen): It is used to compile Go packages into LLVM IR files (*.ll).
* [gentests](chore/gentests): It refreshes the built-in golden test data under `cl/_test*`, including `out.ll` and `expect.txt`. Directories that use source-embedded `// LITTEST` checks are skipped for `out.ll` regeneration.
* [litgen](chore/litgen): It generates and refreshes source-embedded `// LITTEST` FileCheck directives from the current LLVM IR for marked Go source files.
* [gentests](chore/gentests): It refreshes runtime output and package metadata golden data under `cl/_test*`.
* [litgen](chore/litgen): It maintains explicitly opted-in, source-embedded FileCheck snapshots of post-ABI, pre-optimization LLVM IR. It supports function/global selection, target-specific prefixes, update-only operation, stale-check verification, and stable LLVM value abstractions. Small handwritten checks remain manual.
* [ssadump](chore/ssadump): It is a Go SSA builder and interpreter.

For local workflows and test-golden refresh commands, see [dev/README.md](dev/README.md#6-refresh-test-goldens).
Expand Down
37 changes: 0 additions & 37 deletions chore/gentests/gentests.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import (

"github.com/goplus/llgo/cl/cltest"
"github.com/goplus/llgo/internal/build"
"github.com/goplus/llgo/internal/littest"
"github.com/goplus/llgo/internal/llgen"
"github.com/goplus/llgo/internal/lto"
"github.com/goplus/llgo/xtool/env/llvm"
"github.com/goplus/mod"
Expand All @@ -36,38 +34,11 @@ func main() {
dir, _, err := mod.FindGoMod(".")
check(err)

llgenDir(dir + "/cl/_testlibc")
llgenDir(dir + "/cl/_testlibgo")
llgenDir(dir + "/cl/_testrt")
llgenDir(dir + "/cl/_testgo")
llgenDir(dir + "/cl/_testpy")
llgenDir(dir + "/cl/_testdata")
genMetaDir(dir + "/cl/_testmeta")

genExpects(dir)
}

func llgenDir(dir string) {
fis, err := os.ReadDir(dir)
check(err)
for _, fi := range fis {
name := fi.Name()
if !fi.IsDir() || strings.HasPrefix(name, "_") {
continue
}
testDir := dir + "/" + name
skip, err := dirHasLITTESTSource(testDir)
check(err)
if skip {
fmt.Fprintln(os.Stderr, "skip llgen", testDir, "(// LITTEST)")
continue
}
fmt.Fprintln(os.Stderr, "llgen", testDir)
check(os.Chdir(testDir))
llgen.SmartDoFile(testDir)
}
}

func genExpects(root string) {
runExpectDir(root, "cl/_testlibc")
runExpectDir(root, "cl/_testlibgo")
Expand Down Expand Up @@ -150,11 +121,3 @@ func check(err error) {
panic(err)
}
}

func dirHasLITTESTSource(dir string) (bool, error) {
_, ok, err := littest.FindMarkedSourceFile(dir)
if err != nil {
return false, err
}
return ok, nil
}
35 changes: 0 additions & 35 deletions chore/gentests/gentests_test.go

This file was deleted.

Loading
Loading