mirror of
https://github.com/golang/go
synced 2024-11-12 06:30:21 -07:00
cmd/compile: constant fold more of IsInBounds and IsSliceInBounds
Fixes #14721 Change-Id: Id1d5a819e5c242b91a37c4e464ed3f00c691aff5 Reviewed-on: https://go-review.googlesource.com/20482 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Alexandru Moșoi <alexandru@mosoi.ro> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
b594b8b039
commit
bbd3ffbd83
@ -77,8 +77,12 @@
|
|||||||
(Rsh8x64 (Const8 [0]) _) -> (Const8 [0])
|
(Rsh8x64 (Const8 [0]) _) -> (Const8 [0])
|
||||||
(Rsh8Ux64 (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 (Const32 [c]) (Const32 [d])) -> (ConstBool [b2i(inBounds32(c,d))])
|
||||||
(IsInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(inBounds64(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 (Const32 [c]) (Const32 [d])) -> (ConstBool [b2i(sliceInBounds32(c,d))])
|
||||||
(IsSliceInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(sliceInBounds64(c,d))])
|
(IsSliceInBounds (Const64 [c]) (Const64 [d])) -> (ConstBool [b2i(sliceInBounds64(c,d))])
|
||||||
|
|
||||||
@ -664,9 +668,9 @@
|
|||||||
//(Mod64 n (Const64 [1])) -> (Const64 [0])
|
//(Mod64 n (Const64 [1])) -> (Const64 [0])
|
||||||
//(Mod64u n (Const64 [1])) -> (Const64 [0])
|
//(Mod64u n (Const64 [1])) -> (Const64 [0])
|
||||||
|
|
||||||
// Unsigned divide by power of 2. Currently handled by frontend.
|
// Unsigned divide by power of 2.
|
||||||
//(Div64u <t> n (Const64 [c])) && isPowerOfTwo(c) -> (Rsh64Ux64 n (Const64 <t> [log2(c)]))
|
(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]))
|
(Mod64u <t> n (Const64 [c])) && isPowerOfTwo(c) -> (And64 n (Const64 <t> [c-1]))
|
||||||
|
|
||||||
// Signed divide by power of 2. Currently handled by frontend.
|
// Signed divide by power of 2. Currently handled by frontend.
|
||||||
// n / c = n >> log(c) if n >= 0
|
// n / c = n >> log(c) if n >= 0
|
||||||
|
@ -1577,6 +1577,26 @@ func rewriteValuegeneric_OpDiv64(v *Value, config *Config) bool {
|
|||||||
func rewriteValuegeneric_OpDiv64u(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpDiv64u(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = 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]))
|
// match: (Div64u <t> x (Const64 [c]))
|
||||||
// cond: umagic64ok(c) && !umagic64a(c)
|
// cond: umagic64ok(c) && !umagic64a(c)
|
||||||
// result: (Rsh64Ux64 (Hmul64u <t> (Const64 <t> [umagic64m(c)]) x) (Const64 <t> [umagic64s(c)]))
|
// result: (Rsh64Ux64 (Hmul64u <t> (Const64 <t> [umagic64m(c)]) x) (Const64 <t> [umagic64s(c)]))
|
||||||
@ -2467,6 +2487,50 @@ func rewriteValuegeneric_OpITab(v *Value, config *Config) bool {
|
|||||||
func rewriteValuegeneric_OpIsInBounds(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpIsInBounds(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = 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]))
|
// match: (IsInBounds (Const32 [c]) (Const32 [d]))
|
||||||
// cond:
|
// cond:
|
||||||
// result: (ConstBool [b2i(inBounds32(c,d))])
|
// result: (ConstBool [b2i(inBounds32(c,d))])
|
||||||
@ -2504,6 +2568,50 @@ func rewriteValuegeneric_OpIsInBounds(v *Value, config *Config) bool {
|
|||||||
func rewriteValuegeneric_OpIsSliceInBounds(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpIsSliceInBounds(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = 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]))
|
// match: (IsSliceInBounds (Const32 [c]) (Const32 [d]))
|
||||||
// cond:
|
// cond:
|
||||||
// result: (ConstBool [b2i(sliceInBounds32(c,d))])
|
// result: (ConstBool [b2i(sliceInBounds32(c,d))])
|
||||||
@ -3875,6 +3983,26 @@ func rewriteValuegeneric_OpMod64(v *Value, config *Config) bool {
|
|||||||
func rewriteValuegeneric_OpMod64u(v *Value, config *Config) bool {
|
func rewriteValuegeneric_OpMod64u(v *Value, config *Config) bool {
|
||||||
b := v.Block
|
b := v.Block
|
||||||
_ = b
|
_ = 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]))
|
// match: (Mod64u <t> x (Const64 [c]))
|
||||||
// cond: umagic64ok(c)
|
// cond: umagic64ok(c)
|
||||||
// result: (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))
|
// result: (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c])))
|
||||||
|
Loading…
Reference in New Issue
Block a user