This patch improves the X - (X / Y) * Y simplification a bit; with using convert[12]? we're also able to fold INTEGER_CSTs with different types.
Except using convert[12]? I also had to convert both operands of the resulting expression to keep the gimple verifier happy. Bootstrapped/regtested on x86_64-linux, applying to trunk. 2015-06-30 Marek Polacek <pola...@redhat.com> * match.pd (X - (X / Y) * Y): Use convert1 and convert2. Convert both operands of the resulting expression. * gcc.dg/fold-minus-6.c: New test. diff --git gcc/match.pd gcc/match.pd index 682784b..e6728f4 100644 --- gcc/match.pd +++ gcc/match.pd @@ -240,9 +240,9 @@ along with GCC; see the file COPYING3. If not see /* X - (X / Y) * Y is the same as X % Y. */ (simplify - (minus (convert? @0) (convert? (mult (trunc_div @0 @1) @1))) + (minus (convert1? @0) (convert2? (mult (trunc_div @0 @1) @1))) (if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type)) - (convert (trunc_mod @0 @1)))) + (trunc_mod (convert @0) (convert @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. diff --git gcc/testsuite/gcc.dg/fold-minus-6.c gcc/testsuite/gcc.dg/fold-minus-6.c index e69de29..1c22c25 100644 --- gcc/testsuite/gcc.dg/fold-minus-6.c +++ gcc/testsuite/gcc.dg/fold-minus-6.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-cddce1" } */ + +int +fn1 (int x) +{ + return 42L - (42 / x) * x; +} + +long +fn2 (int x) +{ + return 42L - (42 / x) * x; +} + +int +fn3 (long int x) +{ + return 42L - (42 / x) * x; +} + +int +fn4 (int a, int b) +{ + return a - (unsigned) ((a / b) * b); +} + +int +fn5 (int a, unsigned int b) +{ + return a - ((a / b) * b); +} + +unsigned int +fn6 (int a, int b) +{ + return a - ((a / b) * b); +} + +/* { dg-final { scan-tree-dump-not " / " "cddce1" } } */ +/* { dg-final { scan-tree-dump-not " - " "cddce1" } } */ +/* { dg-final { scan-tree-dump-not " \\+ " "cddce1" } } */ Marek