aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Randall <keithr@alum.mit.edu>2019-10-06 23:03:28 -0700
committerKeith Randall <khr@golang.org>2019-10-07 15:16:26 +0000
commit72dc9ab1919e9fac9f3e63a109232cd79a050255 (patch)
tree63cd5f811755011f2dc0c5c5e8401daa8206b90b
parentfc2915fabdda25912058b4e51b385e73e8ed2b4b (diff)
downloadgo-72dc9ab1919e9fac9f3e63a109232cd79a050255.tar.xz
cmd/compile: reuse dead register before reusing register holding constant
For commuting ops, check whether the second argument is dead before checking if the first argument is rematerializeable. Reusing the register holding a dead value is always best. Fixes #33580 Change-Id: I7372cfc03d514e6774d2d9cc727a3e6bf6ce2657 Reviewed-on: https://go-review.googlesource.com/c/go/+/199559 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
-rw-r--r--src/cmd/compile/internal/ssa/regalloc.go24
-rw-r--r--test/codegen/issue33580.go25
2 files changed, 36 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go
index 6ffa1e3848..3f326722ae 100644
--- a/src/cmd/compile/internal/ssa/regalloc.go
+++ b/src/cmd/compile/internal/ssa/regalloc.go
@@ -1328,27 +1328,25 @@ func (s *regAllocState) regalloc(f *Func) {
// arg0 is dead. We can clobber its register.
goto ok
}
+ if opcodeTable[v.Op].commutative && !s.liveAfterCurrentInstruction(v.Args[1]) {
+ args[0], args[1] = args[1], args[0]
+ goto ok
+ }
if s.values[v.Args[0].ID].rematerializeable {
// We can rematerialize the input, don't worry about clobbering it.
goto ok
}
+ if opcodeTable[v.Op].commutative && s.values[v.Args[1].ID].rematerializeable {
+ args[0], args[1] = args[1], args[0]
+ goto ok
+ }
if countRegs(s.values[v.Args[0].ID].regs) >= 2 {
// we have at least 2 copies of arg0. We can afford to clobber one.
goto ok
}
- if opcodeTable[v.Op].commutative {
- if !s.liveAfterCurrentInstruction(v.Args[1]) {
- args[0], args[1] = args[1], args[0]
- goto ok
- }
- if s.values[v.Args[1].ID].rematerializeable {
- args[0], args[1] = args[1], args[0]
- goto ok
- }
- if countRegs(s.values[v.Args[1].ID].regs) >= 2 {
- args[0], args[1] = args[1], args[0]
- goto ok
- }
+ if opcodeTable[v.Op].commutative && countRegs(s.values[v.Args[1].ID].regs) >= 2 {
+ args[0], args[1] = args[1], args[0]
+ goto ok
}
// We can't overwrite arg0 (or arg1, if commutative). So we
diff --git a/test/codegen/issue33580.go b/test/codegen/issue33580.go
new file mode 100644
index 0000000000..1ded944c33
--- /dev/null
+++ b/test/codegen/issue33580.go
@@ -0,0 +1,25 @@
+// asmcheck
+
+// 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.
+
+// Make sure we reuse large constant loads, if we can.
+// See issue 33580.
+
+package codegen
+
+const (
+ A = 7777777777777777
+ B = 8888888888888888
+)
+
+func f(x, y uint64) uint64 {
+ p := x & A
+ q := y & A
+ r := x & B
+ // amd64:-"MOVQ.*8888888888888888"
+ s := y & B
+
+ return p * q * r * s
+}