cmd/compile: combine operations with immediate on riscv64

Replace two immediate operations with one, where possible.

Change-Id: Idc00e868155c9ca1d872aaaf70ea1f73e9eac4d6
Reviewed-on: https://go-review.googlesource.com/c/go/+/428497
Reviewed-by: Wayne Zuo <wdvxdr@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Joel Sing <joel@sing.id.au>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Joel Sing 2022-09-04 05:23:07 +10:00
parent 83d94daec2
commit 7234c90352
2 changed files with 51 additions and 0 deletions

View File

@ -788,6 +788,11 @@
(ORI [-1] x) => (MOVDconst [-1])
(ORI [x] (MOVDconst [y])) => (MOVDconst [x | y])
// Combine operations with immediate.
(ADDI [x] (ADDI [y] z)) && is32Bit(x + y) => (ADDI [x + y] z)
(ANDI [x] (ANDI [y] z)) => (ANDI [x & y] z)
(ORI [x] (ORI [y] z)) => (ORI [x | y] z)
// Negation of a constant.
(NEG (MOVDconst [x])) => (MOVDconst [-x])
(NEGW (MOVDconst [x])) => (MOVDconst [int64(int32(-x))])

View File

@ -3174,6 +3174,24 @@ func rewriteValueRISCV64_OpRISCV64ADDI(v *Value) bool {
v.AuxInt = int64ToAuxInt(x + y)
return true
}
// match: (ADDI [x] (ADDI [y] z))
// cond: is32Bit(x + y)
// result: (ADDI [x + y] z)
for {
x := auxIntToInt64(v.AuxInt)
if v_0.Op != OpRISCV64ADDI {
break
}
y := auxIntToInt64(v_0.AuxInt)
z := v_0.Args[0]
if !(is32Bit(x + y)) {
break
}
v.reset(OpRISCV64ADDI)
v.AuxInt = int64ToAuxInt(x + y)
v.AddArg(z)
return true
}
return false
}
func rewriteValueRISCV64_OpRISCV64AND(v *Value) bool {
@ -3235,6 +3253,20 @@ func rewriteValueRISCV64_OpRISCV64ANDI(v *Value) bool {
v.AuxInt = int64ToAuxInt(x & y)
return true
}
// match: (ANDI [x] (ANDI [y] z))
// result: (ANDI [x & y] z)
for {
x := auxIntToInt64(v.AuxInt)
if v_0.Op != OpRISCV64ANDI {
break
}
y := auxIntToInt64(v_0.AuxInt)
z := v_0.Args[0]
v.reset(OpRISCV64ANDI)
v.AuxInt = int64ToAuxInt(x & y)
v.AddArg(z)
return true
}
return false
}
func rewriteValueRISCV64_OpRISCV64FMADDD(v *Value) bool {
@ -5439,6 +5471,20 @@ func rewriteValueRISCV64_OpRISCV64ORI(v *Value) bool {
v.AuxInt = int64ToAuxInt(x | y)
return true
}
// match: (ORI [x] (ORI [y] z))
// result: (ORI [x | y] z)
for {
x := auxIntToInt64(v.AuxInt)
if v_0.Op != OpRISCV64ORI {
break
}
y := auxIntToInt64(v_0.AuxInt)
z := v_0.Args[0]
v.reset(OpRISCV64ORI)
v.AuxInt = int64ToAuxInt(x | y)
v.AddArg(z)
return true
}
return false
}
func rewriteValueRISCV64_OpRISCV64SEQZ(v *Value) bool {