Hello,

before we completely forget about it, this fixes the pattern as discussed around https://gcc.gnu.org/ml/gcc-patches/2015-10/msg01459.html .

Note that, as seen in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68008#c1 , we would sometimes like to allow a conversion between trunc_div and mult, but that's a separate generalization and I did not want to think of the proper conditions for its validity.

Bootstrap+regtest on ppc64le-redhat-linux.

2015-10-30  Marc Glisse  <marc.gli...@inria.fr>

        * match.pd (X-(X/Y)*Y): Properly handle conversions and commutativity.

--
Marc Glisse
Index: gcc/match.pd
===================================================================
--- gcc/match.pd        (revision 229478)
+++ gcc/match.pd        (working copy)
@@ -311,24 +311,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* X % -Y is the same as X % Y.  */
 (simplify
  (trunc_mod @0 (convert? (negate @1)))
  (if (!TYPE_UNSIGNED (type)
       && !TYPE_OVERFLOW_TRAPS (type)
       && tree_nop_conversion_p (type, TREE_TYPE (@1)))
   (trunc_mod @0 (convert @1))))
 
 /* X - (X / Y) * Y is the same as X % Y.  */
 (simplify
- (minus (convert1? @0) (convert2? (mult (trunc_div @0 @1) @1)))
- (if ((INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
-      && TYPE_UNSIGNED (TREE_TYPE (@0)) == TYPE_UNSIGNED (type))
-  (trunc_mod (convert @0) (convert @1))))
+ (minus (convert1? @2) (convert2? (mult:c (trunc_div @0 @1) @1)))
+ (if (operand_equal_p (@0, @2, 0)
+      && (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type)))
+  (convert (trunc_mod @0 @1))))
 
 /* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR,
    i.e. "X % C" into "X & (C - 1)", if X and C are positive.
    Also optimize A % (C << N)  where C is a power of 2,
    to A & ((C << N) - 1).  */
 (match (power_of_two_cand @1)
  INTEGER_CST@1)
 (match (power_of_two_cand @1)
  (lshift INTEGER_CST@1 @2))
 (for mod (trunc_mod floor_mod)

Reply via email to