https://gcc.gnu.org/g:54f8428e0342935d5f9c3282fbae1db63cf90ac1

commit r17-550-g54f8428e0342935d5f9c3282fbae1db63cf90ac1
Author: Jakub Jelinek <[email protected]>
Date:   Sat May 16 10:50:57 2026 +0200

    Add __builtin_bitreverse128 [PR50481]
    
    We already have __builtin_bswap{16,32,64,128}, the last one has been
    added ~6 years ago.  So, I think we should have also
    __builtin_bitreverse128.
    
    The following patch does that.
    
    Note, we don't have __builtin_bswapg and I don't think we should, one can
    only byteswap something which has number of bits divisible by CHAR_BIT.
    For __builtin_bitreverseg that isn't a problem, but am not sure I want to
    spend time handling it on say unsigned _BitInt(357).  Perhaps only if there
    is some real-world use-case.
    
    2026-05-16  Jakub Jelinek  <[email protected]>
    
            PR target/50481
            * doc/extend.texi (__builtin_bitreverse32, __builtin_bitreverse64):
            Tweak wording for consistency with __builtin_bswap*.
            (__builtin_bitreverse128): Document.
            * builtins.def (BUILT_IN_BITREVERSE128): New.
            * builtins.cc (expand_builtin): Handle also BUILT_IN_BITREVERSE128.
            (is_inexpensive_builtin): Likewise.
            * fold-const-call.cc (fold_const_call_ss): Handle also
            CFN_BUILT_IN_BITREVERSE128.
            * fold-const.cc (tree_call_nonnegative_warnv_p): Likewise.
            * tree-ssa-ccp.cc (evaluate_stmt): Handle also 
BUILT_IN_BITREVERSE128.
            * tree-ssa-phiopt.cc (empty_bb_or_one_feeding_into_p): Handle also
            CFN_BUILT_IN_BITREVERSE128.
            (cond_removal_in_builtin_zero_pattern): Likewise.
    
            * gcc.dg/builtin-bitreverse-1.c: Add __builtin_bitreverse128 tests.
            * gcc.dg/builtin-bitreverse-2.c: Likewise.
    
    Reviewed-by: Andrew Pinski <[email protected]>

Diff:
---
 gcc/builtins.cc                             |  2 ++
 gcc/builtins.def                            |  1 +
 gcc/doc/extend.texi                         |  9 +++++++--
 gcc/fold-const-call.cc                      |  1 +
 gcc/fold-const.cc                           |  1 +
 gcc/testsuite/gcc.dg/builtin-bitreverse-1.c | 21 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/builtin-bitreverse-2.c |  9 ++++++++-
 gcc/tree-ssa-ccp.cc                         |  1 +
 gcc/tree-ssa-phiopt.cc                      |  2 ++
 9 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index 0475bb88a617..72310f1c928e 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -8188,6 +8188,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, 
machine_mode mode,
     case BUILT_IN_BITREVERSE16:
     case BUILT_IN_BITREVERSE32:
     case BUILT_IN_BITREVERSE64:
+    case BUILT_IN_BITREVERSE128:
       target = expand_builtin_unop (target_mode, exp, target, subtarget,
                                    bitreverse_optab);
       if (target)
@@ -12357,6 +12358,7 @@ is_inexpensive_builtin (tree decl)
       case BUILT_IN_BITREVERSE16:
       case BUILT_IN_BITREVERSE32:
       case BUILT_IN_BITREVERSE64:
