mirror of
https://github.com/golang/go
synced 2024-11-26 14:26:51 -07:00
cmd/compile: handle non-negatives in prove
Handle this case: if 0 <= i && i < len(a) { use a[i] } Shaves about 5k from pkg/tools/linux_amd64/*. Change-Id: I6675ff49aa306b0d241b074c5738e448204cd981 Reviewed-on: https://go-review.googlesource.com/21431 Run-TryBot: Alexandru Moșoi <alexandru@mosoi.ro> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
72c1180852
commit
27ebc84716
@ -296,6 +296,15 @@ func (ft *factsTable) update(v, w *Value, d domain, r relation) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isNonNegative returns true if v is known to be non-negative.
|
||||||
|
func (ft *factsTable) isNonNegative(v *Value) bool {
|
||||||
|
if isNonNegative(v) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
l, has := ft.limits[v.ID]
|
||||||
|
return has && (l.min >= 0 || l.umax <= math.MaxInt64)
|
||||||
|
}
|
||||||
|
|
||||||
// checkpoint saves the current state of known relations.
|
// checkpoint saves the current state of known relations.
|
||||||
// Called when descending on a branch.
|
// Called when descending on a branch.
|
||||||
func (ft *factsTable) checkpoint() {
|
func (ft *factsTable) checkpoint() {
|
||||||
@ -608,8 +617,7 @@ func simplifyBlock(ft *factsTable, b *Block) branch {
|
|||||||
// to the upper bound than this is proven. Most useful in cases such as:
|
// to the upper bound than this is proven. Most useful in cases such as:
|
||||||
// if len(a) <= 1 { return }
|
// if len(a) <= 1 { return }
|
||||||
// do something with a[1]
|
// do something with a[1]
|
||||||
// TODO: use constant bounds to do isNonNegative.
|
if (c.Op == OpIsInBounds || c.Op == OpIsSliceInBounds) && ft.isNonNegative(c.Args[0]) {
|
||||||
if (c.Op == OpIsInBounds || c.Op == OpIsSliceInBounds) && isNonNegative(c.Args[0]) {
|
|
||||||
m := ft.get(a0, a1, signed)
|
m := ft.get(a0, a1, signed)
|
||||||
if m != 0 && tr.r&m == m {
|
if m != 0 && tr.r&m == m {
|
||||||
if b.Func.pass.debug > 0 {
|
if b.Func.pass.debug > 0 {
|
||||||
|
@ -29,11 +29,30 @@ func f1(a []int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func f1b(a []int, i int, j uint) int {
|
func f1b(a []int, i int, j uint) int {
|
||||||
if i >= 0 && i < len(a) { // TODO: handle this case
|
if i >= 0 && i < len(a) {
|
||||||
return a[i]
|
return a[i] // ERROR "Proved non-negative bounds IsInBounds$"
|
||||||
|
}
|
||||||
|
if i >= 10 && i < len(a) {
|
||||||
|
return a[i] // ERROR "Proved non-negative bounds IsInBounds$"
|
||||||
|
}
|
||||||
|
if i >= 10 && i < len(a) {
|
||||||
|
return a[i] // ERROR "Proved non-negative bounds IsInBounds$"
|
||||||
|
}
|
||||||
|
if i >= 10 && i < len(a) { // todo: handle this case
|
||||||
|
return a[i-10]
|
||||||
}
|
}
|
||||||
if j < uint(len(a)) {
|
if j < uint(len(a)) {
|
||||||
return a[j] // ERROR "Proved IsInBounds"
|
return a[j] // ERROR "Proved IsInBounds$"
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func f1c(a []int, i int64) int {
|
||||||
|
c := uint64(math.MaxInt64 + 10) // overflows int
|
||||||
|
d := int64(c)
|
||||||
|
if i >= d && i < int64(len(a)) {
|
||||||
|
// d overflows, should not be handled.
|
||||||
|
return a[i]
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user