aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-05-06 11:20:20 +0200
committerJakub Jelinek <jakub@redhat.com>2020-05-06 11:20:20 +0200
commita7b76d574b19190da190a60c065f347f40bab59e (patch)
tree5302a249505a7b87485ecd073d9150dabf6e1cd5 /gcc
parent380a681518c3b387476be1064097f24b0847726d (diff)
downloadgcc-a7b76d574b19190da190a60c065f347f40bab59e.zip
gcc-a7b76d574b19190da190a60c065f347f40bab59e.tar.gz
gcc-a7b76d574b19190da190a60c065f347f40bab59e.tar.bz2
match.pd: Optimize ~(~X +- Y) into (X -+ Y) [PR94921]
According to my verification proglet, this transformation for signed types with undefined overflow doesn't introduce nor remove any UB cases, so should be valid even for signed integral types. Not using a for because of the :c on plus which can't be there on minus. 2020-05-06 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/94921 * match.pd (~(~X - Y) -> X + Y, ~(~X + Y) -> X - Y): New simplifications. * gcc.dg/tree-ssa/pr94921.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/match.pd8
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr94921.c18
4 files changed, 36 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e0dd54c..8bb2893 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-05-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/94921
+ * match.pd (~(~X - Y) -> X + Y, ~(~X + Y) -> X - Y): New
+ simplifications.
+
2020-05-06 Richard Biener <rguenther@suse.de>
PR tree-optimization/94965
diff --git a/gcc/match.pd b/gcc/match.pd
index d957517..9259dd4 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1010,6 +1010,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
@0))
#endif
+/* ~(~X - Y) -> X + Y and ~(~X + Y) -> X - Y. */
+(simplify
+ (bit_not (minus (bit_not @0) @1))
+ (plus @0 @1))
+(simplify
+ (bit_not (plus:c (bit_not @0) @1))
+ (minus @0 @1))
+
/* x + (x & 1) -> (x + 1) & ~1 */
(simplify
(plus:c @0 (bit_and:s @0 integer_onep@1))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1f01ff0..a66a012 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2020-05-06 Jakub Jelinek <jakub@redhat.com>
+ PR tree-optimization/94921
+ * match.pd (~(~X - Y) -> X + Y, ~(~X + Y) -> X - Y): New
+ simplifications.
+
PR rtl-optimization/94873
* gcc.dg/pr94873.c: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94921.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94921.c
new file mode 100644
index 0000000..2c752ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94921.c
@@ -0,0 +1,18 @@
+/* PR tree-optimization/94921 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump " \[ab]_\[0-9]+\\\(D\\\) \\+ \[ab]_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump " c_\[0-9]+\\\(D\\\) - d_\[0-9]+\\\(D\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " ~\[abcd]\?_\[0-9]\+" "optimized" } } */
+
+int
+foo (int a, int b)
+{
+ return ~(~a - b);
+}
+
+int
+bar (int c, int d)
+{
+ return ~(~c + d);
+}