Skip to content

Commit ec92bc6

Browse files
Jorropogopherbot
authored andcommitted
cmd/compile: rewrite Rsh to RshU if arguments are proved positive
Fixes #76332 Change-Id: I9044025d5dc599531c7f88ed2870bcf3d8b0acbd Reviewed-on: https://go-review.googlesource.com/c/go/+/721206 Reviewed-by: Mark Freeman <[email protected]> Reviewed-by: Keith Randall <[email protected]> Auto-Submit: Jorropo <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 3820f94 commit ec92bc6

File tree

3 files changed

+43
-20
lines changed

3 files changed

+43
-20
lines changed

src/cmd/compile/internal/ssa/prove.go

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2664,14 +2664,30 @@ var mostNegativeDividend = map[Op]int64{
26642664
OpMod64: -1 << 63,
26652665
}
26662666
var unsignedOp = map[Op]Op{
2667-
OpDiv8: OpDiv8u,
2668-
OpDiv16: OpDiv16u,
2669-
OpDiv32: OpDiv32u,
2670-
OpDiv64: OpDiv64u,
2671-
OpMod8: OpMod8u,
2672-
OpMod16: OpMod16u,
2673-
OpMod32: OpMod32u,
2674-
OpMod64: OpMod64u,
2667+
OpDiv8: OpDiv8u,
2668+
OpDiv16: OpDiv16u,
2669+
OpDiv32: OpDiv32u,
2670+
OpDiv64: OpDiv64u,
2671+
OpMod8: OpMod8u,
2672+
OpMod16: OpMod16u,
2673+
OpMod32: OpMod32u,
2674+
OpMod64: OpMod64u,
2675+
OpRsh8x8: OpRsh8Ux8,
2676+
OpRsh8x16: OpRsh8Ux16,
2677+
OpRsh8x32: OpRsh8Ux32,
2678+
OpRsh8x64: OpRsh8Ux64,
2679+
OpRsh16x8: OpRsh16Ux8,
2680+
OpRsh16x16: OpRsh16Ux16,
2681+
OpRsh16x32: OpRsh16Ux32,
2682+
OpRsh16x64: OpRsh16Ux64,
2683+
OpRsh32x8: OpRsh32Ux8,
2684+
OpRsh32x16: OpRsh32Ux16,
2685+
OpRsh32x32: OpRsh32Ux32,
2686+
OpRsh32x64: OpRsh32Ux64,
2687+
OpRsh64x8: OpRsh64Ux8,
2688+
OpRsh64x16: OpRsh64Ux16,
2689+
OpRsh64x32: OpRsh64Ux32,
2690+
OpRsh64x64: OpRsh64Ux64,
26752691
}
26762692

