]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fold boolean NOT into branches
authorKeith Randall <khr@golang.org>
Tue, 18 Nov 2025 06:40:26 +0000 (22:40 -0800)
committerKeith Randall <khr@golang.org>
Tue, 18 Nov 2025 17:31:58 +0000 (09:31 -0800)
Gets rid of an EOR $1 instruction.

Change-Id: Ib032b0cee9ac484329c978af9b1305446f8d5dac
Reviewed-on: https://go-review.googlesource.com/c/go/+/721501
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Keith Randall <khr@google.com>
src/cmd/compile/internal/ssa/_gen/ARM64.rules
src/cmd/compile/internal/ssa/rewriteARM64.go
test/codegen/bool.go

index 04f43f3137fb5f56cc71f8ee4378e344c00b7763..53bb35d2897b940acde0499ce10ecac2d431a0ab 100644 (file)
 (TBNZ [0] (GreaterThanF  cc) yes no) => (FGT cc yes no)
 (TBNZ [0] (GreaterEqualF cc) yes no) => (FGE cc yes no)
 
+(TB(Z|NZ) [0] (XORconst [1] x) yes no) => (TB(NZ|Z) [0] x yes no)
+
 ((EQ|NE|LT|LE|GT|GE) (CMPconst  [0] z:(AND        x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (TST                x y) yes no)
 ((EQ|NE|LT|LE|GT|GE) (CMPconst  [0] x:(ANDconst [c] y)) yes no) && x.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (TSTconst         [c] y) yes no)
 ((EQ|NE|LT|LE|GT|GE) (CMPWconst [0] z:(AND        x y)) yes no) && z.Uses == 1 => ((EQ|NE|LT|LE|GT|GE) (TSTW               x y) yes no)
index 6137ec13a0557c2473e7e4701849e9283c2889e3..b3f790dbda576bd8d7e7fd52b57e4f60a34b5178 100644 (file)
@@ -25321,6 +25321,37 @@ func rewriteBlockARM64(b *Block) bool {
                        b.resetWithControl(BlockARM64FGE, cc)
                        return true
                }
+               // match: (TBNZ [0] (XORconst [1] x) yes no)
+               // result: (TBZ [0] x yes no)
+               for b.Controls[0].Op == OpARM64XORconst {
+                       v_0 := b.Controls[0]
+                       if auxIntToInt64(v_0.AuxInt) != 1 {
+                               break
+                       }
+                       x := v_0.Args[0]
+                       if auxIntToInt64(b.AuxInt) != 0 {
+                               break
+                       }
+                       b.resetWithControl(BlockARM64TBZ, x)
+                       b.AuxInt = int64ToAuxInt(0)
+                       return true
+               }
+       case BlockARM64TBZ:
+               // match: (TBZ [0] (XORconst [1] x) yes no)
+               // result: (TBNZ [0] x yes no)
+               for b.Controls[0].Op == OpARM64XORconst {
+                       v_0 := b.Controls[0]
+                       if auxIntToInt64(v_0.AuxInt) != 1 {
+                               break
+                       }
+                       x := v_0.Args[0]
+                       if auxIntToInt64(b.AuxInt) != 0 {
+                               break
+                       }
+                       b.resetWithControl(BlockARM64TBNZ, x)
+                       b.AuxInt = int64ToAuxInt(0)
+                       return true
+               }
        case BlockARM64UGE:
                // match: (UGE (FlagConstant [fc]) yes no)
                // cond: fc.uge()
index 37f85a45b71bf4de8ffc5fcb1d042a3b779ece6a..8fe7a946876ecda1b8ed601a245d45ecc6718617 100644 (file)
@@ -313,3 +313,18 @@ func constantWrite(b bool, p *bool) {
                *p = b
        }
 }
+
+func boolCompare1(p, q *bool) int {
+       // arm64:-"EOR [$]1"
+       if *p == *q {
+               return 5
+       }
+       return 7
+}
+func boolCompare2(p, q *bool) int {
+       // arm64:-"EOR [$]1"
+       if *p != *q {
+               return 5
+       }
+       return 7
+}