Skip to content

Commit

Permalink
cmd/compile: reuse dead register before reusing register holding cons…
Browse files Browse the repository at this point in the history
…tant

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>
  • Loading branch information
randall77 committed Oct 7, 2019
1 parent fc2915f commit 72dc9ab
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 13 deletions.
24 changes: 11 additions & 13 deletions src/cmd/compile/internal/ssa/regalloc.go
Expand Up @@ -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
Expand Down
25 changes: 25 additions & 0 deletions 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
}

0 comments on commit 72dc9ab

Please sign in to comment.