]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: improve subtraction of constants on riscv64
authorJoel Sing <joel@sing.id.au>
Sun, 1 Mar 2020 17:23:12 +0000 (04:23 +1100)
committerJoel Sing <joel@sing.id.au>
Tue, 3 Mar 2020 11:36:47 +0000 (11:36 +0000)
Convert subtraction of a constant into an ADDI with a negative immediate,
where possible.

Change-Id: Ie8d54b7538f0012e5f898abea233b2957fe31899
Reviewed-on: https://go-review.googlesource.com/c/go/+/221679
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/compile/internal/ssa/gen/RISCV64.rules
src/cmd/compile/internal/ssa/rewriteRISCV64.go

index 4ab4656bd564f45a7530334105c05faee82b898e..3fd482b50c5da0d58fdf0ff86660789d8712239b 100644 (file)
 (MOVDconst <t> [c]) && !is32Bit(c) && int32(c) <  0 -> (ADD (SLLI <t> [32] (MOVDconst [c>>32+1])) (MOVDconst [int64(int32(c))]))
 (MOVDconst <t> [c]) && !is32Bit(c) && int32(c) >= 0 -> (ADD (SLLI <t> [32] (MOVDconst [c>>32+0])) (MOVDconst [int64(int32(c))]))
 
-// Fold ADD+MOVDconst into ADDI where possible.
-(ADD (MOVDconst [off]) ptr) && is32Bit(off) -> (ADDI [off] ptr)
-
 (Addr ...) -> (MOVaddr ...)
 (LocalAddr {sym} base _) -> (MOVaddr {sym} base)
 
 (ClosureCall ...) -> (CALLclosure ...)
 (InterCall   ...) -> (CALLinter   ...)
 
+// Optimizations
+
+// Fold ADD+MOVDconst into ADDI where possible.
+(ADD (MOVDconst [off]) ptr) && is32Bit(off) -> (ADDI [off] ptr)
+
+// Convert subtraction of a const into ADDI with negative immediate, where possible.
+(SUB x (MOVBconst [val])) && is32Bit(-val) -> (ADDI [-val] x)
+(SUB x (MOVHconst [val])) && is32Bit(-val) -> (ADDI [-val] x)
+(SUB x (MOVWconst [val])) && is32Bit(-val) -> (ADDI [-val] x)
+(SUB x (MOVDconst [val])) && is32Bit(-val) -> (ADDI [-val] x)
+
 // remove redundant *const ops
 (ADDI [0]  x) -> x
index 2e0b34de8d5fc6e5e3879195c888c5e75df3cd8f..128f7bb2b292a721c6dcab8e239e222a9fcdf45f 100644 (file)
@@ -404,6 +404,8 @@ func rewriteValueRISCV64(v *Value) bool {
                return rewriteValueRISCV64_OpRISCV64MOVWload(v)
        case OpRISCV64MOVWstore:
                return rewriteValueRISCV64_OpRISCV64MOVWstore(v)
+       case OpRISCV64SUB:
+               return rewriteValueRISCV64_OpRISCV64SUB(v)
        case OpRotateLeft16:
                return rewriteValueRISCV64_OpRotateLeft16(v)
        case OpRotateLeft32:
@@ -2877,6 +2879,79 @@ func rewriteValueRISCV64_OpRISCV64MOVWstore(v *Value) bool {
        }
        return false
 }
+func rewriteValueRISCV64_OpRISCV64SUB(v *Value) bool {
+       v_1 := v.Args[1]
+       v_0 := v.Args[0]
+       // match: (SUB x (MOVBconst [val]))
+       // cond: is32Bit(-val)
+       // result: (ADDI [-val] x)
+       for {
+               x := v_0
+               if v_1.Op != OpRISCV64MOVBconst {
+                       break
+               }
+               val := v_1.AuxInt
+               if !(is32Bit(-val)) {
+                       break
+               }
+               v.reset(OpRISCV64ADDI)
+               v.AuxInt = -val
+               v.AddArg(x)
+               return true
+       }
+       // match: (SUB x (MOVHconst [val]))
+       // cond: is32Bit(-val)
+       // result: (ADDI [-val] x)
+       for {
+               x := v_0
+               if v_1.Op != OpRISCV64MOVHconst {
+                       break
+               }
+               val := v_1.AuxInt
+               if !(is32Bit(-val)) {
+                       break
+               }
+               v.reset(OpRISCV64ADDI)
+               v.AuxInt = -val
+               v.AddArg(x)
+               return true
+       }
+       // match: (SUB x (MOVWconst [val]))
+       // cond: is32Bit(-val)
+       // result: (ADDI [-val] x)
+       for {
+               x := v_0
+               if v_1.Op != OpRISCV64MOVWconst {
+                       break
+               }
+               val := v_1.AuxInt
+               if !(is32Bit(-val)) {
+                       break
+               }
+               v.reset(OpRISCV64ADDI)
+               v.AuxInt = -val
+               v.AddArg(x)
+               return true
+       }
+       // match: (SUB x (MOVDconst [val]))
+       // cond: is32Bit(-val)
+       // result: (ADDI [-val] x)
+       for {
+               x := v_0
+               if v_1.Op != OpRISCV64MOVDconst {
+                       break
+               }
+               val := v_1.AuxInt
+               if !(is32Bit(-val)) {
+                       break
+               }
+               v.reset(OpRISCV64ADDI)
+               v.AuxInt = -val
+               v.AddArg(x)
+               return true
+       }
+       return false
+}
 func rewriteValueRISCV64_OpRotateLeft16(v *Value) bool {
        v_1 := v.Args[1]
        v_0 := v.Args[0]