26772693
var bytesizeToConst = [...]Op{
@@ -2758,8 +2774,15 @@ func simplifyBlock(sdom SparseTree, ft *factsTable, b *Block) {
27582774
case OpRsh8x8, OpRsh8x16, OpRsh8x32, OpRsh8x64,
27592775
OpRsh16x8, OpRsh16x16, OpRsh16x32, OpRsh16x64,
27602776
OpRsh32x8, OpRsh32x16, OpRsh32x32, OpRsh32x64,
2761-
OpRsh64x8, OpRsh64x16, OpRsh64x32, OpRsh64x64,
2762-
OpLsh8x8, OpLsh8x16, OpLsh8x32, OpLsh8x64,
2777+
OpRsh64x8, OpRsh64x16, OpRsh64x32, OpRsh64x64:
2778+
if ft.isNonNegative(v.Args[0]) {
2779+
if b.Func.pass.debug > 0 {
2780+
b.Func.Warnl(v.Pos, "Proved %v is unsigned", v.Op)
2781+
}
2782+
v.Op = unsignedOp[v.Op]
2783+
}
2784+
fallthrough
2785+
case OpLsh8x8, OpLsh8x16, OpLsh8x32, OpLsh8x64,
27632786
OpLsh16x8, OpLsh16x16, OpLsh16x32, OpLsh16x64,
27642787
OpLsh32x8, OpLsh32x16, OpLsh32x32, OpLsh32x64,
27652788
OpLsh64x8, OpLsh64x16, OpLsh64x32, OpLsh64x64,

test/prove.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ func f9(a, b bool) int {
253253

254254
func f10(a string) int {
255255
n := len(a)
256-
b := a[:n>>1] // ERROR "Proved IsSliceInBounds$"
256+
b := a[:n>>1] // ERROR "(Proved IsSliceInBounds|Proved Rsh64x64 is unsigned)$"
257257
// We optimize comparisons with small constant strings (see cmd/compile/internal/gc/walk.go),
258258
// so this string literal must be long.
259259
if b == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" {
@@ -1086,7 +1086,7 @@ func issue57077(s []int) (left, right []int) {
10861086
}
10871087

10881088
func issue76332(s []int) (left, right []int) {
1089-
middle := len(s) >> 1
1089+
middle := len(s) >> 1 // ERROR "Proved Rsh64x64 is unsigned$"
10901090
left = s[:middle] // ERROR "Proved IsSliceInBounds$"
10911091
right = s[middle:] // ERROR "Proved IsSliceInBounds$"
10921092
return
@@ -2564,7 +2564,7 @@ func rightshift(v *[256]int) int {
25642564
}
25652565
}
25662566
for i := range 1024 { // ERROR "Induction"
2567-
if v[i>>2] == 0 { // ERROR "Proved IsInBounds"
2567+
if v[i>>2] == 0 { // ERROR "(Proved IsInBounds|Proved Rsh64x64 is unsigned)"
25682568
return i
25692569
}
25702570
}

test/prove_constant_folding.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ func f0u(x uint) int {
3030
}
3131

3232
if x < 1000 {
33-
return int(x)>>31 // ERROR "Proved.+is constant 0$"
33+
return int(x) >> 31 // ERROR "(Proved.+is constant 0|Proved Rsh[0-9]+x[0-9]+ is unsigned)$"
3434
}
3535
if x := int32(x); x < -1000 {
36-
return int(x>>31) // ERROR "Proved.+is constant -1$"
36+
return int(x >> 31) // ERROR "Proved.+is constant -1$"
3737
}
3838

3939
return int(x) + 1
@@ -45,35 +45,35 @@ func sh64(n int64) int64 {
4545
if n < 0 {
4646
return n
4747
}
48-
return n >> 63 // ERROR "Proved .+ is constant 0$"
48+
return n >> 63 // ERROR "(Proved .+ is constant 0|Proved Rsh[0-9]+x[0-9]+ is unsigned)$"
4949
}
5050

5151
func sh32(n int32) int32 {
5252
if n < 0 {
5353
return n
5454
}
55-
return n >> 31 // ERROR "Proved .+ is constant 0$"
55+
return n >> 31 // ERROR "(Proved .+ is constant 0|Proved Rsh[0-9]+x[0-9]+ is unsigned)$"
5656
}
5757

5858
func sh32x64(n int32) int32 {
5959
if n < 0 {
6060
return n
6161
}
62-
return n >> uint64(31) // ERROR "Proved .+ is constant 0$"
62+
return n >> uint64(31) // ERROR "(Proved .+ is constant 0|Proved Rsh[0-9]+x[0-9]+ is unsigned)$"
6363
}
6464

6565
func sh32x64n(n int32) int32 {
6666
if n >= 0 {
6767
return 0
6868
}
69-
return n >> 31// ERROR "Proved .+ is constant -1$"
69+
return n >> 31 // ERROR "Proved .+ is constant -1$"
7070
}
7171

7272
func sh16(n int16) int16 {
7373
if n < 0 {
7474
return n
7575
}
76-
return n >> 15 // ERROR "Proved .+ is constant 0$"
76+
return n >> 15 // ERROR "(Proved .+ is constant 0|Proved Rsh[0-9]+x[0-9]+ is unsigned)$"
7777
}
7878

7979
func sh64noopt(n int64) int64 {

0 commit comments

Comments
 (0)