]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: deadcode for LoweredMuluhilo on riscv64
authorWayne Zuo <wdvxdr@golangcn.org>
Wed, 24 Aug 2022 14:17:51 +0000 (22:17 +0800)
committerGopher Robot <gobot@golang.org>
Wed, 24 Aug 2022 18:08:33 +0000 (18:08 +0000)
This is a follow up of CL 425101 on RISCV64.

According to RISCV Volume 1, Unprivileged Spec v. 20191213 Chapter 7.1:
If both the high and low bits of the same product are required, then the
recommended code sequence is: MULH[[S]U] rdh, rs1, rs2; MUL rdl, rs1, rs2
(source register specifiers must be in same order and rdh cannot be the
same as rs1 or rs2). Microarchitectures can then fuse these into a single
multiply operation instead of performing two separate multiplies.

So we should not split Muluhilo to separate instructions.

Updates #54607

Change-Id: If47461f3aaaf00e27cd583a9990e144fb8bcdb17
Reviewed-on: https://go-review.googlesource.com/c/go/+/425203
Auto-Submit: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Wayne Zuo <wdvxdr@golangcn.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/compile/internal/ssa/gen/RISCV64.rules
src/cmd/compile/internal/ssa/rewriteRISCV64.go
test/codegen/mathbits.go

index dd20be2aeb9722f04c73712081bdc0c7258b9341..5bc47ee1cc185c83220940adffca1abcddbdb8a7 100644 (file)
 (SLTI  [x] (MOVDconst [y])) => (MOVDconst [b2i(int64(y) < int64(x))])
 (SLTIU [x] (MOVDconst [y])) => (MOVDconst [b2i(uint64(y) < uint64(x))])
 
+// deadcode for LoweredMuluhilo
+(Select0 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MULHU x y)
+(Select1 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MUL x y)
+
 // Merge negation into fused multiply-add and multiply-subtract.
 //
 // Key:
index 2677e99dc028bcb1e68b6c61094c23d9f4e17450..9253d2d7296c6388c2f48471f504493eb0ff02a4 100644 (file)
@@ -605,6 +605,10 @@ func rewriteValueRISCV64(v *Value) bool {
                return rewriteValueRISCV64_OpRsh8x64(v)
        case OpRsh8x8:
                return rewriteValueRISCV64_OpRsh8x8(v)
+       case OpSelect0:
+               return rewriteValueRISCV64_OpSelect0(v)
+       case OpSelect1:
+               return rewriteValueRISCV64_OpSelect1(v)
        case OpSignExt16to32:
                v.Op = OpRISCV64MOVHreg
                return true
@@ -6030,6 +6034,48 @@ func rewriteValueRISCV64_OpRsh8x8(v *Value) bool {
                return true
        }
 }
+func rewriteValueRISCV64_OpSelect0(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (Select0 m:(LoweredMuluhilo x y))
+       // cond: m.Uses == 1
+       // result: (MULHU x y)
+       for {
+               m := v_0
+               if m.Op != OpRISCV64LoweredMuluhilo {
+                       break
+               }
+               y := m.Args[1]
+               x := m.Args[0]
+               if !(m.Uses == 1) {
+                       break
+               }
+               v.reset(OpRISCV64MULHU)
+               v.AddArg2(x, y)
+               return true
+       }
+       return false
+}
+func rewriteValueRISCV64_OpSelect1(v *Value) bool {
+       v_0 := v.Args[0]
+       // match: (Select1 m:(LoweredMuluhilo x y))
+       // cond: m.Uses == 1
+       // result: (MUL x y)
+       for {
+               m := v_0
+               if m.Op != OpRISCV64LoweredMuluhilo {
+                       break
+               }
+               y := m.Args[1]
+               x := m.Args[0]
+               if !(m.Uses == 1) {
+                       break
+               }
+               v.reset(OpRISCV64MUL)
+               v.AddArg2(x, y)
+               return true
+       }
+       return false
+}
 func rewriteValueRISCV64_OpSlicemask(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
index 20c945fbc3a2c622d61e975a244dafba149a4513..a507d32843d6333105c76ab95453bf756e5a1511 100644 (file)
@@ -800,12 +800,14 @@ func Mul64(x, y uint64) (hi, lo uint64) {
 
 func Mul64HiOnly(x, y uint64) uint64 {
        // arm64:"UMULH",-"MUL"
+       // riscv64:"MULHU",-"MUL\t"
        hi, _ := bits.Mul64(x, y)
        return hi
 }
 
 func Mul64LoOnly(x, y uint64) uint64 {
        // arm64:"MUL",-"UMULH"
+       // riscv64:"MUL\t",-"MULHU"
        _, lo := bits.Mul64(x, y)
        return lo
 }