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.

        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

Reply via email to