diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go index 7c69327990..960db67da7 100644 --- a/src/cmd/compile/internal/ssa/prove.go +++ b/src/cmd/compile/internal/ssa/prove.go @@ -1015,6 +1015,11 @@ func addLocalInductiveFacts(ft *factsTable, b *Block) { // // If all of these conditions are true, then i1 < max and i1 >= min. + // To ensure this is a loop header node. + if len(b.Preds) != 2 { + return + } + for _, i1 := range b.Values { if i1.Op != OpPhi { continue @@ -1056,6 +1061,9 @@ func addLocalInductiveFacts(ft *factsTable, b *Block) { } br = negative } + if br == unknown { + continue + } tr, has := domainRelationTable[pred.Control.Op] if !has { diff --git a/test/fixedbugs/issue40367.go b/test/fixedbugs/issue40367.go new file mode 100644 index 0000000000..0dc5ad7120 --- /dev/null +++ b/test/fixedbugs/issue40367.go @@ -0,0 +1,41 @@ +// run + +// Copyright 2020 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 + +func case1() { + rates := []int32{1,2,3,4,5,6} + var sink [6]int + j := len(sink) + for star, _ := range rates { + if star+1 < 1 { + panic("") + } + j-- + sink[j] = j + } +} + +func case2() { + i := 0 + var sink [3]int + j := len(sink) +top: + j-- + sink[j] = j + if i < 2 { + i++ + if i < 1 { + return + } + goto top + } +} + +func main() { + case1() + case2() +} \ No newline at end of file diff --git a/test/prove.go b/test/prove.go index f6dd9f0955..fc143969a0 100644 --- a/test/prove.go +++ b/test/prove.go @@ -670,7 +670,8 @@ func oforuntil(b []int) { i := 0 if len(b) > i { top: - println(b[i]) // ERROR "Induction variable: limits \[0,\?\), increment 1$" "Proved IsInBounds$" + // TODO: remove the todo of next line once we complete the following optimization of CL 244579 + // println(b[i]) // todo: ERROR "Induction variable: limits \[0,\?\), increment 1$" "Proved IsInBounds$" i++ if i < len(b) { goto top @@ -696,7 +697,8 @@ func range1(b []int) { // range2 elements are larger, so they use the general form of a range loop. func range2(b [][32]int) { for i, v := range b { - b[i][0] = v[0] + 1 // ERROR "Induction variable: limits \[0,\?\), increment 1$" "Proved IsInBounds$" + // TODO: remove the todo of next line once we complete the following optimization of CL 244579 + b[i][0] = v[0] + 1 // todo: ERROR "Induction variable: limits \[0,\?\), increment 1$" "Proved IsInBounds$" if i < len(b) { // ERROR "Proved Less64$" println("x") }