]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal: remove incorrect riscv64 SLTI rule
authorMark Ryan <markdryan@rivosinc.com>
Thu, 13 Nov 2025 11:28:29 +0000 (12:28 +0100)
committerGopher Robot <gobot@golang.org>
Fri, 14 Nov 2025 19:01:26 +0000 (11:01 -0800)
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>
src/cmd/compile/internal/ssa/_gen/RISCV64.rules
src/cmd/compile/internal/ssa/rewriteRISCV64.go
src/cmd/compile/internal/test/testdata/arith_test.go

index 6166bd5584de13433ae57830a6facbeef1298a80..13a8cab3b52abc45f6316fefeded3570493621f8 100644 (file)
 // 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.
index 24fef3fe724eb31bfb8da4310d2d085463b6356d..284d88967ba2d2f927dfe1dad39c90a68926f006 100644 (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 {
index 8984cd3e2685581cd99e0f0d763fa8ff770eed48..34ac73c068dc6cc62102b6c9b3e722ec6880a390 100644 (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)