This moves &X ==/!= ptr comparison folding which triggers surprisingly
often.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2015-06-29  Richard Biener  <rguent...@suse.de>

        * genmatch.c (add_operator): Treat ADDR_EXPR as atom.
        * fold-const.c (fold_binary_loc): Move &A - &B simplification
        via ptr_difference_const ...
        * match.pd: ... here.
        When matching (X ^ Y) == Y also match with swapped operands.

Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c      (revision 225007)
+++ gcc/genmatch.c      (working copy)
@@ -324,6 +324,9 @@ add_operator (enum tree_code code, const
       /* And allow CONSTRUCTOR for vector initializers.  */
       && !(code == CONSTRUCTOR))
     return;
+  /* Treat ADDR_EXPR as atom, thus don't allow matching its operand.  */
+  if (code == ADDR_EXPR)
+    nargs = 0;
   operator_id *op = new operator_id (code, id, nargs, tcc);
   id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT);
   if (*slot)
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 225007)
+++ gcc/fold-const.c    (working copy)
@@ -10618,16 +10562,6 @@ fold_binary_loc (location_t loc,
                            fold_convert_loc (loc, type,
                                              negate_expr (arg1)));
 
-      /* Try folding difference of addresses.  */
-      {
-       HOST_WIDE_INT diff;
-
-       if ((TREE_CODE (arg0) == ADDR_EXPR
-            || TREE_CODE (arg1) == ADDR_EXPR)
-           && ptr_difference_const (arg0, arg1, &diff))
-         return build_int_cst_type (type, diff);
-      }
-
       /* Fold &a[i] - &a[j] to i-j.  */
       if (TREE_CODE (arg0) == ADDR_EXPR
          && TREE_CODE (TREE_OPERAND (arg0, 0)) == ARRAY_REF
Index: gcc/match.pd
===================================================================
*** gcc/match.pd        (revision 225007)
--- gcc/match.pd        (working copy)
*************** (define_operator_list swapped_tcc_compar
*** 545,550 ****
--- 545,565 ----
    (with { tree algn = wide_int_to_tree (TREE_TYPE (@0), wi::bit_not (@1)); }
     (bit_and @0 { algn; })))
  
+ /* Try folding difference of addresses.  */
+ (simplify
+  (minus (convert ADDR_EXPR@0) (convert @1))
+  (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
+   (with { HOST_WIDE_INT diff; }
+    (if (ptr_difference_const (@0, @1, &diff))
+     { build_int_cst_type (type, diff); }))))
+ (simplify
+  (minus (convert @0) (convert ADDR_EXPR@1))
+  (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
+   (with { HOST_WIDE_INT diff; }
+    (if (ptr_difference_const (@0, @1, &diff))
+     { build_int_cst_type (type, diff); }))))
+ 
+ 
  
  /* We can't reassociate at all for saturating types.  */
  (if (!TYPE_SATURATING (type))
*************** (define_operator_list swapped_tcc_compar
*** 1229,1235 ****
   /* (X ^ Y) == Y becomes X == 0.
      Likewise (X ^ Y) == X becomes Y == 0.  */
   (simplify
!   (cmp (bit_xor:c @0 @1) @0)
    (cmp @1 { build_zero_cst (TREE_TYPE (@1)); }))
  
   /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2).  */
--- 1244,1250 ----
   /* (X ^ Y) == Y becomes X == 0.
      Likewise (X ^ Y) == X becomes Y == 0.  */
   (simplify
!   (cmp:c (bit_xor:c @0 @1) @0)
    (cmp @1 { build_zero_cst (TREE_TYPE (@1)); }))
  
   /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2).  */

Reply via email to