]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: convert branch with zero to more optimal branch zero on loong64
authorXiaolin Zhao <zhaoxiaolin@loongson.cn>
Wed, 6 Aug 2025 07:50:24 +0000 (15:50 +0800)
committerabner chenc <chenguoqi@loongson.cn>
Mon, 11 Aug 2025 14:37:59 +0000 (07:37 -0700)
This reduces 7500+ instructions from the go toolchain binary on loong64.

file         before      after      Δ       %
asm          555066      554406   -660    -0.1189%
cgo          481480      480764   -716    -0.1487%
compile      2475836     2474776  -1060   -0.0428%
cover        516536      515788   -748    -0.1448%
link         702220      701216   -1004   -0.1430%
preprofile   238626      238122   -504    -0.2112%
vet          792798      791894   -904    -0.1140%
go           1573108     1571676  -1432   -0.0910%
gofmt        320578      320042   -536    -0.1672%
total        7656248     7648684  -7564   -0.0988%

Change-Id: I51b70a1543bc258b7664caa8647e75eecbaf5eed
Reviewed-on: https://go-review.googlesource.com/c/go/+/693495
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/ssa/_gen/LOONG64.rules
src/cmd/compile/internal/ssa/rewriteLOONG64.go

index 02339cc1e4c262fa8a7f3636cec348de775dc06a..4c195076288b33298068508cafad58f397c2a0cd 100644 (file)
 (GEZ (MOVVconst [c]) yes no) && c >= 0 => (First yes no)
 (GEZ (MOVVconst [c]) yes no) && c <  0 => (First no yes)
 
+// Convert branch with zero to more optimal branch zero.
+(BEQ  (MOVVconst [0]) cond yes no) => (EQZ cond yes no)
+(BEQ  cond (MOVVconst [0]) yes no) => (EQZ cond yes no)
+(BNE  (MOVVconst [0]) cond yes no) => (NEZ cond yes no)
+(BNE  cond (MOVVconst [0]) yes no) => (NEZ cond yes no)
+(BLT  (MOVVconst [0]) cond yes no) => (GTZ cond yes no)
+(BLT  cond (MOVVconst [0]) yes no) => (LTZ cond yes no)
+(BLTU (MOVVconst [0]) cond yes no) => (NEZ cond yes no)
+(BGE  (MOVVconst [0]) cond yes no) => (LEZ cond yes no)
+(BGE  cond (MOVVconst [0]) yes no) => (GEZ cond yes no)
+(BGEU (MOVVconst [0]) cond yes no) => (EQZ cond yes no)
+
 // Arch-specific inlining for small or disjoint runtime.memmove
 // Match post-lowering calls, register version.
 (SelectN [0] call:(CALLstatic {sym} dst src (MOVVconst [sz]) mem))
index 87dae2194beae982dfd734277924c4f08627eb2f..3065e2c315b50b1f432626b8a6197e5f98b4810c 100644 (file)
@@ -11479,6 +11479,122 @@ func rewriteValueLOONG64_OpZero(v *Value) bool {
 func rewriteBlockLOONG64(b *Block) bool {
        typ := &b.Func.Config.Types
        switch b.Kind {
+       case BlockLOONG64BEQ:
+               // match: (BEQ (MOVVconst [0]) cond yes no)
+               // result: (EQZ cond yes no)
+               for b.Controls[0].Op == OpLOONG64MOVVconst {
+                       v_0 := b.Controls[0]
+                       if auxIntToInt64(v_0.AuxInt) != 0 {
+                               break
+                       }
+                       cond := b.Controls[1]
+                       b.resetWithControl(BlockLOONG64EQZ, cond)
+                       return true
+               }
+               // match: (BEQ cond (MOVVconst [0]) yes no)
+               // result: (EQZ cond yes no)
+               for b.Controls[1].Op == OpLOONG64MOVVconst {
+                       cond := b.Controls[0]
+                       v_1 := b.Controls[1]
+                       if auxIntToInt64(v_1.AuxInt) != 0 {
+                               break
+                       }
+                       b.resetWithControl(BlockLOONG64EQZ, cond)
+                       return true
+               }
+       case BlockLOONG64BGE:
+               // match: (BGE (MOVVconst [0]) cond yes no)
+               // result: (LEZ cond yes no)
+               for b.Controls[0].Op == OpLOONG64MOVVconst {
+                       v_0 := b.Controls[0]
+                       if auxIntToInt64(v_0.AuxInt) != 0 {
+                               break
+                       }
+                       cond := b.Controls[1]
+                       b.resetWithControl(BlockLOONG64LEZ, cond)
+                       return true
+               }
+               // match: (BGE cond (MOVVconst [0]) yes no)
+               // result: (GEZ cond yes no)
+               for b.Controls[1].Op == OpLOONG64MOVVconst {
+                       cond := b.Controls[0]
+                       v_1 := b.Controls[1]
+                       if auxIntToInt64(v_1.AuxInt) != 0 {
+                               break
+                       }
+                       b.resetWithControl(BlockLOONG64GEZ, cond)
+                       return true
+               }
+       case BlockLOONG64BGEU:
+               // match: (BGEU (MOVVconst [0]) cond yes no)
+               // result: (EQZ cond yes no)
+               for b.Controls[0].Op == OpLOONG64MOVVconst {
+                       v_0 := b.Controls[0]
+                       if auxIntToInt64(v_0.AuxInt) != 0 {
+                               break
+                       }
+                       cond := b.Controls[1]
+                       b.resetWithControl(BlockLOONG64EQZ, cond)
+                       return true
+               }
+       case BlockLOONG64BLT:
+               // match: (BLT (MOVVconst [0]) cond yes no)
+               // result: (GTZ cond yes no)
+               for b.Controls[0].Op == OpLOONG64MOVVconst {
+                       v_0 := b.Controls[0]
+                       if auxIntToInt64(v_0.AuxInt) != 0 {
+                               break
+                       }
+                       cond := b.Controls[1]
+                       b.resetWithControl(BlockLOONG64GTZ, cond)
+                       return true
+               }
+               // match: (BLT cond (MOVVconst [0]) yes no)
+               // result: (LTZ cond yes no)
+               for b.Controls[1].Op == OpLOONG64MOVVconst {
+                       cond := b.Controls[0]
+                       v_1 := b.Controls[1]
+                       if auxIntToInt64(v_1.AuxInt) != 0 {
+                               break
+                       }
+                       b.resetWithControl(BlockLOONG64LTZ, cond)
+                       return true
+               }
+       case BlockLOONG64BLTU:
+               // match: (BLTU (MOVVconst [0]) cond yes no)
+               // result: (NEZ cond yes no)
+               for b.Controls[0].Op == OpLOONG64MOVVconst {
+                       v_0 := b.Controls[0]
+                       if auxIntToInt64(v_0.AuxInt) != 0 {
+                               break
+                       }
+                       cond := b.Controls[1]
+                       b.resetWithControl(BlockLOONG64NEZ, cond)
+                       return true
+               }
+       case BlockLOONG64BNE:
+               // match: (BNE (MOVVconst [0]) cond yes no)
+               // result: (NEZ cond yes no)
+               for b.Controls[0].Op == OpLOONG64MOVVconst {
+                       v_0 := b.Controls[0]
+                       if auxIntToInt64(v_0.AuxInt) != 0 {
+                               break
+                       }
+                       cond := b.Controls[1]
+                       b.resetWithControl(BlockLOONG64NEZ, cond)
+                       return true
+               }
+               // match: (BNE cond (MOVVconst [0]) yes no)
+               // result: (NEZ cond yes no)
+               for b.Controls[1].Op == OpLOONG64MOVVconst {
+                       cond := b.Controls[0]
+                       v_1 := b.Controls[1]
+                       if auxIntToInt64(v_1.AuxInt) != 0 {
+                               break
+                       }
+                       b.resetWithControl(BlockLOONG64NEZ, cond)
+                       return true
+               }
        case BlockLOONG64EQZ:
                // match: (EQZ (FPFlagTrue cmp) yes no)
                // result: (FPF cmp yes no)