(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.
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 {
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 {
--- /dev/null
+// 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
+}