On Tue, Jul 21, 2015 at 11:15 AM, Hurugalawadi, Naveen
<naveen.hurugalaw...@caviumnetworks.com> wrote:
> Hi,
>
> Please find attached the patch which performs following patterns folding
> in match.pd:-
>
> a ==/!= a p+ b to b ==/!= 0.
> a << N ==/!= 0 to a&(-1>>N) ==/!= 0.
> a * N ==/!= 0 where N is a power of 2 to a & (-1<<N2) ==/!= 0 where N2 is 
> log2 of N.
>
> Please review the same and let us know if its okay?

+(match unsigned_integral_valued_p
+ @0
+ (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))))

please avoid adding matches for simple things like this, instead inline the if.

> a * N ==/!= 0 where N is a power of 2 to a & (-1<<N2) ==/!= 0 where N2 is 
> log2 of N.

We have the similar (for the signed case)

/* Transform comparisons of the form X * C1 CMP 0 to X CMP 0 in the
   signed arithmetic case.  That form is created by the compiler
   often enough for folding it to be of value.  One example is in
   computing loop trip counts after Operator Strength Reduction.  */

which shows the transform may be valid for other comparison codes as well.
Note as Jakub says the (-1 << N2) constant may be expensive to generate.
Did you check if we expand to a multiply again if that is the case?

Also you have the same idea in two patterns so if a & (-1 << N2) should
be canonical on GIMPLE (I'd say gimple should prefer "smaller" constants
when the number of operations is the same) then why not simplify
all multiplies that way instead of just those feeding comparisons?  That is,
a * N -> a << N?

So we have the remaining

+/* Fold a ==/!= a p + b to b ==/!= 0.  */
+(for op (ne eq)
+ (simplify
+  (op:c @0 (pointer_plus @0 @1))
+  (op @1 { build_zero_cst (TREE_TYPE (@1)); })))

fold_comparison has the more "complete"

  /* For comparisons of pointers we can decompose it to a compile time
     comparison of the base objects and the offsets into the object.
     This requires at least one operand being an ADDR_EXPR or a
     POINTER_PLUS_EXPR to do more than the operand_equal_p test below.  */

but it looks like you are implementing fold_binarys

      /* Transform comparisons of the form X +- Y CMP X to Y CMP 0.  */
      if ((TREE_CODE (arg0) == PLUS_EXPR
           || TREE_CODE (arg0) == POINTER_PLUS_EXPR
           || TREE_CODE (arg0) == MINUS_EXPR)
          && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg0,
                                                                        0)),
                              arg1, 0)
          && (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
              || POINTER_TYPE_P (TREE_TYPE (arg0))))
        {
          tree val = TREE_OPERAND (arg0, 1);
          return omit_two_operands_loc (loc, type,
                                    fold_build2_loc (loc, code, type,
                                                 val,
                                                 build_int_cst (TREE_TYPE (val),
                                                                0)),
                                    TREE_OPERAND (arg0, 0), arg1);
        }

but leave out non-pointer support.  So please start over with just
moving the above
code from fold-const.c to match.pd as a pattern.

Thanks,
Richard.


> Regression Tested on X86_64.
>
> On Behalf of Andrew Pinski.
>
> Thanks,
>
> gcc/testsuite/ChangeLog:
>
> 2015-01-21  Andrew Pinski  <apin...@cavium.com>
>
>         * testsuite/gcc.dg/tree-ssa/compare-shiftmult-1.c: New testcase.
>         * testsuite/gcc.dg/tree-ssa/compare_pointers-1.c: New testcase.
>
> gcc/ChangeLog:
>
> 2015-01-21  Andrew Pinski  <apin...@cavium.com>
>
>         * match.pd (define_predicates): Add integer_pow2p.
>         Add pattern for folding of a ==/!= a p+ b to b ==/!= 0.
>         (unsigned_integral_valued_p): New match.
>         Add pattern for folding of a<<N ==/!= 0 to a&(-1>>N) ==/!= 0.
>         Add pattern for folding of a*N ==/!= 0 where N is a power of 2
>         to a&(-1<<N2) ==/!= 0 where N2 is log2 of N.

Reply via email to