-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
Go version
go version go1.26-devel_337f7b1 Sat Nov 22 06:13:24 2025 -0800 linux/amd64
Output of go env in your module/workspace:
Workspace is `go.godbolt.org` on `x86-64 gc (tip)` as above.What did you do?
[Code+output tested here]
Compile these simplified examples:
func testReslice0(s []byte, k int) byte {
if k < 0 || k >= len(s) {
return 0
}
s = s[k:] // Proved IsSliceInBounds
return s[0] // bounds check!
}
func testReslice1(s []byte, k int) byte {
if k < 0 || k > len(s) - 1 {
return 0
}
s = s[k:] // Proved IsSliceInBounds + slicemask not needed (by limit)
return s[0] // Proved IsInBounds
}What did you see happen?
testReslice0 has an extra bounds check (and slice mask) that testReslice1 does not have.
What did you expect to see?
testReslice0 should not contain an extra bounds check, as 0 <= k < len(s), meaning s after slicing off k elements must still contain an element left for s[0] to succeed.
testReslice1 contains the following debug prove output that testReslice0 does not have:
<source>:4:30: x+d >= w; x:v13 b2 delta:-1 w:-1 d:signed
<source>:4:30: x+d >= w; x:v13 b2 delta:-1 w:0 d:signed
<source>:7:10: Proved slicemask not needed (by limit)
It appears that when there is no subtraction involved, the limits are not detected and propagated to the slice mask operation and later. This may be due to optimizations added by the recently introduced detectSliceLenRelation (@dr2chase) and/or detectSubRelations (@randall77) that don't have an equivalent without the subtraction from len(s).
Solving this would, for example, eliminate an extra bounds check in the runtime's decoderune.