diff options
| author | David Chase <drchase@google.com> | 2025-11-24 15:00:11 -0500 |
|---|---|---|
| committer | David Chase <drchase@google.com> | 2025-11-24 15:49:12 -0800 |
| commit | 62cd044a79b9f2ba889bca59b3b12400dc41dd85 (patch) | |
| tree | a120624e15b2a31014cc6e215a48cefbecf3fe99 /src/cmd/compile | |
| parent | f1e376f342af82d6f5bdba23cdc5c35b5bfd9064 (diff) | |
| download | go-62cd044a79b9f2ba889bca59b3b12400dc41dd85.tar.xz | |
cmd/compile: add cases for StringLen to prove
Tricky index-offset logic had been added for slices,
but not for strings. This fixes that, and also adds
tests for same behavior in string/slice cases, and adds
a new test for code in prove that had been added but not
explicitly tested.
Fixes #76270.
Change-Id: Ibd92b89e944d86b7f30b4486a9008e6f1ac6af7d
Reviewed-on: https://go-review.googlesource.com/c/go/+/723980
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile')
| -rw-r--r-- | src/cmd/compile/internal/ssa/prove.go | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go index 5581da445d..536965a0a0 100644 --- a/src/cmd/compile/internal/ssa/prove.go +++ b/src/cmd/compile/internal/ssa/prove.go @@ -2040,14 +2040,14 @@ func (ft *factsTable) flowLimit(v *Value) { // // slicecap - index >= slicelen - index >= K // -// Note that "index" is not useed for indexing in this pattern, but +// Note that "index" is not used for indexing in this pattern, but // in the motivating example (chunked slice iteration) it is. func (ft *factsTable) detectSliceLenRelation(v *Value) { if v.Op != OpSub64 { return } - if !(v.Args[0].Op == OpSliceLen || v.Args[0].Op == OpSliceCap) { + if !(v.Args[0].Op == OpSliceLen || v.Args[0].Op == OpStringLen || v.Args[0].Op == OpSliceCap) { return } @@ -2070,9 +2070,9 @@ func (ft *factsTable) detectSliceLenRelation(v *Value) { continue } var lenOffset *Value - if bound := ow.Args[0]; bound.Op == OpSliceLen && bound.Args[0] == slice { + if bound := ow.Args[0]; (bound.Op == OpSliceLen || bound.Op == OpStringLen) && bound.Args[0] == slice { lenOffset = ow.Args[1] - } else if bound := ow.Args[1]; bound.Op == OpSliceLen && bound.Args[0] == slice { + } else if bound := ow.Args[1]; (bound.Op == OpSliceLen || bound.Op == OpStringLen) && bound.Args[0] == slice { lenOffset = ow.Args[0] } if lenOffset == nil || lenOffset.Op != OpConst64 { @@ -2332,7 +2332,7 @@ func unsignedSubUnderflows(a, b uint64) bool { // iteration where the index is not directly compared to the length. // if isReslice, then delta can be equal to K. func checkForChunkedIndexBounds(ft *factsTable, b *Block, index, bound *Value, isReslice bool) bool { - if bound.Op != OpSliceLen && bound.Op != OpSliceCap { + if bound.Op != OpSliceLen && bound.Op != OpStringLen && bound.Op != OpSliceCap { return false } @@ -2367,9 +2367,9 @@ func checkForChunkedIndexBounds(ft *factsTable, b *Block, index, bound *Value, i } if ow := o.w; ow.Op == OpAdd64 { var lenOffset *Value - if bound := ow.Args[0]; bound.Op == OpSliceLen && bound.Args[0] == slice { + if bound := ow.Args[0]; (bound.Op == OpSliceLen || bound.Op == OpStringLen) && bound.Args[0] == slice { lenOffset = ow.Args[1] - } else if bound := ow.Args[1]; bound.Op == OpSliceLen && bound.Args[0] == slice { + } else if bound := ow.Args[1]; (bound.Op == OpSliceLen || bound.Op == OpStringLen) && bound.Args[0] == slice { lenOffset = ow.Args[0] } if lenOffset == nil || lenOffset.Op != OpConst64 { |
