Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/cmd/compile/internal/ssa/known_bits.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -273,6 +274,43 @@ 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
}
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
}
}
}

func (kbe knownBitsEntry) String() string {
lut := []rune{ // indexed by knownBit<<1 | valueBit
0b00: '?',
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/go/testdata/script/cover_atomic_pkgall.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions src/cmd/go/testdata/script/cover_pkgall_runtime.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions src/cmd/go/testdata/script/cover_test_race_issue56370.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[!race] skip

[GOARCH:loong64] skip 'broken on loong64: #78219'

go test -race -cover issue.56370/filter

-- go.mod --
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/go/testdata/script/test_race.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

go test testrace

[GOARCH:loong64] skip 'broken on loong64: #78219'

! go test -race testrace
stdout 'FAIL: TestRace'
! stdout 'PASS'
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/go/testdata/script/test_race_issue26995.txt
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/go/testdata/script/testing_issue40908.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[!race] skip

[GOARCH:loong64] skip 'broken on loong64: #78219'

go test -race testrace

-- go.mod --
Expand Down
44 changes: 44 additions & 0 deletions test/known_bits.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,47 @@ 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$"
}

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$"
}
Loading