PR c/37261
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Aug 2008 18:59:13 +0000 (18:59 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Aug 2008 18:59:13 +0000 (18:59 +0000)
* fold-const.c (fold_binary): In (X | C1) & C2 canonicalization
compute new & and | in type rather than TREE_TYPE (arg0).

* gcc.dg/pr37261.c: New test.

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

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

index d326fc9..afc52ad 100644 (file)
@@ -1,5 +1,9 @@
 2008-08-29  Jakub Jelinek  <jakub@redhat.com>
 
+       PR c/37261
+       * fold-const.c (fold_binary): In (X | C1) & C2 canonicalization
+       compute new & and | in type rather than TREE_TYPE (arg0).
+
        * dwarf2out.c (fortran_common): Update comment.
        (gen_variable_die): Swap com_die and var_die variables in Fortran
        COMMON block handling code.
index af16433..01936bd 100644 (file)
@@ -10737,14 +10737,13 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
          && TREE_CODE (arg1) == INTEGER_CST
          && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
        {
-         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);
+         tree tmp1 = fold_convert (type, arg1);
+         tree tmp2 = fold_convert (type, TREE_OPERAND (arg0, 0));
+         tree tmp3 = fold_convert (type, TREE_OPERAND (arg0, 1));
+         tmp2 = fold_build2 (BIT_AND_EXPR, type, tmp2, tmp1);
+         tmp3 = fold_build2 (BIT_AND_EXPR, type, tmp3, tmp1);
          return fold_convert (type,
-                              fold_build2 (BIT_IOR_EXPR, TREE_TYPE (arg0),
-                                           tmp2, tmp3));
+                              fold_build2 (BIT_IOR_EXPR, type, tmp2, tmp3));
        }
 
       /* (X | Y) & Y is (X, Y).  */
index 5f0d09e..7cae5e9 100644 (file)
@@ -1,4 +1,7 @@
-2008-08-22  Jakub Jelinek  <jakub@redhat.com>
+2008-08-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/37261
+       * gcc.dg/pr37261.c: New test.
 
        PR fortran/23057
        * gfortran.dg/debug/pr35154-dwarf2.f: Adjust for replacement
diff --git a/gcc/testsuite/gcc.dg/pr37261.c b/gcc/testsuite/gcc.dg/pr37261.c
new file mode 100644 (file)
index 0000000..a05ada1
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR c/37261 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+unsigned
+foo (int x)
+{
+  unsigned a = ((x & 1) | 2) & 0x80000000;     /* { dg-bogus "integer overflow in expression" } */
+  unsigned b = ((x & 2) | 2) & 0x80000000;     /* { dg-bogus "integer overflow in expression" } */
+  unsigned c = ((x & 4) | 2) & 0x80000000;     /* { dg-bogus "integer overflow in expression" } */
+  return a + b + c;
+}
+
+/* { dg-final { scan-tree-dump "return 0" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */