Commit 6a24b2d0 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: add boolean simplification rules

These collectively fire a few hundred times during make.bash,
mostly rewriting XOR SETNE -> SETEQ.

Fixes #17905.

Change-Id: Ic5eb241ee93ed67099da3de11f59e4df9fab64a3
Reviewed-on: https://go-review.googlesource.com/42491
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
parent 9aeced65
...@@ -544,6 +544,18 @@ ...@@ -544,6 +544,18 @@
(SETNE (TESTQ (MOVQconst [c]) x)) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETB (BTQconst [log2(c)] x)) (SETNE (TESTQ (MOVQconst [c]) x)) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETB (BTQconst [log2(c)] x))
(SETEQ (TESTQ (MOVQconst [c]) x)) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETAE (BTQconst [log2(c)] x)) (SETEQ (TESTQ (MOVQconst [c]) x)) && isPowerOfTwo(c) && log2(c) < 64 && !config.nacl -> (SETAE (BTQconst [log2(c)] x))
// Fold boolean negation into SETcc.
(XORLconst [1] (SETNE x)) -> (SETEQ x)
(XORLconst [1] (SETEQ x)) -> (SETNE x)
(XORLconst [1] (SETL x)) -> (SETGE x)
(XORLconst [1] (SETGE x)) -> (SETL x)
(XORLconst [1] (SETLE x)) -> (SETG x)
(XORLconst [1] (SETG x)) -> (SETLE x)
(XORLconst [1] (SETB x)) -> (SETAE x)
(XORLconst [1] (SETAE x)) -> (SETB x)
(XORLconst [1] (SETBE x)) -> (SETA x)
(XORLconst [1] (SETA x)) -> (SETBE x)
// Convert BTQconst to BTLconst if possible. It has a shorter encoding. // Convert BTQconst to BTLconst if possible. It has a shorter encoding.
(BTQconst [c] x) && c < 32 -> (BTLconst [c] x) (BTQconst [c] x) && c < 32 -> (BTLconst [c] x)
......
...@@ -233,6 +233,7 @@ ...@@ -233,6 +233,7 @@
(NeqB (ConstBool [c]) (ConstBool [d])) -> (ConstBool [b2i(c != d)]) (NeqB (ConstBool [c]) (ConstBool [d])) -> (ConstBool [b2i(c != d)])
(NeqB (ConstBool [0]) x) -> x (NeqB (ConstBool [0]) x) -> x
(NeqB (ConstBool [1]) x) -> (Not x) (NeqB (ConstBool [1]) x) -> (Not x)
(NeqB (Not x) (Not y)) -> (NeqB x y)
(Eq64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) -> (Eq64 (Const64 <t> [c-d]) x) (Eq64 (Const64 <t> [c]) (Add64 (Const64 <t> [d]) x)) -> (Eq64 (Const64 <t> [c-d]) x)
(Eq32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) -> (Eq32 (Const32 <t> [int64(int32(c-d))]) x) (Eq32 (Const32 <t> [c]) (Add32 (Const32 <t> [d]) x)) -> (Eq32 (Const32 <t> [int64(int32(c-d))]) x)
......
...@@ -334,7 +334,7 @@ func rewriteValueAMD64(v *Value) bool { ...@@ -334,7 +334,7 @@ func rewriteValueAMD64(v *Value) bool {
case OpAMD64XORL: case OpAMD64XORL:
return rewriteValueAMD64_OpAMD64XORL_0(v) || rewriteValueAMD64_OpAMD64XORL_10(v) return rewriteValueAMD64_OpAMD64XORL_0(v) || rewriteValueAMD64_OpAMD64XORL_10(v)
case OpAMD64XORLconst: case OpAMD64XORLconst:
return rewriteValueAMD64_OpAMD64XORLconst_0(v) return rewriteValueAMD64_OpAMD64XORLconst_0(v) || rewriteValueAMD64_OpAMD64XORLconst_10(v)
case OpAMD64XORQ: case OpAMD64XORQ:
return rewriteValueAMD64_OpAMD64XORQ_0(v) return rewriteValueAMD64_OpAMD64XORQ_0(v)
case OpAMD64XORQconst: case OpAMD64XORQconst:
...@@ -35274,6 +35274,169 @@ func rewriteValueAMD64_OpAMD64XORL_10(v *Value) bool { ...@@ -35274,6 +35274,169 @@ func rewriteValueAMD64_OpAMD64XORL_10(v *Value) bool {
return false return false
} }
func rewriteValueAMD64_OpAMD64XORLconst_0(v *Value) bool { func rewriteValueAMD64_OpAMD64XORLconst_0(v *Value) bool {
// match: (XORLconst [1] (SETNE x))
// cond:
// result: (SETEQ x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETNE {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETEQ)
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETEQ x))
// cond:
// result: (SETNE x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETEQ {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETNE)
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETL x))
// cond:
// result: (SETGE x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETL {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETGE)
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETGE x))
// cond:
// result: (SETL x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETGE {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETL)
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETLE x))
// cond:
// result: (SETG x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETLE {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETG)
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETG x))
// cond:
// result: (SETLE x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETG {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETLE)
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETB x))
// cond:
// result: (SETAE x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETB {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETAE)
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETAE x))
// cond:
// result: (SETB x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETAE {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETB)
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETBE x))
// cond:
// result: (SETA x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETBE {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETA)
v.AddArg(x)
return true
}
// match: (XORLconst [1] (SETA x))
// cond:
// result: (SETBE x)
for {
if v.AuxInt != 1 {
break
}
v_0 := v.Args[0]
if v_0.Op != OpAMD64SETA {
break
}
x := v_0.Args[0]
v.reset(OpAMD64SETBE)
v.AddArg(x)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64XORLconst_10(v *Value) bool {
// match: (XORLconst [c] (XORLconst [d] x)) // match: (XORLconst [c] (XORLconst [d] x))
// cond: // cond:
// result: (XORLconst [c ^ d] x) // result: (XORLconst [c ^ d] x)
......
...@@ -14573,6 +14573,44 @@ func rewriteValuegeneric_OpNeqB_0(v *Value) bool { ...@@ -14573,6 +14573,44 @@ func rewriteValuegeneric_OpNeqB_0(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true return true
} }
// match: (NeqB (Not x) (Not y))
// cond:
// result: (NeqB x y)
for {
v_0 := v.Args[0]
if v_0.Op != OpNot {
break
}
x := v_0.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpNot {
break
}
y := v_1.Args[0]
v.reset(OpNeqB)
v.AddArg(x)
v.AddArg(y)
return true
}
// match: (NeqB (Not y) (Not x))
// cond:
// result: (NeqB x y)
for {
v_0 := v.Args[0]
if v_0.Op != OpNot {
break
}
y := v_0.Args[0]
v_1 := v.Args[1]
if v_1.Op != OpNot {
break
}
x := v_1.Args[0]
v.reset(OpNeqB)
v.AddArg(x)
v.AddArg(y)
return true
}
return false return false
} }
func rewriteValuegeneric_OpNeqInter_0(v *Value) bool { func rewriteValuegeneric_OpNeqInter_0(v *Value) bool {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment