Drop Z from X + Z < Y + Z
authorMarc Glisse <marc.glisse@inria.fr>
Fri, 28 Apr 2017 20:51:05 +0000 (22:51 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Fri, 28 Apr 2017 20:51:05 +0000 (20:51 +0000)
2017-04-28  Marc Glisse  <marc.glisse@inria.fr>

gcc/
* match.pd (X+Z OP Y+Z, X-Z OP Y-Z, Z-X OP Z-Y): New transformations.

gcc/testsuite/
* gcc.dg/tree-ssa/cmpexactdiv-2.c: Update for X-Z OP Y-Z.

From-SVN: r247398

gcc/ChangeLog
gcc/match.pd
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv-2.c

index 9f885b429de165d61e3a37e205977ac77803f74b..d1204f18311eca1f656a3642c817976e0aa7e936 100644 (file)
@@ -1,3 +1,7 @@
+2017-04-28  Marc Glisse  <marc.glisse@inria.fr>
+
+       * match.pd (X+Z OP Y+Z, X-Z OP Y-Z, Z-X OP Z-Y): New transformations.
+
 2017-04-28  Bernd Edlinger  <bernd.edlinger@hotmail.de>
 
        * configure.ac (SYSTEM_HEADER_DIR, BUILD_SYSTEM_HEADER_DIR,
index 44745df9afa546d5380c99d1ec276deb8babe915..e3d98baa12fa62ca103624d4b387dfd21e580252 100644 (file)
@@ -1042,6 +1042,54 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (if (wi::gt_p(@2, 0, TYPE_SIGN (TREE_TYPE (@2))))
    (cmp @0 @1))))
 
+/* X + Z < Y + Z is the same as X < Y when there is no overflow.  */
+(for op (lt le ge gt)
+ (simplify
+  (op (plus:c @0 @2) (plus:c @1 @2))
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+   (op @0 @1))))
+/* For equality and subtraction, this is also true with wrapping overflow.  */
+(for op (eq ne minus)
+ (simplify
+  (op (plus:c @0 @2) (plus:c @1 @2))
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+          || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))))
+   (op @0 @1))))
+
+/* X - Z < Y - Z is the same as X < Y when there is no overflow.  */
+(for op (lt le ge gt)
+ (simplify
+  (op (minus @0 @2) (minus @1 @2))
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+   (op @0 @1))))
+/* For equality and subtraction, this is also true with wrapping overflow.  */
+(for op (eq ne minus)
+ (simplify
+  (op (minus @0 @2) (minus @1 @2))
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+          || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))))
+   (op @0 @1))))
+
+/* Z - X < Z - Y is the same as Y < X when there is no overflow.  */
+(for op (lt le ge gt)
+ (simplify
+  (op (minus @2 @0) (minus @2 @1))
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+   (op @1 @0))))
+/* For equality and subtraction, this is also true with wrapping overflow.  */
+(for op (eq ne minus)
+ (simplify
+  (op (minus @2 @0) (minus @2 @1))
+  (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))
+          || TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0))))
+   (op @1 @0))))
+
 /* ((X inner_op C0) outer_op C1)
    With X being a tree where value_range has reasoned certain bits to always be
    zero throughout its computed value range,
index 499f7808a1efed02406c2cab3594c20bb539f20d..92db79cded76b231da1d48f1bfb90b92dce1d163 100644 (file)
@@ -1,3 +1,7 @@
+2017-04-28  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.dg/tree-ssa/cmpexactdiv-2.c: Update for X-Z OP Y-Z.
+
 2017-04-28  Tom de Vries  <tom@codesourcery.com>
 
        * g++.dg/abi/bitfield3.C: Remove superfluous "" in
index e7f11b988c0c30ccd53d48b9301f947b5fe90116..a41811cf5713cc01164d7f9c2aeada2dc3ab6d96 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-optimized-raw" } */
+/* { dg-options "-O -fstrict-overflow -fdump-tree-optimized-raw" } */
 
 int f (long *a, long *b, long *c) {
     __PTRDIFF_TYPE__ l1 = b - a;
@@ -7,5 +7,5 @@ int f (long *a, long *b, long *c) {
     return l1 < l2;
 }
 
-/* Eventually we also want to remove all minus_expr.  */
+/* { dg-final { scan-tree-dump-not "minus_expr" "optimized" } } */
 /* { dg-final { scan-tree-dump-not "exact_div_expr" "optimized" } } */