]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: enable brachelim pass on loong64
authorWayne Zuo <wdvxdr@golangcn.org>
Sat, 9 Jul 2022 11:26:47 +0000 (19:26 +0800)
committerGopher Robot <gobot@golang.org>
Wed, 9 Nov 2022 06:10:55 +0000 (06:10 +0000)
Change-Id: I4fd1c307901c265ab9865bf8a74460ddc15e5d14
Reviewed-on: https://go-review.googlesource.com/c/go/+/416735
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: xiaodong liu <teaofmoli@gmail.com>
Auto-Submit: Wayne Zuo <wdvxdr@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Wayne Zuo <wdvxdr@golangcn.org>

src/cmd/compile/internal/loong64/ssa.go
src/cmd/compile/internal/ssa/_gen/LOONG64.rules
src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go
src/cmd/compile/internal/ssa/branchelim.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteLOONG64.go
test/codegen/condmove.go

index 68a2d8ac1bdc71aed4ebe7de1a363effd3656ba7..a1cebdca560104eb82f7b6831a137aacdc137e6f 100644 (file)
@@ -786,6 +786,13 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                p := s.Prog(obj.AGETCALLERPC)
                p.To.Type = obj.TYPE_REG
                p.To.Reg = v.Reg()
+       case ssa.OpLOONG64MASKEQZ, ssa.OpLOONG64MASKNEZ:
+               p := s.Prog(v.Op.Asm())
+               p.From.Type = obj.TYPE_REG
+               p.From.Reg = v.Args[1].Reg()
+               p.Reg = v.Args[0].Reg()
+               p.To.Type = obj.TYPE_REG
+               p.To.Reg = v.Reg()
        case ssa.OpClobber, ssa.OpClobberReg:
                // TODO: implement for clobberdead experiment. Nop is ok for now.
        default:
