diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2022-10-03 17:31:32 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2022-10-04 06:23:14 +0200 |
commit | f50d103183c551c7f9f9f20efaf2ebbf83d5e99f (patch) | |
tree | 77e624677cb5b50d227f3697078e6d93f18a8dc1 /gcc | |
parent | 70e3f71a279856eabf99bbc92c0345c3ad20b615 (diff) | |
download | gcc-f50d103183c551c7f9f9f20efaf2ebbf83d5e99f.zip gcc-f50d103183c551c7f9f9f20efaf2ebbf83d5e99f.tar.gz gcc-f50d103183c551c7f9f9f20efaf2ebbf83d5e99f.tar.bz2 |
[PR107130] range-ops: Separate out ffs and popcount optimizations.
__builtin_popcount and __builtin_ffs were sharing the same range-ops
entry, but the nonzero mask optimization is not valid for ffs.
Separate them out into two entries.
PR tree-optimization/107130
gcc/ChangeLog:
* gimple-range-op.cc (class cfn_popcount): Call op_cfn_ffs.
(class cfn_ffs): New.
(gimple_range_op_handler::maybe_builtin_call): Separate out
CASE_CFN_FFS into its own case.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/pr107130.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-range-op.cc | 37 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr107130.c | 19 |
2 files changed, 46 insertions, 10 deletions
diff --git a/gcc/gimple-range-op.cc b/gcc/gimple-range-op.cc index 3a7c907..5b71d1c 100644 --- a/gcc/gimple-range-op.cc +++ b/gcc/gimple-range-op.cc @@ -387,8 +387,8 @@ cfn_toupper_tolower::fold_range (irange &r, tree type, const irange &lh, return true; } -// Implement range operator for CFN_BUILT_IN_FFS and CFN_BUILT_IN_POPCOUNT. -class cfn_popcount : public range_operator +// Implement range operator for CFN_BUILT_IN_FFS. +class cfn_ffs : public range_operator { public: using range_operator::fold_range; @@ -397,14 +397,6 @@ 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. @@ -420,6 +412,26 @@ public: r.set (build_int_cst (type, mini), build_int_cst (type, maxi)); return true; } +} op_cfn_ffs; + +// Implement range operator for CFN_BUILT_IN_POPCOUNT. +class cfn_popcount : public cfn_ffs +{ +public: + using range_operator::fold_range; + virtual bool fold_range (irange &r, tree type, const irange &lh, + const irange &rh, relation_kind rel) const + { + // 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; + } + return cfn_ffs::fold_range (r, type, lh, rh, rel); + } } op_cfn_popcount; // Implement range operator for CFN_BUILT_IN_CLZ @@ -734,6 +746,11 @@ gimple_range_op_handler::maybe_builtin_call () break; CASE_CFN_FFS: + m_op1 = gimple_call_arg (call, 0); + m_int = &op_cfn_ffs; + m_valid = true; + break; + CASE_CFN_POPCOUNT: m_op1 = gimple_call_arg (call, 0); m_int = &op_cfn_popcount; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107130.c b/gcc/testsuite/gcc.dg/tree-ssa/pr107130.c new file mode 100644 index 0000000..11fb816 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107130.c @@ -0,0 +1,19 @@ +// { dg-do compile } +// { dg-options "-Os -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre -fdump-tree-vrp1" } + +static inline int +foo (int i) +{ + return __builtin_ffsl (i); +} + +int +main (void) +{ + int x = foo (41); + if (x != 1) + __builtin_abort (); + return 0; +} + +// { dg-final { scan-tree-dump-not "builtin_abort" "vrp1" } } |