From 8a44c8efaefbbda6dd7ab4ee9a5e449fefbf5e1a Mon Sep 17 00:00:00 2001 From: Cherry Zhang Date: Tue, 14 Mar 2017 18:21:23 -0400 Subject: [PATCH] cmd/compile: don't spill rematerializeable value when resolving merge edges Fixes #19515. Change-Id: I4bcce152cef52d00fbb5ab4daf72a6e742bae27c Reviewed-on: https://go-review.googlesource.com/38158 Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/regalloc.go | 11 +++-- test/fixedbugs/issue19515.go | 51 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 test/fixedbugs/issue19515.go diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index aac950a76b..e40fe17ad4 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -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 index 0000000000..a1605bec96 --- /dev/null +++ b/test/fixedbugs/issue19515.go @@ -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{}) +} + -- 2.48.1