From: James A. Morrison Date: Sun, 12 Jun 2005 08:03:23 +0000 (+0000) Subject: re PR tree-optimization/14796 ([tree-ssa] combine two shifts into one) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e3d025cb0d1ff48a9c6b34fd134350368105e695;p=gcc.git re PR tree-optimization/14796 ([tree-ssa] combine two shifts into one) 2005-06-12 James A. Morrison PR tree-optimization/14796 * fold-const.c (fold_binary): Transform (A >> C) << C into one BIT_AND_EXPR. : Transform (A OP c1) OP c2 into A OP (c1 + c2). From-SVN: r100853 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4a6d731acb1..6582d719891 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2005-06-12 James A. Morrison + + PR tree-optimization/14796 + * fold-const.c (fold_binary): Transform (A >> C) << C into + one BIT_AND_EXPR. + : Transform (A OP c1) OP c2 into A OP (c1 + c2). + 2005-06-11 Geoffrey Keating * config/rs6000/predicates.md (reg_or_arith_cint_operand): Delete. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 96fffe995d4..1994410d4be 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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< + + * gcc.dg/pr14796-1.c: New. + * gcc.dg/pr14796-2.c: New. + 2005-06-11 Steven G. Kargl PR fortran/17792 diff --git a/gcc/testsuite/gcc.dg/pr14796-1.c b/gcc/testsuite/gcc.dg/pr14796-1.c new file mode 100644 index 00000000000..c927e2b5403 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr14796-1.c @@ -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" } } */ diff --git a/gcc/testsuite/gcc.dg/pr14796-2.c b/gcc/testsuite/gcc.dg/pr14796-2.c new file mode 100644 index 00000000000..de4ec27da91 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr14796-2.c @@ -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" } } */