197 lines
4.5 KiB
Diff
197 lines
4.5 KiB
Diff
|
From 8a317ebc0f50339628c003bf06107cd865406dd4 Mon Sep 17 00:00:00 2001
|
||
|
From: Keith Randall <khr@google.com>
|
||
|
Date: Tue, 30 Jul 2019 16:14:20 -0700
|
||
|
Subject: [PATCH] cmd/compile: don't eliminate all registers when restricting
|
||
|
to desired ones
|
||
|
|
||
|
We shouldn't mask to desired registers if we haven't masked out all the
|
||
|
forbidden registers yet. In this path we haven't masked out the nospill
|
||
|
registers yet. If the resulting mask contains only nospill registers, then
|
||
|
allocReg fails.
|
||
|
|
||
|
This can only happen on resultNotInArgs-marked instructions, which exist
|
||
|
only on the ARM64, MIPS, MIPS64, and PPC64 ports.
|
||
|
|
||
|
Maybe there's a better way to handle resultNotInArgs instructions.
|
||
|
But for 1.13, this is a low-risk fix.
|
||
|
|
||
|
Fixes #33355
|
||
|
|
||
|
Change-Id: I1082f78f798d1371bde65c58cc265540480e4fa4
|
||
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/188178
|
||
|
Run-TryBot: Keith Randall <khr@golang.org>
|
||
|
TryBot-Result: Gobot Gobot <gobot@golang.org>
|
||
|
Reviewed-by: David Chase <drchase@google.com>
|
||
|
---
|
||
|
src/cmd/compile/internal/ssa/regalloc.go | 2 +-
|
||
|
test/fixedbugs/issue33355.go | 147 +++++++++++++++++++++++
|
||
|
2 files changed, 148 insertions(+), 1 deletion(-)
|
||
|
create mode 100644 test/fixedbugs/issue33355.go
|
||
|
|
||
|
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go
|
||
|
index b6fae5e0a3e..8abbf615076 100644
|
||
|
--- a/src/cmd/compile/internal/ssa/regalloc.go
|
||
|
+++ b/src/cmd/compile/internal/ssa/regalloc.go
|
||
|
@@ -1455,7 +1455,7 @@ func (s *regAllocState) regalloc(f *Func) {
|
||
|
}
|
||
|
}
|
||
|
// Avoid registers we're saving for other values.
|
||
|
- if mask&^desired.avoid != 0 {
|
||
|
+ if mask&^desired.avoid&^s.nospill != 0 {
|
||
|
mask &^= desired.avoid
|
||
|
}
|
||
|
r := s.allocReg(mask, v)
|
||
|
diff --git a/test/fixedbugs/issue33355.go b/test/fixedbugs/issue33355.go
|
||
|
new file mode 100644
|
||
|
index 00000000000..c4b1e2e1a23
|
||
|
--- /dev/null
|
||
|
+++ b/test/fixedbugs/issue33355.go
|
||
|
@@ -0,0 +1,147 @@
|
||
|
+// compile
|
||
|
+
|
||
|
+// Copyright 2019 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.
|
||
|
+
|
||
|
+// This code failed on arm64 in the register allocator.
|
||
|
+// See issue 33355.
|
||
|
+
|
||
|
+package server
|
||
|
+
|
||
|
+import (
|
||
|
+ "bytes"
|
||
|
+ "sync"
|
||
|
+)
|
||
|
+
|
||
|
+type client struct {
|
||
|
+ junk [4]int
|
||
|
+ mu sync.Mutex
|
||
|
+ srv *Server
|
||
|
+ gw *gateway
|
||
|
+ msgb [100]byte
|
||
|
+}
|
||
|
+
|
||
|
+type gateway struct {
|
||
|
+ cfg *gatewayCfg
|
||
|
+ outsim *sync.Map
|
||
|
+}
|
||
|
+
|
||
|
+type gatewayCfg struct {
|
||
|
+ replyPfx []byte
|
||
|
+}
|
||
|
+
|
||
|
+type Account struct {
|
||
|
+ Name string
|
||
|
+}
|
||
|
+
|
||
|
+type Server struct {
|
||
|
+ gateway *srvGateway
|
||
|
+}
|
||
|
+
|
||
|
+type srvGateway struct {
|
||
|
+ outo []*client
|
||
|
+}
|
||
|
+
|
||
|
+type subscription struct {
|
||
|
+ queue []byte
|
||
|
+ client *client
|
||
|
+}
|
||
|
+
|
||
|
+type outsie struct {
|
||
|
+ ni map[string]struct{}
|
||
|
+ sl *Sublist
|
||
|
+ qsubs int
|
||
|
+}
|
||
|
+
|
||
|
+type Sublist struct {
|
||
|
+}
|
||
|
+
|
||
|
+type SublistResult struct {
|
||
|
+ psubs []*subscription
|
||
|
+ qsubs [][]*subscription
|
||
|
+}
|
||
|
+
|
||
|
+var subPool = &sync.Pool{}
|
||
|
+
|
||
|
+func (c *client) sendMsgToGateways(acc *Account, msg, subject, reply []byte, qgroups [][]byte) {
|
||
|
+ var gws []*client
|
||
|
+ gw := c.srv.gateway
|
||
|
+ for i := 0; i < len(gw.outo); i++ {
|
||
|
+ gws = append(gws, gw.outo[i])
|
||
|
+ }
|
||
|
+ var (
|
||
|
+ subj = string(subject)
|
||
|
+ queuesa = [512]byte{}
|
||
|
+ queues = queuesa[:0]
|
||
|
+ mreply []byte
|
||
|
+ dstPfx []byte
|
||
|
+ checkReply = len(reply) > 0
|
||
|
+ )
|
||
|
+
|
||
|
+ sub := subPool.Get().(*subscription)
|
||
|
+
|
||
|
+ if subjectStartsWithGatewayReplyPrefix(subject) {
|
||
|
+ dstPfx = subject[:8]
|
||
|
+ }
|
||
|
+ for i := 0; i < len(gws); i++ {
|
||
|
+ gwc := gws[i]
|
||
|
+ if dstPfx != nil {
|
||
|
+ gwc.mu.Lock()
|
||
|
+ ok := bytes.Equal(dstPfx, gwc.gw.cfg.replyPfx)
|
||
|
+ gwc.mu.Unlock()
|
||
|
+ if !ok {
|
||
|
+ continue
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ qr := gwc.gatewayInterest(acc.Name, subj)
|
||
|
+ queues = queuesa[:0]
|
||
|
+ for i := 0; i < len(qr.qsubs); i++ {
|
||
|
+ qsubs := qr.qsubs[i]
|
||
|
+ queue := qsubs[0].queue
|
||
|
+ add := true
|
||
|
+ for _, qn := range qgroups {
|
||
|
+ if bytes.Equal(queue, qn) {
|
||
|
+ add = false
|
||
|
+ break
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if add {
|
||
|
+ qgroups = append(qgroups, queue)
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if len(queues) == 0 {
|
||
|
+ continue
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if checkReply {
|
||
|
+ checkReply = false
|
||
|
+ mreply = reply
|
||
|
+ }
|
||
|
+ mh := c.msgb[:10]
|
||
|
+ mh = append(mh, subject...)
|
||
|
+ if len(queues) > 0 {
|
||
|
+ mh = append(mh, mreply...)
|
||
|
+ mh = append(mh, queues...)
|
||
|
+ }
|
||
|
+ sub.client = gwc
|
||
|
+ }
|
||
|
+ subPool.Put(sub)
|
||
|
+}
|
||
|
+
|
||
|
+func subjectStartsWithGatewayReplyPrefix(subj []byte) bool {
|
||
|
+ return len(subj) > 8 && string(subj[:4]) == "foob"
|
||
|
+}
|
||
|
+
|
||
|
+func (c *client) gatewayInterest(acc, subj string) *SublistResult {
|
||
|
+ ei, _ := c.gw.outsim.Load(acc)
|
||
|
+ var r *SublistResult
|
||
|
+ e := ei.(*outsie)
|
||
|
+ r = e.sl.Match(subj)
|
||
|
+ return r
|
||
|
+}
|
||
|
+
|
||
|
+func (s *Sublist) Match(subject string) *SublistResult {
|
||
|
+ return nil
|
||
|
+}
|
||
|
+
|