cmd/compile: propagate unsigned relations for Rsh if arguments are positive

Updates #76332

Change-Id: Ifaa4d12897138d88d56b9d4e530c53dcee70bd58
Reviewed-on: https://go-review.googlesource.com/c/go/+/721205
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Jorropo <jorropo.pgm@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Mark Freeman <markfreeman@google.com>
Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
Jorropo 2025-11-18 01:33:40 +01:00 committed by Gopher Robot
parent d474f1fd21
commit 3820f94c1d
2 changed files with 27 additions and 5 deletions

View file

@ -2474,9 +2474,18 @@ func addLocalFacts(ft *factsTable, b *Block) {
//ft.update(b, v, v.Args[0], unsigned, gt|eq) //ft.update(b, v, v.Args[0], unsigned, gt|eq)
//ft.update(b, v, v.Args[1], unsigned, gt|eq) //ft.update(b, v, v.Args[1], unsigned, gt|eq)
case OpDiv64, OpDiv32, OpDiv16, OpDiv8: case OpDiv64, OpDiv32, OpDiv16, OpDiv8:
if ft.isNonNegative(v.Args[0]) && ft.isNonNegative(v.Args[1]) { if !ft.isNonNegative(v.Args[1]) {
ft.update(b, v, v.Args[0], unsigned, lt|eq) break
} }
fallthrough
case OpRsh8x64, OpRsh8x32, OpRsh8x16, OpRsh8x8,
OpRsh16x64, OpRsh16x32, OpRsh16x16, OpRsh16x8,
OpRsh32x64, OpRsh32x32, OpRsh32x16, OpRsh32x8,
OpRsh64x64, OpRsh64x32, OpRsh64x16, OpRsh64x8:
if !ft.isNonNegative(v.Args[0]) {
break
}
fallthrough
case OpDiv64u, OpDiv32u, OpDiv16u, OpDiv8u, case OpDiv64u, OpDiv32u, OpDiv16u, OpDiv8u,
OpRsh8Ux64, OpRsh8Ux32, OpRsh8Ux16, OpRsh8Ux8, OpRsh8Ux64, OpRsh8Ux32, OpRsh8Ux16, OpRsh8Ux8,
OpRsh16Ux64, OpRsh16Ux32, OpRsh16Ux16, OpRsh16Ux8, OpRsh16Ux64, OpRsh16Ux32, OpRsh16Ux16, OpRsh16Ux8,
@ -2491,12 +2500,17 @@ func addLocalFacts(ft *factsTable, b *Block) {
zl := ft.limits[z.ID] zl := ft.limits[z.ID]
var uminDivisor uint64 var uminDivisor uint64
switch v.Op { switch v.Op {
case OpDiv64u, OpDiv32u, OpDiv16u, OpDiv8u: case OpDiv64u, OpDiv32u, OpDiv16u, OpDiv8u,
OpDiv64, OpDiv32, OpDiv16, OpDiv8:
uminDivisor = zl.umin uminDivisor = zl.umin
case OpRsh8Ux64, OpRsh8Ux32, OpRsh8Ux16, OpRsh8Ux8, case OpRsh8Ux64, OpRsh8Ux32, OpRsh8Ux16, OpRsh8Ux8,
OpRsh16Ux64, OpRsh16Ux32, OpRsh16Ux16, OpRsh16Ux8, OpRsh16Ux64, OpRsh16Ux32, OpRsh16Ux16, OpRsh16Ux8,
OpRsh32Ux64, OpRsh32Ux32, OpRsh32Ux16, OpRsh32Ux8, OpRsh32Ux64, OpRsh32Ux32, OpRsh32Ux16, OpRsh32Ux8,
OpRsh64Ux64, OpRsh64Ux32, OpRsh64Ux16, OpRsh64Ux8: OpRsh64Ux64, OpRsh64Ux32, OpRsh64Ux16, OpRsh64Ux8,
OpRsh8x64, OpRsh8x32, OpRsh8x16, OpRsh8x8,
OpRsh16x64, OpRsh16x32, OpRsh16x16, OpRsh16x8,
OpRsh32x64, OpRsh32x32, OpRsh32x16, OpRsh32x8,
OpRsh64x64, OpRsh64x32, OpRsh64x16, OpRsh64x8:
uminDivisor = 1 << zl.umin uminDivisor = 1 << zl.umin
default: default:
panic("unreachable") panic("unreachable")

View file

@ -253,9 +253,10 @@ func f9(a, b bool) int {
func f10(a string) int { func f10(a string) int {
n := len(a) n := len(a)
b := a[:n>>1] // ERROR "Proved IsSliceInBounds$"
// We optimize comparisons with small constant strings (see cmd/compile/internal/gc/walk.go), // We optimize comparisons with small constant strings (see cmd/compile/internal/gc/walk.go),
// so this string literal must be long. // so this string literal must be long.
if a[:n>>1] == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" { if b == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" {
return 0 return 0
} }
return 1 return 1
@ -1084,6 +1085,13 @@ func issue57077(s []int) (left, right []int) {
return return
} }
func issue76332(s []int) (left, right []int) {
middle := len(s) >> 1
left = s[:middle] // ERROR "Proved IsSliceInBounds$"
right = s[middle:] // ERROR "Proved IsSliceInBounds$"
return
}
func issue51622(b []byte) int { func issue51622(b []byte) int {
if len(b) >= 3 && b[len(b)-3] == '#' { // ERROR "Proved IsInBounds$" if len(b) >= 3 && b[len(b)-3] == '#' { // ERROR "Proved IsInBounds$"
return len(b) return len(b)