aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/shortcircuit.go
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2021-02-22 11:55:14 -0800
committerJosh Bleecher Snyder <josharian@gmail.com>2021-02-22 20:27:09 +0000
commit04903476fe6a1bba4ed751f5e234bccb5a651a9b (patch)
tree14b5810689891c9b32c901277a066be00312562e /src/cmd/compile/internal/ssa/shortcircuit.go
parent87e984ab2988afccdb75a4c235b318ec6be46e6a (diff)
downloadgo-04903476fe6a1bba4ed751f5e234bccb5a651a9b.tar.gz
go-04903476fe6a1bba4ed751f5e234bccb5a651a9b.zip
cmd/compile: reject some rare looping CFGs in shortcircuit
One CFGs that shortcircuit looks for is: p q \ / b / \ t u The test case creates a CFG like that in which p == t. That caused the compiler to generate a (short-lived) invalid phi value. Fix this with a relatively big hammer: Disallow single-length loops entirely. This is probably overkill, but it such loops are very rare. This doesn't change the generated code for anything in std. It generates worse code for the test case: It no longer compiles the entire function away. Fixes #44465 Change-Id: Ib8cdcd6cc9d7f48b4dab253652038ace24eae152 Reviewed-on: https://go-review.googlesource.com/c/go/+/295130 Trust: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/ssa/shortcircuit.go')
-rw-r--r--src/cmd/compile/internal/ssa/shortcircuit.go7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/shortcircuit.go b/src/cmd/compile/internal/ssa/shortcircuit.go
index 7b4ee2e81c..c72c86a67e 100644
--- a/src/cmd/compile/internal/ssa/shortcircuit.go
+++ b/src/cmd/compile/internal/ssa/shortcircuit.go
@@ -266,6 +266,13 @@ func shortcircuitPhiPlan(b *Block, ctl *Value, cidx int, ti int64) func(*Value,
// u is the "untaken" branch: the successor we never go to when coming in from p.
u := b.Succs[1^ti].b
+ // In the following CFG matching, ensure that b's preds are entirely distinct from b's succs.
+ // This is probably a stronger condition than required, but this happens extremely rarely,
+ // and it makes it easier to avoid getting deceived by pretty ASCII charts. See #44465.
+ if p0, p1 := b.Preds[0].b, b.Preds[1].b; p0 == t || p1 == t || p0 == u || p1 == u {
+ return nil
+ }
+
// Look for some common CFG structures
// in which the outbound paths from b merge,
// with no other preds joining them.