]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: reuse dead register before reusing register holding constant
authorKeith Randall <keithr@alum.mit.edu>
Mon, 7 Oct 2019 06:03:28 +0000 (23:03 -0700)
committerKeith Randall <khr@golang.org>
Mon, 7 Oct 2019 15:16:26 +0000 (15:16 +0000)
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>
src/cmd/compile/internal/ssa/regalloc.go
test/codegen/issue33580.go [new file with mode: 0644]

index 6ffa1e38484db2d1143b559180b99da8e5578280..3f326722aec49f8c5f7c7ad1354791e3d1f6508c 100644 (file)
@@ -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 (file)
index 0000000..1ded944
--- /dev/null
@@ -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
+}