index 33cc8a6ae3a26f2f957db998cb4f46155e81d4b2..2810f0afe12a468c5a283b06f9a4295e0ae5e8ca 100644 (file)
 (PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
 (PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
 
+(CondSelect <t> x y cond) => (OR (MASKEQZ <t> x cond) (MASKNEZ <t> y cond))
+
 // Optimizations
 
 // Absorb boolean tests into block
 (ORconst  [-1] _) => (MOVVconst [-1])
 (XORconst [0]  x) => x
 (XORconst [-1] x) => (NORconst [0] x)
+(MASKEQZ (MOVVconst [0]) cond) => (MOVVconst [0])
+(MASKNEZ (MOVVconst [0]) cond) => (MOVVconst [0])
 
 // generic constant folding
 (ADDVconst [c] (MOVVconst [d]))  => (MOVVconst [c+d])
index 5a84529192cd54569ebef1ef4f4c007d8027aa25..3b9fc7c8713d3bd9c74352ee39effc54c33d322c 100644 (file)
@@ -192,6 +192,9 @@ func init() {
                {name: "SQRTD", argLength: 1, reg: fp11, asm: "SQRTD"}, // sqrt(arg0), float64
                {name: "SQRTF", argLength: 1, reg: fp11, asm: "SQRTF"}, // sqrt(arg0), float32
 
+               {name: "MASKEQZ", argLength: 2, reg: gp21, asm: "MASKEQZ"}, // returns 0 if arg1 == 0, otherwise returns arg0
+               {name: "MASKNEZ", argLength: 2, reg: gp21, asm: "MASKNEZ"}, // returns 0 if arg1 != 0, otherwise returns arg0
+
                // shifts
                {name: "SLLV", argLength: 2, reg: gp21, asm: "SLLV"},                      // arg0 << arg1, shift amount is mod 64
                {name: "SLLVconst", argLength: 1, reg: gp11, asm: "SLLV", aux: "Int64"},   // arg0 << auxInt
index 7a08654f4e1ef4c57c9082ed4c5dcda03f0d8fca..5a06bfb2209a8eb581c423781845710c079e5757 100644 (file)
@@ -22,7 +22,7 @@ import "cmd/internal/src"
 func branchelim(f *Func) {
        // FIXME: add support for lowering CondSelects on more architectures
        switch f.Config.arch {
-       case "arm64", "ppc64le", "ppc64", "amd64", "wasm":
+       case "arm64", "ppc64le", "ppc64", "amd64", "wasm", "loong64":
                // implemented
        default:
                return
@@ -83,6 +83,15 @@ func canCondSelect(v *Value, arch string, loadAddr *sparseSet) bool {
                // See issue #26306.
                return false
        }
+       if arch == "loong64" {
+               // We should not generate conditional moves if neither of the arguments is constant zero,
+               // because it requires three instructions (OR, MASKEQZ, MASKNEZ) and will increase the
+               // register pressure.
+               if !(v.Args[0].isGenericIntConst() && v.Args[0].AuxInt == 0) &&
+                       !(v.Args[1].isGenericIntConst() && v.Args[1].AuxInt == 0) {
+                       return false
+               }
+       }
        // For now, stick to simple scalars that fit in registers
        switch {
        case v.Type.Size() > v.Block.Func.Config.RegSize:
index 994a0c9464e625614d0fa5e428b00fcb2dd8b538..fe57305bc6efca4ac72a684c7fee9a2457c79fb4 100644 (file)
@@ -1740,6 +1740,8 @@ const (
        OpLOONG64NEGD
        OpLOONG64SQRTD
        OpLOONG64SQRTF
+       OpLOONG64MASKEQZ
+       OpLOONG64MASKNEZ
        OpLOONG64SLLV
        OpLOONG64SLLVconst
        OpLOONG64SRLV
@@ -23263,6 +23265,34 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:   "MASKEQZ",
+               argLen: 2,
+               asm:    loong64.AMASKEQZ,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+                               {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+                       },
+                       outputs: []outputInfo{
+                               {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+                       },
+               },
+       },
+       {
+               name:   "MASKNEZ",
+               argLen: 2,
+               asm:    loong64.AMASKNEZ,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+                               {1, 1072693240}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 g R23 R24 R25 R26 R27 R28 R29 R31
+                       },
+                       outputs: []outputInfo{
+                               {0, 1070596088}, // R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R23 R24 R25 R26 R27 R28 R29 R31
+                       },
+               },
+       },
        {
                name:   "SLLV",
                argLen: 2,
index d57289e058f24ab4e626cc0050133d985f00e7e4..26d6594fef3fc8f1c8095d6a4dd92b3b64df2c07 100644 (file)
@@ -100,6 +100,8 @@ func rewriteValueLOONG64(v *Value) bool {
                return rewriteValueLOONG64_OpCom64(v)
        case OpCom8:
                return rewriteValueLOONG64_OpCom8(v)
+       case OpCondSelect:
+               return rewriteValueLOONG64_OpCondSelect(v)
        case OpConst16:
                return rewriteValueLOONG64_OpConst16(v)
        case OpConst32:
@@ -229,6 +231,10 @@ func rewriteValueLOONG64(v *Value) bool {
                return rewriteValueLOONG64_OpLOONG64LoweredAtomicStore32(v)
        case OpLOONG64LoweredAtomicStore64:
                return rewriteValueLOONG64_OpLOONG64LoweredAtomicStore64(v)
+       case OpLOONG64MASKEQZ:
+               return rewriteValueLOONG64_OpLOONG64MASKEQZ(v)
+       case OpLOONG64MASKNEZ:
+               return rewriteValueLOONG64_OpLOONG64MASKNEZ(v)
        case OpLOONG64MOVBUload:
                return rewriteValueLOONG64_OpLOONG64MOVBUload(v)
        case OpLOONG64MOVBUreg:
@@ -779,6 +785,27 @@ func rewriteValueLOONG64_OpCom8(v *Value) bool {
                return true
        }
 }
+func rewriteValueLOONG64_OpCondSelect(v *Value) bool {
+       v_2 := v.Args[2]
+       v_1 := v.Args[1]
+       v_0 := v.Args[0]
+       b := v.Block
+       // match: (CondSelect <t> x y cond)
+       // result: (OR (MASKEQZ <t> x cond) (MASKNEZ <t> y cond))
+       for {
+               t := v.Type
+               x := v_0
+               y := v_1
+               cond := v_2
+               v.reset(OpLOONG64OR)
+               v0 := b.NewValue0(v.Pos, OpLOONG64MASKEQZ, t)
+               v0.AddArg2(x, cond)
+               v1 := b.NewValue0(v.Pos, OpLOONG64MASKNEZ, t)
+               v1.AddArg2(y, cond)
+               v.AddArg2(v0, v1)
+               return true
+       }
+}
 func rewriteValueLOONG64_OpConst16(v *Value) bool {
        // match: (Const16 [val])
        // result: (MOVVconst [int64(val)])
@@ -1596,6 +1623,34 @@ func rewriteValueLOONG64_OpLOONG64LoweredAtomicStore64(v *Value) bool {
        }
        return false
 }
+func rewriteValueLOONG64_OpLOONG64MASKEQZ(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (MASKEQZ (MOVVconst [0]) cond)
+       // result: (MOVVconst [0])
+       for {
+               if v_0.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpLOONG64MOVVconst)
+               v.AuxInt = int64ToAuxInt(0)
+               return true
+       }
+       return false
+}
+func rewriteValueLOONG64_OpLOONG64MASKNEZ(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (MASKNEZ (MOVVconst [0]) cond)
+       // result: (MOVVconst [0])
+       for {
+               if v_0.Op != OpLOONG64MOVVconst || auxIntToInt64(v_0.AuxInt) != 0 {
+                       break
+               }
+               v.reset(OpLOONG64MOVVconst)
+               v.AuxInt = int64ToAuxInt(0)
+               return true
+       }
+       return false
+}
 func rewriteValueLOONG64_OpLOONG64MOVBUload(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]
index 793bd7f973b0651ae2c75608d490915d2bf7ad5c..bfab62213be7983d7307631719795430a35230f3 100644 (file)
@@ -422,3 +422,21 @@ func cmovFcmp1(s, t float64, a, b int) {
        // arm64:"CSINC\tEQ", -"CSEL"
        r5 = x5
 }
+
+func cmovzero1(c bool) int {
+       var x int
+       if c {
+               x = 182
+       }
+       // loong64:"MASKEQZ", -"MASKNEZ"
+       return x
+}
+
+func cmovzero2(c bool) int {
+       var x int
+       if !c {
+               x = 182
+       }
+       // loong64:"MASKNEZ", -"MASKEQZ"
+       return x
+}