From 0c12cd5e90c8582adc5ed452d9eaa910f682b94b Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Tue, 13 Mar 2012 13:47:35 +0000 Subject: [PATCH] re PR middle-end/52134 (Does not fold (x * 4) & -4) 2012-03-13 Richard Guenther PR middle-end/52134 * fold-const.c (fold_binary_loc): Fold (X * Y) & -(1 << CST) to X * Y if Y is a constant multiple of 1 << CST. * gcc.dg/pr52134.c: New testcase. From-SVN: r185334 --- gcc/ChangeLog | 6 ++++++ gcc/fold-const.c | 14 ++++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr52134.c | 14 ++++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/pr52134.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34d49a2705a..d5c679cf479 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2012-03-13 Richard Guenther + + PR middle-end/52134 + * fold-const.c (fold_binary_loc): Fold (X * Y) & -(1 << CST) to X * Y + if Y is a constant multiple of 1 << CST. + 2012-03-13 Georg-Johann Lay PR target/52488 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0f806752dd3..ab653ea074b 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -11398,6 +11398,20 @@ fold_binary_loc (location_t loc, fold_convert_loc (loc, type, arg0)); } + /* Fold (X * Y) & -(1 << CST) to X * Y if Y is a constant + multiple of 1 << CST. */ + if (TREE_CODE (arg1) == INTEGER_CST) + { + double_int cst1 = tree_to_double_int (arg1); + double_int ncst1 = double_int_ext (double_int_neg (cst1), + TYPE_PRECISION (TREE_TYPE (arg1)), + TYPE_UNSIGNED (TREE_TYPE (arg1))); + if (double_int_equal_p (double_int_and (cst1, ncst1), ncst1) + && multiple_of_p (type, arg0, + double_int_to_tree (TREE_TYPE (arg1), ncst1))) + return fold_convert_loc (loc, type, arg0); + } + /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M, ((A & N) + B) & M -> (A + B) & M Similarly if (N & M) == 0, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e2f1b876ae7..1e6c43facdc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-03-13 Richard Guenther + + PR middle-end/52134 + * gcc.dg/pr52134.c: New testcase. + 2012-03-13 Rainer Orth * ada/acats/tests/cd/cdd1001.a (CDD1001): Fix typo. diff --git a/gcc/testsuite/gcc.dg/pr52134.c b/gcc/testsuite/gcc.dg/pr52134.c new file mode 100644 index 00000000000..44cb4a6f3de --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr52134.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-original" } */ + +unsigned f(unsigned t) +{ + return (t*4)&-4; +} +int f1(int t) +{ + return (t*4)&-4; +} + +/* { dg-final { scan-tree-dump-not "\\\&" "original" } } */ +/* { dg-final { cleanup-tree-dump "original" } } */