From 2298ade7e57440cf008e0f7a2114fe37019bc2b0 Mon Sep 17 00:00:00 2001 From: Dmitry Melnik Date: Wed, 20 Oct 2010 12:26:10 +0000 Subject: [PATCH] fold-const.c (fold_binary_loc): New transformation. 2010-10-20 Dmitry Melnik gcc/ * fold-const.c (fold_binary_loc): New transformation. gcc/testsuite/ * gcc.dg/20101013-1.c: New test. From-SVN: r165720 --- gcc/ChangeLog | 4 ++++ gcc/fold-const.c | 25 +++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/20101013-1.c | 11 +++++++++++ 4 files changed, 44 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/20101013-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 686b5912802..3db8d6e3446 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2010-10-20 Dmitry Melnik + + * fold-const.c (fold_binary_loc): New transformation. + 2010-10-20 H.J. Lu PR target/46085 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 808f491cbb8..decb0fba8f5 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -11599,6 +11599,31 @@ fold_binary_loc (location_t loc, return NULL_TREE; case TRUNC_DIV_EXPR: + /* Optimize (X & (-A)) / A where A is a power of 2, + to X >> log2(A) */ + if (TREE_CODE (arg0) == BIT_AND_EXPR + && !TYPE_UNSIGNED (type) && TREE_CODE (arg1) == INTEGER_CST + && integer_pow2p (arg1) && tree_int_cst_sgn (arg1) > 0) + { + tree sum = fold_binary_loc (loc, PLUS_EXPR, TREE_TYPE (arg1), + arg1, TREE_OPERAND (arg0, 1)); + if (sum && integer_zerop (sum)) { + unsigned long pow2; + + if (TREE_INT_CST_LOW (arg1)) + pow2 = exact_log2 (TREE_INT_CST_LOW (arg1)); + else + pow2 = exact_log2 (TREE_INT_CST_HIGH (arg1)) + + HOST_BITS_PER_WIDE_INT; + + return fold_build2_loc (loc, RSHIFT_EXPR, type, + TREE_OPERAND (arg0, 0), + build_int_cst (NULL_TREE, pow2)); + } + } + + /* Fall thru */ + case FLOOR_DIV_EXPR: /* Simplify A / (B << N) where A and B are positive and B is a power of 2, to A >> (N + log2(B)). */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fe74a3faa10..f69e743ac40 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-10-20 Dmitry Melnik + + * gcc.dg/20101013-1.c: New test. + 2010-10-20 H.J. Lu PR target/46085 diff --git a/gcc/testsuite/gcc.dg/20101013-1.c b/gcc/testsuite/gcc.dg/20101013-1.c new file mode 100644 index 00000000000..b5bd3a7ce65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20101013-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int foo(int a) +{ + int x = (a & (~15)) / 16; + return x; +} + +/* { dg-final { scan-tree-dump ">>" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */