mirror of
https://github.com/golang/go
synced 2024-10-14 03:43:28 +00:00
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:
parent
cc1b20e8ad
commit
a7bcc94719
|
@ -801,10 +801,17 @@
|
||||||
(SLTI [x] (MOVDconst [y])) => (MOVDconst [b2i(int64(y) < int64(x))])
|
(SLTI [x] (MOVDconst [y])) => (MOVDconst [b2i(int64(y) < int64(x))])
|
||||||
(SLTIU [x] (MOVDconst [y])) => (MOVDconst [b2i(uint64(y) < uint64(x))])
|
(SLTIU [x] (MOVDconst [y])) => (MOVDconst [b2i(uint64(y) < uint64(x))])
|
||||||
|
|
||||||
(SLT x x) => (MOVDconst [0])
|
// SLTI/SLTIU with known outcomes.
|
||||||
|
(SLTI [x] (ANDI [y] _)) && y >= 0 && int64(y) < int64(x) => (MOVDconst [1])
|
||||||
|
(SLTIU [x] (ANDI [y] _)) && y >= 0 && uint64(y) < uint64(x) => (MOVDconst [1])
|
||||||
|
(SLTI [x] (ORI [y] _)) && y >= 0 && int64(y) >= int64(x) => (MOVDconst [0])
|
||||||
|
(SLTIU [x] (ORI [y] _)) && y >= 0 && uint64(y) >= uint64(x) => (MOVDconst [0])
|
||||||
|
|
||||||
|
// SLT/SLTU with known outcomes.
|
||||||
|
(SLT x x) => (MOVDconst [0])
|
||||||
(SLTU x x) => (MOVDconst [0])
|
(SLTU x x) => (MOVDconst [0])
|
||||||
|
|
||||||
// deadcode for LoweredMuluhilo
|
// Deadcode for LoweredMuluhilo
|
||||||
(Select0 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MULHU x y)
|
(Select0 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MULHU x y)
|
||||||
(Select1 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MUL x y)
|
(Select1 m:(LoweredMuluhilo x y)) && m.Uses == 1 => (MUL x y)
|
||||||
|
|
||||||
|
|
|
@ -5530,6 +5530,38 @@ func rewriteValueRISCV64_OpRISCV64SLTI(v *Value) bool {
|
||||||
v.AuxInt = int64ToAuxInt(b2i(int64(y) < int64(x)))
|
v.AuxInt = int64ToAuxInt(b2i(int64(y) < int64(x)))
|
||||||
return true
|
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
|
return false
|
||||||
}
|
}
|
||||||
func rewriteValueRISCV64_OpRISCV64SLTIU(v *Value) bool {
|
func rewriteValueRISCV64_OpRISCV64SLTIU(v *Value) bool {
|
||||||
|
@ -5546,6 +5578,38 @@ func rewriteValueRISCV64_OpRISCV64SLTIU(v *Value) bool {
|
||||||
v.AuxInt = int64ToAuxInt(b2i(uint64(y) < uint64(x)))
|
v.AuxInt = int64ToAuxInt(b2i(uint64(y) < uint64(x)))
|
||||||
return true
|
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
|
return false
|
||||||
}
|
}
|
||||||
func rewriteValueRISCV64_OpRISCV64SLTU(v *Value) bool {
|
func rewriteValueRISCV64_OpRISCV64SLTU(v *Value) bool {
|
||||||
|
|
|
@ -11,65 +11,65 @@ package codegen
|
||||||
// ------------------ //
|
// ------------------ //
|
||||||
|
|
||||||
func lshConst64x64(v int64) int64 {
|
func lshConst64x64(v int64) int64 {
|
||||||
// riscv64:"SLLI",-"AND",-"SLTIU"
|
|
||||||
// ppc64le:"SLD"
|
|
||||||
// ppc64:"SLD"
|
// ppc64:"SLD"
|
||||||
|
// ppc64le:"SLD"
|
||||||
|
// riscv64:"SLLI",-"AND",-"SLTIU"
|
||||||
return v << uint64(33)
|
return v << uint64(33)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshConst64Ux64(v uint64) uint64 {
|
func rshConst64Ux64(v uint64) uint64 {
|
||||||
// riscv64:"SRLI",-"AND",-"SLTIU"
|
|
||||||
// ppc64le:"SRD"
|
|
||||||
// ppc64:"SRD"
|
// ppc64:"SRD"
|
||||||
|
// ppc64le:"SRD"
|
||||||
|
// riscv64:"SRLI",-"AND",-"SLTIU"
|
||||||
return v >> uint64(33)
|
return v >> uint64(33)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshConst64x64(v int64) int64 {
|
func rshConst64x64(v int64) int64 {
|
||||||
// riscv64:"SRAI",-"OR",-"SLTIU"
|
|
||||||
// ppc64le:"SRAD"
|
|
||||||
// ppc64:"SRAD"
|
// ppc64:"SRAD"
|
||||||
|
// ppc64le:"SRAD"
|
||||||
|
// riscv64:"SRAI",-"OR",-"SLTIU"
|
||||||
return v >> uint64(33)
|
return v >> uint64(33)
|
||||||
}
|
}
|
||||||
|
|
||||||
func lshConst32x64(v int32) int32 {
|
func lshConst32x64(v int32) int32 {
|
||||||
// riscv64:"SLLI",-"AND",-"SLTIU"
|
|
||||||
// ppc64le:"SLW"
|
|
||||||
// ppc64:"SLW"
|
// ppc64:"SLW"
|
||||||
|
// ppc64le:"SLW"
|
||||||
|
// riscv64:"SLLI",-"AND",-"SLTIU"
|
||||||
return v << uint64(29)
|
return v << uint64(29)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshConst32Ux64(v uint32) uint32 {
|
func rshConst32Ux64(v uint32) uint32 {
|
||||||
// riscv64:"SRLI",-"AND",-"SLTIU"
|
|
||||||
// ppc64le:"SRW"
|
|
||||||
// ppc64:"SRW"
|
// ppc64:"SRW"
|
||||||
|
// ppc64le:"SRW"
|
||||||
|
// riscv64:"SRLI",-"AND",-"SLTIU"
|
||||||
return v >> uint64(29)
|
return v >> uint64(29)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshConst32x64(v int32) int32 {
|
func rshConst32x64(v int32) int32 {
|
||||||
// riscv64:"SRAI",-"OR",-"SLTIU"
|
|
||||||
// ppc64le:"SRAW"
|
|
||||||
// ppc64:"SRAW"
|
// ppc64:"SRAW"
|
||||||
|
// ppc64le:"SRAW"
|
||||||
|
// riscv64:"SRAI",-"OR",-"SLTIU"
|
||||||
return v >> uint64(29)
|
return v >> uint64(29)
|
||||||
}
|
}
|
||||||
|
|
||||||
func lshConst64x32(v int64) int64 {
|
func lshConst64x32(v int64) int64 {
|
||||||
// riscv64:"SLLI",-"AND",-"SLTIU"
|
|
||||||
// ppc64le:"SLD"
|
|
||||||
// ppc64:"SLD"
|
// ppc64:"SLD"
|
||||||
|
// ppc64le:"SLD"
|
||||||
|
// riscv64:"SLLI",-"AND",-"SLTIU"
|
||||||
return v << uint32(33)
|
return v << uint32(33)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshConst64Ux32(v uint64) uint64 {
|
func rshConst64Ux32(v uint64) uint64 {
|
||||||
// riscv64:"SRLI",-"AND",-"SLTIU"
|
|
||||||
// ppc64le:"SRD"
|
|
||||||
// ppc64:"SRD"
|
// ppc64:"SRD"
|
||||||
|
// ppc64le:"SRD"
|
||||||
|
// riscv64:"SRLI",-"AND",-"SLTIU"
|
||||||
return v >> uint32(33)
|
return v >> uint32(33)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshConst64x32(v int64) int64 {
|
func rshConst64x32(v int64) int64 {
|
||||||
// riscv64:"SRAI",-"OR",-"SLTIU"
|
|
||||||
// ppc64le:"SRAD"
|
|
||||||
// ppc64:"SRAD"
|
// ppc64:"SRAD"
|
||||||
|
// ppc64le:"SRAD"
|
||||||
|
// riscv64:"SRAI",-"OR",-"SLTIU"
|
||||||
return v >> uint32(33)
|
return v >> uint32(33)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,90 +78,90 @@ func rshConst64x32(v int64) int64 {
|
||||||
// ------------------ //
|
// ------------------ //
|
||||||
|
|
||||||
func lshMask64x64(v int64, s uint64) int64 {
|
func lshMask64x64(v int64, s uint64) int64 {
|
||||||
|
// arm64:"LSL",-"AND"
|
||||||
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
||||||
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
||||||
// riscv64:"SLL",-"AND\t",-"SLTIU"
|
// riscv64:"SLL",-"AND\t",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
// arm64:"LSL",-"AND"
|
|
||||||
return v << (s & 63)
|
return v << (s & 63)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshMask64Ux64(v uint64, s uint64) uint64 {
|
func rshMask64Ux64(v uint64, s uint64) uint64 {
|
||||||
|
// arm64:"LSR",-"AND",-"CSEL"
|
||||||
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
||||||
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
||||||
// riscv64:"SRL",-"AND\t",-"SLTIU"
|
// riscv64:"SRL",-"AND\t",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
// arm64:"LSR",-"AND",-"CSEL"
|
|
||||||
return v >> (s & 63)
|
return v >> (s & 63)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshMask64x64(v int64, s uint64) int64 {
|
func rshMask64x64(v int64, s uint64) int64 {
|
||||||
|
// arm64:"ASR",-"AND",-"CSEL"
|
||||||
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
||||||
// ppc64le:"ANDCC",-ORN",-"ISEL"
|
// ppc64le:"ANDCC",-ORN",-"ISEL"
|
||||||
// riscv64:"SRA",-"OR",-"SLTIU"
|
// riscv64:"SRA",-"OR",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
// arm64:"ASR",-"AND",-"CSEL"
|
|
||||||
return v >> (s & 63)
|
return v >> (s & 63)
|
||||||
}
|
}
|
||||||
|
|
||||||
func lshMask32x64(v int32, s uint64) int32 {
|
func lshMask32x64(v int32, s uint64) int32 {
|
||||||
|
// arm64:"LSL",-"AND"
|
||||||
// ppc64:"ISEL",-"ORN"
|
// ppc64:"ISEL",-"ORN"
|
||||||
// ppc64le:"ISEL",-"ORN"
|
// ppc64le:"ISEL",-"ORN"
|
||||||
// riscv64:"SLL","AND","SLTIU"
|
// riscv64:"SLL",-"AND\t",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
// arm64:"LSL",-"AND"
|
|
||||||
return v << (s & 63)
|
return v << (s & 63)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshMask32Ux64(v uint32, s uint64) uint32 {
|
func rshMask32Ux64(v uint32, s uint64) uint32 {
|
||||||
|
// arm64:"LSR",-"AND"
|
||||||
// ppc64:"ISEL",-"ORN"
|
// ppc64:"ISEL",-"ORN"
|
||||||
// ppc64le:"ISEL",-"ORN"
|
// ppc64le:"ISEL",-"ORN"
|
||||||
// riscv64:"SRL","AND","SLTIU"
|
// riscv64:"SRL",-"AND\t",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
// arm64:"LSR",-"AND"
|
|
||||||
return v >> (s & 63)
|
return v >> (s & 63)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshMask32x64(v int32, s uint64) int32 {
|
func rshMask32x64(v int32, s uint64) int32 {
|
||||||
|
// arm64:"ASR",-"AND"
|
||||||
// ppc64:"ISEL",-"ORN"
|
// ppc64:"ISEL",-"ORN"
|
||||||
// ppc64le:"ISEL",-"ORN"
|
// ppc64le:"ISEL",-"ORN"
|
||||||
// riscv64:"SRA","OR","SLTIU"
|
// riscv64:"SRA",-"OR",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
// arm64:"ASR",-"AND"
|
|
||||||
return v >> (s & 63)
|
return v >> (s & 63)
|
||||||
}
|
}
|
||||||
|
|
||||||
func lshMask64x32(v int64, s uint32) int64 {
|
func lshMask64x32(v int64, s uint32) int64 {
|
||||||
|
// arm64:"LSL",-"AND"
|
||||||
// ppc64:"ANDCC",-"ORN"
|
// ppc64:"ANDCC",-"ORN"
|
||||||
// ppc64le:"ANDCC",-"ORN"
|
// ppc64le:"ANDCC",-"ORN"
|
||||||
// riscv64:"SLL",-"AND\t",-"SLTIU"
|
// riscv64:"SLL",-"AND\t",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
// arm64:"LSL",-"AND"
|
|
||||||
return v << (s & 63)
|
return v << (s & 63)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshMask64Ux32(v uint64, s uint32) uint64 {
|
func rshMask64Ux32(v uint64, s uint32) uint64 {
|
||||||
|
// arm64:"LSR",-"AND",-"CSEL"
|
||||||
// ppc64:"ANDCC",-"ORN"
|
// ppc64:"ANDCC",-"ORN"
|
||||||
// ppc64le:"ANDCC",-"ORN"
|
// ppc64le:"ANDCC",-"ORN"
|
||||||
// riscv64:"SRL",-"AND\t",-"SLTIU"
|
// riscv64:"SRL",-"AND\t",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
// arm64:"LSR",-"AND",-"CSEL"
|
|
||||||
return v >> (s & 63)
|
return v >> (s & 63)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rshMask64x32(v int64, s uint32) int64 {
|
func rshMask64x32(v int64, s uint32) int64 {
|
||||||
|
// arm64:"ASR",-"AND",-"CSEL"
|
||||||
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
||||||
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
||||||
// riscv64:"SRA",-"OR",-"SLTIU"
|
// riscv64:"SRA",-"OR",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
// arm64:"ASR",-"AND",-"CSEL"
|
|
||||||
return v >> (s & 63)
|
return v >> (s & 63)
|
||||||
}
|
}
|
||||||
|
|
||||||
func lshMask64x32Ext(v int64, s int32) int64 {
|
func lshMask64x32Ext(v int64, s int32) int64 {
|
||||||
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
||||||
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
||||||
// riscv64:"SLL","AND","SLTIU"
|
// riscv64:"SLL",-"AND\t",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
return v << uint(s&63)
|
return v << uint(s&63)
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ func lshMask64x32Ext(v int64, s int32) int64 {
|
||||||
func rshMask64Ux32Ext(v uint64, s int32) uint64 {
|
func rshMask64Ux32Ext(v uint64, s int32) uint64 {
|
||||||
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
||||||
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
||||||
// riscv64:"SRL","AND","SLTIU"
|
// riscv64:"SRL",-"AND\t",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
return v >> uint(s&63)
|
return v >> uint(s&63)
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ func rshMask64Ux32Ext(v uint64, s int32) uint64 {
|
||||||
func rshMask64x32Ext(v int64, s int32) int64 {
|
func rshMask64x32Ext(v int64, s int32) int64 {
|
||||||
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
// ppc64:"ANDCC",-"ORN",-"ISEL"
|
||||||
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
// ppc64le:"ANDCC",-"ORN",-"ISEL"
|
||||||
// riscv64:"SRA","OR","SLTIU"
|
// riscv64:"SRA",-"OR",-"SLTIU"
|
||||||
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
// s390x:-"RISBGZ",-"AND",-"LOCGR"
|
||||||
return v >> uint(s&63)
|
return v >> uint(s&63)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue