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)