On Sun, Aug 25, 2024 at 10:28 PM Andrew Pinski <quic_apin...@quicinc.com> wrote: > > When expanding popcount used for equal to 1 (or rather > __builtin_stdc_has_single_bit), > the wrong mode was bsing used for the mode of the store flags. We were using > the mode > of the argument to popcount but since popcount's return value is always int, > the mode > of the expansion here should have been the mode of the return type rater than > the argument. > > Built and tested on aarch64-linux-gnu with no regressions. > Also bootstrapped and tested on x86_64-linux-gnu.
OK. Richard. > PR middle-end/116480 > > gcc/ChangeLog: > > * internal-fn.cc (expand_POPCOUNT): Use the correct mode > for store flags. > > gcc/testsuite/ChangeLog: > > * gcc.dg/torture/pr116480-1.c: New test. > * gcc.dg/torture/pr116480-2.c: New test. > > Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> > --- > gcc/internal-fn.cc | 3 ++- > gcc/testsuite/gcc.dg/torture/pr116480-1.c | 8 ++++++++ > gcc/testsuite/gcc.dg/torture/pr116480-2.c | 8 ++++++++ > 3 files changed, 18 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr116480-1.c > create mode 100644 gcc/testsuite/gcc.dg/torture/pr116480-2.c > > diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc > index a96e61e527c..89da13b38ce 100644 > --- a/gcc/internal-fn.cc > +++ b/gcc/internal-fn.cc > @@ -5311,6 +5311,7 @@ expand_POPCOUNT (internal_fn fn, gcall *stmt) > bool nonzero_arg = integer_zerop (gimple_call_arg (stmt, 1)); > tree type = TREE_TYPE (arg); > machine_mode mode = TYPE_MODE (type); > + machine_mode lhsmode = TYPE_MODE (TREE_TYPE (lhs)); > do_pending_stack_adjust (); > start_sequence (); > expand_unary_optab_fn (fn, stmt, popcount_optab); > @@ -5318,7 +5319,7 @@ expand_POPCOUNT (internal_fn fn, gcall *stmt) > end_sequence (); > start_sequence (); > rtx plhs = expand_normal (lhs); > - rtx pcmp = emit_store_flag (NULL_RTX, EQ, plhs, const1_rtx, mode, 0, 0); > + rtx pcmp = emit_store_flag (NULL_RTX, EQ, plhs, const1_rtx, lhsmode, 0, 0); > if (pcmp == NULL_RTX) > { > fail: > diff --git a/gcc/testsuite/gcc.dg/torture/pr116480-1.c > b/gcc/testsuite/gcc.dg/torture/pr116480-1.c > new file mode 100644 > index 00000000000..15a5727941c > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr116480-1.c > @@ -0,0 +1,8 @@ > +/* { dg-do compile { target int128 } } */ > + > +int > +foo(unsigned __int128 b) > +{ > + return __builtin_popcountg(b) == 1; > +} > + > diff --git a/gcc/testsuite/gcc.dg/torture/pr116480-2.c > b/gcc/testsuite/gcc.dg/torture/pr116480-2.c > new file mode 100644 > index 00000000000..7bf690283b4 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr116480-2.c > @@ -0,0 +1,8 @@ > +/* { dg-do compile { target bitint } } */ > + > +int > +foo(unsigned _BitInt(127) b) > +{ > + return __builtin_popcountg(b) == 1; > +} > + > -- > 2.43.0 >