aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2017-02-23 13:49:25 -0500
committerAustin Clements <austin@google.com>2017-04-05 16:58:17 +0000
commitbf71119d54f7f2c64908af7c1af46ed2cbce0967 (patch)
tree0524c81e32ec975cc558be73d45beaeb8118ab84
parent11a224bc5617577fd7c2e02c7ee072303e8d592d (diff)
downloadgo-bf71119d54f7f2c64908af7c1af46ed2cbce0967.tar.gz
go-bf71119d54f7f2c64908af7c1af46ed2cbce0967.zip
[release-branch.go1.8] cmd/compile: repaired loop-finder to handle trickier nesting
The loop-A-encloses-loop-C code did not properly handle the case where really C was already known to be enclosed by B, and A was nearest-outer to B, not C. Fixes #19217. Change-Id: I755dd768e823cb707abdc5302fed39c11cdb34d4 Reviewed-on: https://go-review.googlesource.com/39596 Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/cmd/compile/internal/ssa/likelyadjust.go23
-rw-r--r--test/fixedbugs/issue19217.go39
2 files changed, 56 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/ssa/likelyadjust.go b/src/cmd/compile/internal/ssa/likelyadjust.go
index 38a5e81f91..a4e5534cf8 100644
--- a/src/cmd/compile/internal/ssa/likelyadjust.go
+++ b/src/cmd/compile/internal/ssa/likelyadjust.go
@@ -33,13 +33,24 @@ type loop struct {
// outerinner records that outer contains inner
func (sdom SparseTree) outerinner(outer, inner *loop) {
+ // There could be other outer loops found in some random order,
+ // locate the new outer loop appropriately among them.
oldouter := inner.outer
- if oldouter == nil || sdom.isAncestorEq(oldouter.header, outer.header) {
- inner.outer = outer
- outer.isInner = false
- if inner.containsCall {
- outer.setContainsCall()
- }
+ for oldouter != nil && sdom.isAncestor(outer.header, oldouter.header) {
+ inner = oldouter
+ oldouter = inner.outer
+ }
+ if outer == oldouter {
+ return
+ }
+ if oldouter != nil {
+ outer.outer = oldouter
+ }
+
+ inner.outer = outer
+ outer.isInner = false
+ if inner.containsCall {
+ outer.setContainsCall()
}
}
diff --git a/test/fixedbugs/issue19217.go b/test/fixedbugs/issue19217.go
new file mode 100644
index 0000000000..96794064a4
--- /dev/null
+++ b/test/fixedbugs/issue19217.go
@@ -0,0 +1,39 @@
+// compile
+
+// Copyright 2017 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 foo
+
+import (
+ "encoding/binary"
+)
+
+type DbBuilder struct {
+ arr []int
+}
+
+func (bld *DbBuilder) Finish() error {
+ defer bld.Finish()
+
+ var hash []byte
+ for _, ixw := range bld.arr {
+ for {
+ if ixw != 0 {
+ panic("ixw != 0")
+ }
+ ixw--
+ insertOne:
+ for {
+ for i := 0; i < 1; i++ {
+ if binary.LittleEndian.Uint16(hash[i:]) == 0 {
+ break insertOne
+ }
+ }
+ }
+ }
+ }
+
+ return nil
+}