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.c (fold_binary): Transform (A >> C) << C into one BIT_AND_EXPR. <shift>: Transform (A OP c1) OP c2 into A OP (c1 + c2). From-SVN: r100853
This commit is contained in:
parent
4ae234b0a1
commit
e3d025cb0d
@ -1,3 +1,10 @@
|
||||
2005-06-12 James A. Morrison <phython@gcc.gnu.org>
|
||||
|
||||
PR tree-optimization/14796
|
||||
* fold-const.c (fold_binary): Transform (A >> C) << C into
|
||||
one BIT_AND_EXPR.
|
||||
<shift>: Transform (A OP c1) OP c2 into A OP (c1 + c2).
|
||||
|
||||
2005-06-11 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* config/rs6000/predicates.md (reg_or_arith_cint_operand): Delete.
|
||||
|
@ -8742,6 +8742,59 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
|
||||
don't try to compute it in the compiler. */
|
||||
if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) < 0)
|
||||
return NULL_TREE;
|
||||
|
||||
/* Turn (a OP c1) OP c2 into a OP (c1+c2). */
|
||||
if (TREE_CODE (arg0) == code && host_integerp (arg1, false)
|
||||
&& TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type)
|
||||
&& host_integerp (TREE_OPERAND (arg0, 1), false)
|
||||
&& TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < TYPE_PRECISION (type))
|
||||
{
|
||||
HOST_WIDE_INT low = (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1))
|
||||
+ TREE_INT_CST_LOW (arg1));
|
||||
|
||||
/* Deal with a OP (c1 + c2) being undefined but (a OP c1) OP c2
|
||||
being well defined. */
|
||||
if (low >= TYPE_PRECISION (type))
|
||||
{
|
||||
if (code == LROTATE_EXPR || code == RROTATE_EXPR)
|
||||
low = low % TYPE_PRECISION (type);
|
||||
else if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR)
|
||||
return build_int_cst (type, 0);
|
||||
else
|
||||
low = TYPE_PRECISION (type) - 1;
|
||||
}
|
||||
|
||||
return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
|
||||
build_int_cst (type, low));
|
||||
}
|
||||
|
||||
/* Transform (x >> c) << c into x & (-1<<c) */
|
||||
if (code == LSHIFT_EXPR && TREE_CODE (arg0) == RSHIFT_EXPR
|
||||
&& host_integerp (arg1, false)
|
||||
&& TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type)
|
||||
&& host_integerp (TREE_OPERAND (arg0, 1), false)
|
||||
&& TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < TYPE_PRECISION (type))
|
||||
{
|
||||
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;
|
||||
|
||||
if (low0 == low1)
|
||||
{
|
||||
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);
|
||||
|
||||
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)
|
||||
|
@ -1,3 +1,8 @@
|
||||
2005-06-12 James A. Morrison <phython@gcc.gnu.org>
|
||||
|
||||
* gcc.dg/pr14796-1.c: New.
|
||||
* gcc.dg/pr14796-2.c: New.
|
||||
|
||||
2005-06-11 Steven G. Kargl <kargls@comcast.net>
|
||||
|
||||
PR fortran/17792
|
||||
|
14
gcc/testsuite/gcc.dg/pr14796-1.c
Normal file
14
gcc/testsuite/gcc.dg/pr14796-1.c
Normal file
@ -0,0 +1,14 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
int f (int a) {
|
||||
return (a << 3) << 6;
|
||||
}
|
||||
|
||||
int g (int b) {
|
||||
return (b >> 5) << 5;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "a << 9" "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump "b & -32" "gimple" } } */
|
||||
/* { dg-final { cleanup-tree-dump "gimple" } } */
|
22
gcc/testsuite/gcc.dg/pr14796-2.c
Normal file
22
gcc/testsuite/gcc.dg/pr14796-2.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
int f (int a) {
|
||||
return (a << 31) << 6;
|
||||
}
|
||||
|
||||
unsigned int g (unsigned int a) {
|
||||
return (a >> 7) >> 25;
|
||||
}
|
||||
|
||||
int h (int b) {
|
||||
return (b >> 30) >> 30;
|
||||
}
|
||||
|
||||
long long j (long long c) {
|
||||
return (c >> 35) << 35;
|
||||
}
|
||||
/* { dg-final { scan-tree-dump-times "= 0" 2 "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump "b >> 31" "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump "c & -34359738368" "gimple" } } */
|
||||
/* { dg-final { cleanup-tree-dump "gimple" } } */
|
Loading…
Reference in New Issue
Block a user