]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: optimize x & 1 != 0 to x & 1 on amd64
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 23 Apr 2020 07:21:59 +0000 (00:21 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 23 Apr 2020 17:52:28 +0000 (17:52 +0000)
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>
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/rewriteAMD64.go
test/codegen/bool.go [new file with mode: 0644]

index bda8429c5fe925947acfe7420aff59fcf391db2c..0b02301c7d55bf349d51e5be4aa3c14ed115a69b 100644 (file)
 (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.
index df36e41d2da04a35be77a2bdf35ac66e114a3608..fee9cfee35b6fd29502e19704406ae2d317d8487 100644 (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 {
diff --git a/test/codegen/bool.go b/test/codegen/bool.go
new file mode 100644 (file)
index 0000000..929b1b4
--- /dev/null
@@ -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
+}