re PR target/86677 (popcount builtin detection is breaking some kernel build)
authorKugan Vivekanandarajah <kuganv@linaro.org>
Mon, 12 Nov 2018 23:43:56 +0000 (23:43 +0000)
committerKugan Vivekanandarajah <kugan@gcc.gnu.org>
Mon, 12 Nov 2018 23:43:56 +0000 (23:43 +0000)
gcc/ChangeLog:

2018-11-13  Kugan Vivekanandarajah  <kuganv@linaro.org>

PR middle-end/86677
PR middle-end/87528
* tree-scalar-evolution.c (expression_expensive_p): Make BUILTIN POPCOUNT
as expensive when backend does not define it.

gcc/testsuite/ChangeLog:

2018-11-13  Kugan Vivekanandarajah  <kuganv@linaro.org>

PR middle-end/86677
PR middle-end/87528
* g++.dg/tree-ssa/pr86544.C: Run only for target supporting popcount
pattern.
* gcc.dg/tree-ssa/popcount.c: Likewise.
* gcc.dg/tree-ssa/popcount2.c: Likewise.
* gcc.dg/tree-ssa/popcount3.c: Likewise.
* gcc.target/aarch64/popcount4.c: New test.
* lib/target-supports.exp (check_effective_target_popcountl): New.

From-SVN: r266039

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/pr86544.C
gcc/testsuite/gcc.dg/tree-ssa/popcount.c
gcc/testsuite/gcc.dg/tree-ssa/popcount2.c
gcc/testsuite/gcc.dg/tree-ssa/popcount3.c
gcc/testsuite/gcc.target/aarch64/popcount4.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp
gcc/tree-scalar-evolution.c

index fd352724cefe693a122ab6d46fdde6ab1ce58feb..16ecf33dc349934fcb1308baf73c61a946d0df21 100644 (file)
@@ -1,3 +1,10 @@
+2018-11-13  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       PR middle-end/86677
+       PR middle-end/87528
+       * tree-scalar-evolution.c (expression_expensive_p): Make BUILTIN POPCOUNT
+       as expensive when backend does not define it.
+
 2018-11-12  Fredrik Noring  <noring@nocrew.org>
 
        * config.gcc: Update with-llsc defaults for MIPS r5900.
index 3bc031e70a7fba1368cd01be39a35ae8f2f63e73..cff23eee5a1594afd80ec043de601da65763ad0b 100644 (file)
@@ -1,3 +1,15 @@
+2018-11-13  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       PR middle-end/86677
+       PR middle-end/87528
+       * g++.dg/tree-ssa/pr86544.C: Run only for target supporting popcount
+       pattern.
+       * gcc.dg/tree-ssa/popcount.c: Likewise.
+       * gcc.dg/tree-ssa/popcount2.c: Likewise.
+       * gcc.dg/tree-ssa/popcount3.c: Likewise.
+       * gcc.target/aarch64/popcount4.c: New test.
+       * lib/target-supports.exp (check_effective_target_popcountl): New.
+
 2018-11-12  Martin Liska  <mliska@suse.cz>
 
        PR gcov-profile/87442
index fd844b48deb49341fc81950c91b741cb582f7d7e..ef438916a8019320564f444ace08e2f4b4190684 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-require-effective-target popcountl } */
 /* { dg-options "-O2 -fdump-tree-phiopt4 -fdump-tree-optimized" } */
 
 int PopCount (long b) {
index a5ec3b34f962de8b5658e41082559d68c1101320..b4694109411a4631697463519acbe7d9df65bf6e 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-require-effective-target popcountl } */
 /* { dg-options "-O3 -fdump-tree-optimized -fno-tree-ch" } */
 
 extern int foo (int);
index 9096c6bee04e27b6ec7e23fb86bc6b9a3e1f4406..ef73e345573de721833e98e89c252640a55f7c60 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-do run } */
+/* { dg-require-effective-target popcountl } */
 /* { dg-options "-O2 -fno-tree-ch -fdump-tree-optimized" } */
 
 int
index fd844b48deb49341fc81950c91b741cb582f7d7e..ef438916a8019320564f444ace08e2f4b4190684 100644 (file)
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-require-effective-target popcountl } */
 /* { dg-options "-O2 -fdump-tree-phiopt4 -fdump-tree-optimized" } */
 
 int PopCount (long b) {
diff --git a/gcc/testsuite/gcc.target/aarch64/popcount4.c b/gcc/testsuite/gcc.target/aarch64/popcount4.c
new file mode 100644 (file)
index 0000000..ee55b2e
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -mgeneral-regs-only" } */
+
+int PopCount (long b) {
+    int c = 0;
+
+    while (b) {
+       b &= b - 1;
+       c++;
+    }
+    return c;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_popcount" 0 "optimized" } } */
index e0c58010dd27b04d20b1d7130eb2622fe27b46f6..8e16efcd6401e1c9a03113f84b4a07c3675cc747 100644 (file)
@@ -6522,6 +6522,17 @@ proc check_effective_target_sync_long_long { } {
     }
 }
 
+# Return 1 if the target supports popcount on long.
+
+proc check_effective_target_popcountl { } {
+    return [check_no_messages_and_pattern popcountl "!\\(call" rtl-expand {
+       int foo (long b)
+         {
+           return __builtin_popcountl (b);
+         }
+    } "" ]
+}
+
 # Return 1 if the target supports atomic operations on "long long"
 # and can execute them.
 #
index 02174b1864c1a9b952b47a9606eed8a30ff872ad..964712ca7674bfb43bc0c89ae38eaf2a552fab0a 100644 (file)
@@ -257,7 +257,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "backend.h"
+#include "target.h"
 #include "rtl.h"
+#include "optabs-query.h"
 #include "tree.h"
 #include "gimple.h"
 #include "ssa.h"
@@ -282,6 +284,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-fold.h"
 #include "tree-into-ssa.h"
 #include "builtins.h"
+#include "case-cfn-macros.h"
 
 static tree analyze_scalar_evolution_1 (struct loop *, tree);
 static tree analyze_scalar_evolution_for_address_of (struct loop *loop,
@@ -3500,6 +3503,36 @@ expression_expensive_p (tree expr)
     {
       tree arg;
       call_expr_arg_iterator iter;
+      /* Even though is_inexpensive_builtin might say true, we will get a
+        library call for popcount when backend does not have an instruction
+        to do so.  We consider this to be expenseive and generate
+        __builtin_popcount only when backend defines it.  */
+      combined_fn cfn = get_call_combined_fn (expr);
+      switch (cfn)
+       {
+       CASE_CFN_POPCOUNT:
+         /* Check if opcode for popcount is available in the mode required.  */
+         if (optab_handler (popcount_optab,
+                            TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (expr, 0))))
+             == CODE_FOR_nothing)
+           {
+             machine_mode mode;
+             mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (expr, 0)));
+             scalar_int_mode int_mode;
+
+             /* If the mode is of 2 * UNITS_PER_WORD size, we can handle
+                double-word popcount by emitting two single-word popcount
+                instructions.  */
+             if (is_a <scalar_int_mode> (mode, &int_mode)
+                 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
+                 && (optab_handler (popcount_optab, word_mode)
+                     != CODE_FOR_nothing))
+                 break;
+             return true;
+           }
+       default:
+         break;
+       }
 
       if (!is_inexpensive_builtin (get_callee_fndecl (expr)))
        return true;