diff --git a/go/ssa/blockopt.go b/go/ssa/blockopt.go index 64cfbeb8..e79260a2 100644 --- a/go/ssa/blockopt.go +++ b/go/ssa/blockopt.go @@ -117,6 +117,14 @@ func fuseBlocks(f *Function, a *BasicBlock) bool { if len(b.Preds) != 1 { return false } + + // Degenerate &&/|| ops may result in a straight-line CFG + // containing φ-nodes. (Ideally we'd replace such them with + // their sole operand but that requires Referrers, built later.) + if b.hasPhi() { + return false // not sound without further effort + } + // Eliminate jump at end of A, then copy all of B across. a.Instrs = append(a.Instrs[:len(a.Instrs)-1], b.Instrs...) for _, instr := range b.Instrs { diff --git a/go/ssa/interp/testdata/coverage.go b/go/ssa/interp/testdata/coverage.go index 5921f296..503e4e2f 100644 --- a/go/ssa/interp/testdata/coverage.go +++ b/go/ssa/interp/testdata/coverage.go @@ -636,3 +636,9 @@ func init() { panic(got) } } + +// Regression test for issue 7840 (covered by SSA sanity checker). +func bug7840() bool { + // This creates a single-predecessor block with a φ-node. + return false && a == 0 && a == 0 +}