[dev.ssa] cmd/compile: Eval append args after growslice

For appending large types, we want to evaluate the
values being appended after the growslice call, not before.
Evaluating them before leads to phi operations on large types
which confuses the lowering pass.

The order pass has already removed any side-effects from the
values being appended, so it doesn't matter if we do this
last eval before or after the growslice call.

This change fixes a bunch (but not all) of our failed lowerings.

Change-Id: I7c697d4d5275d71b7ef4677b830fd86c52ba03a4
Reviewed-on: https://go-review.googlesource.com/15430
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index f4d5946..7e00fc9 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -1860,18 +1860,12 @@
 		// Evaluate slice
 		slice := s.expr(n.List.N)
 
-		// Evaluate args
-		nargs := int64(count(n.List) - 1)
-		args := make([]*ssa.Value, 0, nargs)
-		for l := n.List.Next; l != nil; l = l.Next {
-			args = append(args, s.expr(l.N))
-		}
-
 		// Allocate new blocks
 		grow := s.f.NewBlock(ssa.BlockPlain)
 		assign := s.f.NewBlock(ssa.BlockPlain)
 
 		// Decide if we need to grow
+		nargs := int64(count(n.List) - 1)
 		p := s.newValue1(ssa.OpSlicePtr, pt, slice)
 		l := s.newValue1(ssa.OpSliceLen, Types[TINT], slice)
 		c := s.newValue1(ssa.OpSliceCap, Types[TINT], slice)
@@ -1901,6 +1895,13 @@
 
 		// assign new elements to slots
 		s.startBlock(assign)
+
+		// Evaluate args
+		args := make([]*ssa.Value, 0, nargs)
+		for l := n.List.Next; l != nil; l = l.Next {
+			args = append(args, s.expr(l.N))
+		}
+
 		p = s.variable(&ptrVar, pt)          // generates phi for ptr
 		c = s.variable(&capVar, Types[TINT]) // generates phi for cap
 		p2 := s.newValue2(ssa.OpPtrIndex, pt, p, l)