cmd/compile: fix prove pass when upper condition is <= maxint

When the terminating condition is <= X, we need to make sure that
X+step doesn't overflow.

Fixes #53600

Change-Id: I36e5384d05b4d7168e48db6094200fcae409bfe5
Reviewed-on: https://go-review.googlesource.com/c/go/+/415219
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
This commit is contained in:
Keith Randall 2022-06-29 13:22:59 -07:00 committed by David Chase
parent 17083a2fdf
commit 31b8c23c57
3 changed files with 57 additions and 0 deletions

View file

@ -159,6 +159,13 @@ func findIndVar(f *Func) []indVar {
step = -step
}
if flags&indVarMaxInc != 0 && max.Op == OpConst64 && max.AuxInt+step < max.AuxInt {
// For a <= comparison, we need to make sure that a value equal to
// max can be incremented without overflowing.
// (For a < comparison, the %step check below ensures no overflow.)
continue
}
// Up to now we extracted the induction variable (ind),
// the increment delta (inc), the temporary sum (nxt),
// the minimum value (min) and the maximum value (max).

View file

@ -0,0 +1,42 @@
// run
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "math"
func main() {
f()
g()
h()
}
func f() {
for i := int64(math.MaxInt64); i <= math.MaxInt64; i++ {
if i < 0 {
println("done")
return
}
println(i, i < 0)
}
}
func g() {
for i := int64(math.MaxInt64) - 1; i <= math.MaxInt64; i++ {
if i < 0 {
println("done")
return
}
println(i, i < 0)
}
}
func h() {
for i := int64(math.MaxInt64) - 2; i <= math.MaxInt64; i += 2 {
if i < 0 {
println("done")
return
}
println(i, i < 0)
}
}

View file

@ -0,0 +1,8 @@
9223372036854775807 false
done
9223372036854775806 false
9223372036854775807 false
done
9223372036854775805 false
9223372036854775807 false
done