This fixes a ??? and handles NOP_EXPR and CONVERT_EXPR matching
similar to GIMPLE by using CASE_CONVERT.  This uncovers a
mismatch between fold-const.c and tree-ssa-forwprop.c transforms
which try to do opposite things with ((T) X) & CST vs.
(T) (X & CST).  I have disabled the forwprop transform on GENERIC.
It also uncovers that the C++ FE uses a mix of NOP_EXPR and
CONVERT_EXPR both when building expressions and when checking
for them.  Jason - is there any difference between NOP_EXPR and
CONVERT_EXPR as far as the C++ FE is concerned?  I have
silenced -Wsign-compare warnings that the patch caused by
making enum_cast_to_int "accept" both NOP_EXPR and CONVERT_EXPR
as conversion code (ok for trunk?).

Bootstrap and testing on x86_64-unknown-linux-gnu in progress.

Richard.

2014-09-26  Richard Biener  <rguent...@suse.de>

        * genmatch.c (dt_node::gen_kids): Handle conversions in
        generic expressions properly.
        * match-bitwise.pd ((type) X & CST -> (type) (X & ((type-x) CST))):
        Disable on GENERIC as it conflicts with a transform in fold-const.c.

        cp/
        * typeck.c (enum_cast_to_int): Use CONVERT_EXPR_P to check
        for conversions.

Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c      (revision 215638)
+++ gcc/genmatch.c      (working copy)
@@ -1719,8 +1719,10 @@ dt_node::gen_kids (FILE *f, bool gimple)
     {
       expr *e = as_a <expr *>(generic_exprs[i]->op);
       id_base *op = e->operation;
-      /* ??? CONVERT */
-      fprintf (f, "case %s:\n", op->id);
+      if (*op == CONVERT_EXPR || *op == NOP_EXPR)
+       fprintf (f, "CASE_CONVERT:\n");
+      else
+       fprintf (f, "case %s:\n", op->id);
       fprintf (f, "{\n");
       generic_exprs[i]->gen (f, gimple);
       fprintf (f, "break;\n"
Index: gcc/match-bitwise.pd
===================================================================
--- gcc/match-bitwise.pd        (revision 215554)
+++ gcc/match-bitwise.pd        (working copy)
@@ -28,7 +28,13 @@ along with GCC; see the file COPYING3.
   (bitop (convert @0) (convert? @1))
   (if (((TREE_CODE (@1) == INTEGER_CST
         && INTEGRAL_TYPE_P (TREE_TYPE (@0))
-        && int_fits_type_p (@1, TREE_TYPE (@0)))
+        && int_fits_type_p (@1, TREE_TYPE (@0))
+        /* ???  This transform conflicts with fold-const.c doing
+           Convert (T)(x & c) into (T)x & (T)c, if c is an integer
+           constants (if x has signed type, the sign bit cannot be set
+           in c).  This folds extension into the BIT_AND_EXPR.
+           Restrict it to GIMPLE to avoid endless recursions.  */
+        && (bitop != BIT_AND_EXPR || GIMPLE))
        || types_compatible_p (TREE_TYPE (@0), TREE_TYPE (@1)))
        && (/* That's a good idea if the conversion widens the operand, thus
              after hoisting the conversion the operation will be narrower.  */
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c     (revision 215554)
+++ gcc/cp/typeck.c     (working copy)
@@ -3858,7 +3858,7 @@ build_x_array_ref (location_t loc, tree
 static bool
 enum_cast_to_int (tree op)
 {
-  if (TREE_CODE (op) == NOP_EXPR
+  if (CONVERT_EXPR_P (op)
       && TREE_TYPE (op) == integer_type_node
       && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == ENUMERAL_TYPE
       && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 0))))

Reply via email to