diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/pr86544.C | 15 | ||||
-rw-r--r-- | gcc/tree-ssa-phiopt.c | 26 |
4 files changed, 41 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 920b105..b34ae54 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-07-18 Kugan Vivekanandarajah <kuganv@linaro.org> + + PR middle-end/86544 + * tree-ssa-phiopt.c (cond_removal_in_popcount_pattern): Handle comparision with EQ_EXPR + in last stmt. + 2018-07-18 Kelvin Nilsen <kelvin@gcc.gnu.org> * doc/extend.texi (PowerPC AltiVec Built-in Functions): Rename diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1b7364a..f0e0825 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-07-18 Kugan Vivekanandarajah <kuganv@linaro.org> + + PR middle-end/86544 + * g++.dg/tree-ssa/pr86544.C: New test. + 2018-07-18 Jakub Jelinek <jakub@redhat.com> PR c++/86550 diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr86544.C b/gcc/testsuite/g++.dg/tree-ssa/pr86544.C new file mode 100644 index 0000000..8a90089 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr86544.C @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt3 -fdump-tree-optimized" } */ + +int PopCount (long b) { + int c = 0; + + while (b) { + b &= b - 1; + c++; + } + return c; +} + +/* { dg-final { scan-tree-dump-times "__builtin_popcount" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "if" 0 "phiopt3" } } */ diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 656f840..1667bad 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -1614,8 +1614,22 @@ cond_removal_in_popcount_pattern (basic_block cond_bb, basic_block middle_bb, arg = gimple_assign_rhs1 (cast); } + cond = last_stmt (cond_bb); + + /* Cond_bb has a check for b_4 [!=|==] 0 before calling the popcount + builtin. */ + if (gimple_code (cond) != GIMPLE_COND + || (gimple_cond_code (cond) != NE_EXPR + && gimple_cond_code (cond) != EQ_EXPR) + || !integer_zerop (gimple_cond_rhs (cond)) + || arg != gimple_cond_lhs (cond)) + return false; + /* Canonicalize. */ - if (e2->flags & EDGE_TRUE_VALUE) + if ((e2->flags & EDGE_TRUE_VALUE + && gimple_cond_code (cond) == NE_EXPR) + || (e1->flags & EDGE_TRUE_VALUE + && gimple_cond_code (cond) == EQ_EXPR)) { std::swap (arg0, arg1); std::swap (e1, e2); @@ -1625,16 +1639,6 @@ cond_removal_in_popcount_pattern (basic_block cond_bb, basic_block middle_bb, if (lhs != arg0 || !integer_zerop (arg1)) return false; - cond = last_stmt (cond_bb); - - /* Cond_bb has a check for b_4 != 0 before calling the popcount - builtin. */ - if (gimple_code (cond) != GIMPLE_COND - || gimple_cond_code (cond) != NE_EXPR - || !integer_zerop (gimple_cond_rhs (cond)) - || arg != gimple_cond_lhs (cond)) - return false; - /* And insert the popcount builtin and cast stmt before the cond_bb. */ gsi = gsi_last_bb (cond_bb); if (cast) |