cmd/compile/internal: remove incorrect riscv64 SLTI rule

The rule

(SLTI  [x] (ORI  [y] _)) && y >= 0 && int64(y) >= int64(x) => (MOVDconst [0])

is incorrect as it only generates correct code if the unknown value
being compared is >= 0. If the unknown value is < 0 the rule will
incorrectly produce a constant value of 0, whereas the code optimized
away by the rule would have produced a value of 1.

A new test that causes the faulty rule to generate incorrect code
is also added to ensure that the error does not return.

Change-Id: I69224e0776596f1b9538acf9dacf9009d305f966
Reviewed-on: https://go-review.googlesource.com/c/go/+/720220
Reviewed-by: Meng Zhuo <mengzhuo1203@gmail.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Joel Sing <joel@sing.id.au>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Mark Ryan 2025-11-13 12:28:29 +01:00 committed by Gopher Robot
parent 2cdcc4150b
commit a0e738c657
3 changed files with 14 additions and 17 deletions

View file

@ -792,7 +792,6 @@
// 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.

View file

@ -7362,22 +7362,6 @@ func rewriteValueRISCV64_OpRISCV64SLTI(v *Value) bool {
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 {

View file

@ -444,6 +444,19 @@ func testBitwiseRshU_ssa(a uint32, b, c uint32) uint32 {
return a >> b >> c
}
//go:noinline
func orLt_ssa(x int) bool {
y := x - x
return (x | 2) < y
}
// test riscv64 SLTI rules
func testSetIfLessThan(t *testing.T) {
if want, got := true, orLt_ssa(-7); got != want {
t.Errorf("orLt_ssa(-7) = %t want %t", got, want)
}
}
//go:noinline
func testShiftCX_ssa() int {
v1 := uint8(3)
@ -977,6 +990,7 @@ func TestArithmetic(t *testing.T) {
testRegallocCVSpill(t)
testSubqToNegq(t)
testBitwiseLogic(t)
testSetIfLessThan(t)
testOcom(t)
testLrot(t)
testShiftCX(t)