aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2024-08-25 10:10:06 -0700
committerAndrew Pinski <quic_apinski@quicinc.com>2024-08-26 02:35:05 -0700
commit53b86cac7e77ddff4e8a215408f7331ebc5bf22c (patch)
treef6a8e66e3ef2f5e9b547d8cfe5e9a72b2faee124 /gcc
parentb4ac2c23d8745d98984954e88f02aa73f1c3594b (diff)
downloadgcc-53b86cac7e77ddff4e8a215408f7331ebc5bf22c.zip
gcc-53b86cac7e77ddff4e8a215408f7331ebc5bf22c.tar.gz
gcc-53b86cac7e77ddff4e8a215408f7331ebc5bf22c.tar.bz2
expand: Use the correct mode for store flags for popcount [PR116480]
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_apinski@quicinc.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/internal-fn.cc3
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr116480-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr116480-2.c8
3 files changed, 18 insertions, 1 deletions
diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index a96e61e..89da13b 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 0000000..15a5727
--- /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 0000000..7bf6902
--- /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;
+}
+