Skip to content

Commit a031f4e

Browse files
committed
cmd/compile: fix min/max builtin code generation
Our large-function phi placement algorithm is incompatible with phi opcodes already existing in the SSA representation. Instead, use simple variable assignments and have the phi placement algorithm place the phis we need for min/max. Turns out the small-function phi placement algorithm doesn't have this sensitivity, so this bug only occurs in large functions (>500 basic blocks). Maybe we should document/check that no phis are present when we start phi placement (regardless of size). Leaving for a potential separate CL. We should probably also fix the placement algorithm to handle existing phis correctly. But this CL is probably a lot smaller/safer than messing with phi placement. Fixes #60982 Change-Id: I59ba7f506c72b22bc1485099a335d96315ebef67 Reviewed-on: https://go-review.googlesource.com/c/go/+/505756 Reviewed-by: Keith Randall <[email protected]> Run-TryBot: Keith Randall <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Cuong Manh Le <[email protected]>
1 parent ea927e5 commit a031f4e

File tree

2 files changed

+2030
-3
lines changed

2 files changed

+2030
-3
lines changed

src/cmd/compile/internal/ssagen/ssa.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,7 @@ var (
949949
typVar = ssaMarker("typ")
950950
okVar = ssaMarker("ok")
951951
deferBitsVar = ssaMarker("deferBits")
952+
ternaryVar = ssaMarker("ternary")
952953
)
953954

954955
// startBlock sets the current block we're generating code in to b.
@@ -3622,18 +3623,26 @@ func (s *state) minMax(n *ir.CallExpr) *ssa.Value {
36223623
func (s *state) ternary(cond, x, y *ssa.Value) *ssa.Value {
36233624
bThen := s.f.NewBlock(ssa.BlockPlain)
36243625
bElse := s.f.NewBlock(ssa.BlockPlain)
3626+
bEnd := s.f.NewBlock(ssa.BlockPlain)
36253627

36263628
b := s.endBlock()
36273629
b.Kind = ssa.BlockIf
36283630
b.SetControl(cond)
36293631
b.AddEdgeTo(bThen)
36303632
b.AddEdgeTo(bElse)
36313633

3634+
s.startBlock(bThen)
3635+
s.vars[ternaryVar] = x
3636+
s.endBlock().AddEdgeTo(bEnd)
3637+
36323638
s.startBlock(bElse)
3633-
s.endBlock().AddEdgeTo(bThen)
3639+
s.vars[ternaryVar] = y
3640+
s.endBlock().AddEdgeTo(bEnd)
36343641

3635-
s.startBlock(bThen)
3636-
return s.newValue2(ssa.OpPhi, x.Type, x, y)
3642+
s.startBlock(bEnd)
3643+
r := s.variable(ternaryVar, x.Type)
3644+
delete(s.vars, ternaryVar)
3645+
return r
36373646
}
36383647

36393648
// condBranch evaluates the boolean expression cond and branches to yes

0 commit comments

Comments
 (0)