aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorJonah Uellenberg <JonahUellenberg@gmail.com>2026-01-29 19:45:27 +0000
committerGopher Robot <gobot@golang.org>2026-01-29 14:08:19 -0800
commit14a4cb13e389d8dbc1ba3ba0097e208f1436a22a (patch)
treecc5cc4779a33f574f50b52e80571590c7ca324b2 /src/cmd
parentee7a2119ac17ea2a6bbf12b4c8001bf39c388166 (diff)
downloadgo-14a4cb13e389d8dbc1ba3ba0097e208f1436a22a.tar.xz
cmd/compile: make prove use non-equality in subtraction for a stronger bound
Given: s := /* slice */ k := /* proved valid index in s (0 <= k < len(s)) */ v := s[k:] len(v) >= 1, so v[0] needs no bounds check. However, for len(v) = len(s) - k, we only checked if len(s) >= k and so could only prove len(v) >= 0, thus the bounds check wasn't removed. As far as I can tell these checks were commented out for performance, but after benchmarking prove I see no difference. Fixes: #76429 Change-Id: I39ba2a18cbabc0559924d4d226dcb99dbe9a06ed GitHub-Last-Rev: 53f3344d261986cd021c8d7b8435ab89b5438b8f GitHub-Pull-Request: golang/go#76609 Reviewed-on: https://go-review.googlesource.com/c/go/+/725100 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/compile/internal/ssa/prove.go24
1 files changed, 11 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go
index c9f75daa67..1083874100 100644
--- a/src/cmd/compile/internal/ssa/prove.go
+++ b/src/cmd/compile/internal/ssa/prove.go
@@ -2187,24 +2187,22 @@ func (ft *factsTable) detectSubRelations(v *Value) {
return // x-y might overflow
}
- // Subtracting a positive number only makes
- // things smaller.
- if yLim.min >= 0 {
+ // Subtracting a positive non-zero number only makes
+ // things smaller. If it's positive or zero, it might
+ // also do nothing (x-0 == v).
+ if yLim.min > 0 {
+ ft.update(v.Block, v, x, signed, lt)
+ } else if yLim.min == 0 {
ft.update(v.Block, v, x, signed, lt|eq)
- // TODO: is this worth it?
- //if yLim.min > 0 {
- // ft.update(v.Block, v, x, signed, lt)
- //}
}
// Subtracting a number from a bigger one
- // can't go below 0.
- if ft.orderS.OrderedOrEqual(y, x) {
+ // can't go below 1. If the numbers might be
+ // equal, then it can't go below 0.
+ if ft.orderS.Ordered(y, x) {
+ ft.signedMin(v, 1)
+ } else if ft.orderS.OrderedOrEqual(y, x) {
ft.setNonNegative(v)
- // TODO: is this worth it?
- //if ft.orderS.Ordered(y, x) {
- // ft.signedMin(v, 1)
- //}
}
}