PR middle-end/48136
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Mar 2011 10:24:44 +0000 (10:24 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Mar 2011 10:24:44 +0000 (10:24 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171041 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr48136.c [new file with mode: 0644]

index 34d3d94..e5f4c4e 100644 (file)
@@ -1,5 +1,10 @@
 2011-03-16  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.
+
        * var-tracking.c (prepare_call_arguments): Add ATTRIBUTE_UNUSED
        to nargs.
 
index 5d92e0d..f8630a2 100644 (file)
@@ -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
index ddbc232..7e952dc 100644 (file)
@@ -1,5 +1,8 @@
 2011-03-16  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/48136
+       * gcc.c-torture/compile/pr48136.c: New test.
+
        * g++.dg/debug/dwarf2/icf.C: Adjust for -fenable-icf-debug removal.
 
        PR debug/45882
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr48136.c b/gcc/testsuite/gcc.c-torture/compile/pr48136.c
new file mode 100644 (file)
index 0000000..77581ac
--- /dev/null
@@ -0,0 +1,7 @@
+/* PR middle-end/48136 */
+
+int
+foo (int x, int y)
+{
+  return (x ^ 5U) == (y ^ 1);
+}