2007-10-08 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Oct 2007 14:44:14 +0000 (14:44 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Oct 2007 14:44:14 +0000 (14:44 +0000)
PR middle-end/33691
PR middle-end/33694
PR middle-end/33696
* fold-const.c (fold_binary): Use the correct types when
folding (A | CST1) & CST2 to (A & CST2) | (CST1 & CST2).
(fold_binary): Use the correct types when folding
(-A) - B to (-B) - A.
(fold_unary): Use the correct types when folding ~(X).

* gcc.dg/pr33691.c: New testcase.
        * gcc.dg/pr33694.c: Likewise.
        * gcc.dg/pr33696.c: Likewise.

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

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr33691.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr33694.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr33696.c [new file with mode: 0644]

index 5fed689..a54a60c 100644 (file)
@@ -1,3 +1,14 @@
+2007-10-08  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/33691
+       PR middle-end/33694
+       PR middle-end/33696
+       * fold-const.c (fold_binary): Use the correct types when
+       folding (A | CST1) & CST2 to (A & CST2) | (CST1 & CST2).
+       (fold_binary): Use the correct types when folding
+       (-A) - B to (-B) - A.
+       (fold_unary): Use the correct types when folding ~(X).
+
 2007-10-08  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        * doc/invoke.texi (Wall): fix formatting issues.
index 46e0e33..0313c0c 100644 (file)
@@ -8374,10 +8374,11 @@ fold_unary (enum tree_code code, tree type, tree op0)
       if (TREE_CODE (arg0) == INTEGER_CST)
         return fold_not_const (arg0, type);
       else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
-       return TREE_OPERAND (arg0, 0);
+       return TREE_OPERAND (op0, 0);
       /* Convert ~ (-A) to A - 1.  */
       else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
-       return fold_build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0),
+       return fold_build2 (MINUS_EXPR, type,
+                           fold_convert (type, TREE_OPERAND (arg0, 0)),
                            build_int_cst (type, 1));
       /* Convert ~ (A - 1) or ~ (A + -1) to -A.  */
       else if (INTEGRAL_TYPE_P (type)
@@ -8385,7 +8386,8 @@ fold_unary (enum tree_code code, tree type, tree op0)
                    && integer_onep (TREE_OPERAND (arg0, 1)))
                   || (TREE_CODE (arg0) == PLUS_EXPR
                       && integer_all_onesp (TREE_OPERAND (arg0, 1)))))
-       return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0));
+       return fold_build1 (NEGATE_EXPR, type,
+                           fold_convert (type, TREE_OPERAND (arg0, 0)));
       /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify.  */
       else if (TREE_CODE (arg0) == BIT_XOR_EXPR
               && (tem = fold_unary (BIT_NOT_EXPR, type,
@@ -10126,15 +10128,17 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
        }
       /* A - (-B) -> A + B */
       if (TREE_CODE (arg1) == NEGATE_EXPR)
-       return fold_build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0));
+       return fold_build2 (PLUS_EXPR, type, op0,
+                           fold_convert (type, TREE_OPERAND (arg1, 0)));
       /* (-A) - B -> (-B) - A  where B is easily negated and we can swap.  */
       if (TREE_CODE (arg0) == NEGATE_EXPR
          && (FLOAT_TYPE_P (type)
              || INTEGRAL_TYPE_P (type))
          && negate_expr_p (arg1)
          && reorder_operands_p (arg0, arg1))
-       return fold_build2 (MINUS_EXPR, type, negate_expr (arg1),
-                           TREE_OPERAND (arg0, 0));
+       return fold_build2 (MINUS_EXPR, type,
+                           fold_convert (type, negate_expr (arg1)),
+                           fold_convert (type, TREE_OPERAND (arg0, 0)));
       /* Convert -A - 1 to ~A.  */
       if (INTEGRAL_TYPE_P (type)
          && TREE_CODE (arg0) == NEGATE_EXPR
@@ -10889,11 +10893,16 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
       if (TREE_CODE (arg0) == BIT_IOR_EXPR
          && TREE_CODE (arg1) == INTEGER_CST
          && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
-       return fold_build2 (BIT_IOR_EXPR, type,
-                           fold_build2 (BIT_AND_EXPR, type,
-                                        TREE_OPERAND (arg0, 0), arg1),
-                           fold_build2 (BIT_AND_EXPR, type,
-                                        TREE_OPERAND (arg0, 1), arg1));
+       {
+         tree tmp1 = fold_convert (TREE_TYPE (arg0), arg1);
+         tree tmp2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
+                                  TREE_OPERAND (arg0, 0), tmp1);
+         tree tmp3 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
+                                  TREE_OPERAND (arg0, 1), tmp1);
+         return fold_convert (type,
+                              fold_build2 (BIT_IOR_EXPR, TREE_TYPE (arg0),
+                                           tmp2, tmp3));
+       }
 
       /* (X | Y) & Y is (X, Y).  */
       if (TREE_CODE (arg0) == BIT_IOR_EXPR
index 3997ac3..9af8f71 100644 (file)
@@ -1,3 +1,12 @@
+2007-10-08  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/33691
+       PR middle-end/33694
+       PR middle-end/33696
+       * gcc.dg/pr33691.c: New testcase.
+       * gcc.dg/pr33694.c: Likewise.
+       * gcc.dg/pr33696.c: Likewise.
+
 2007-10-07  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR libfortran/33683
diff --git a/gcc/testsuite/gcc.dg/pr33691.c b/gcc/testsuite/gcc.dg/pr33691.c
new file mode 100644 (file)
index 0000000..9321361
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+/* ICEd with type-checking enabled.  */
+
+unsigned int mgaSetTexImages(int i)
+{
+    return ((i | 0x40) & 0xffffffc0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr33694.c b/gcc/testsuite/gcc.dg/pr33694.c
new file mode 100644 (file)
index 0000000..eb7655e
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+
+/* This used to ICE with type-checking enabled.  */
+
+__SIZE_TYPE__ cnfs_mapcntl(long pagesize)
+{
+     return ~(__SIZE_TYPE__)(pagesize - 1);
+}
diff --git a/gcc/testsuite/gcc.dg/pr33696.c b/gcc/testsuite/gcc.dg/pr33696.c
new file mode 100644 (file)
index 0000000..97bbfe8
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+/* This used to ICE with type-checking enabled.  */
+
+typedef unsigned char uint8_t;
+typedef unsigned int uint_least32_t;
+extern int foo (long int __off);
+void write (uint_least32_t chunk_len)
+{
+     uint8_t tmp[4];
+     foo (-(long)chunk_len - sizeof(tmp));
+}
+