From 001c60ccfeaf9a480a56203418af804ad42e88b9 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Tue, 27 Sep 2022 10:30:00 +0200 Subject: [PATCH] range-ops: Calculate the popcount of a singleton. The legacy popcount folding didn't actually fold singleton ranges. I don't think anyone noticed because there are match.pd patterns that fold __builtin_popcount using the global nonzero bits set by CCP. It's good form to handle this, even without CCP's help. Tested on x86-64 Linux. gcc/ChangeLog: * gimple-range-op.cc (cfn_popcount): Calculate the popcount of a singleton. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/popcount6b.c: New test. --- gcc/gimple-range-op.cc | 8 ++++++++ gcc/testsuite/gcc.dg/tree-ssa/popcount6b.c | 6 ++++++ 2 files changed, 14 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/popcount6b.c diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index d7c6dfa933d1..3f5e5852e5a2 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -397,6 +397,14 @@ public: { if (lh.undefined_p ()) return false; + // Calculating the popcount of a singleton is trivial. + if (lh.singleton_p ()) + { + wide_int nz = lh.get_nonzero_bits (); + wide_int pop = wi::shwi (wi::popcount (nz), TYPE_PRECISION (type)); + r.set (type, pop, pop); + return true; + } // __builtin_ffs* and __builtin_popcount* return [0, prec]. int prec = TYPE_PRECISION (lh.type ()); // If arg is non-zero, then ffs or popcount are non-zero. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/popcount6b.c b/gcc/testsuite/gcc.dg/tree-ssa/popcount6b.c new file mode 100644 index 000000000000..90336ecb070b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/popcount6b.c @@ -0,0 +1,6 @@ +// { dg-do compile } +// { dg-options "-O2 -fdump-tree-evrp -fno-tree-ccp" } + +#include "popcount6.c" + +// { dg-final { scan-tree-dump "return 1;" "evrp" } } -- 2.47.2