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>
// 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.
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 {
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)
testRegallocCVSpill(t)
testSubqToNegq(t)
testBitwiseLogic(t)
+ testSetIfLessThan(t)
testOcom(t)
testLrot(t)
testShiftCX(t)