mirror of
https://github.com/golang/go
synced 2024-11-22 04:14:42 -07:00
cmd/compile: compute bits.Len*'s limits from argument's limits
Change-Id: Ie3c7e5eaba6a9a29389018625c4b784d07c6f173 Reviewed-on: https://go-review.googlesource.com/c/go/+/603537 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
9b6efc25cd
commit
0c7523ff59
@ -1666,6 +1666,27 @@ func (ft *factsTable) flowLimit(v *Value) bool {
|
||||
return ft.unsignedMax(v, 7)
|
||||
}
|
||||
|
||||
case OpBitLen64:
|
||||
a := ft.limits[v.Args[0].ID]
|
||||
return ft.unsignedMinMax(v,
|
||||
uint64(bits.Len64(a.umin)),
|
||||
uint64(bits.Len64(a.umax)))
|
||||
case OpBitLen32:
|
||||
a := ft.limits[v.Args[0].ID]
|
||||
return ft.unsignedMinMax(v,
|
||||
uint64(bits.Len32(uint32(a.umin))),
|
||||
uint64(bits.Len32(uint32(a.umax))))
|
||||
case OpBitLen16:
|
||||
a := ft.limits[v.Args[0].ID]
|
||||
return ft.unsignedMinMax(v,
|
||||
uint64(bits.Len16(uint16(a.umin))),
|
||||
uint64(bits.Len16(uint16(a.umax))))
|
||||
case OpBitLen8:
|
||||
a := ft.limits[v.Args[0].ID]
|
||||
return ft.unsignedMinMax(v,
|
||||
uint64(bits.Len8(uint8(a.umin))),
|
||||
uint64(bits.Len8(uint8(a.umax))))
|
||||
|
||||
// Masks.
|
||||
case OpAnd64, OpAnd32, OpAnd16, OpAnd8:
|
||||
// AND can only make the value smaller.
|
||||
|
102
test/prove.go
102
test/prove.go
@ -8,7 +8,10 @@
|
||||
|
||||
package main
|
||||
|
||||
import "math"
|
||||
import (
|
||||
"math"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
func f0(a []int) int {
|
||||
a[0] = 1
|
||||
@ -1193,6 +1196,103 @@ func f22(b bool, x, y int) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func bitLen64(x uint64, ensureBothBranchesCouldHappen bool) int {
|
||||
const max = math.MaxUint64
|
||||
sz := bits.Len64(max)
|
||||
|
||||
if x >= max>>3 {
|
||||
return 42
|
||||
}
|
||||
if x <= max>>6 {
|
||||
return 42
|
||||
}
|
||||
|
||||
y := bits.Len64(x)
|
||||
|
||||
if ensureBothBranchesCouldHappen {
|
||||
if sz-6 <= y && y <= sz-3 { // ERROR "Proved Leq64$"
|
||||
return -42
|
||||
}
|
||||
} else {
|
||||
if y < sz-6 || sz-3 < y { // ERROR "Disproved Less64$"
|
||||
return 1337
|
||||
}
|
||||
}
|
||||
return y
|
||||
}
|
||||
func bitLen32(x uint32, ensureBothBranchesCouldHappen bool) int {
|
||||
const max = math.MaxUint32
|
||||
sz := bits.Len32(max)
|
||||
|
||||
if x >= max>>3 {
|
||||
return 42
|
||||
}
|
||||
if x <= max>>6 {
|
||||
return 42
|
||||
}
|
||||
|
||||
y := bits.Len32(x)
|
||||
|
||||
if ensureBothBranchesCouldHappen {
|
||||
if sz-6 <= y && y <= sz-3 { // ERROR "Proved Leq64$"
|
||||
return -42
|
||||
}
|
||||
} else {
|
||||
if y < sz-6 || sz-3 < y { // ERROR "Disproved Less64$"
|
||||
return 1337
|
||||
}
|
||||
}
|
||||
return y
|
||||
}
|
||||
func bitLen16(x uint16, ensureBothBranchesCouldHappen bool) int {
|
||||
const max = math.MaxUint16
|
||||
sz := bits.Len16(max)
|
||||
|
||||
if x >= max>>3 {
|
||||
return 42
|
||||
}
|
||||
if x <= max>>6 {
|
||||
return 42
|
||||
}
|
||||
|
||||
y := bits.Len16(x)
|
||||
|
||||
if ensureBothBranchesCouldHappen {
|
||||
if sz-6 <= y && y <= sz-3 { // ERROR "Proved Leq64$"
|
||||
return -42
|
||||
}
|
||||
} else {
|
||||
if y < sz-6 || sz-3 < y { // ERROR "Disproved Less64$"
|
||||
return 1337
|
||||
}
|
||||
}
|
||||
return y
|
||||
}
|
||||
func bitLen8(x uint8, ensureBothBranchesCouldHappen bool) int {
|
||||
const max = math.MaxUint8
|
||||
sz := bits.Len8(max)
|
||||
|
||||
if x >= max>>3 {
|
||||
return 42
|
||||
}
|
||||
if x <= max>>6 {
|
||||
return 42
|
||||
}
|
||||
|
||||
y := bits.Len8(x)
|
||||
|
||||
if ensureBothBranchesCouldHappen {
|
||||
if sz-6 <= y && y <= sz-3 { // ERROR "Proved Leq64$"
|
||||
return -42
|
||||
}
|
||||
} else {
|
||||
if y < sz-6 || sz-3 < y { // ERROR "Disproved Less64$"
|
||||
return 1337
|
||||
}
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func useInt(a int) {
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user