aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2024-10-26 14:19:32 -0700
committerKeith Randall <khr@golang.org>2024-10-29 16:46:48 +0000
commit4dcbb00be200bc1f88b534c311ed4289eb2fbdd5 (patch)
treece9db27b0c526acdba9240b50c85c931659366fb /test
parentf5526b56dbf45ce1f2e856f4aa78674dd0b5afe3 (diff)
downloadgo-4dcbb00be200bc1f88b534c311ed4289eb2fbdd5.tar.xz
cmd/compile: teach prove about min/max phi operations
If there is a phi that is computing the minimum of its two inputs, then we know the result of the phi is smaller than or equal to both of its inputs. Similarly for maxiumum (although max seems less useful). This pattern happens for the case n := copy(a, b) n is the minimum of len(a) and len(b), so with this optimization we know both n <= len(a) and n <= len(b). That extra information is helpful for subsequent slicing of a or b. Fixes #16833 Change-Id: Ib4238fd1edae0f2940f62a5516a6b363bbe7928c Reviewed-on: https://go-review.googlesource.com/c/go/+/622240 Reviewed-by: Carlos Amedee <carlos@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'test')
-rw-r--r--test/prove.go42
1 files changed, 42 insertions, 0 deletions
diff --git a/test/prove.go b/test/prove.go
index 2265b637ba..edfd8908a2 100644
--- a/test/prove.go
+++ b/test/prove.go
@@ -1670,6 +1670,48 @@ func neg64mightOverflowDuringNeg(a uint64, ensureAllBranchesCouldHappen func() b
return z
}
+func phiMin(a, b []byte) {
+ _ = a[:min(len(a), len(b))] // ERROR "Proved IsSliceInBounds"
+ _ = b[:min(len(a), len(b))] // ERROR "Proved IsSliceInBounds"
+ _ = a[:max(len(a), len(b))]
+ _ = b[:max(len(a), len(b))]
+ x := len(a)
+ if x > len(b) {
+ x = len(b)
+ useInt(0)
+ }
+ _ = a[:x] // ERROR "Proved IsSliceInBounds"
+ y := len(a)
+ if y > len(b) {
+ y = len(b)
+ useInt(0)
+ } else {
+ useInt(1)
+ }
+ _ = b[:y] // ERROR "Proved IsSliceInBounds"
+}
+
+func issue16833(a, b []byte) {
+ n := copy(a, b)
+ _ = a[n:] // ERROR "Proved IsSliceInBounds"
+ _ = b[n:] // ERROR "Proved IsSliceInBounds"
+ _ = a[:n] // ERROR "Proved IsSliceInBounds"
+ _ = b[:n] // ERROR "Proved IsSliceInBounds"
+}
+
+func clampedIdx1(x []int, i int) int {
+ if len(x) == 0 {
+ return 0
+ }
+ return x[min(max(0, i), len(x)-1)] // ERROR "Proved IsInBounds"
+}
+func clampedIdx2(x []int, i int) int {
+ if len(x) == 0 {
+ return 0
+ }
+ return x[max(min(i, len(x)-1), 0)] // TODO: can't get rid of this bounds check yet
+}
+
//go:noinline
func useInt(a int) {
}