[PR86544] Fix Popcount detection generates different code on C and C++

Message ID CAELXzTMBKQ1xjW7rskYfuZeM5d1RrUC1BpQtQK-EQw5f3nyYog@mail.gmail.com
State New
Headers show
Series
  • [PR86544] Fix Popcount detection generates different code on C and C++
Related show

Commit Message

Kugan Vivekanandarajah July 18, 2018, 2:18 a.m.
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  <kuganv@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  <kuganv@linaro.org>

    PR middle-end/86544
    * g++.dg/tree-ssa/pr86544.C: New test.

Comments

Richard Biener July 18, 2018, 9:55 a.m. | #1
On Wed, Jul 18, 2018 at 4:19 AM Kugan Vivekanandarajah
<kugan.vivekanandarajah@linaro.org> wrote:
>

> 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?


OK.

Richard.

> Thanks,

> Kugan

>

> gcc/ChangeLog:

>

> 2018-07-18  Kugan Vivekanandarajah  <kuganv@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  <kuganv@linaro.org>

>

>     PR middle-end/86544

>     * g++.dg/tree-ssa/pr86544.C: New test.

Patch

From c482a4225764e0b338abafb7ccea4553f273f5d5 Mon Sep 17 00:00:00 2001
From: Kugan Vivekanandarajah <kugan.vivekanandarajah@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