From 233a3732945a9269e4689441ae8c6b9d0071f816 Mon Sep 17 00:00:00 2001 From: Li Jie Date: Mon, 23 Mar 2026 10:41:35 +0800 Subject: [PATCH 1/2] test: cover arm64 stdlib sysreg cross-target paths --- stdlib_cpu_arm64_test.go | 18 ++++--- stdlib_runtime_sys_arm64_test.go | 90 ++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 17 deletions(-) diff --git a/stdlib_cpu_arm64_test.go b/stdlib_cpu_arm64_test.go index 0cc199f..9deecd6 100644 --- a/stdlib_cpu_arm64_test.go +++ b/stdlib_cpu_arm64_test.go @@ -7,21 +7,18 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "strings" "testing" ) func TestStdlibInternalCPU_ARM64_Compile(t *testing.T) { - if runtime.GOARCH != "arm64" { - t.Skip("host is not arm64") - } llc, _, ok := findLlcAndClang(t) if !ok { t.Skip("llc not found") } + const triple = "aarch64-unknown-linux-gnu" - goroot := runtime.GOROOT() + goroot := testGOROOT(t) src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "cpu", "cpu_arm64.s")) if err != nil { t.Fatal(err) @@ -55,9 +52,10 @@ func TestStdlibInternalCPU_ARM64_Compile(t *testing.T) { }, } ll, err := Translate(file, Options{ - TargetTriple: testTargetTriple(runtime.GOOS, runtime.GOARCH), + TargetTriple: triple, ResolveSym: resolve, Sigs: sigs, + Goarch: "arm64", }) if err != nil { t.Fatal(err) @@ -69,9 +67,13 @@ func TestStdlibInternalCPU_ARM64_Compile(t *testing.T) { if err := os.WriteFile(llPath, []byte(ll), 0644); err != nil { t.Fatal(err) } - cmd := exec.Command(llc, "-filetype=obj", llPath, "-o", objPath) + cmd := exec.Command(llc, "-mtriple="+triple, "-filetype=obj", llPath, "-o", objPath) out, err := cmd.CombinedOutput() if err != nil { - t.Fatalf("llc failed: %v\n%s", err, string(out)) + s := string(out) + if llcUnsupportedTarget(s) { + t.Skipf("llc does not support triple %q: %s", triple, strings.TrimSpace(s)) + } + t.Fatalf("llc failed: %v\n%s", err, s) } } diff --git a/stdlib_runtime_sys_arm64_test.go b/stdlib_runtime_sys_arm64_test.go index 6335023..673fb33 100644 --- a/stdlib_runtime_sys_arm64_test.go +++ b/stdlib_runtime_sys_arm64_test.go @@ -7,21 +7,18 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "strings" "testing" ) func TestStdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { - if runtime.GOARCH != "arm64" { - t.Skip("host is not arm64") - } llc, _, ok := findLlcAndClang(t) if !ok { t.Skip("llc not found") } + const triple = "aarch64-unknown-linux-gnu" - goroot := runtime.GOROOT() + goroot := testGOROOT(t) src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "runtime", "sys", "dit_arm64.s")) if err != nil { if os.IsNotExist(err) { @@ -61,10 +58,10 @@ func TestStdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { }, } ll, err := Translate(file, Options{ - TargetTriple: testTargetTriple(runtime.GOOS, runtime.GOARCH), + TargetTriple: triple, ResolveSym: resolve, Sigs: sigs, - Goarch: runtime.GOARCH, + Goarch: "arm64", }) if err != nil { t.Fatal(err) @@ -76,9 +73,84 @@ func TestStdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { if err := os.WriteFile(llPath, []byte(ll), 0644); err != nil { t.Fatal(err) } - cmd := exec.Command(llc, "-filetype=obj", llPath, "-o", objPath) + cmd := exec.Command(llc, "-mtriple="+triple, "-filetype=obj", llPath, "-o", objPath) out, err := cmd.CombinedOutput() if err != nil { - t.Fatalf("llc failed: %v\n%s", err, string(out)) + s := string(out) + if llcUnsupportedTarget(s) { + t.Skipf("llc does not support triple %q: %s", triple, strings.TrimSpace(s)) + } + t.Fatalf("llc failed: %v\n%s", err, s) + } +} + +func TestTranslateGoModule_StdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { + llc, _, ok := findLlcAndClang(t) + if !ok { + t.Skip("llc not found") + } + const triple = "aarch64-unknown-linux-gnu" + + goroot := testGOROOT(t) + src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "runtime", "sys", "dit_arm64.s")) + if err != nil { + if os.IsNotExist(err) { + t.Skip("internal/runtime/sys/dit_arm64.s not present in this GOROOT") + } + t.Fatal(err) + } + pkg := mustGoPackage(t, "internal/runtime/sys", `package sys +func EnableDIT() bool +func DITEnabled() bool +func DisableDIT() +`) + + tr, err := TranslateGoModule(pkg, src, GoModuleOptions{ + FileName: "dit_arm64.s", + GOOS: "linux", + GOARCH: "arm64", + TargetTriple: triple, + ResolveSym: testResolveSym("internal/runtime/sys"), + }) + if err != nil { + t.Fatal(err) + } + defer tr.Module.Dispose() + + tmp := t.TempDir() + llPath := filepath.Join(tmp, "dit-gomod.ll") + objPath := filepath.Join(tmp, "dit-gomod.o") + if err := os.WriteFile(llPath, []byte(tr.Module.String()), 0644); err != nil { + t.Fatal(err) + } + cmd := exec.Command(llc, "-mtriple="+triple, "-filetype=obj", llPath, "-o", objPath) + out, err := cmd.CombinedOutput() + if err != nil { + s := string(out) + if llcUnsupportedTarget(s) { + t.Skipf("llc does not support triple %q: %s", triple, strings.TrimSpace(s)) + } + t.Fatalf("llc failed: %v\n%s", err, s) + } +} + +func testGOROOT(t *testing.T) string { + t.Helper() + goroot := os.Getenv("GOROOT") + if goroot == "" { + goroot = testGoEnv(t, "GOROOT") + } + if goroot == "" { + t.Skip("GOROOT not available") + } + return goroot +} + +func testGoEnv(t *testing.T, key string) string { + t.Helper() + out, err := exec.Command("go", "env", key).CombinedOutput() + if err != nil { + t.Fatalf("go env %s failed: %v\n%s", key, err, string(out)) } + return strings.TrimSpace(string(out)) } From a7e4d585f201e7b2b03fece8686242824a941053 Mon Sep 17 00:00:00 2001 From: Li Jie Date: Mon, 23 Mar 2026 10:51:43 +0800 Subject: [PATCH 2/2] test: factor arm64 stdlib compile helpers --- stdlib_arm64_test_helpers_test.go | 53 +++++++++++++++++++++++++++ stdlib_cpu_arm64_test.go | 23 +++--------- stdlib_runtime_sys_arm64_test.go | 60 +++---------------------------- 3 files changed, 62 insertions(+), 74 deletions(-) create mode 100644 stdlib_arm64_test_helpers_test.go diff --git a/stdlib_arm64_test_helpers_test.go b/stdlib_arm64_test_helpers_test.go new file mode 100644 index 0000000..c7d8b5a --- /dev/null +++ b/stdlib_arm64_test_helpers_test.go @@ -0,0 +1,53 @@ +//go:build !llgo +// +build !llgo + +package plan9asm + +import ( + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +const arm64LinuxGNUTriple = "aarch64-unknown-linux-gnu" + +func testGOROOT(t *testing.T) string { + t.Helper() + if goroot := os.Getenv("GOROOT"); goroot != "" { + return goroot + } + goroot, err := testGoEnv("GOROOT") + if err != nil || goroot == "" { + t.Skip("GOROOT not available") + } + return goroot +} + +func testGoEnv(key string) (string, error) { + out, err := exec.Command("go", "env", key).CombinedOutput() + if err != nil { + return "", err + } + return strings.TrimSpace(string(out)), nil +} + +func compileLLVMToObject(t *testing.T, llc, triple, llName, objName, ll string) { + t.Helper() + tmp := t.TempDir() + llPath := filepath.Join(tmp, llName) + objPath := filepath.Join(tmp, objName) + if err := os.WriteFile(llPath, []byte(ll), 0644); err != nil { + t.Fatal(err) + } + cmd := exec.Command(llc, "-mtriple="+triple, "-filetype=obj", llPath, "-o", objPath) + out, err := cmd.CombinedOutput() + if err != nil { + s := string(out) + if llcUnsupportedTarget(s) { + t.Skipf("llc does not support triple %q: %s", triple, strings.TrimSpace(s)) + } + t.Fatalf("llc failed: %v\n%s", err, s) + } +} diff --git a/stdlib_cpu_arm64_test.go b/stdlib_cpu_arm64_test.go index 9deecd6..de1c28a 100644 --- a/stdlib_cpu_arm64_test.go +++ b/stdlib_cpu_arm64_test.go @@ -5,7 +5,6 @@ package plan9asm import ( "os" - "os/exec" "path/filepath" "strings" "testing" @@ -16,11 +15,13 @@ func TestStdlibInternalCPU_ARM64_Compile(t *testing.T) { if !ok { t.Skip("llc not found") } - const triple = "aarch64-unknown-linux-gnu" goroot := testGOROOT(t) src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "cpu", "cpu_arm64.s")) if err != nil { + if os.IsNotExist(err) { + t.Skip("internal/cpu/cpu_arm64.s not present in this GOROOT") + } t.Fatal(err) } @@ -52,7 +53,7 @@ func TestStdlibInternalCPU_ARM64_Compile(t *testing.T) { }, } ll, err := Translate(file, Options{ - TargetTriple: triple, + TargetTriple: arm64LinuxGNUTriple, ResolveSym: resolve, Sigs: sigs, Goarch: "arm64", @@ -61,19 +62,5 @@ func TestStdlibInternalCPU_ARM64_Compile(t *testing.T) { t.Fatal(err) } - tmp := t.TempDir() - llPath := filepath.Join(tmp, "cpu.ll") - objPath := filepath.Join(tmp, "cpu.o") - if err := os.WriteFile(llPath, []byte(ll), 0644); err != nil { - t.Fatal(err) - } - cmd := exec.Command(llc, "-mtriple="+triple, "-filetype=obj", llPath, "-o", objPath) - out, err := cmd.CombinedOutput() - if err != nil { - s := string(out) - if llcUnsupportedTarget(s) { - t.Skipf("llc does not support triple %q: %s", triple, strings.TrimSpace(s)) - } - t.Fatalf("llc failed: %v\n%s", err, s) - } + compileLLVMToObject(t, llc, arm64LinuxGNUTriple, "cpu.ll", "cpu.o", ll) } diff --git a/stdlib_runtime_sys_arm64_test.go b/stdlib_runtime_sys_arm64_test.go index 673fb33..d6f2c37 100644 --- a/stdlib_runtime_sys_arm64_test.go +++ b/stdlib_runtime_sys_arm64_test.go @@ -5,7 +5,6 @@ package plan9asm import ( "os" - "os/exec" "path/filepath" "strings" "testing" @@ -16,7 +15,6 @@ func TestStdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { if !ok { t.Skip("llc not found") } - const triple = "aarch64-unknown-linux-gnu" goroot := testGOROOT(t) src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "runtime", "sys", "dit_arm64.s")) @@ -58,7 +56,7 @@ func TestStdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { }, } ll, err := Translate(file, Options{ - TargetTriple: triple, + TargetTriple: arm64LinuxGNUTriple, ResolveSym: resolve, Sigs: sigs, Goarch: "arm64", @@ -67,21 +65,7 @@ func TestStdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { t.Fatal(err) } - tmp := t.TempDir() - llPath := filepath.Join(tmp, "dit.ll") - objPath := filepath.Join(tmp, "dit.o") - if err := os.WriteFile(llPath, []byte(ll), 0644); err != nil { - t.Fatal(err) - } - cmd := exec.Command(llc, "-mtriple="+triple, "-filetype=obj", llPath, "-o", objPath) - out, err := cmd.CombinedOutput() - if err != nil { - s := string(out) - if llcUnsupportedTarget(s) { - t.Skipf("llc does not support triple %q: %s", triple, strings.TrimSpace(s)) - } - t.Fatalf("llc failed: %v\n%s", err, s) - } + compileLLVMToObject(t, llc, arm64LinuxGNUTriple, "dit.ll", "dit.o", ll) } func TestTranslateGoModule_StdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { @@ -89,7 +73,6 @@ func TestTranslateGoModule_StdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) if !ok { t.Skip("llc not found") } - const triple = "aarch64-unknown-linux-gnu" goroot := testGOROOT(t) src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "runtime", "sys", "dit_arm64.s")) @@ -109,7 +92,7 @@ func DisableDIT() FileName: "dit_arm64.s", GOOS: "linux", GOARCH: "arm64", - TargetTriple: triple, + TargetTriple: arm64LinuxGNUTriple, ResolveSym: testResolveSym("internal/runtime/sys"), }) if err != nil { @@ -117,40 +100,5 @@ func DisableDIT() } defer tr.Module.Dispose() - tmp := t.TempDir() - llPath := filepath.Join(tmp, "dit-gomod.ll") - objPath := filepath.Join(tmp, "dit-gomod.o") - if err := os.WriteFile(llPath, []byte(tr.Module.String()), 0644); err != nil { - t.Fatal(err) - } - cmd := exec.Command(llc, "-mtriple="+triple, "-filetype=obj", llPath, "-o", objPath) - out, err := cmd.CombinedOutput() - if err != nil { - s := string(out) - if llcUnsupportedTarget(s) { - t.Skipf("llc does not support triple %q: %s", triple, strings.TrimSpace(s)) - } - t.Fatalf("llc failed: %v\n%s", err, s) - } -} - -func testGOROOT(t *testing.T) string { - t.Helper() - goroot := os.Getenv("GOROOT") - if goroot == "" { - goroot = testGoEnv(t, "GOROOT") - } - if goroot == "" { - t.Skip("GOROOT not available") - } - return goroot -} - -func testGoEnv(t *testing.T, key string) string { - t.Helper() - out, err := exec.Command("go", "env", key).CombinedOutput() - if err != nil { - t.Fatalf("go env %s failed: %v\n%s", key, err, string(out)) - } - return strings.TrimSpace(string(out)) + compileLLVMToObject(t, llc, arm64LinuxGNUTriple, "dit-gomod.ll", "dit-gomod.o", tr.Module.String()) }