diff mbox

Fix X - (X / Y) * Y in match.pd

Message ID alpine.DEB.2.02.1510291540100.19735@laptop-mg.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse Oct. 29, 2015, 3:06 p.m. UTC
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.glisse@inria.fr>

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

Comments

Richard Biener Oct. 29, 2015, 3:25 p.m. UTC | #1
On Thu, Oct 29, 2015 at 4:06 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> 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.

Ok, can you add a comment why we can't use matching captures before
the operand_equal_p?  Just in case somebody stumbles across this...

Richard.

> 2015-10-30  Marc Glisse  <marc.glisse@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)
>
diff mbox

Patch

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)