Attached patch fixes phi-opt not optimizing c++ testcase where we have if (b_4(D) == 0) instead of if (b_4(D) != 0) as shown in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86544
Patch bootstrapped and regression tested on x86_64-linux-gnu with no new regressions. Is this OK for trunk? Thanks, Kugan gcc/ChangeLog: 2018-07-18 Kugan Vivekanandarajah <kug...@linaro.org> PR middle-end/86544 * tree-ssa-phiopt.c (cond_removal_in_popcount_pattern): Handle comparison with EQ_EXPR in last stmt. gcc/testsuite/ChangeLog: 2018-07-18 Kugan Vivekanandarajah <kug...@linaro.org> PR middle-end/86544 * g++.dg/tree-ssa/pr86544.C: New test.
From c482a4225764e0b338abafb7ccea4553f273f5d5 Mon Sep 17 00:00:00 2001 From: Kugan Vivekanandarajah <kugan.vivekanandara...@linaro.org> Date: Wed, 18 Jul 2018 08:14:16 +1000 Subject: [PATCH] fix cpp testcase Change-Id: Icd59b31faef2ac66beb42990cb69cbbe38c238aa --- gcc/testsuite/g++.dg/tree-ssa/pr86544.C | 15 +++++++++++++++ gcc/tree-ssa-phiopt.c | 26 +++++++++++++++----------- 2 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr86544.C 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) -- 2.7.4