]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
fold-const.c (fold_unary): Fold (T1)(~(T2)X) as ~(T1)X...
authorRoger Sayle <roger@eyesopen.com>
Tue, 28 Mar 2006 17:06:19 +0000 (17:06 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 28 Mar 2006 17:06:19 +0000 (17:06 +0000)
* fold-const.c (fold_unary) <NOP_EXPR>: Fold (T1)(~(T2)X) as
~(T1)X, when T1 and T2 are integer types of the same precision
and (T2)X isn't an extension.

* gcc.dg/fold-convnotconv-1.c: New test case.

From-SVN: r112455

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

index 69f7f65f6fcbbb8c8e929eb3cacfc0f9219aa01a..64bbd152acf160e85ecfab1dbc6c4313631a9a23 100644 (file)
@@ -1,3 +1,9 @@
+2006-03-28  Roger Sayle  <roger@eyesopen.com>
+
+       * fold-const.c (fold_unary) <NOP_EXPR>: Fold (T1)(~(T2)X) as
+       ~(T1)X, when T1 and T2 are integer types of the same precision
+       and (T2)X isn't an extension.
+
 2006-03-28  Jeff Law  <law@redhat.com>
 
        PR tree-optimization/26796
index 1381184f115c9039038d525bb913d397419bc30a..695dc5d35122ca504e07c62d9f3e4bc4d0235f51 100644 (file)
@@ -7074,6 +7074,22 @@ fold_unary (enum tree_code code, tree type, tree op0)
                           TREE_OPERAND (arg0, 1));
        }
 
+      /* Convert (T1)(~(T2)X) into ~(T1)X if T1 and T2 are integral types
+        of the same precision, and X is a integer type not narrower than
+        types T1 or T2, i.e. the cast (T2)X isn't an extension.  */
+      if (INTEGRAL_TYPE_P (type)
+         && TREE_CODE (op0) == BIT_NOT_EXPR
+         && INTEGRAL_TYPE_P (TREE_TYPE (op0))
+         && (TREE_CODE (TREE_OPERAND (op0, 0)) == NOP_EXPR
+             || TREE_CODE (TREE_OPERAND (op0, 0)) == CONVERT_EXPR)
+         && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0)))
+       {
+         tem = TREE_OPERAND (TREE_OPERAND (op0, 0), 0);
+         if (INTEGRAL_TYPE_P (TREE_TYPE (tem))
+             && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (tem)))
+           return fold_build1 (BIT_NOT_EXPR, type, fold_convert (type, tem));
+       }
+
       tem = fold_convert_const (code, type, arg0);
       return tem ? tem : NULL_TREE;
 
index c2383d247b5db5b1fda5a27eb0228b0149e7f3d4..8443fdaded5c95555276e271be1dcfae19bee9b9 100644 (file)
@@ -1,3 +1,7 @@
+2006-03-28  Roger Sayle  <roger@eyesopen.com>
+
+       * gcc.dg/fold-convnotconv-1.c: New test case.
+
 2006-03-28 Paul Thomas <pault@gcc.gnu.org>
 
        PR fortran/26779
diff --git a/gcc/testsuite/gcc.dg/fold-convnotconv-1.c b/gcc/testsuite/gcc.dg/fold-convnotconv-1.c
new file mode 100644 (file)
index 0000000..fc07903
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+
+int test1(int a)
+{
+  return ~(unsigned int)a;
+}
+
+unsigned int test2(unsigned int b)
+{
+  return ~(int)b;
+}
+
+/* { dg-final { scan-tree-dump-times "~a" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "~b" 1 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
+