]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: lowered MulUintptr on riscv64
authorMeng Zhuo <mzh@golangcn.org>
Sat, 31 Jul 2021 10:20:10 +0000 (10:20 +0000)
committerMeng Zhuo <mzh@golangcn.org>
Tue, 17 Aug 2021 01:29:37 +0000 (01:29 +0000)
According to RISCV instruction set manual v2.2 Sec 6.1
MULHU followed by MUL will be fused into one multiply by microarchitecture

name              old time/op  new time/op  delta
MulUintptr/small  11.2ns ±24%   9.2ns ± 0%  -17.54%  (p=0.000 n=10+9)
MulUintptr/large  15.9ns ± 0%  10.9ns ± 0%  -31.55%  (p=0.000 n=8+8)

Change-Id: I3d152218f83948cbc5c576bda29dc86e9b4206ee
Reviewed-on: https://go-review.googlesource.com/c/go/+/338753
Trust: Meng Zhuo <mzh@golangcn.org>
Reviewed-by: Joel Sing <joel@sing.id.au>
src/cmd/compile/internal/riscv64/ssa.go
src/cmd/compile/internal/ssa/gen/RISCV64.rules
src/cmd/compile/internal/ssa/gen/RISCV64Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewriteRISCV64.go
src/cmd/compile/internal/ssagen/ssa.go

index c635d93b719d291c8019f0f4afcb8260893b5d3b..d3cbb4ec24b17530e49e656484f66e5cc86b322c 100644 (file)
@@ -297,6 +297,27 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                p1.Reg = r0
                p1.To.Type = obj.TYPE_REG
                p1.To.Reg = v.Reg1()
+       case ssa.OpRISCV64LoweredMuluover:
+               r0 := v.Args[0].Reg()
+               r1 := v.Args[1].Reg()
+               p := s.Prog(riscv.AMULHU)
+               p.From.Type = obj.TYPE_REG
+               p.From.Reg = r1
+               p.Reg = r0
+               p.To.Type = obj.TYPE_REG
+               p.To.Reg = v.Reg1()
+               p1 := s.Prog(riscv.AMUL)
+               p1.From.Type = obj.TYPE_REG
+               p1.From.Reg = r1
+               p1.Reg = r0
+               p1.To.Type = obj.TYPE_REG
+               p1.To.Reg = v.Reg0()
+               p2 := s.Prog(riscv.ASNEZ)
+               p2.From.Type = obj.TYPE_REG
+               p2.From.Reg = v.Reg1()
+               p2.To.Type = obj.TYPE_REG
+               p2.To.Reg = v.Reg1()
+
        case ssa.OpRISCV64FSQRTS, ssa.OpRISCV64FNEGS, ssa.OpRISCV64FSQRTD, ssa.OpRISCV64FNEGD,
                ssa.OpRISCV64FMVSX, ssa.OpRISCV64FMVDX,
                ssa.OpRISCV64FCVTSW, ssa.OpRISCV64FCVTSL, ssa.OpRISCV64FCVTWS, ssa.OpRISCV64FCVTLS,
index b21ebe6abbd1cf157116cde39361d582bfb7f6b9..1acef2a27395875979deb79bfe69e3bf2af06737 100644 (file)
@@ -30,6 +30,7 @@
 
 (Mul64 ...) => (MUL  ...)
 (Mul64uhilo ...) => (LoweredMuluhilo ...)
+(Mul64uover ...) => (LoweredMuluover ...)
 (Mul32 ...) => (MULW ...)
 (Mul16 x y) => (MULW (SignExt16to32 x) (SignExt16to32 y))
 (Mul8 x y)  => (MULW (SignExt8to32 x)  (SignExt8to32 y))
index cb9051f954e82e3798e6c6c965aa0dd1082c2d9e..d36daa8b839a6f0fb73021a0d0b856f886b4bfe4 100644 (file)
@@ -159,6 +159,7 @@ func init() {
                {name: "MULH", argLength: 2, reg: gp21, asm: "MULH", commutative: true, typ: "Int64"},
                {name: "MULHU", argLength: 2, reg: gp21, asm: "MULHU", commutative: true, typ: "UInt64"},
                {name: "LoweredMuluhilo", argLength: 2, reg: gp22, resultNotInArgs: true}, // arg0 * arg1, return (hi, lo)
+               {name: "LoweredMuluover", argLength: 2, reg: gp22, resultNotInArgs: true}, // arg0 * arg1, return (64 bits of arg0*arg1, overflow)
 
                {name: "DIV", argLength: 2, reg: gp21, asm: "DIV", typ: "Int64"}, // arg0 / arg1
                {name: "DIVU", argLength: 2, reg: gp21, asm: "DIVU", typ: "UInt64"},
index 7893ce837e7ba5bd24a3da2cc951572db5f8ad5b..8ce13abed30aa693d1625609767319e1c94263a2 100644 (file)
@@ -2070,6 +2070,7 @@ const (
        OpRISCV64MULH
        OpRISCV64MULHU
        OpRISCV64LoweredMuluhilo
+       OpRISCV64LoweredMuluover
        OpRISCV64DIV
        OpRISCV64DIVU
        OpRISCV64DIVW
@@ -27619,6 +27620,21 @@ var opcodeTable = [...]opInfo{
                        },
                },
        },
+       {
+               name:            "LoweredMuluover",
+               argLen:          2,
+               resultNotInArgs: true,
+               reg: regInfo{
+                       inputs: []inputInfo{
+                               {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+                               {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+                       },
+                       outputs: []outputInfo{
+                               {0, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+                               {1, 1006632948}, // X3 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X28 X29 X30
+                       },
+               },
+       },
        {
                name:   "DIV",
                argLen: 2,
index f315c0d3a8a5b1793ec5fd6ba65a479b53bf96f5..e9f17206de673bf51f089260f0559e940fb8329d 100644 (file)
@@ -359,6 +359,9 @@ func rewriteValueRISCV64(v *Value) bool {
        case OpMul64uhilo:
                v.Op = OpRISCV64LoweredMuluhilo
                return true
+       case OpMul64uover:
+               v.Op = OpRISCV64LoweredMuluover
+               return true
        case OpMul8:
                return rewriteValueRISCV64_OpMul8(v)
        case OpNeg16:
index 237135d5c7007733b19f593937d92f98a21bb4b6..39d3b206ac6e1b5f259acd4dd72c5dbd376f0814 100644 (file)
@@ -3779,7 +3779,7 @@ func InitTables() {
                        }
                        return s.newValue2(ssa.OpMul64uover, types.NewTuple(types.Types[types.TUINT], types.Types[types.TUINT]), args[0], args[1])
                },
-               sys.AMD64, sys.I386, sys.MIPS64)
+               sys.AMD64, sys.I386, sys.MIPS64, sys.RISCV64)
        add("runtime", "KeepAlive",
                func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
                        data := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, args[0])