aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2020-07-30 10:37:36 -0700
committerCarlos Amedee <carlos@golang.org>2020-08-03 15:12:45 +0000
commit739b9d5afe04b16a3726475c2ae2a136d3920477 (patch)
treefd0cc391b3808cf986ef2fce95a1ea695bccbce7
parentedfd6f28486017dcb136cd3f3ec252706d4b326e (diff)
downloadgo-739b9d5afe04b16a3726475c2ae2a136d3920477.tar.gz
go-739b9d5afe04b16a3726475c2ae2a136d3920477.zip
[release-branch.go1.14] cmd/compile: don't addLocalInductiveFacts if there is no direct edge from if block to phi block
Currently in addLocalInductiveFacts, we only check whether direct edge from if block to phi block exists. If not, the following logic will treat the phi block as the first successor, which is wrong. This patch makes prove pass more conservative, so we disable some cases in test/prove.go. We will do some optimization in the following CL and enable these cases then. Fixes #40501. Change-Id: I27cf0248f3a82312a6f7dabe11c79a1a34cf5412 Reviewed-on: https://go-review.googlesource.com/c/go/+/244579 Reviewed-by: Zach Jones <zachj1@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-on: https://go-review.googlesource.com/c/go/+/245958 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Carlos Amedee <carlos@golang.org>
-rw-r--r--src/cmd/compile/internal/ssa/prove.go8
-rw-r--r--test/fixedbugs/issue40367.go41
-rw-r--r--test/prove.go6
3 files changed, 53 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go
index 774fa94dbc..05062009b7 100644
--- a/src/cmd/compile/internal/ssa/prove.go
+++ b/src/cmd/compile/internal/ssa/prove.go
@@ -1069,6 +1069,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
@@ -1111,6 +1116,9 @@ func addLocalInductiveFacts(ft *factsTable, b *Block) {
}
br = negative
}
+ if br == unknown {
+ continue
+ }
tr, has := domainRelationTable[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 eba0f79af2..6e562b1169 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
@@ -720,7 +721,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")
}