From 728b4adadc8d6c80a4fe929bb83ff646ba019a3a Mon Sep 17 00:00:00 2001 From: Guoqi Chen Date: Tue, 1 Sep 2026 15:18:34 +0800 Subject: [PATCH 1/3] cmd/go: skip race-related script tests on loong64 The race detector on loong64 requires a 48-bit VMA. However, some loong64 machines only have a 40-bit VMA (such as Loongson-2K3000), which causes the race execution to fail with the following error: FATAL: ThreadSanitizer: unsupported VMA range FATAL: Found 39 - Supported 47 exit status 66 Skip these tests on loong64 for now. Updates #78219 Change-Id: I8cc0b32e6e502431097c31e7935e933274126412 Reviewed-on: https://go-review.googlesource.com/c/go/+/825484 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com Reviewed-by: Michael Matloob Reviewed-by: sophie zhao Reviewed-by: Michael Matloob Reviewed-by: Michael Pratt --- src/cmd/go/testdata/script/cover_atomic_pkgall.txt | 2 ++ src/cmd/go/testdata/script/cover_pkgall_runtime.txt | 2 ++ src/cmd/go/testdata/script/cover_test_race_issue56370.txt | 2 ++ src/cmd/go/testdata/script/test_race.txt | 2 ++ src/cmd/go/testdata/script/test_race_issue26995.txt | 2 ++ src/cmd/go/testdata/script/testing_issue40908.txt | 2 ++ 6 files changed, 12 insertions(+) diff --git a/src/cmd/go/testdata/script/cover_atomic_pkgall.txt b/src/cmd/go/testdata/script/cover_atomic_pkgall.txt index 8f4397b4602de3..ad2093b7ad83c6 100644 --- a/src/cmd/go/testdata/script/cover_atomic_pkgall.txt +++ b/src/cmd/go/testdata/script/cover_atomic_pkgall.txt @@ -7,6 +7,8 @@ stdout ok[\s\S]+?coverage [!race] stop +[GOARCH:loong64] skip 'broken on loong64: #78219' + go test -coverpkg=all -race x stdout ok[\s\S]+?coverage diff --git a/src/cmd/go/testdata/script/cover_pkgall_runtime.txt b/src/cmd/go/testdata/script/cover_pkgall_runtime.txt index f92df35f636c01..600941b315c716 100644 --- a/src/cmd/go/testdata/script/cover_pkgall_runtime.txt +++ b/src/cmd/go/testdata/script/cover_pkgall_runtime.txt @@ -7,6 +7,8 @@ stdout ok[\s\S]+?coverage [!race] stop +[GOARCH:loong64] skip 'broken on loong64: #78219' + go test -coverpkg=all -race x stdout ok[\s\S]+?coverage diff --git a/src/cmd/go/testdata/script/cover_test_race_issue56370.txt b/src/cmd/go/testdata/script/cover_test_race_issue56370.txt index a18c2a7a41c870..94b2ea05d3cae9 100644 --- a/src/cmd/go/testdata/script/cover_test_race_issue56370.txt +++ b/src/cmd/go/testdata/script/cover_test_race_issue56370.txt @@ -1,5 +1,7 @@ [!race] skip +[GOARCH:loong64] skip 'broken on loong64: #78219' + go test -race -cover issue.56370/filter -- go.mod -- diff --git a/src/cmd/go/testdata/script/test_race.txt b/src/cmd/go/testdata/script/test_race.txt index c42f494bd84328..948c45105ea8b6 100644 --- a/src/cmd/go/testdata/script/test_race.txt +++ b/src/cmd/go/testdata/script/test_race.txt @@ -2,6 +2,8 @@ go test testrace +[GOARCH:loong64] skip 'broken on loong64: #78219' + ! go test -race testrace stdout 'FAIL: TestRace' ! stdout 'PASS' diff --git a/src/cmd/go/testdata/script/test_race_issue26995.txt b/src/cmd/go/testdata/script/test_race_issue26995.txt index f979facd7e16eb..a19da4b892220a 100644 --- a/src/cmd/go/testdata/script/test_race_issue26995.txt +++ b/src/cmd/go/testdata/script/test_race_issue26995.txt @@ -1,5 +1,7 @@ [!race] skip +[GOARCH:loong64] skip 'broken on loong64: #78219' + go test -v -race stdout 'testing_test.go:26: directCall' stdout 'testing_test.go:27: interfaceTBCall' diff --git a/src/cmd/go/testdata/script/testing_issue40908.txt b/src/cmd/go/testdata/script/testing_issue40908.txt index 70122cdb8c8b33..8f744a89fc9986 100644 --- a/src/cmd/go/testdata/script/testing_issue40908.txt +++ b/src/cmd/go/testdata/script/testing_issue40908.txt @@ -1,5 +1,7 @@ [!race] skip +[GOARCH:loong64] skip 'broken on loong64: #78219' + go test -race testrace -- go.mod -- From 4f21e8a96366a3e1708a4fdc25bcb6a80fe15cf4 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 13 Aug 2026 06:28:39 +0200 Subject: [PATCH 2/3] cmd/compile: teach known bits to remove no-op ands This has 32 hits when building the std and cmd. This code looks very 1:1 with code already existing in prove's simplifyValue method. However known bits can catch cases prove misses because prove doesn't support the 0 & ? entry (where ? is the no-op argument being removed). This is important as it allows to optimize no-op ands when neither argument is const, but where one argument is completely shadowed. Prove's blind spot exists because prove will never have a known LSB after an unkown MSB. This means the 0 & ? case can never be proven by prove since it implies either both arguments are const (will be handled by generic.rules) or there must be a ? & ? case at the LSB. Change-Id: I837d707e7a4f6aae2c82d84e939bebe39dca6a09 Reviewed-on: https://go-review.googlesource.com/c/go/+/814340 Reviewed-by: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Michael Pratt LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com --- src/cmd/compile/internal/ssa/known_bits.go | 22 ++++++++++++++++++++++ test/known_bits.go | 21 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/cmd/compile/internal/ssa/known_bits.go b/src/cmd/compile/internal/ssa/known_bits.go index 693e494219e82f..d922558e5a5260 100644 --- a/src/cmd/compile/internal/ssa/known_bits.go +++ b/src/cmd/compile/internal/ssa/known_bits.go @@ -45,6 +45,7 @@ func KnownBits(f *Func) { } val, k := kb.fold(v) if k != -1 { + kb.simplifyValue(v) continue } if f.Pass.Debug > 0 { @@ -273,6 +274,27 @@ func (kb *knownBitsState) fold(v *Value) (value, known int64) { } } +func (kb *knownBitsState) simplifyValue(v *Value) { + switch v.Op { + case ssaop.OpAnd64, ssaop.OpAnd32, ssaop.OpAnd16, ssaop.OpAnd8: + x, xk := kb.fold(v.Args[0]) + y, yk := kb.fold(v.Args[1]) + for i := range 2 { + xAllCouldBeOnes := x | ^xk + yAllCouldBeZeros := ^y + if xAllCouldBeOnes&yAllCouldBeZeros == 0 { + if f := v.Block.Func; f.Pass.Debug > 0 { + f.Warnl(v.Pos, "Removed %v no-op %v", v, v.Op) + } + v.CopyOf(v.Args[i]) + return + } + x, y = y, x + xk, yk = yk, xk + } + } +} + func (kbe knownBitsEntry) String() string { lut := []rune{ // indexed by knownBit<<1 | valueBit 0b00: '?', diff --git a/test/known_bits.go b/test/known_bits.go index 5d6f2bdb203507..327e89a31da80c 100644 --- a/test/known_bits.go +++ b/test/known_bits.go @@ -429,3 +429,24 @@ func unknownBitsSextAfterTrunc(x int64, cond1, cond2 bool) int64 { return int64(truncated) & (-1 << 63) } + +func pruneNoopAnd(x, y uint8) uint8 { + // x & y => is x &= y a noop ? + // 1. 0 & 0 => noop + // 2. 1 & 0 => keep and + // 3. ? & 0 => keep and + // 4. 0 & 1 => noop + // 5. 1 & 1 => noop + // 6. ? & 1 => noop + // 7. 0 & ? => noop; can't be handled by prove + // 8. 1 & ? => keep and + // 9. ? & ? => keep and + + // Test patterns: 76541 + x &= 0b01000 + x |= 0b00100 + y &= 0b10000 + y |= 0b01110 + + return x & y // ERROR "Removed v[0-9]+ no-op And8$" +} From 8213feb42277dd335bbab97e8d97837d8634b0fc Mon Sep 17 00:00:00 2001 From: Jorropo Date: Thu, 13 Aug 2026 06:41:34 +0200 Subject: [PATCH 3/3] cmd/compile: teach known bits to remove no-op or This does not trigger when building the std nor cmd. This code looks very 1:1 with code already existing in prove's simplifyValue method. However known bits can catch cases prove misses because prove doesn't support the 1 | ? entry (where ? is the no-op argument being removed). This is important as it allows to optimize no-op ors when neither argument is const, but where one argument is completely shadowed. Prove's blind spot exists because prove will never have a known LSB after an unkown MSB. This means the 0 | ? case can never be proven by prove since it implies either both arguments are const (will be handled by generic.rules) or there must be a ? | ? case at the LSB. Change-Id: I33b3631774341beb62d5235c8bc82a6f2504d824 Reviewed-on: https://go-review.googlesource.com/c/go/+/814341 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com Reviewed-by: Keith Randall Reviewed-by: Keith Randall Reviewed-by: Michael Pratt --- src/cmd/compile/internal/ssa/known_bits.go | 16 +++++++++++++++ test/known_bits.go | 23 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/cmd/compile/internal/ssa/known_bits.go b/src/cmd/compile/internal/ssa/known_bits.go index d922558e5a5260..063586a6d06573 100644 --- a/src/cmd/compile/internal/ssa/known_bits.go +++ b/src/cmd/compile/internal/ssa/known_bits.go @@ -292,6 +292,22 @@ func (kb *knownBitsState) simplifyValue(v *Value) { x, y = y, x xk, yk = yk, xk } + case ssaop.OpOr64, ssaop.OpOr32, ssaop.OpOr16, ssaop.OpOr8: + x, xk := kb.fold(v.Args[0]) + y, yk := kb.fold(v.Args[1]) + for i := range 2 { + xAllCouldBeZeros := ^x + yAllCouldBeOnes := y | ^yk + if xAllCouldBeZeros&yAllCouldBeOnes == 0 { + if f := v.Block.Func; f.Pass.Debug > 0 { + f.Warnl(v.Pos, "Removed %v no-op %v", v, v.Op) + } + v.CopyOf(v.Args[i]) + return + } + x, y = y, x + xk, yk = yk, xk + } } } diff --git a/test/known_bits.go b/test/known_bits.go index 327e89a31da80c..5de802ee9e00bf 100644 --- a/test/known_bits.go +++ b/test/known_bits.go @@ -450,3 +450,26 @@ func pruneNoopAnd(x, y uint8) uint8 { return x & y // ERROR "Removed v[0-9]+ no-op And8$" } + +func pruneNoopOr(x, y uint8) uint8 { + // x | y => is x |= y a noop ? + // 1. 0 | 0 => noop + // 2. 1 | 0 => noop + // 3. ? | 0 => noop + // 4. 0 | 1 => keep or + // 5. 1 | 1 => noop + // 6. ? | 1 => keep or + // 7. 0 | ? => keep or + // 8. 1 | ? => noop; can't be handled by prove + // 9. ? | ? => keep or + + // Test patterns: 85321 + // invert the and & or in setup otherwise generic.rules reassociate in a + // form known bits doesn't for. + x |= 0b11010 + x &= 0b11110 + y |= 0b01000 + y &= 0b11000 + + return x | y // ERROR "Removed v[0-9]+ no-op Or8$" +}