From 561b147e4be4732c85f2725c7e12ab0a3577c962 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Fri, 19 May 2017 15:10:10 -0700 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- .../compile/internal/ssa/gen/generic.rules | 11 + .../compile/internal/ssa/rewritegeneric.go | 299 +++++++++++++++++- 2 files changed, 309 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index b8d7381420..bb4a83738f 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -208,6 +208,17 @@ // (Mod64u x y) is always between 0 (inclusive) and y (exclusive). (IsInBounds (Mod32u _ 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< (ConstBool [1]) +(IsInBounds (ZeroExt8to32 (Rsh8Ux64 _ (Const64 [c]))) (Const32 [d])) && 0 < c && c < 8 && 1< (ConstBool [1]) +(IsInBounds (ZeroExt8to16 (Rsh8Ux64 _ (Const64 [c]))) (Const16 [d])) && 0 < c && c < 8 && 1< (ConstBool [1]) +(IsInBounds (Rsh8Ux64 _ (Const64 [c])) (Const64 [d])) && 0 < c && c < 8 && 1< (ConstBool [1]) +(IsInBounds (ZeroExt16to64 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1< (ConstBool [1]) +(IsInBounds (ZeroExt16to32 (Rsh16Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 16 && 1< (ConstBool [1]) +(IsInBounds (Rsh16Ux64 _ (Const64 [c])) (Const64 [d])) && 0 < c && c < 16 && 1< (ConstBool [1]) +(IsInBounds (ZeroExt32to64 (Rsh32Ux64 _ (Const64 [c]))) (Const64 [d])) && 0 < c && c < 32 && 1< (ConstBool [1]) +(IsInBounds (Rsh32Ux64 _ (Const64 [c])) (Const64 [d])) && 0 < c && c < 32 && 1< (ConstBool [1]) +(IsInBounds (Rsh64Ux64 _ (Const64 [c])) (Const64 [d])) && 0 < c && c < 64 && 1< (ConstBool [1]) (IsSliceInBounds x x) -> (ConstBool [1]) (IsSliceInBounds (And32 (Const32 [c]) _) (Const32 [d])) && 0 <= c && c <= d -> (ConstBool [1]) diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 95b2c62f07..89ef75e136 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -134,7 +134,7 @@ func rewriteValuegeneric(v *Value) bool { case OpInterCall: return rewriteValuegeneric_OpInterCall_0(v) 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: return rewriteValuegeneric_OpIsNonNil_0(v) case OpIsSliceInBounds: @@ -9754,6 +9754,303 @@ func rewriteValuegeneric_OpIsInBounds_20(v *Value) bool { v.AuxInt = 1 return true } + // match: (IsInBounds (ZeroExt8to64 (Rsh8Ux64 _ (Const64 [c]))) (Const64 [d])) + // cond: 0 < c && c < 8 && 1<