[PATCH] Fix fallout of my fold_binary EQ/NE patch (PR middle-end/48136)

Jakub Jelinek jakub@redhat.com
Tue Mar 15 19:41:00 GMT 2011


Hi!

The addition of STRIP_NOPS for EQ_EXPR/NE_EXPR revealed a bunch of cases
which rely on arg0 and arg1 having the same type.  Only the last hunk
fixes the testcase, the rest is what I saw and it was possible the
types wouldn't match.  Tried to construct testcases for the other cases,
but didn't succeed, earlier folding already modified the operands so it
didn't look like what the code was expecting.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-03-15  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/48136
	* fold-const.c (fold_binary_loc) <case EQ_EXPR, NE_EXPR>: Make sure
	arg0/arg1 or their arguments are always fold converted to matching
	types.

	* gcc.c-torture/compile/pr48136.c: New test.

--- gcc/fold-const.c.jj	2011-03-15 09:47:12.000000000 +0100
+++ gcc/fold-const.c	2011-03-15 17:13:29.000000000 +0100
@@ -12342,7 +12342,8 @@ fold_binary_loc (location_t loc,
 		{
 		  tem = fold_build2_loc (loc, LSHIFT_EXPR, itype, arg01, arg001);
 		  tem = fold_build2_loc (loc, BIT_AND_EXPR, itype, arg000, tem);
-		  return fold_build2_loc (loc, code, type, tem, arg1);
+		  return fold_build2_loc (loc, code, type, tem,
+					  fold_convert_loc (loc, itype, arg1));
 		}
 	      /* Otherwise, for signed (arithmetic) shifts,
 		 ((X >> C1) & C2) != 0 is rewritten as X < 0, and
@@ -12393,8 +12394,10 @@ fold_binary_loc (location_t loc,
 	  tree notc = fold_build1_loc (loc, BIT_NOT_EXPR,
 				   TREE_TYPE (TREE_OPERAND (arg0, 1)),
 				   TREE_OPERAND (arg0, 1));
-	  tree dandnotc = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0),
-				       arg1, notc);
+	  tree dandnotc
+	    = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0),
+			       fold_convert_loc (loc, TREE_TYPE (arg0), arg1),
+			       notc);
 	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
 	  if (integer_nonzerop (dandnotc))
 	    return omit_one_operand_loc (loc, type, rslt, arg0);
@@ -12407,8 +12410,10 @@ fold_binary_loc (location_t loc,
 	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
 	{
 	  tree notd = fold_build1_loc (loc, BIT_NOT_EXPR, TREE_TYPE (arg1), arg1);
-	  tree candnotd = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0),
-				       TREE_OPERAND (arg0, 1), notd);
+	  tree candnotd
+	    = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0),
+			       TREE_OPERAND (arg0, 1),
+			       fold_convert_loc (loc, TREE_TYPE (arg0), notd));
 	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
 	  if (integer_nonzerop (candnotd))
 	    return omit_one_operand_loc (loc, type, rslt, arg0);
@@ -12483,13 +12488,13 @@ fold_binary_loc (location_t loc,
       if (TREE_CODE (arg0) == BIT_XOR_EXPR
 	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
 	return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0),
-			    build_int_cst (TREE_TYPE (arg1), 0));
+				build_int_cst (TREE_TYPE (arg0), 0));
       /* Likewise (X ^ Y) == X becomes Y == 0.  X has no side-effects.  */
       if (TREE_CODE (arg0) == BIT_XOR_EXPR
 	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
 	  && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
 	return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 1),
-			    build_int_cst (TREE_TYPE (arg1), 0));
+				build_int_cst (TREE_TYPE (arg0), 0));
 
       /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2).  */
       if (TREE_CODE (arg0) == BIT_XOR_EXPR
@@ -12507,10 +12512,12 @@ fold_binary_loc (location_t loc,
 	  && integer_pow2p (TREE_OPERAND (arg0, 1)))
 	{
 	  tem = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0),
-			     TREE_OPERAND (TREE_OPERAND (arg0, 0), 0),
-			     TREE_OPERAND (arg0, 1));
+				 TREE_OPERAND (TREE_OPERAND (arg0, 0), 0),
+				 TREE_OPERAND (arg0, 1));
 	  return fold_build2_loc (loc, code == EQ_EXPR ? NE_EXPR : EQ_EXPR,
-			      type, tem, arg1);
+				  type, tem,
+				  fold_convert_loc (loc, TREE_TYPE (arg0),
+						    arg1));
 	}
 
       /* Fold ((X & C) ^ C) eq/ne 0 into (X & C) ne/eq 0, when the
@@ -12554,8 +12561,9 @@ fold_binary_loc (location_t loc,
       if (TREE_CODE (arg0) == NEGATE_EXPR
           && TREE_CODE (arg1) == NEGATE_EXPR)
 	return fold_build2_loc (loc, code, type,
-			    TREE_OPERAND (arg0, 0),
-			    TREE_OPERAND (arg1, 0));
+				TREE_OPERAND (arg0, 0),
+				fold_convert_loc (loc, TREE_TYPE (arg0),
+						  TREE_OPERAND (arg1, 0)));
 
       /* Fold (X & C) op (Y & C) as (X ^ Y) & C op 0", and symmetries.  */
       if (TREE_CODE (arg0) == BIT_AND_EXPR
@@ -12628,12 +12636,13 @@ fold_binary_loc (location_t loc,
 	  /* Optimize (X ^ C1) op (Y ^ C2) as (X ^ (C1 ^ C2)) op Y.  */
 	  if (TREE_CODE (arg01) == INTEGER_CST
 	      && TREE_CODE (arg11) == INTEGER_CST)
-	    return fold_build2_loc (loc, code, type,
-				fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00,
-					     fold_build2_loc (loc,
-							  BIT_XOR_EXPR, itype,
-							  arg01, arg11)),
-				arg10);
+	    {
+	      tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg01,
+				     fold_convert_loc (loc, itype, arg11));
+	      tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, tem);
+	      return fold_build2_loc (loc, code, type, tem,
+				      fold_convert_loc (loc, itype, arg10));
+	    }
 	}
 
       /* Attempt to simplify equality/inequality comparisons of complex
--- gcc/testsuite/gcc.c-torture/compile/pr48136.c.jj	2011-03-15 17:27:43.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr48136.c	2011-03-15 17:27:23.000000000 +0100
@@ -0,0 +1,7 @@
+/* PR middle-end/48136 */
+
+int
+foo (int x, int y)
+{
+  return (x ^ 5U) == (y ^ 1);
+}

	Jakub



More information about the Gcc-patches mailing list