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:
