diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go index 3181edca29..a934cd2c7b 100644 --- a/src/cmd/compile/internal/ssa/loopbce.go +++ b/src/cmd/compile/internal/ssa/loopbce.go @@ -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). diff --git a/test/fixedbugs/issue53600.go b/test/fixedbugs/issue53600.go new file mode 100644 index 0000000000..fd3a9e5e47 --- /dev/null +++ b/test/fixedbugs/issue53600.go @@ -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) + } +} diff --git a/test/fixedbugs/issue53600.out b/test/fixedbugs/issue53600.out new file mode 100644 index 0000000000..5590c7dcfb --- /dev/null +++ b/test/fixedbugs/issue53600.out @@ -0,0 +1,8 @@ +9223372036854775807 false +done +9223372036854775806 false +9223372036854775807 false +done +9223372036854775805 false +9223372036854775807 false +done