public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-9192] expand: Add trivial folding for bit query builtins at expansion time [PR114044]
@ 2024-02-27  8:55 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2024-02-27  8:55 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c3c44c01d20b00ab5228f32596153b7f4cbc6036

commit r14-9192-gc3c44c01d20b00ab5228f32596153b7f4cbc6036
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Feb 27 09:52:07 2024 +0100

    expand: Add trivial folding for bit query builtins at expansion time [PR114044]
    
    While it seems a lot of places in various optimization passes fold
    bit query internal functions with INTEGER_CST arguments to INTEGER_CST
    when there is a lhs, when lhs is missing, all the removals of such dead
    stmts are guarded with -ftree-dce, so with -fno-tree-dce those unfolded
    ifn calls remain in the IL until expansion.  If they have large/huge
    BITINT_TYPE arguments, there is no BLKmode optab and so expansion ICEs,
    and bitint lowering doesn't touch such calls because it doesn't know they
    need touching, functions only containing those will not even be further
    processed by the pass because there are no non-small BITINT_TYPE SSA_NAMEs
    + the 2 exceptions (stores of BITINT_TYPE INTEGER_CSTs and conversions
    from BITINT_TYPE INTEGER_CSTs to floating point SSA_NAMEs) and when walking
    there is no special case for calls with BITINT_TYPE INTEGER_CSTs either,
    those are for normal calls normally handled at expansion time.
    
    So, the following patch adjust the expansion of these 6 ifns, by doing
    nothing if there is no lhs, and also just in case and user disabled all
    possible passes that would fold this handles the case of setting lhs
    to ifn call with INTEGER_CST argument.
    
    2024-02-27  Jakub Jelinek  <jakub@redhat.com>
    
            PR rtl-optimization/114044
            * internal-fn.def (CLRSB, CLZ, CTZ, FFS, PARITY): Use
            DEF_INTERNAL_INT_EXT_FN macro rather than DEF_INTERNAL_INT_FN.
            * internal-fn.h (expand_CLRSB, expand_CLZ, expand_CTZ, expand_FFS,
            expand_PARITY): Declare.
            * internal-fn.cc (expand_bitquery, expand_CLRSB, expand_CLZ,
            expand_CTZ, expand_FFS, expand_PARITY): New functions.
            (expand_POPCOUNT): Use expand_bitquery.
    
            * gcc.dg/bitint-95.c: New test.

Diff:
---
 gcc/internal-fn.cc               | 55 ++++++++++++++++++++++++++++++++++++++++
 gcc/internal-fn.def              | 10 ++++----
 gcc/internal-fn.h                |  5 ++++
 gcc/testsuite/gcc.dg/bitint-95.c | 45 ++++++++++++++++++++++++++++++++
 4 files changed, 110 insertions(+), 5 deletions(-)

diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc
index a07f25f3aee..fcf47c7fa12 100644
--- a/gcc/internal-fn.cc
+++ b/gcc/internal-fn.cc
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "explow.h"
 #include "rtl-iter.h"
 #include "gimple-range.h"
+#include "fold-const-call.h"
 
 /* For lang_hooks.types.type_for_mode.  */
 #include "langhooks.h"
@@ -5107,9 +5108,63 @@ expand_BITINTTOFLOAT (internal_fn, gcall *stmt)
     emit_move_insn (target, val);
 }
 
+static bool
+expand_bitquery (internal_fn fn, gcall *stmt)
+{
+  tree lhs = gimple_call_lhs (stmt);
+  if (lhs == NULL_TREE)
+    return false;
+  tree arg = gimple_call_arg (stmt, 0);
+  if (TREE_CODE (arg) == INTEGER_CST)
+    {
+      tree ret = fold_const_call (as_combined_fn (fn), TREE_TYPE (arg), arg);
+      gcc_checking_assert (ret && TREE_CODE (ret) == INTEGER_CST);
+      expand_assignment (lhs, ret, false);
+      return false;
+    }
+  return true;
+}
+
+void
+expand_CLRSB (internal_fn fn, gcall *stmt)
+{
+  if (expand_bitquery (fn, stmt))
+    expand_unary_optab_fn (fn, stmt, clrsb_optab);
+}
+
+void
+expand_CLZ (internal_fn fn, gcall *stmt)
+{
+  if (expand_bitquery (fn, stmt))
+    expand_unary_optab_fn (fn, stmt, clz_optab);
+}
+
+void
+expand_CTZ (internal_fn fn, gcall *stmt)
+{
+  if (expand_bitquery (fn, stmt))
+    expand_unary_optab_fn (fn, stmt, ctz_optab);
+}
+
+void
+expand_FFS (internal_fn fn, gcall *stmt)
+{
+  if (expand_bitquery (fn, stmt))
+    expand_unary_optab_fn (fn, stmt, ffs_optab);
+}
+
+void
+expand_PARITY (internal_fn fn, gcall *stmt)
+{
+  if (expand_bitquery (fn, stmt))
+    expand_unary_optab_fn (fn, stmt, parity_optab);
+}
+
 void
 expand_POPCOUNT (internal_fn fn, gcall *stmt)
 {
+  if (!expand_bitquery (fn, stmt))
+    return;
   if (gimple_call_num_args (stmt) == 1)
     {
       expand_unary_optab_fn (fn, stmt, popcount_optab);
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index c14d30365c1..848bb9dbff3 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -440,11 +440,11 @@ DEF_INTERNAL_OPTAB_FN (COMPLEX_FMS, ECF_CONST, cmls, ternary)
 DEF_INTERNAL_OPTAB_FN (COMPLEX_FMS_CONJ, ECF_CONST, cmls_conj, ternary)
 
 /* Unary integer ops.  */
-DEF_INTERNAL_INT_FN (CLRSB, ECF_CONST | ECF_NOTHROW, clrsb, unary)
-DEF_INTERNAL_INT_FN (CLZ, ECF_CONST | ECF_NOTHROW, clz, unary)
-DEF_INTERNAL_INT_FN (CTZ, ECF_CONST | ECF_NOTHROW, ctz, unary)
-DEF_INTERNAL_INT_FN (FFS, ECF_CONST | ECF_NOTHROW, ffs, unary)
-DEF_INTERNAL_INT_FN (PARITY, ECF_CONST | ECF_NOTHROW, parity, unary)
+DEF_INTERNAL_INT_EXT_FN (CLRSB, ECF_CONST | ECF_NOTHROW, clrsb, unary)
+DEF_INTERNAL_INT_EXT_FN (CLZ, ECF_CONST | ECF_NOTHROW, clz, unary)
+DEF_INTERNAL_INT_EXT_FN (CTZ, ECF_CONST | ECF_NOTHROW, ctz, unary)
+DEF_INTERNAL_INT_EXT_FN (FFS, ECF_CONST | ECF_NOTHROW, ffs, unary)
+DEF_INTERNAL_INT_EXT_FN (PARITY, ECF_CONST | ECF_NOTHROW, parity, unary)
 DEF_INTERNAL_INT_EXT_FN (POPCOUNT, ECF_CONST | ECF_NOTHROW, popcount, unary)
 
 DEF_INTERNAL_FN (GOMP_TARGET_REV, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW, NULL)
diff --git a/gcc/internal-fn.h b/gcc/internal-fn.h
index bccee1c3e09..2785a5a95a2 100644
--- a/gcc/internal-fn.h
+++ b/gcc/internal-fn.h
@@ -262,6 +262,11 @@ extern void expand_MULBITINT (internal_fn, gcall *);
 extern void expand_DIVMODBITINT (internal_fn, gcall *);
 extern void expand_FLOATTOBITINT (internal_fn, gcall *);
 extern void expand_BITINTTOFLOAT (internal_fn, gcall *);
+extern void expand_CLRSB (internal_fn, gcall *);
+extern void expand_CLZ (internal_fn, gcall *);
+extern void expand_CTZ (internal_fn, gcall *);
+extern void expand_FFS (internal_fn, gcall *);
+extern void expand_PARITY (internal_fn, gcall *);
 extern void expand_POPCOUNT (internal_fn, gcall *);
 
 extern bool vectorized_internal_fn_supported_p (internal_fn, tree);
diff --git a/gcc/testsuite/gcc.dg/bitint-95.c b/gcc/testsuite/gcc.dg/bitint-95.c
new file mode 100644
index 00000000000..9794652ed13
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-95.c
@@ -0,0 +1,45 @@
+/* PR rtl-optimization/114044 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-O -fno-tree-dce" } */
+
+void
+foo (void)
+{
+  unsigned _BitInt (575) a = 3;
+  __builtin_clzg (a);
+}
+
+void
+bar (void)
+{
+  unsigned _BitInt (575) a = 3;
+  __builtin_ctzg (a);
+}
+
+void
+baz (void)
+{
+  signed _BitInt (575) a = 3;
+  __builtin_clrsbg (a);
+}
+
+void
+qux (void)
+{
+  signed _BitInt (575) a = 3;
+  __builtin_ffsg (a);
+}
+
+void
+garply (void)
+{
+  unsigned _BitInt (575) a = 3;
+  __builtin_parityg (a);
+}
+
+void
+corge (void)
+{
+  unsigned _BitInt (575) a = 3;
+  __builtin_popcountg (a);
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-02-27  8:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-27  8:55 [gcc r14-9192] expand: Add trivial folding for bit query builtins at expansion time [PR114044] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).