Uniqued by LOC this adds 3 known bits hits when building the std. Updates #78633 Change-Id: I44f2ae1ed31f798d7881691729cce5d9707e8edc Reviewed-on: https://go-review.googlesource.com/c/go/+/766120 Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Jorropo <jorropo.pgm@gmail.com> Reviewed-by: Mark Freeman <markfreeman@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Carlos Amedee <carlos@golang.org>
434 lines
8.0 KiB
Go
434 lines
8.0 KiB
Go
// errorcheck -0 -d=ssa/known_bits/debug=1
|
|
|
|
//go:build amd64 || arm64 || s390x || ppc64le || riscv64
|
|
|
|
// Copyright 2026 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package a
|
|
|
|
func knownBitsPhiAnd(cond bool) int {
|
|
x := 1
|
|
if cond {
|
|
x = 3
|
|
}
|
|
return x & 1 // ERROR "known value of v[0-9]+ \(And64\): 1$"
|
|
}
|
|
|
|
func knownBitsPhiAndGarbage(cond bool, x int) int {
|
|
x &^= 1
|
|
if cond {
|
|
x = 2
|
|
}
|
|
return x & 1 // ERROR "known value of v[0-9]+ \(And64\): 0$"
|
|
}
|
|
|
|
func unknownBitsPhiAnd(cond bool) int {
|
|
x := 1
|
|
if cond {
|
|
x = 2
|
|
}
|
|
return x & 1
|
|
}
|
|
|
|
func knownBitsOrGarbage(x, unknown int) int {
|
|
x |= 7
|
|
x |= unknown &^ 3
|
|
return x & 3 // ERROR "known value of v[0-9]+ \(And64\): 3$"
|
|
}
|
|
|
|
func unknownBitsOrGarbage(x, unknown int) int {
|
|
x |= 1
|
|
x |= unknown
|
|
return x & 3
|
|
}
|
|
|
|
func knownBitsDeferPattern(a, b bool) int {
|
|
bits := 0
|
|
bits |= 1 << 0
|
|
if a {
|
|
bits |= 1 << 1
|
|
}
|
|
bits |= 1 << 2
|
|
if b {
|
|
bits |= 1 << 3
|
|
}
|
|
return bits & (1<<2 | 1<<0) // ERROR "known value of v[0-9]+ \(And64\): 5$"
|
|
}
|
|
|
|
func knownBitsDeferPatternGarbage(a, b bool, garbage int) int {
|
|
bits := 0
|
|
bits |= 1 << 0
|
|
if a {
|
|
bits |= 1 << 1
|
|
}
|
|
bits |= 1 << 2
|
|
if b {
|
|
bits |= 1 << 3
|
|
}
|
|
bits ^= garbage &^ (1<<2 | 1<<0)
|
|
return bits & (1<<2 | 1<<0) // ERROR "known value of v[0-9]+ \(And64\): 5$"
|
|
}
|
|
|
|
func knownBitsXorToggle(a, b, c bool) int {
|
|
bits := 0
|
|
bits ^= 1 << 0
|
|
if a {
|
|
bits ^= 1 << 1
|
|
}
|
|
bits ^= 1 << 2
|
|
if b {
|
|
bits ^= 1 << 3
|
|
}
|
|
bits ^= 1 << 2
|
|
if c {
|
|
bits ^= 1 << 4
|
|
}
|
|
return bits & (1<<2 | 1<<0) // ERROR "known value of v[0-9]+ \(And64\): 1$"
|
|
}
|
|
|
|
func knownBitsXorToggleGarbage(a, b, c bool, garbage int) int {
|
|
bits := 0
|
|
bits ^= 1 << 0
|
|
if a {
|
|
bits ^= 1 << 1
|
|
}
|
|
bits ^= 1 << 2
|
|
if b {
|
|
bits ^= 1 << 3
|
|
}
|
|
bits ^= 1 << 2
|
|
if c {
|
|
bits ^= 1 << 4
|
|
}
|
|
bits ^= garbage &^ (1<<2 | 1<<0)
|
|
return bits & (1<<2 | 1<<0) // ERROR "known value of v[0-9]+ \(And64\): 1$"
|
|
}
|
|
|
|
func unknownBitsXorToggle(a, b, c bool) int {
|
|
bits := 0
|
|
bits ^= 1 << 0
|
|
if a {
|
|
bits ^= 1 << 1
|
|
}
|
|
bits ^= 1 << 2
|
|
if b {
|
|
bits ^= 1 << 2
|
|
}
|
|
bits ^= 1 << 2
|
|
if c {
|
|
bits ^= 1 << 4
|
|
}
|
|
return bits & (1<<2 | 1<<0)
|
|
}
|
|
|
|
func knownBitsPhiComAnd(cond bool) int {
|
|
x := 1
|
|
if cond {
|
|
x = 3
|
|
}
|
|
return ^x & 1 // ERROR "known value of v[0-9]+ \(And64\): 0$"
|
|
}
|
|
|
|
func knownBitsPhiComAndGarbage(cond bool, garbage int) int {
|
|
x := 1
|
|
if cond {
|
|
x = 3
|
|
}
|
|
x ^= garbage &^ 1
|
|
return ^x & 1 // ERROR "known value of v[0-9]+ \(And64\): 0$"
|
|
}
|
|
|
|
func unknownBitsPhiComAnd(cond bool) int {
|
|
x := 1
|
|
if cond {
|
|
x = 2
|
|
}
|
|
return ^x & 1
|
|
}
|
|
|
|
func knownBitsEqFalse(x, y uint64) bool {
|
|
x |= 1
|
|
y &^= 1
|
|
return x == y // ERROR "known value of v[0-9]+ \(Eq64\): false$"
|
|
}
|
|
|
|
func knownBitsEqTrue(x uint64, cond bool) bool {
|
|
x |= (1<<32 - 1) << 32
|
|
if cond {
|
|
x |= 42
|
|
}
|
|
x |= 1<<32 - 1 // ERROR "known value of v[0-9]+ \(Or64\): -1$"
|
|
return x == 1<<64-1 // ERROR "known value of v[0-9]+ \(Eq64\): true$"
|
|
}
|
|
|
|
func unknownBitsEq(x, y uint64) bool {
|
|
x |= 1
|
|
return x == y
|
|
}
|
|
|
|
func knownBitsNeqTrue(x, y uint64) bool {
|
|
x |= 1
|
|
y &^= 1
|
|
return x != y // ERROR "known value of v[0-9]+ \(Neq64\): true$"
|
|
}
|
|
|
|
func knownBitsNeqFalse(x uint64, cond bool) bool {
|
|
x |= (1<<32 - 1) << 32
|
|
if cond {
|
|
x |= 42
|
|
}
|
|
x |= 1<<32 - 1
|
|
return x != 1<<64-1 // ERROR "known value of v[0-9]+ \(Neq64\): false$"
|
|
}
|
|
|
|
func unknownBitsNeq(x, y uint64) bool {
|
|
x |= 1
|
|
return x != y
|
|
}
|
|
|
|
func knownBitsZeroExtPassThrough(x uint8) uint64 {
|
|
x |= 6
|
|
return uint64(x) & 6 // ERROR "known value of v[0-9]+ \(And64\): 6$"
|
|
}
|
|
|
|
func knownBitsZeroExtUpperHalf(x uint16) uint32 {
|
|
return uint32(x) & 0xFFFF0000 // ERROR "known value of v[0-9]+ \(And32\): 0$"
|
|
}
|
|
|
|
func unknownBitsZeroExt(x uint16) uint32 {
|
|
x |= 0xAAAA
|
|
return uint32(x) & 0xFFFFF000
|
|
}
|
|
|
|
func cvtBoolToUint8(cond bool) (r uint8) {
|
|
if cond {
|
|
r = 1
|
|
}
|
|
return r
|
|
}
|
|
|
|
func knownBitsCvtBoolToUint8False(x, y uint64) uint8 {
|
|
x |= 1
|
|
y &^= 1
|
|
bool := x == y // ERROR "known value of v[0-9]+ \(Eq64\): false$"
|
|
return cvtBoolToUint8(bool) & 1 // ERROR "known value of v[0-9]+ \(CvtBoolToUint8\): 0$"
|
|
}
|
|
|
|
func knownBitsCvtBoolToUint8True(x int64, cond bool) uint8 {
|
|
x |= 6
|
|
if cond {
|
|
x |= 1
|
|
x |= 4
|
|
}
|
|
// I would expect "known value of v[0-9]+ \(And64\): 6$" to be required, but somehow it's not there even tho the AND is being folded.
|
|
// I think it's an issue with the And's LOC meaning known bits prints it without a LOC and errorcheck skips it.
|
|
r := cvtBoolToUint8(x&6 == 6) // ERROR "known value of v[0-9]+ \(Eq64\): true$" "known value of v[0-9]+ \(CvtBoolToUint8\): 1$"
|
|
if cond {
|
|
r |= 4 // ERROR "known value of v[0-9]+ \(Or8\): 5$"
|
|
}
|
|
return r & 3 // ERROR "known value of v[0-9]+ \(And8\): 1$"
|
|
}
|
|
|
|
func unknownBitsCvtBoolToUint8(cond bool) uint8 {
|
|
return cvtBoolToUint8(cond) & 1
|
|
}
|
|
|
|
func knownBitsSignExtPassThrough(x int8) int64 {
|
|
x |= 6
|
|
return int64(x) & 6 // ERROR "known value of v[0-9]+ \(And64\): 6$"
|
|
}
|
|
|
|
func knownBitsSignExtUpperHalf(x int16) int32 {
|
|
x |= -1 << 15
|
|
return int32(x) & (-1 << 16) // ERROR "known value of v[0-9]+ \(And32\): -65536$"
|
|
}
|
|
|
|
func unknownBitsSignExt(x int16) int32 {
|
|
x |= -0b010101010101010
|
|
return int32(x) & -1 << 12
|
|
}
|
|
|
|
func knownBitsLsh(x, y uint32) uint32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 2
|
|
|
|
// ???01111?
|
|
// ?01111???
|
|
// ---------
|
|
// ????11???
|
|
|
|
return (x << y) & 0b11000 // ERROR "known value of v[0-9]+ \(And32\): 24$"
|
|
}
|
|
|
|
func knownBitsLshZero(x, y uint64) uint64 {
|
|
x &^= 2
|
|
y &^= 2
|
|
y |= 128
|
|
|
|
return (x << y) & 8 // ERROR "known value of v[0-9]+ \(And64\): 0$" "known value of v[0-9]+ \(Lsh64x[0-9]+\): 0$"
|
|
}
|
|
|
|
func unknownBitsLshLeftSideMsb(x uint32, y uint32) uint32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 2
|
|
|
|
return (x << y) & 0b111000
|
|
}
|
|
|
|
func unknownBitsLshLeftSideLsb(x uint32, y uint32) uint32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 2
|
|
|
|
return (x << y) & 0b011100
|
|
}
|
|
|
|
func unknownBitsLshRightSide(x uint32, y uint32) uint32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 6
|
|
|
|
return (x << y) & 0b11000
|
|
}
|
|
|
|
func knownBitsRshU(x, y uint32) uint32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 2
|
|
|
|
// ?01111?
|
|
// ???0111
|
|
// -------
|
|
// ????11?
|
|
|
|
return (x >> y) & 0b110 // ERROR "known value of v[0-9]+ \(And32\): 6$"
|
|
}
|
|
|
|
func knownBitsRshUZero(x, y uint64) uint64 {
|
|
x &^= 4
|
|
y &^= 2
|
|
y |= 128
|
|
|
|
return (x >> y) & 1 // ERROR "known value of v[0-9]+ \(And64\): 0$" "known value of v[0-9]+ \(Rsh64Ux[0-9]+\): 0$"
|
|
}
|
|
|
|
func unknownBitsRshULeftSideMsb(x uint32, y uint32) uint32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 2
|
|
|
|
return (x >> y) & 0b1110
|
|
}
|
|
|
|
func unknownBitsRshULeftSideLsb(x uint32, y uint32) uint32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 2
|
|
|
|
return (x >> y) & 0b111
|
|
}
|
|
|
|
func unknownBitsRshURightSide(x uint32, y uint32) uint32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 6
|
|
|
|
return (x >> y) & 0b110
|
|
}
|
|
|
|
func knownBitsRsh(x, y int32) int32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 2
|
|
|
|
// ?01111?
|
|
// ???0111
|
|
// -------
|
|
// ????11?
|
|
|
|
return (x >> y) & 0b110 // ERROR "known value of v[0-9]+ \(And32\): 6$"
|
|
}
|
|
|
|
func knownBitsRshSignCopy(x, y int64) int64 {
|
|
x |= -1 << 63
|
|
y |= 128
|
|
|
|
return (x >> y) & 1 // ERROR "known value of v[0-9]+ \(And64\): 1$"
|
|
}
|
|
|
|
func unknownBitsRshLeftSideMsb(x int32, y int32) int32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 2
|
|
|
|
return (x >> y) & 0b1110
|
|
}
|
|
|
|
func unknownBitsRshLeftSideLsb(x int32, y int32) int32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 2
|
|
|
|
return (x >> y) & 0b111
|
|
}
|
|
|
|
func unknownBitsRshRightSide(x int32, y int32) int32 {
|
|
x |= 0b11110
|
|
x &^= 0b100000
|
|
y &= 6
|
|
|
|
return (x >> y) & 0b110
|
|
}
|
|
|
|
func knownBitsTrunc(x int64, cond bool) int32 {
|
|
x |= 2
|
|
if cond {
|
|
x = 3
|
|
}
|
|
|
|
return int32(x) & 2 // ERROR "known value of v[0-9]+ \(And32\): 2$"
|
|
}
|
|
|
|
func unknownBitsTrunc(x int64, cond bool) int32 {
|
|
x |= 2
|
|
if cond {
|
|
x = 3
|
|
}
|
|
|
|
return int32(x) & 1
|
|
}
|
|
|
|
func knownBitsSextAfterTrunc(x int64, cond1, cond2 bool) int64 {
|
|
x |= -1 << 31
|
|
if cond1 {
|
|
x = -3
|
|
}
|
|
|
|
truncated := int32(x)
|
|
|
|
if cond2 {
|
|
truncated |= 4
|
|
}
|
|
|
|
return int64(truncated) & (-1 << 63) // ERROR "known value of v[0-9]+ \(And64\): -9223372036854775808$"
|
|
}
|
|
|
|
func unknownBitsSextAfterTrunc(x int64, cond1, cond2 bool) int64 {
|
|
x |= 2
|
|
if cond1 {
|
|
x = 3
|
|
}
|
|
|
|
truncated := int32(x)
|
|
|
|
if cond2 {
|
|
truncated |= 4
|
|
}
|
|
|
|
return int64(truncated) & (-1 << 63)
|
|
}
|