diff --git a/gcc/testsuite/gcc.target/aarch64/popcount4.c b/gcc/testsuite/gcc.target/aarch64/popcount4.c index e69de29..ee55b2e 100644 --- a/gcc/testsuite/gcc.target/aarch64/popcount4.c +++ b/gcc/testsuite/gcc.target/aarch64/popcount4.c @@ -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" } } */ diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index 69122f2..ec8e4ec 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -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,23 @@ expression_expensive_p (tree expr) { tree arg; call_expr_arg_iterator iter; + tree fndecl = get_callee_fndecl (expr); + + if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) + { + combined_fn cfn = as_combined_fn (DECL_FUNCTION_CODE (fndecl)); + switch (cfn) + { + CASE_CFN_POPCOUNT: + /* Check if opcode for popcount is available. */ + if (optab_handler (popcount_optab, + TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (expr, 0)))) + == CODE_FOR_nothing) + return true; + default: + break; + } + } if (!is_inexpensive_builtin (get_callee_fndecl (expr))) return true;