Commit 72dc9ab1 authored by Keith Randall's avatar Keith Randall Committed by Keith Randall

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: default avatarDavid Chase <drchase@google.com>
parent fc2915fa
...@@ -1328,27 +1328,25 @@ func (s *regAllocState) regalloc(f *Func) { ...@@ -1328,27 +1328,25 @@ func (s *regAllocState) regalloc(f *Func) {
// arg0 is dead. We can clobber its register. // arg0 is dead. We can clobber its register.
goto ok 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 { if s.values[v.Args[0].ID].rematerializeable {
// We can rematerialize the input, don't worry about clobbering it. // We can rematerialize the input, don't worry about clobbering it.
goto ok 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 { if countRegs(s.values[v.Args[0].ID].regs) >= 2 {
// we have at least 2 copies of arg0. We can afford to clobber one. // we have at least 2 copies of arg0. We can afford to clobber one.
goto ok goto ok
} }
if opcodeTable[v.Op].commutative { if opcodeTable[v.Op].commutative && countRegs(s.values[v.Args[1].ID].regs) >= 2 {
if !s.liveAfterCurrentInstruction(v.Args[1]) { args[0], args[1] = args[1], args[0]
args[0], args[1] = args[1], args[0] goto ok
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
}
} }
// We can't overwrite arg0 (or arg1, if commutative). So we // We can't overwrite arg0 (or arg1, if commutative). So we
......
// 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
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment