cmd/compile: resolve known outcomes for SLTI/SLTIU on riscv64

When SLTI/SLTIU is used with ANDI/ORI, it may be possible to determine the
outcome based on the values of the immediates. Resolve these cases.

Improves code generation for various shift operations.

While here, sort tests by architecture to improve readability and ease
future maintenance.

Change-Id: I87e71e016a0e396a928e7d6389a2df61583dfd8d
Reviewed-on: https://go-review.googlesource.com/c/go/+/428217
Reviewed-by: Wayne Zuo <wdvxdr@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Jenny Rakoczy <jenny@golang.org>
Reviewed-by: Jenny Rakoczy <jenny@golang.org>
Run-TryBot: Joel Sing <joel@sing.id.au>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Jenny Rakoczy <jenny@golang.org>
This commit is contained in:
Joel Sing 2022-09-01 20:36:34 +10:00
parent cc1b20e8ad
commit a7bcc94719
3 changed files with 106 additions and 35 deletions

View file

@ -5530,6 +5530,38 @@ func rewriteValueRISCV64_OpRISCV64SLTI(v *Value) bool {
v.AuxInt = int64ToAuxInt(b2i(int64(y) < int64(x)))
return true
}
// match: (SLTI [x] (ANDI [y] _))
// cond: y >= 0 && int64(y) < int64(x)
// result: (MOVDconst [1])
for {
x := auxIntToInt64(v.AuxInt)
if v_0.Op != OpRISCV64ANDI {
break
}
y := auxIntToInt64(v_0.AuxInt)
if !(y >= 0 && int64(y) < int64(x)) {
break
}
v.reset(OpRISCV64MOVDconst)
v.AuxInt = int64ToAuxInt(1)
return true
}
// match: (SLTI [x] (ORI [y] _))
// cond: y >= 0 && int64(y) >= int64(x)
// result: (MOVDconst [0])
for {
x := auxIntToInt64(v.AuxInt)
if v_0.Op != OpRISCV64ORI {
break
}
y := auxIntToInt64(v_0.AuxInt)
if !(y >= 0 && int64(y) >= int64(x)) {
break
}
v.reset(OpRISCV64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueRISCV64_OpRISCV64SLTIU(v *Value) bool {
@ -5546,6 +5578,38 @@ func rewriteValueRISCV64_OpRISCV64SLTIU(v *Value) bool {
v.AuxInt = int64ToAuxInt(b2i(uint64(y) < uint64(x)))
return true
}
// match: (SLTIU [x] (ANDI [y] _))
// cond: y >= 0 && uint64(y) < uint64(x)
// result: (MOVDconst [1])
for {
x := auxIntToInt64(v.AuxInt)
if v_0.Op != OpRISCV64ANDI {
break
}
y := auxIntToInt64(v_0.AuxInt)
if !(y >= 0 && uint64(y) < uint64(x)) {
break
}
v.reset(OpRISCV64MOVDconst)
v.AuxInt = int64ToAuxInt(1)
return true
}
// match: (SLTIU [x] (ORI [y] _))
// cond: y >= 0 && uint64(y) >= uint64(x)
// result: (MOVDconst [0])
for {
x := auxIntToInt64(v.AuxInt)
if v_0.Op != OpRISCV64ORI {
break
}
y := auxIntToInt64(v_0.AuxInt)
if !(y >= 0 && uint64(y) >= uint64(x)) {
break
}
v.reset(OpRISCV64MOVDconst)
v.AuxInt = int64ToAuxInt(0)
return true
}
return false
}
func rewriteValueRISCV64_OpRISCV64SLTU(v *Value) bool {