(Rsh8x64 (Const8 [0]) _) -> (Const8 [0])
(Rsh8Ux64 (Const8 [0]) _) -> (Const8 [0])
+(IsInBounds (And32 (Const32 [c]) _) (Const32 [d])) && inBounds32(c, d) -> (ConstBool [1])
+(IsInBounds (And64 (Const64 [c]) _) (Const64 [d])) && inBounds64(c, d) -> (ConstBool [1])
(IsInBounds (Const32 [c]) (Const32 [d])) -> (ConstBool [b2i(inBounds32(c,d))])
(IsInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(inBounds64(c,d))])
+(IsSliceInBounds (And32 (Const32 [c]) _) (Const32 [d])) && sliceInBounds32(c, d) -> (ConstBool [1])
+(IsSliceInBounds (And64 (Const64 [c]) _) (Const64 [d])) && sliceInBounds64(c, d) -> (ConstBool [1])
(IsSliceInBounds (Const32 [c]) (Const32 [d])) -> (ConstBool [b2i(sliceInBounds32(c,d))])
(IsSliceInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(sliceInBounds64(c,d))])
//(Mod64 n (Const64 [1])) -> (Const64 [0])
//(Mod64u n (Const64 [1])) -> (Const64 [0])
-// Unsigned divide by power of 2. Currently handled by frontend.
-//(Div64u <t> n (Const64 [c])) && isPowerOfTwo(c) -> (Rsh64Ux64 n (Const64 <t> [log2(c)]))
-//(Mod64u <t> n (Const64 [c])) && isPowerOfTwo(c) -> (And64 n (Const64 <t> [c-1]))
+// Unsigned divide by power of 2.
+(Div64u <t> n (Const64 [c])) && isPowerOfTwo(c) -> (Rsh64Ux64 n (Const64 <t> [log2(c)]))
+(Mod64u <t> n (Const64 [c])) && isPowerOfTwo(c) -> (And64 n (Const64 <t> [c-1]))
// Signed divide by power of 2. Currently handled by frontend.
// n / c = n >> log(c) if n >= 0
func rewriteValuegeneric_OpDiv64u(v *Value, config *Config) bool {
b := v.Block
_ = b
+ // match: (Div64u <t> n (Const64 [c]))
+ // cond: isPowerOfTwo(c)
+ // result: (Rsh64Ux64 n (Const64 <t> [log2(c)]))
+ for {
+ t := v.Type
+ n := v.Args[0]
+ if v.Args[1].Op != OpConst64 {
+ break
+ }
+ c := v.Args[1].AuxInt
+ if !(isPowerOfTwo(c)) {
+ break
+ }
+ v.reset(OpRsh64Ux64)
+ v.AddArg(n)
+ v0 := b.NewValue0(v.Line, OpConst64, t)
+ v0.AuxInt = log2(c)
+ v.AddArg(v0)
+ return true
+ }
// match: (Div64u <t> x (Const64 [c]))
// cond: umagic64ok(c) && !umagic64a(c)
// result: (Rsh64Ux64 (Hmul64u <t> (Const64 <t> [umagic64m(c)]) x) (Const64 <t> [umagic64s(c)]))
func rewriteValuegeneric_OpIsInBounds(v *Value, config *Config) bool {
b := v.Block
_ = b
+ // match: (IsInBounds (And32 (Const32 [c]) _) (Const32 [d]))
+ // cond: inBounds32(c, d)
+ // result: (ConstBool [1])
+ for {
+ if v.Args[0].Op != OpAnd32 {
+ break
+ }
+ if v.Args[0].Args[0].Op != OpConst32 {
+ break
+ }
+ c := v.Args[0].Args[0].AuxInt
+ if v.Args[1].Op != OpConst32 {
+ break
+ }
+ d := v.Args[1].AuxInt
+ if !(inBounds32(c, d)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = 1
+ return true
+ }
+ // match: (IsInBounds (And64 (Const64 [c]) _) (Const64 [d]))
+ // cond: inBounds64(c, d)
+ // result: (ConstBool [1])
+ for {
+ if v.Args[0].Op != OpAnd64 {
+ break
+ }
+ if v.Args[0].Args[0].Op != OpConst64 {
+ break
+ }
+ c := v.Args[0].Args[0].AuxInt
+ if v.Args[1].Op != OpConst64 {
+ break
+ }
+ d := v.Args[1].AuxInt
+ if !(inBounds64(c, d)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = 1
+ return true
+ }
// match: (IsInBounds (Const32 [c]) (Const32 [d]))
// cond:
// result: (ConstBool [b2i(inBounds32(c,d))])
func rewriteValuegeneric_OpIsSliceInBounds(v *Value, config *Config) bool {
b := v.Block
_ = b
+ // match: (IsSliceInBounds (And32 (Const32 [c]) _) (Const32 [d]))
+ // cond: sliceInBounds32(c, d)
+ // result: (ConstBool [1])
+ for {
+ if v.Args[0].Op != OpAnd32 {
+ break
+ }
+ if v.Args[0].Args[0].Op != OpConst32 {
+ break
+ }
+ c := v.Args[0].Args[0].AuxInt
+ if v.Args[1].Op != OpConst32 {
+ break
+ }
+ d := v.Args[1].AuxInt
+ if !(sliceInBounds32(c, d)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = 1
+ return true
+ }
+ // match: (IsSliceInBounds (And64 (Const64 [c]) _) (Const64 [d]))
+ // cond: sliceInBounds64(c, d)
+ // result: (ConstBool [1])
+ for {
+ if v.Args[0].Op != OpAnd64 {
+ break
+ }
+ if v.Args[0].Args[0].Op != OpConst64 {
+ break
+ }
+ c := v.Args[0].Args[0].AuxInt
+ if v.Args[1].Op != OpConst64 {
+ break
+ }
+ d := v.Args[1].AuxInt
+ if !(sliceInBounds64(c, d)) {
+ break
+ }
+ v.reset(OpConstBool)
+ v.AuxInt = 1
+ return true
+ }
// match: (IsSliceInBounds (Const32 [c]) (Const32 [d]))
// cond:
// result: (ConstBool [b2i(sliceInBounds32(c,d))])
func rewriteValuegeneric_OpMod64u(v *Value, config *Config) bool {
b := v.Block
_ = b
+ // match: (Mod64u <t> n (Const64 [c]))
+ // cond: isPowerOfTwo(c)
+ // result: (And64 n (Const64 <t> [c-1]))
+ for {
+ t := v.Type
+ n := v.Args[0]
+ if v.Args[1].Op != OpConst64 {
+ break
+ }
+ c := v.Args[1].AuxInt
+ if !(isPowerOfTwo(c)) {
+ break
+ }
+ v.reset(OpAnd64)
+ v.AddArg(n)
+ v0 := b.NewValue0(v.Line, OpConst64, t)
+ v0.AuxInt = c - 1
+ v.AddArg(v0)
+ return true
+ }
// match: (Mod64u <t> x (Const64 [c]))
// cond: umagic64ok(c)
// result: (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))