]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't spill rematerializeable value when resolving merge edges
authorCherry Zhang <cherryyz@google.com>
Tue, 14 Mar 2017 22:21:23 +0000 (18:21 -0400)
committerCherry Zhang <cherryyz@google.com>
Tue, 14 Mar 2017 22:55:52 +0000 (22:55 +0000)
Fixes #19515.

Change-Id: I4bcce152cef52d00fbb5ab4daf72a6e742bae27c
Reviewed-on: https://go-review.googlesource.com/38158
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/regalloc.go
test/fixedbugs/issue19515.go [new file with mode: 0644]

index aac950a76b9ce5475cea59126f35dd476006441d..e40fe17ad4cbe60284b6c7b565c3926245d072ef 100644 (file)
@@ -2227,6 +2227,7 @@ func (e *edgeState) findRegFor(typ Type) Location {
        // 1) an unused register
        // 2) a non-unique register not holding a final value
        // 3) a non-unique register
+       // 4) TODO: a register holding a rematerializeable value
        x := m &^ e.usedRegs
        if x != 0 {
                return &e.s.registers[pickReg(x)]
@@ -2252,10 +2253,12 @@ func (e *edgeState) findRegFor(typ Type) Location {
                a := e.cache[vid]
                for _, c := range a {
                        if r, ok := e.s.f.getHome(c.ID).(*Register); ok && m>>uint(r.num)&1 != 0 {
-                               x := e.p.NewValue1(c.Pos, OpStoreReg, c.Type, c)
-                               e.set(t, vid, x, false, c.Pos)
-                               if e.s.f.pass.debug > regDebug {
-                                       fmt.Printf("  SPILL %s->%s %s\n", r.Name(), t.Name(), x.LongString())
+                               if !c.rematerializeable() {
+                                       x := e.p.NewValue1(c.Pos, OpStoreReg, c.Type, c)
+                                       e.set(t, vid, x, false, c.Pos)
+                                       if e.s.f.pass.debug > regDebug {
+                                               fmt.Printf("  SPILL %s->%s %s\n", r.Name(), t.Name(), x.LongString())
+                                       }
                                }
                                // r will now be overwritten by the caller. At some point
                                // later, the newly saved value will be moved back to its
diff --git a/test/fixedbugs/issue19515.go b/test/fixedbugs/issue19515.go
new file mode 100644 (file)
index 0000000..a1605be
--- /dev/null
@@ -0,0 +1,51 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 19515: compiler panics on spilling int128 constant.
+
+package x
+
+type VScrollPanel struct {
+       x, y int
+}
+
+type Color struct {
+       R, G, B, A float32
+}
+
+func maxF(a, b float32) float32 {
+       if a > b {
+               return 0
+       }
+       return 1
+}
+
+type TransformMatrix [6]float32
+
+type Paint struct {
+       xform      TransformMatrix
+       feather    float32
+       innerColor Color
+       outerColor Color
+}
+
+func BoxGradient(x, y, w, h, f float32, iColor, oColor Color) Paint {
+       return Paint{
+               xform:      TransformMatrix{9, 0, 0, 0, x, y},
+               feather:    maxF(1.0, f),
+               innerColor: iColor,
+               outerColor: oColor,
+       }
+}
+
+func (v *VScrollPanel) Draw() {
+       x := float32(v.x)
+       y := float32(v.y)
+
+       BoxGradient(x+x-2, y-1, 0, 0, 0, Color{}, Color{})
+       BoxGradient(x+y-2, y-1, 0, 0, 0, Color{}, Color{})
+}
+