1
0
mirror of https://github.com/golang/go synced 2024-07-08 12:18:55 +00:00

cmd/compile: optimize x & 1 != 0 to x & 1 on amd64

Triggers a handful of times in std+cmd.

Change-Id: I9bb8ce9a5f8bae2547cb61157cd8f256e1b63e76
Reviewed-on: https://go-review.googlesource.com/c/go/+/229602
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2020-04-23 00:21:59 -07:00
parent 917aa72c14
commit e7c1873691
3 changed files with 85 additions and 0 deletions

View File

@ -571,6 +571,10 @@
(SETB (TEST(Q|L|W|B) x x)) -> (ConstBool [0])
(SETAE (TEST(Q|L|W|B) x x)) -> (ConstBool [1])
// x & 1 != 0 -> x & 1
(SETNE (TEST(B|W)const [1] x)) => (AND(L|L)const [1] x)
(SETB (BT(L|Q)const [0] x)) => (AND(L|Q)const [1] x)
// Recognize bit tests: a&(1<<b) != 0 for b suitably bounded
// Note that BTx instructions use the carry bit, so we need to convert tests for zero flag
// into tests for carry flags.

View File

@ -21833,6 +21833,30 @@ func rewriteValueAMD64_OpAMD64SETB(v *Value) bool {
v.AuxInt = 0
return true
}
// match: (SETB (BTLconst [0] x))
// result: (ANDLconst [1] x)
for {
if v_0.Op != OpAMD64BTLconst || auxIntToInt8(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64ANDLconst)
v.AuxInt = int32ToAuxInt(1)
v.AddArg(x)
return true
}
// match: (SETB (BTQconst [0] x))
// result: (ANDQconst [1] x)
for {
if v_0.Op != OpAMD64BTQconst || auxIntToInt8(v_0.AuxInt) != 0 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64ANDQconst)
v.AuxInt = int32ToAuxInt(1)
v.AddArg(x)
return true
}
// match: (SETB (InvertFlags x))
// result: (SETA x)
for {
@ -24176,6 +24200,30 @@ func rewriteValueAMD64_OpAMD64SETLstore(v *Value) bool {
func rewriteValueAMD64_OpAMD64SETNE(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
// match: (SETNE (TESTBconst [1] x))
// result: (ANDLconst [1] x)
for {
if v_0.Op != OpAMD64TESTBconst || auxIntToInt8(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64ANDLconst)
v.AuxInt = int32ToAuxInt(1)
v.AddArg(x)
return true
}
// match: (SETNE (TESTWconst [1] x))
// result: (ANDLconst [1] x)
for {
if v_0.Op != OpAMD64TESTWconst || auxIntToInt16(v_0.AuxInt) != 1 {
break
}
x := v_0.Args[0]
v.reset(OpAMD64ANDLconst)
v.AuxInt = int32ToAuxInt(1)
v.AddArg(x)
return true
}
// match: (SETNE (TESTL (SHLL (MOVLconst [1]) x) y))
// result: (SETB (BTL x y))
for {

33
test/codegen/bool.go Normal file
View File

@ -0,0 +1,33 @@
// asmcheck
// Copyright 2020 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.
package codegen
// This file contains codegen tests related to boolean simplifications/optimizations.
func convertNeq0B(x uint8, c bool) bool {
// amd64:"ANDL\t[$]1",-"SETNE"
b := x&1 != 0
return c && b
}
func convertNeq0W(x uint16, c bool) bool {
// amd64:"ANDL\t[$]1",-"SETNE"
b := x&1 != 0
return c && b
}
func convertNeq0L(x uint32, c bool) bool {
// amd64:"ANDL\t[$]1",-"SETB"
b := x&1 != 0
return c && b
}
func convertNeq0Q(x uint64, c bool) bool {
// amd64:"ANDQ\t[$]1",-"SETB"
b := x&1 != 0
return c && b
}