]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't addLocalInductiveFacts if there is no direct edge from if block...
authorCholerae Hu <choleraehyq@gmail.com>
Fri, 24 Jul 2020 03:00:36 +0000 (11:00 +0800)
committerKeith Randall <khr@golang.org>
Thu, 30 Jul 2020 17:23:11 +0000 (17:23 +0000)
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 #40367.

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>

src/cmd/compile/internal/ssa/prove.go
test/fixedbugs/issue40367.go [new file with mode: 0644]
test/prove.go

index a8e43d01147110fd1eaec53c80cfc8d63351a4bf..6c6be39d34b60376e71874c3e2c2b016b18c01b9 100644 (file)
@@ -1051,6 +1051,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
@@ -1093,6 +1098,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 (file)
index 0000000..0dc5ad7
--- /dev/null
@@ -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
index d37021d28305ae589156bbbaadbb39e5da32236a..3c19c513b65a61d2a69c4a3e14f7e600f6d82075 100644 (file)
@@ -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")
                }