diff options
| author | Keith Randall <keithr@alum.mit.edu> | 2019-10-06 23:03:28 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2019-10-07 15:16:26 +0000 |
| commit | 72dc9ab1919e9fac9f3e63a109232cd79a050255 (patch) | |
| tree | 63cd5f811755011f2dc0c5c5e8401daa8206b90b | |
| parent | fc2915fabdda25912058b4e51b385e73e8ed2b4b (diff) | |
| download | go-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.go | 24 | ||||
| -rw-r--r-- | test/codegen/issue33580.go | 25 |
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 +} |
