From b2dc1f82a5b2aa3132cb1fb0135efe1202a1e837 Mon Sep 17 00:00:00 2001 From: Todd Neal Date: Fri, 18 Mar 2016 07:05:58 -0500 Subject: [PATCH] cmd/compile: perform minimal phi elimination during critical Phi splitting sometimes leads to a phi with only a single predecessor. This must be replaced with a copy to maintain a valid SSA form. Fixes #14857 Change-Id: I5ab2423fb6c85a061928e3206b02185ea8c79cd7 Reviewed-on: https://go-review.googlesource.com/20826 Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/critical.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cmd/compile/internal/ssa/critical.go b/src/cmd/compile/internal/ssa/critical.go index 38d4ca40dd1..cd6c58b0b14 100644 --- a/src/cmd/compile/internal/ssa/critical.go +++ b/src/cmd/compile/internal/ssa/critical.go @@ -53,6 +53,9 @@ func critical(f *Func) { // find or record the block that we used to split // critical edges for this argument if d = blocks[argID]; d == nil { + // splitting doesn't necessarily remove the critical edge, + // since we're iterating over len(f.Blocks) above, this forces + // the new blocks to be re-examined. d = f.NewBlock(BlockPlain) d.Line = c.Line blocks[argID] = d @@ -101,6 +104,11 @@ func critical(f *Func) { if phi != nil { phi.Args = filterNilValues(phi.Args) b.Preds = filterNilBlocks(b.Preds) + // splitting occasionally leads to a phi having + // a single argument (occurs with -N) + if len(phi.Args) == 1 { + phi.Op = OpCopy + } } } }