mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: learn transitive proofs for safe unsigned subs
I've split this into it's own CL to make git bisect more effective. Change-Id: I436ff21a3e2362b3924de25a458534eb9947e013 Reviewed-on: https://go-review.googlesource.com/c/go/+/685821 Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
parent
d574856482
commit
f32cf8e4b0
2 changed files with 76 additions and 0 deletions
|
|
@ -2164,6 +2164,10 @@ func signedAddOverflowsOrUnderflows(a, b int64, t *types.Type) bool {
|
|||
}
|
||||
}
|
||||
|
||||
func unsignedSubUnderflows(a, b uint64) bool {
|
||||
return a < b
|
||||
}
|
||||
|
||||
func addLocalFacts(ft *factsTable, b *Block) {
|
||||
// Propagate constant ranges among values in this block.
|
||||
// We do this before the second loop so that we have the
|
||||
|
|
@ -2226,6 +2230,17 @@ func addLocalFacts(ft *factsTable, b *Block) {
|
|||
}
|
||||
ft.update(b, v, v.Args[0], signed, r)
|
||||
}
|
||||
case OpSub64, OpSub32, OpSub16, OpSub8:
|
||||
x := ft.limits[v.Args[0].ID]
|
||||
y := ft.limits[v.Args[1].ID]
|
||||
if !unsignedSubUnderflows(x.umin, y.umax) {
|
||||
r := lt
|
||||
if !y.nonzero() {
|
||||
r |= eq
|
||||
}
|
||||
ft.update(b, v, v.Args[0], unsigned, r)
|
||||
}
|
||||
// FIXME: we could also do signed facts but the overflow checks are much trickier and I don't need it yet.
|
||||
case OpAnd64, OpAnd32, OpAnd16, OpAnd8:
|
||||
ft.update(b, v, v.Args[0], unsigned, lt|eq)
|
||||
ft.update(b, v, v.Args[1], unsigned, lt|eq)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue