cmd/compile: avoid remainder in loopbce when increment=0

For non-unit increment, loopbce checks to see if the
increment evenly divides the difference between (constant)
loop start and end.  This test panics when the increment
is zero.

Fix: check for zero, if found, don't optimize the loop.

Also added missing copyright notice to loopbce.go.

Fixes #26043.

Change-Id: I5f460104879cacc94481949234c9ce8c519d6380
Reviewed-on: https://go-review.googlesource.com/120759
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
David Chase 2018-06-25 15:26:45 -04:00
parent 6d70952897
commit 7e9d55eeeb
2 changed files with 37 additions and 1 deletions

View file

@ -1,3 +1,7 @@
// Copyright 2018 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 ssa
import "fmt"
@ -154,7 +158,7 @@ nextb:
// if the increment is ±1 or when the limits are constants.
if inc.AuxInt != 1 && inc.AuxInt != -1 {
ok := false
if min.Op == OpConst64 && max.Op == OpConst64 {
if min.Op == OpConst64 && max.Op == OpConst64 && inc.AuxInt != 0 {
if max.AuxInt > min.AuxInt && max.AuxInt%inc.AuxInt == min.AuxInt%inc.AuxInt { // handle overflow
ok = true
}

View file

@ -0,0 +1,32 @@
// compile
// Copyright 2018 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.
// This program results in a loop inferred to increment
// j by 0, causing bounds check elimination to attempt
// something%0, which panics (in the bug).
package q
func f() {
var s1 string
var b bool
if b {
b = !b
s1 += "a"
}
var s2 string
var i, j int
if (s1 <= "") || (s2 >= "") {
j = len(s1[:6])
} else {
i = len("b")
}
for j < 0 {
j += i
}
}