diff mbox

[match-and-simplify] Enable conversions properly for GENERIC

Message ID alpine.LSU.2.11.1409261250590.20733@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Sept. 26, 2014, 10:54 a.m. UTC
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  <rguenther@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.

Comments

Jason Merrill Sept. 26, 2014, 3:25 p.m. UTC | #1
On 09/26/2014 06:54 AM, Richard Biener wrote:
> 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?

There are a few cases where CONVERT_EXPR is special, but mostly no.

> 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?).

OK.

Jason
diff mbox

Patch

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))))