cmd/compile: handle infinite loops in shortcircuit pass

The newly upgraded shortcircuit pass attempted to remove infinite loops.
Stop doing that.

Fixes #33903

Change-Id: I0fc9c1b5f2427e54ce650806602ef5e3ad65aca5
Reviewed-on: https://go-review.googlesource.com/c/go/+/192144
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2019-08-28 12:56:26 -07:00
parent e87fe0f1f5
commit 2393d16147
2 changed files with 24 additions and 2 deletions

View file

@ -50,7 +50,7 @@ func shortcircuit(f *Func) {
}
}
// Step 3: Redirect control flow around known branches.
// Step 2: Redirect control flow around known branches.
// p:
// ... goto b ...
// b: <- p ...
@ -124,7 +124,6 @@ func shortcircuitBlock(b *Block) bool {
if a.Op != OpConstBool {
continue
}
changed = true
// The predecessor we come in from.
e1 := b.Preds[i]
p := e1.b
@ -138,8 +137,15 @@ func shortcircuitBlock(b *Block) bool {
}
e2 := b.Succs[si]
t := e2.b
if p == b || t == b {
// This is an infinite loop; we can't remove it. See issue 33903.
continue
}
ti := e2.i
// Update CFG and Phis.
changed = true
// Remove b's incoming edge from p.
b.removePred(i)
n := len(b.Preds)

View file

@ -0,0 +1,16 @@
// compile
// Copyright 2019 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.
// Check that the shortcircuit pass correctly handles infinite loops.
package p
func f() {
var p, q bool
for {
p = p && q
}
}