aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJames A. Morrison <phython@gcc.gnu.org>2005-06-13 00:18:41 +0000
committerJames A. Morrison <phython@gcc.gnu.org>2005-06-13 00:18:41 +0000
commita165e746471b32ea442c325732f5c2907034db45 (patch)
tree0e491ce1198062f770844aa5c3a1dadc4b298c0c /gcc
parent61e58d36f29d9c190c6e520a47f45e83582d9b74 (diff)
downloadgcc-a165e746471b32ea442c325732f5c2907034db45.zip
gcc-a165e746471b32ea442c325732f5c2907034db45.tar.gz
gcc-a165e746471b32ea442c325732f5c2907034db45.tar.bz2
re PR tree-optimization/14796 ([tree-ssa] combine two shifts into one)
2005-06-12 James A. Morrison <phython@gcc.gnu.org> PR tree-optimization/14796 * fold-const (fold_binary): Transform (X << C) >> C into X & (-1>>C) for unsigned types. From-SVN: r100869
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c15
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/pr14796-1.c10
4 files changed, 27 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1995605..b18b1e4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-06-12 James A. Morrison <phython@gcc.gnu.org>
+
+ PR tree-optimization/14796
+ * fold-const (fold_binary): Transform (X << C) >> C into X & (-1>>C)
+ for unsigned types.
+
2005-06-12 Kazu Hirata <kazu@codesourcery.com>
* cgraphunit.c, tree-ssa-loop-ivopts.c,
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 1994410..af3f01c 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8768,8 +8768,11 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
build_int_cst (type, low));
}
- /* Transform (x >> c) << c into x & (-1<<c) */
- if (code == LSHIFT_EXPR && TREE_CODE (arg0) == RSHIFT_EXPR
+ /* Transform (x >> c) << c into x & (-1<<c), or transform (x << c) >> c
+ into x & ((unsigned)-1 >> c) for unsigned types. */
+ if (((code == LSHIFT_EXPR && TREE_CODE (arg0) == RSHIFT_EXPR)
+ || (TYPE_UNSIGNED (type)
+ && code == RSHIFT_EXPR && TREE_CODE (arg0) == LSHIFT_EXPR))
&& host_integerp (arg1, false)
&& TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type)
&& host_integerp (TREE_OPERAND (arg0, 1), false)
@@ -8777,8 +8780,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
{
HOST_WIDE_INT low0 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1));
HOST_WIDE_INT low1 = TREE_INT_CST_LOW (arg1);
- unsigned HOST_WIDE_INT low;
- HOST_WIDE_INT high;
tree lshift;
tree arg00;
@@ -8786,15 +8787,13 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
{
arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
- lshift_double (-1, -1, low0 < low1 ? low0 : low1,
- TYPE_PRECISION (type), &low, &high, 1);
- lshift = build_int_cst_wide (type, low, high);
+ lshift = build_int_cst (type, -1);
+ lshift = int_const_binop (code, lshift, arg1, 0);
return fold_build2 (BIT_AND_EXPR, type, arg00, lshift);
}
}
-
/* Rewrite an LROTATE_EXPR by a constant into an
RROTATE_EXPR by a new constant. */
if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9ae809b..0baaf8a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2005-06-12 James A. Morrison <phython@gcc.gnu.org>
+
+ * ggcc.dg/pr14796-1.c: Add tests for (X << C) >> C.
+
2005-06-12 Roger Sayle <roger@eyesopen.com>
PR c++/21930
diff --git a/gcc/testsuite/gcc.dg/pr14796-1.c b/gcc/testsuite/gcc.dg/pr14796-1.c
index c927e2b..7ddc4fe 100644
--- a/gcc/testsuite/gcc.dg/pr14796-1.c
+++ b/gcc/testsuite/gcc.dg/pr14796-1.c
@@ -9,6 +9,16 @@ int g (int b) {
return (b >> 5) << 5;
}
+unsigned long long h (unsigned long long c) {
+ return (c << 60) >> 60;
+}
+
+int l (int d) {
+ return (d << 6) >> 6;
+}
+
/* { dg-final { scan-tree-dump "a << 9" "gimple" } } */
/* { dg-final { scan-tree-dump "b & -32" "gimple" } } */
+/* { dg-final { scan-tree-dump "c & 15" "gimple" } } */
+/* { dg-final { scan-tree-dump "d << 6" "gimple" } } */
/* { dg-final { cleanup-tree-dump "gimple" } } */