+      case BUILT_IN_BITREVERSE128:
       case BUILT_IN_CLZ:
       case BUILT_IN_CLZIMAX:
       case BUILT_IN_CLZL:
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 68838de55f13..785c1c99c3fe 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -1028,6 +1028,7 @@ DEF_GCC_BUILTIN        (BUILT_IN_BITREVERSE8, 
"bitreverse8", BT_FN_UINT8_UINT8,
 DEF_GCC_BUILTIN        (BUILT_IN_BITREVERSE16, "bitreverse16", 
BT_FN_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_BITREVERSE32, "bitreverse32", 
BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_BITREVERSE64, "bitreverse64", 
BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_BITREVERSE128, "bitreverse128", 
BT_FN_UINT128_UINT128, ATTR_CONST_NOTHROW_LEAF_LIST)
 
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_CLEAR_CACHE, "__clear_cache", 
BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
 /* [trans-mem]: Adjust BUILT_IN_TM_CALLOC if BUILT_IN_CALLOC is changed.  */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 96ed8b45f04f..01ffe30c4410 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -16032,15 +16032,20 @@ are 16-bit.
 @enddefbuiltin
 
 @defbuiltin{uint32_t __builtin_bitreverse32 (uint32_t @var{x})}
-Similar to @code{__builtin_bitreverse8}, except the argument and return types
+Similar to @code{__builtin_bitreverse16}, except the argument and return types
 are 32-bit.
 @enddefbuiltin
 
 @defbuiltin{uint64_t __builtin_bitreverse64 (uint64_t @var{x})}
-Similar to @code{__builtin_bitreverse8}, except the argument and return types
+Similar to @code{__builtin_bitreverse32}, except the argument and return types
 are 64-bit.
 @enddefbuiltin
 
+@defbuiltin{uint128_t __builtin_bitreverse128 (uint128_t @var{x})}
+Similar to @code{__builtin_bitreverse64}, except the argument and return types
+are 128-bit.  Only supported on targets when 128-bit types are supported.
+@enddefbuiltin
+
 @node CRC Builtins
 @subsection CRC Builtins
 @cindex CRC builtins
diff --git a/gcc/fold-const-call.cc b/gcc/fold-const-call.cc
index d473b0dd4280..f982983dba6a 100644
--- a/gcc/fold-const-call.cc
+++ b/gcc/fold-const-call.cc
@@ -1106,6 +1106,7 @@ fold_const_call_ss (wide_int *result, combined_fn fn, 
const wide_int_ref &arg,
     case CFN_BUILT_IN_BITREVERSE16:
     case CFN_BUILT_IN_BITREVERSE32:
     case CFN_BUILT_IN_BITREVERSE64:
+    case CFN_BUILT_IN_BITREVERSE128:
       *result = wi::bitreverse (wide_int::from (arg, precision,
                                                TYPE_SIGN (arg_type)));
       return true;
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 3bc82a108dbc..a7351445eacb 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -14988,6 +14988,7 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn 
fn, tree arg0, tree arg1,
     case CFN_BUILT_IN_BITREVERSE16:
     case CFN_BUILT_IN_BITREVERSE32:
     case CFN_BUILT_IN_BITREVERSE64:
+    case CFN_BUILT_IN_BITREVERSE128:
       /* Always true.  */
       return true;
 
diff --git a/gcc/testsuite/gcc.dg/builtin-bitreverse-1.c 
b/gcc/testsuite/gcc.dg/builtin-bitreverse-1.c
index 0047e8d9e22d..81c104fe9d41 100644
--- a/gcc/testsuite/gcc.dg/builtin-bitreverse-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-bitreverse-1.c
@@ -25,6 +25,14 @@ br64 (unsigned long long x)
   return __builtin_bitreverse64 (x);
 }
 
+#if __SIZEOF_INT128__ == 16
+[[gnu::noipa]] static unsigned __int128
+br128 (unsigned __int128 x)
+{
+  return __builtin_bitreverse128 (x);
+}
+#endif
+
 int
 main ()
 {
@@ -67,5 +75,18 @@ main ()
   if (br64 (0xffffffffffffffffull) != 0xffffffffffffffffull)
     __builtin_abort ();
 #endif
+#if __SIZEOF_INT128__ == 16
+  if (br128 (0) != 0)
+    __builtin_abort ();
+  if (br128 (1) != (unsigned __int128) 1 << 127)
+    __builtin_abort ();
+  if (br128 (((unsigned __int128) 0x0123456789abcdefull << 64)
+            | 0x2468ace013579bdfull)
+      != (((unsigned __int128) 0xfbd9eac807351624ull << 64)
+         | 0xf7b3d591e6a2c480ull))
+    __builtin_abort ();
+  if (br128 (~(unsigned __int128) 0) != ~(unsigned __int128) 0)
+    __builtin_abort ();
+#endif
 #endif
 }
diff --git a/gcc/testsuite/gcc.dg/builtin-bitreverse-2.c 
b/gcc/testsuite/gcc.dg/builtin-bitreverse-2.c
index 42a677cae4b1..86076bed10cc 100644
--- a/gcc/testsuite/gcc.dg/builtin-bitreverse-2.c
+++ b/gcc/testsuite/gcc.dg/builtin-bitreverse-2.c
@@ -12,6 +12,13 @@ _Static_assert (__builtin_bitreverse32 (0x12345678u) == 
0x1e6a2c48u,
 #endif
 #if __SIZEOF_LONG_LONG__ == 8
 _Static_assert (__builtin_bitreverse64 (0x0123456789abcdefull)
-                == 0xf7b3d591e6a2c480ull, "bitreverse64");
+               == 0xf7b3d591e6a2c480ull, "bitreverse64");
+#endif
+#if __SIZEOF_INT128__ == 16
+_Static_assert (__builtin_bitreverse128 (((unsigned __int128)
+                                         0x0123456789abcdefull << 64)
+                                        | 0x2468ace013579bdfull)
+               == (((unsigned __int128) 0xfbd9eac807351624ull << 64)
+                   | 0xf7b3d591e6a2c480ull), "bitreverse128");
 #endif
 #endif
diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
index 891fcc12cafc..d9a41c2e1359 100644
--- a/gcc/tree-ssa-ccp.cc
+++ b/gcc/tree-ssa-ccp.cc
@@ -2466,6 +2466,7 @@ evaluate_stmt (gimple *stmt)
            case BUILT_IN_BITREVERSE16:
            case BUILT_IN_BITREVERSE32:
            case BUILT_IN_BITREVERSE64:
+           case BUILT_IN_BITREVERSE128:
              val = get_value_for_expr (gimple_call_arg (stmt, 0), true);
              if (val.lattice_val == UNDEFINED)
                break;
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index d9e1edb9b144..e654e8236360 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -823,6 +823,7 @@ empty_bb_or_one_feeding_into_p (basic_block bb,
        case CFN_BUILT_IN_BITREVERSE16:
        case CFN_BUILT_IN_BITREVERSE32:
        case CFN_BUILT_IN_BITREVERSE64:
+       case CFN_BUILT_IN_BITREVERSE128:
        CASE_CFN_FFS:
        CASE_CFN_PARITY:
        CASE_CFN_POPCOUNT:
@@ -2586,6 +2587,7 @@ cond_removal_in_builtin_zero_pattern (basic_block cond_bb,
     case CFN_BUILT_IN_BITREVERSE16:
     case CFN_BUILT_IN_BITREVERSE32:
     case CFN_BUILT_IN_BITREVERSE64:
+    case CFN_BUILT_IN_BITREVERSE128:
     CASE_CFN_FFS:
     CASE_CFN_PARITY:
     CASE_CFN_POPCOUNT:

Reply via email to