diff mbox

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

Message ID 20110315194138.GC30899@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek March 15, 2011, 7:41 p.m. UTC
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.


	Jakub

Comments

Richard Biener March 16, 2011, 9:58 a.m. UTC | #1
On Tue, Mar 15, 2011 at 8:41 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> 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?

Ok.

Thanks,
Richard.

> 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
>
diff mbox

Patch

--- 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);
+}