Skip to content

Commit f4d9c30

Browse files
committed
cmd/compile/internal/amd64: use appropriate NEG for div
Currently we generate NEGQ for DIV{Q,L,W}. By generating NEGL and NEGW, we will reduce code size, because NEGL doesn't require rex prefix. This also guarantees that upper 32 bits are zeroed, so we can revert CL 85736, and remove zero-extensions of DIVL results. Also adds test for redundant zero extend elimination. Fixes #23310 Change-Id: Ic58c3104c255a71371a06e09d10a975bbe5df587 Reviewed-on: https://go-review.googlesource.com/96815 Run-TryBot: Ilya Tocar <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 3b7ad16 commit f4d9c30

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

src/cmd/compile/internal/amd64/ssa.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,15 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
266266

267267
// Issue -1 fixup code.
268268
// n / -1 = -n
269-
n1 := s.Prog(x86.ANEGQ)
269+
var n1 *obj.Prog
270+
switch v.Op {
271+
case ssa.OpAMD64DIVQ:
272+
n1 = s.Prog(x86.ANEGQ)
273+
case ssa.OpAMD64DIVL:
274+
n1 = s.Prog(x86.ANEGL)
275+
case ssa.OpAMD64DIVW:
276+
n1 = s.Prog(x86.ANEGW)
277+
}
270278
n1.To.Type = obj.TYPE_REG
271279
n1.To.Reg = x86.REG_AX
272280

src/cmd/compile/internal/ssa/rewrite.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -782,12 +782,8 @@ func zeroUpper32Bits(x *Value, depth int) bool {
782782
OpAMD64ANDL, OpAMD64ANDLconst, OpAMD64ORL, OpAMD64ORLconst,
783783
OpAMD64XORL, OpAMD64XORLconst, OpAMD64NEGL, OpAMD64NOTL:
784784
return true
785-
case OpArg:
785+
case OpArg, OpSelect0, OpSelect1:
786786
return x.Type.Width == 4
787-
case OpSelect0, OpSelect1:
788-
// Disabled for now. See issue 23305.
789-
// TODO: we could look into the arg of the Select to decide.
790-
return false
791787
case OpPhi:
792788
// Phis can use each-other as an arguments, instead of tracking visited values,
793789
// just limit recursion depth.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package ssa
6+
7+
import "testing"
8+
9+
type extTest struct {
10+
f func(uint64, uint64) uint64
11+
arg1 uint64
12+
arg2 uint64
13+
res uint64
14+
name string
15+
}
16+
17+
var extTests = [...]extTest{
18+
{f: func(a, b uint64) uint64 { op1 := int32(a); op2 := int32(b); return uint64(uint32(op1 / op2)) }, arg1: 0x1, arg2: 0xfffffffeffffffff, res: 0xffffffff, name: "div"},
19+
{f: func(a, b uint64) uint64 { op1 := int32(a); op2 := int32(b); return uint64(uint32(op1 * op2)) }, arg1: 0x1, arg2: 0x100000001, res: 0x1, name: "mul"},
20+
{f: func(a, b uint64) uint64 { op1 := int32(a); op2 := int32(b); return uint64(uint32(op1 + op2)) }, arg1: 0x1, arg2: 0xfffffffffffffff, res: 0x0, name: "add"},
21+
{f: func(a, b uint64) uint64 { op1 := int32(a); op2 := int32(b); return uint64(uint32(op1 - op2)) }, arg1: 0x1, arg2: 0xfffffffffffffff, res: 0x2, name: "sub"},
22+
{f: func(a, b uint64) uint64 { op1 := int32(a); op2 := int32(b); return uint64(uint32(op1 | op2)) }, arg1: 0x1, arg2: 0xfffffffffffffff, res: 0xffffffff, name: "or"},
23+
{f: func(a, b uint64) uint64 { op1 := int32(a); op2 := int32(b); return uint64(uint32(op1 ^ op2)) }, arg1: 0x1, arg2: 0xfffffffffffffff, res: 0xfffffffe, name: "xor"},
24+
{f: func(a, b uint64) uint64 { op1 := int32(a); op2 := int32(b); return uint64(uint32(op1 & op2)) }, arg1: 0x1, arg2: 0x100000000000001, res: 0x1, name: "and"},
25+
}
26+
27+
func TestZeroExtension(t *testing.T) {
28+
for _, x := range extTests {
29+
r := x.f(x.arg1, x.arg2)
30+
if x.res != r {
31+
t.Errorf("%s: got %d want %d", x.name, r, x.res)
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)