cmd/compile: add subtraction cancellation rule x-(x-y)==y
cmd/compile: add subtraction cancellation rule x-(x-y)==y closes #80320
diff --git a/src/cmd/compile/internal/ssa/_gen/generic.rules b/src/cmd/compile/internal/ssa/_gen/generic.rules
index 84cf50a..c6bcc8f 100644
--- a/src/cmd/compile/internal/ssa/_gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/_gen/generic.rules
@@ -212,6 +212,9 @@
(And(8|16|32|64) x (Or(8|16|32|64) x y)) => x
(Or(8|16|32|64) x (And(8|16|32|64) x y)) => x
+// Subtraction cancellation: x - (x - y) == y
+(Sub(8|16|32|64) x (Sub(8|16|32|64) x y)) => y
+
(Mod8 (Const8 [c]) (Const8 [d])) && d != 0 => (Const8 [c % d])
(Mod16 (Const16 [c]) (Const16 [d])) && d != 0 => (Const16 [c % d])
(Mod32 (Const32 [c]) (Const32 [d])) && d != 0 => (Const32 [c % d])
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index e39e08d..f43594a 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -35627,6 +35627,20 @@
v.AuxInt = int16ToAuxInt(c - d)
return true
}
+ // match: (Sub16 x (Sub16 x y))
+ // result: y
+ for {
+ x := v_0
+ if v_1.Op != OpSub16 {
+ break
+ }
+ y := v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v.copyOf(y)
+ return true
+ }
// match: (Sub16 x (Const16 <t> [c]))
// cond: x.Op != OpConst16
// result: (Add16 (Const16 <t> [-c]) x)
@@ -36000,6 +36014,20 @@
v.AuxInt = int32ToAuxInt(c - d)
return true
}
+ // match: (Sub32 x (Sub32 x y))
+ // result: y
+ for {
+ x := v_0
+ if v_1.Op != OpSub32 {
+ break
+ }
+ y := v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v.copyOf(y)
+ return true
+ }
// match: (Sub32 x (Const32 <t> [c]))
// cond: x.Op != OpConst32
// result: (Add32 (Const32 <t> [-c]) x)
@@ -36397,6 +36425,20 @@
v.AuxInt = int64ToAuxInt(c - d)
return true
}
+ // match: (Sub64 x (Sub64 x y))
+ // result: y
+ for {
+ x := v_0
+ if v_1.Op != OpSub64 {
+ break
+ }
+ y := v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v.copyOf(y)
+ return true
+ }
// match: (Sub64 x (Const64 <t> [c]))
// cond: x.Op != OpConst64
// result: (Add64 (Const64 <t> [-c]) x)
@@ -36794,6 +36836,20 @@
v.AuxInt = int8ToAuxInt(c - d)
return true
}
+ // match: (Sub8 x (Sub8 x y))
+ // result: y
+ for {
+ x := v_0
+ if v_1.Op != OpSub8 {
+ break
+ }
+ y := v_1.Args[1]
+ if x != v_1.Args[0] {
+ break
+ }
+ v.copyOf(y)
+ return true
+ }
// match: (Sub8 x (Const8 <t> [c]))
// cond: x.Op != OpConst8
// result: (Add8 (Const8 <t> [-c]) x)
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
I spotted some possible problems with your PR:
1. Do you have the right bug reference format? For this repo, the format is usually 'Fixes #12345' or 'Updates #12345' at the end of the commit message.
Please address any problems by updating the GitHub PR.
When complete, mark this comment as 'Done' and click the [blue 'Reply' button](https://go.dev/wiki/GerritBot#i-left-a-reply-to-a-comment-in-gerrit-but-no-one-but-me-can-see-it) above. These findings are based on heuristics; if a finding does not apply, briefly reply here saying so.
To update the commit title or commit message body shown here in Gerrit, you must edit the GitHub PR title and PR description (the first comment) in the GitHub web interface using the 'Edit' button or 'Edit' menu entry there. Note: pushing a new commit to the PR will not automatically update the commit message used by Gerrit.
For more details, see:
(In general for Gerrit code reviews, the change author is expected to [log in to Gerrit](https://go-review.googlesource.com/login/) with a Gmail or other Google account and then close out each piece of feedback by marking it as 'Done' if implemented as suggested or otherwise reply to each review comment. See the [Review](https://go.dev/doc/contribute#review) section of the Contributing Guide for details.)
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Auto-Submit | +1 |
| Code-Review | +2 |
| Commit-Queue | +1 |
I spotted some possible problems with your PR:
1. Do you have the right bug reference format? For this repo, the format is usually 'Fixes #12345' or 'Updates #12345' at the end of the commit message.Please address any problems by updating the GitHub PR.
When complete, mark this comment as 'Done' and click the [blue 'Reply' button](https://go.dev/wiki/GerritBot#i-left-a-reply-to-a-comment-in-gerrit-but-no-one-but-me-can-see-it) above. These findings are based on heuristics; if a finding does not apply, briefly reply here saying so.
To update the commit title or commit message body shown here in Gerrit, you must edit the GitHub PR title and PR description (the first comment) in the GitHub web interface using the 'Edit' button or 'Edit' menu entry there. Note: pushing a new commit to the PR will not automatically update the commit message used by Gerrit.
For more details, see:
- [how to update commit messages](https://go.dev/wiki/GerritBot/#how-does-gerritbot-determine-the-final-commit-message) for PRs imported into Gerrit.
- the Go project's [conventions for commit messages](https://go.dev/doc/contribute#commit_messages) that you should follow.
(In general for Gerrit code reviews, the change author is expected to [log in to Gerrit](https://go-review.googlesource.com/login/) with a Gmail or other Google account and then close out each piece of feedback by marking it as 'Done' if implemented as suggested or otherwise reply to each review comment. See the [Review](https://go.dev/doc/contribute#review) section of the Contributing Guide for details.)
Done
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Code-Review | +2 |
You need to rebase on latest master to fix the CI failure.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Code-Review | +2 |
Maybe move the new rules down here somewhere?
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
You need to rebase on latest master to fix the CI failure.
Done.
Maybe move the new rules down here somewhere?
Sure. Should I keep the comment, or is it better to remove it?
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Code-Review | +2 |
Khashayar FereidaniMaybe move the new rules down here somewhere?
Sure. Should I keep the comment, or is it better to remove it?
The comment is good. More of these rules should have comments.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
This seems to have gotten a whole bunch more rules in patch set 4. Was that intentional?
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
This seems to have gotten a whole bunch more rules in patch set 4. Was that intentional?
Yes, These are result of 3000+ popular go programs/libraries super-optimizer harvest, I'll send the exact samples to the issue for each added rule so we can discuss them.
Khashayar FereidaniMaybe move the new rules down here somewhere?
Keith RandallSure. Should I keep the comment, or is it better to remove it?
The comment is good. More of these rules should have comments.
Done
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |
| Commit-Queue | +1 |
cmd/compile: add subtraction cancellation rule x-(x-y)==yThat not accurate
// ----------------------------------------------------------------------------
// Disabled example rules (https://github.com/golang/go/issues/80320).
//
// The identities below are correct (SMT-verified over all inputs at every
// width) and are implemented in the rule DSL, but they are intentionally
// left commented out. Rules of this kind have not been proven useful in
// practice: a survey of real Go code found no natural occurrence of these
// patterns, and the bar for enabling a rewrite rule in this file is at
// least one real-world Go program that demonstrably benefits. Speculative
// rules add matching work to every compilation and a permanent maintenance
// and testing burden without demonstrated payoff.
//
// They are recorded here as reference implementations. If you find Go code
// in the wild that would naturally be improved by one of these rules, please
// open a pull request enabling that rule, citing the motivating code and the
// issue above.
//
// x | (^x & y) == x | y
//(Or(64|32|16|8) x (And(64|32|16|8) (Com(64|32|16|8) x) y)) => (Or(64|32|16|8) x y)
//
// x & (^x | y) == x & y
//(And(64|32|16|8) x (Or(64|32|16|8) (Com(64|32|16|8) x) y)) => (And(64|32|16|8) x y)
//
// (x & y) | (x & ^y) == x
//(Or(64|32|16|8) (And(64|32|16|8) x y) (And(64|32|16|8) x (Com(64|32|16|8) y))) => x
//
// (x | y) & (x | ^y) == x
//(And(64|32|16|8) (Or(64|32|16|8) x y) (Or(64|32|16|8) x (Com(64|32|16|8) y))) => x
//
// (x | y) - (x & y) == x ^ y
//(Sub(64|32|16|8) (Or(64|32|16|8) x y) (And(64|32|16|8) x y)) => (Xor(64|32|16|8) x y)
//
// (x ^ y) ^ (x | y) == x & y
//(Xor(64|32|16|8) (Xor(64|32|16|8) x y) (Or(64|32|16|8) x y)) => (And(64|32|16|8) x y)
//
// (x ^ y) ^ (x & y) == x | y
//(Xor(64|32|16|8) (Xor(64|32|16|8) x y) (And(64|32|16|8) x y)) => (Or(64|32|16|8) x y)
//
// (x & y) + (x | y) == x + y
//(Add(64|32|16|8) (And(64|32|16|8) x y) (Or(64|32|16|8) x y)) => (Add(64|32|16|8) x y)Please don't add commented out code.
| Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. |