Commit a165e746 by James A. Morrison

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
parent 61e58d36
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> 2005-06-12 Kazu Hirata <kazu@codesourcery.com>
* cgraphunit.c, tree-ssa-loop-ivopts.c, * cgraphunit.c, tree-ssa-loop-ivopts.c,
......
...@@ -8768,8 +8768,11 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) ...@@ -8768,8 +8768,11 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
build_int_cst (type, low)); build_int_cst (type, low));
} }
/* Transform (x >> c) << c into x & (-1<<c) */ /* Transform (x >> c) << c into x & (-1<<c), or transform (x << c) >> c
if (code == LSHIFT_EXPR && TREE_CODE (arg0) == RSHIFT_EXPR 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) && host_integerp (arg1, false)
&& TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type) && TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type)
&& host_integerp (TREE_OPERAND (arg0, 1), false) && host_integerp (TREE_OPERAND (arg0, 1), false)
...@@ -8777,8 +8780,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) ...@@ -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 low0 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1));
HOST_WIDE_INT low1 = TREE_INT_CST_LOW (arg1); HOST_WIDE_INT low1 = TREE_INT_CST_LOW (arg1);
unsigned HOST_WIDE_INT low;
HOST_WIDE_INT high;
tree lshift; tree lshift;
tree arg00; tree arg00;
...@@ -8786,15 +8787,13 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1) ...@@ -8786,15 +8787,13 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
{ {
arg00 = fold_convert (type, TREE_OPERAND (arg0, 0)); arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));
lshift_double (-1, -1, low0 < low1 ? low0 : low1, lshift = build_int_cst (type, -1);
TYPE_PRECISION (type), &low, &high, 1); lshift = int_const_binop (code, lshift, arg1, 0);
lshift = build_int_cst_wide (type, low, high);
return fold_build2 (BIT_AND_EXPR, type, arg00, lshift); return fold_build2 (BIT_AND_EXPR, type, arg00, lshift);
} }
} }
/* Rewrite an LROTATE_EXPR by a constant into an /* Rewrite an LROTATE_EXPR by a constant into an
RROTATE_EXPR by a new constant. */ RROTATE_EXPR by a new constant. */
if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST) if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
......
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> 2005-06-12 Roger Sayle <roger@eyesopen.com>
PR c++/21930 PR c++/21930
......
...@@ -9,6 +9,16 @@ int g (int b) { ...@@ -9,6 +9,16 @@ int g (int b) {
return (b >> 5) << 5; 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 "a << 9" "gimple" } } */
/* { dg-final { scan-tree-dump "b & -32" "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" } } */ /* { dg-final { cleanup-tree-dump "gimple" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment