From bf71119d54f7f2c64908af7c1af46ed2cbce0967 Mon Sep 17 00:00:00 2001 From: David Chase Date: Thu, 23 Feb 2017 13:49:25 -0500 Subject: [PATCH] [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 Reviewed-by: David Chase TryBot-Result: Gobot Gobot --- src/cmd/compile/internal/ssa/likelyadjust.go | 23 +++++++++--- test/fixedbugs/issue19217.go | 39 ++++++++++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 test/fixedbugs/issue19217.go 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 +} -- 2.48.1