This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR64454: (x % y) % y


Hello,

after this patch I think I'll close the PR. This was regtested on ppc64le-redhat-linux.

Apparently I wrote this patch in a file that already had a trivial hunk: -1-A -> ~A is rejected for complex while -A-1 isn't, there is no reason for this difference (maybe there was before integer_all_onesp / integer_minus_onep was introduced), I hope you don't mind.

I am wondering if we want some helper (like :c for commutative operations) to avoid duplicating patterns for x<y and y>x. We could also, when a comparison x<=y doesn't simplify, see if !!(x<=y) simplifies better, but that's becoming a bit complicated.

2015-05-15  Marc Glisse  <marc.glisse@inria.fr>

	PR tree-optimization/64454
gcc/
	* match.pd ((X % Y) % Y, (X % Y) < Y): New patterns.
	(-1 - A -> ~A): Remove unnecessary condition.
gcc/testsuite/
	* gcc.dg/modmod.c: New testcase.

--
Marc Glisse
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 223199)
+++ gcc/match.pd	(working copy)
@@ -204,33 +204,49 @@ along with GCC; see the file COPYING3.
   (if (!integer_zerop (@1))
    @0))
  /* X % 1 is always zero.  */
  (simplify
   (mod @0 integer_onep)
   { build_zero_cst (type); })
  /* X % -1 is zero.  */
  (simplify
   (mod @0 integer_minus_onep@1)
   (if (!TYPE_UNSIGNED (type))
-   { build_zero_cst (type); })))
+   { build_zero_cst (type); }))
+ /* (X % Y) % Y is just X % Y.  */
+ (simplify
+  (mod (mod@2 @0 @1) @1)
+  @2))
 
 /* X % -C is the same as X % C.  */
 (simplify
  (trunc_mod @0 INTEGER_CST@1)
   (if (TYPE_SIGN (type) == SIGNED
        && !TREE_OVERFLOW (@1)
        && wi::neg_p (@1)
        && !TYPE_OVERFLOW_TRAPS (type)
        /* Avoid this transformation if C is INT_MIN, i.e. C == -C.  */
        && !sign_bit_p (@1, @1))
    (trunc_mod @0 (negate @1))))
 
+/* X % Y is smaller than Y.  */
+(for cmp (lt ge)
+ (simplify
+  (cmp (trunc_mod @0 @1) @1)
+  (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
+   { constant_boolean_node (cmp == LT_EXPR, type); })))
+(for cmp (gt le)
+ (simplify
+  (cmp @1 (trunc_mod @0 @1))
+  (if (TYPE_UNSIGNED (TREE_TYPE (@0)))
+   { constant_boolean_node (cmp == GT_EXPR, type); })))
+
 /* x | ~0 -> ~0  */
 (simplify
   (bit_ior @0 integer_all_onesp@1)
   @1)
 
 /* x & 0 -> 0  */
 (simplify
   (bit_and @0 integer_zerop@1)
   @1)
 
@@ -526,22 +542,21 @@ along with GCC; see the file COPYING3.
   /* -A - 1 -> ~A */
   (simplify
    (minus (convert? (negate @0)) integer_each_onep)
    (if (!TYPE_OVERFLOW_TRAPS (type)
 	&& tree_nop_conversion_p (type, TREE_TYPE (@0)))
     (bit_not (convert @0))))
 
   /* -1 - A -> ~A */
   (simplify
    (minus integer_all_onesp @0)
-   (if (TREE_CODE (type) != COMPLEX_TYPE)
-    (bit_not @0)))
+   (bit_not @0))
 
   /* (T)(P + A) - (T)P -> (T) A */
   (for add (plus pointer_plus)
    (simplify
     (minus (convert (add @0 @1))
      (convert @0))
     (if (element_precision (type) <= element_precision (TREE_TYPE (@1))
 	 /* For integer types, if A has a smaller type
 	    than T the result depends on the possible
 	    overflow in P + A.
Index: gcc/testsuite/gcc.dg/modmod.c
===================================================================
--- gcc/testsuite/gcc.dg/modmod.c	(revision 0)
+++ gcc/testsuite/gcc.dg/modmod.c	(working copy)
@@ -0,0 +1,13 @@
+/* { dg-options "-O -fdump-tree-optimized-raw" } */
+
+int f(int a, int b){
+  a %= b;
+  return a % b;
+}
+int g(unsigned a, unsigned b){
+  a %= b;
+  return a < b;
+}
+
+/* { dg-final { scan-tree-dump-times "trunc_mod_expr" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]