mirror of
https://github.com/golang/go
synced 2024-11-18 00:14:47 -07:00
cmd/compile: use right shifts to eliminate bounds checks
These rules trigger a few times during make.bash. When we eliminate boundedness checks from walk.go we'll rely on them more heavily. Updates #19692 Change-Id: I268c36ae2f1401c68dd685b15f2d30f5d6971176 Reviewed-on: https://go-review.googlesource.com/43775 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
2fe53d8d55
commit
561b147e4b
@ -208,6 +208,17 @@
|
|||||||
// (Mod64u x y) is always between 0 (inclusive) and y (exclusive).
|
// (Mod64u x y) is always between 0 (inclusive) and y (exclusive).
|
||||||
(IsInBounds (Mod32u _ y) y) -> (ConstBool [1])
|
(IsInBounds (Mod32u _ y) y) -> (ConstBool [1])
|
||||||
(IsInBounds (Mod64u _ y) y) -> (ConstBool [1])
|
(IsInBounds (Mod64u _ y) y) -> (ConstBool [1])
|
||||||
|
// Right shifting a unsigned number limits its value.
|
||||||
|
(IsInBounds (ZeroExt8to64 (Rsh8Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 8 && 1<<uint( 8-c)-1 < d -> (ConstBool [1])
|
||||||
|
(IsInBounds (ZeroExt8to32 (Rsh8Ux64 _ (Const64 [c]))) (Const32 [d])) && 0 < c && c < 8 && 1<<uint( 8-c)-1 < d -> (ConstBool [1])
|
||||||
|
(IsInBounds (ZeroExt8to16 (Rsh8Ux64 _ (Const64 [c]))) (Const16 [d])) && 0 < c && c < 8 && 1<<uint( 8-c)-1 < d -> (ConstBool [1])
|
||||||
|
(IsInBounds (Rsh8Ux64 _ (Const64 [c])) (Const64 [d])) && 0 < c && c < 8 && 1<<uint( 8-c)-1 < d -> (ConstBool [1])
|
||||||
|
(IsInBounds (ZeroExt16to64 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d -> (ConstBool [1])
|
||||||
|
(IsInBounds (ZeroExt16to32 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d -> (ConstBool [1])
|
||||||
|
(IsInBounds (Rsh16Ux64 _ (Const64 [c])) (Const64 [d])) && 0 < c && c < 16 && 1<<uint(16-c)-1 < d -> (ConstBool [1])
|
||||||
|
(IsInBounds (ZeroExt32to64 (Rsh32Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 32 && 1<<uint(32-c)-1 < d -> (ConstBool [1])
|
||||||
|
(IsInBounds (Rsh32Ux64 _ (Const64 [c])) (Const64 [d])) && 0 < c && c < 32 && 1<<uint(32-c)-1 < d -> (ConstBool [1])
|
||||||
|
(IsInBounds (Rsh64Ux64 _ (Const64 [c])) (Const64 [d])) && 0 < c && c < 64 && 1<<uint(64-c)-1 < d -> (ConstBool [1])
|
||||||
|
|
||||||
(IsSliceInBounds x x) -> (ConstBool [1])
|
(IsSliceInBounds x x) -> (ConstBool [1])
|
||||||
(IsSliceInBounds (And32 (Const32 [c]) _) (Const32 [d])) && 0 <= c && c <= d -> (ConstBool [1])
|
(IsSliceInBounds (And32 (Const32 [c]) _) (Const32 [d])) && 0 <= c && c <= d -> (ConstBool [1])
|
||||||
|
@ -134,7 +134,7 @@ func rewriteValuegeneric(v *Value) bool {
|
|||||||
case OpInterCall:
|
case OpInterCall:
|
||||||
return rewriteValuegeneric_OpInterCall_0(v)
|
return rewriteValuegeneric_OpInterCall_0(v)
|
||||||
case OpIsInBounds:
|
case OpIsInBounds:
|
||||||
return rewriteValuegeneric_OpIsInBounds_0(v) || rewriteValuegeneric_OpIsInBounds_10(v) || rewriteValuegeneric_OpIsInBounds_20(v)
|
return rewriteValuegeneric_OpIsInBounds_0(v) || rewriteValuegeneric_OpIsInBounds_10(v) || rewriteValuegeneric_OpIsInBounds_20(v) || rewriteValuegeneric_OpIsInBounds_30(v)
|
||||||
case OpIsNonNil:
|
case OpIsNonNil:
|
||||||
return rewriteValuegeneric_OpIsNonNil_0(v)
|
return rewriteValuegeneric_OpIsNonNil_0(v)
|
||||||
case OpIsSliceInBounds:
|
case OpIsSliceInBounds:
|
||||||
@ -9754,6 +9754,303 @@ func rewriteValuegeneric_OpIsInBounds_20(v *Value) bool {
|
|||||||
v.AuxInt = 1
|
v.AuxInt = 1
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// match: (IsInBounds (ZeroExt8to64 (Rsh8Ux64 _ (Const64 [c]))) (Const64 [d]))
|
||||||
|
// cond: 0 < c && c < 8 && 1<<uint( 8-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpZeroExt8to64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpRsh8Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0_0.Args[1]
|
||||||
|
v_0_0_1 := v_0_0.Args[1]
|
||||||
|
if v_0_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 8 && 1<<uint(8-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func rewriteValuegeneric_OpIsInBounds_30(v *Value) bool {
|
||||||
|
// match: (IsInBounds (ZeroExt8to32 (Rsh8Ux64 _ (Const64 [c]))) (Const32 [d]))
|
||||||
|
// cond: 0 < c && c < 8 && 1<<uint( 8-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpZeroExt8to32 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpRsh8Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0_0.Args[1]
|
||||||
|
v_0_0_1 := v_0_0.Args[1]
|
||||||
|
if v_0_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst32 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 8 && 1<<uint(8-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (IsInBounds (ZeroExt8to16 (Rsh8Ux64 _ (Const64 [c]))) (Const16 [d]))
|
||||||
|
// cond: 0 < c && c < 8 && 1<<uint( 8-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpZeroExt8to16 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpRsh8Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0_0.Args[1]
|
||||||
|
v_0_0_1 := v_0_0.Args[1]
|
||||||
|
if v_0_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst16 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 8 && 1<<uint(8-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (IsInBounds (Rsh8Ux64 _ (Const64 [c])) (Const64 [d]))
|
||||||
|
// cond: 0 < c && c < 8 && 1<<uint( 8-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpRsh8Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
v_0_1 := v_0.Args[1]
|
||||||
|
if v_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 8 && 1<<uint(8-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (IsInBounds (ZeroExt16to64 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d]))
|
||||||
|
// cond: 0 < c && c < 16 && 1<<uint(16-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpZeroExt16to64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpRsh16Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0_0.Args[1]
|
||||||
|
v_0_0_1 := v_0_0.Args[1]
|
||||||
|
if v_0_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 16 && 1<<uint(16-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (IsInBounds (ZeroExt16to32 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d]))
|
||||||
|
// cond: 0 < c && c < 16 && 1<<uint(16-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpZeroExt16to32 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpRsh16Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0_0.Args[1]
|
||||||
|
v_0_0_1 := v_0_0.Args[1]
|
||||||
|
if v_0_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 16 && 1<<uint(16-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (IsInBounds (Rsh16Ux64 _ (Const64 [c])) (Const64 [d]))
|
||||||
|
// cond: 0 < c && c < 16 && 1<<uint(16-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpRsh16Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
v_0_1 := v_0.Args[1]
|
||||||
|
if v_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 16 && 1<<uint(16-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (IsInBounds (ZeroExt32to64 (Rsh32Ux64 _ (Const64 [c]))) (Const64 [d]))
|
||||||
|
// cond: 0 < c && c < 32 && 1<<uint(32-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpZeroExt32to64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v_0_0 := v_0.Args[0]
|
||||||
|
if v_0_0.Op != OpRsh32Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0_0.Args[1]
|
||||||
|
v_0_0_1 := v_0_0.Args[1]
|
||||||
|
if v_0_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 32 && 1<<uint(32-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (IsInBounds (Rsh32Ux64 _ (Const64 [c])) (Const64 [d]))
|
||||||
|
// cond: 0 < c && c < 32 && 1<<uint(32-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpRsh32Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
v_0_1 := v_0.Args[1]
|
||||||
|
if v_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 32 && 1<<uint(32-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// match: (IsInBounds (Rsh64Ux64 _ (Const64 [c])) (Const64 [d]))
|
||||||
|
// cond: 0 < c && c < 64 && 1<<uint(64-c)-1 < d
|
||||||
|
// result: (ConstBool [1])
|
||||||
|
for {
|
||||||
|
_ = v.Args[1]
|
||||||
|
v_0 := v.Args[0]
|
||||||
|
if v_0.Op != OpRsh64Ux64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = v_0.Args[1]
|
||||||
|
v_0_1 := v_0.Args[1]
|
||||||
|
if v_0_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c := v_0_1.AuxInt
|
||||||
|
v_1 := v.Args[1]
|
||||||
|
if v_1.Op != OpConst64 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
d := v_1.AuxInt
|
||||||
|
if !(0 < c && c < 64 && 1<<uint(64-c)-1 < d) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
v.reset(OpConstBool)
|
||||||
|
v.AuxInt = 1
|
||||||
|
return true
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
func rewriteValuegeneric_OpIsNonNil_0(v *Value) bool {
|
func rewriteValuegeneric_OpIsNonNil_0(v *Value) bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user