diff options
| author | Keith Randall <khr@golang.org> | 2022-07-03 14:52:47 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2022-08-31 22:04:55 +0000 |
| commit | af7f067e0d7f92bcf4d0938d093725a0ac6366b1 (patch) | |
| tree | a567acc9936f6c3d8af4ab4a1b885875be87f824 /src | |
| parent | 52d9e7f543f68a46d7a69443a1ad51283d2f0d4f (diff) | |
| download | go-af7f067e0d7f92bcf4d0938d093725a0ac6366b1.tar.xz | |
cmd/compile: tighten bounds for induction variables in strided loops
for i := 0; i < 9; i += 3
Currently we compute bounds of [0,8]. Really we know that it is [0,6].
CL 415874 computed the better bound as part of overflow detection.
This CL just incorporates that better info to the prove pass.
R=go1.20
Change-Id: Ife82cc415321f6652c2b5d132a40ec23e3385766
Reviewed-on: https://go-review.googlesource.com/c/go/+/415937
Reviewed-by: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/ssa/loopbce.go | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go index 22fb5118ce..d92566f2d3 100644 --- a/src/cmd/compile/internal/ssa/loopbce.go +++ b/src/cmd/compile/internal/ssa/loopbce.go @@ -200,8 +200,15 @@ func findIndVar(f *Func) []indVar { } v = addU(init.AuxInt, diff(v, init.AuxInt)/uint64(step)*uint64(step)) } - // It is ok if we can't overflow when incrementing from the largest value. - return !addWillOverflow(v, step) + if addWillOverflow(v, step) { + return false + } + if inclusive && v != limit.AuxInt || !inclusive && v+1 != limit.AuxInt { + // We know a better limit than the programmer did. Use our limit instead. + limit = f.ConstInt64(f.Config.Types.Int64, v) + inclusive = true + } + return true } if step == 1 && !inclusive { // Can't overflow because maxint is never a possible value. @@ -238,8 +245,15 @@ func findIndVar(f *Func) []indVar { } v = subU(init.AuxInt, diff(init.AuxInt, v)/uint64(-step)*uint64(-step)) } - // It is ok if we can't underflow when decrementing from the smallest value. - return !subWillUnderflow(v, -step) + if subWillUnderflow(v, -step) { + return false + } + if inclusive && v != limit.AuxInt || !inclusive && v-1 != limit.AuxInt { + // We know a better limit than the programmer did. Use our limit instead. + limit = f.ConstInt64(f.Config.Types.Int64, v) + inclusive = true + } + return true } if step == -1 && !inclusive { // Can't underflow because minint is never a possible value. |
