[libcxx-commits] [libcxx] [libc++] Implement C++29 Bit Permutations P3104R6 (PR #217820)

Jan Schultke via libcxx-commits libcxx-commits at lists.llvm.org
Wed Sep 9 00:46:37 PDT 2026


================
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___BIT_BIT_REPEAT_H
+#define _LIBCPP___BIT_BIT_REPEAT_H
+
+#include <__config>
+#include <__type_traits/integer_traits.h>
+#include <limits>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 29
+
+template <__unsigned_integer _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_repeat(_Tp __t, int __l) {
+  _Tp __res = 0;
+  for (int i = 0; i < numeric_limits<_Tp>::digits; ++i) {
+    __res |= ((__t >> (i % __l)) & 1) << i;
+  }
+  return __res;
+}
----------------
eisenwave wrote:

I don't find the claim that the implementations are anywhere near each other plausible, at least for the case where the length is a constant (https://godbolt.org/z/shM5M3vYq):
```cpp
unsigned repeat_4_naive(unsigned x) {
    return bit_repeat_naive(x, 4);
}
unsigned repeat_4(unsigned x) {
    return bit_repeat(x, 4);
}
```
```asm
repeat_4_naive(unsigned int):
        push    rbx
        mov     esi, edi
        and     esi, 1
        mov     r8d, edi
        shr     r8d
        and     r8d, 1
        mov     r9d, edi
        shr     r9d, 2
        and     r9d, 1
        shr     edi, 3
        and     edi, 1
        xor     edx, edx
        xor     eax, eax
.LBB0_1:
        mov     r10d, esi
        mov     ecx, edx
        shl     r10d, cl
        lea     ecx, [rdx + 1]
        mov     r11d, r8d
        shl     r11d, cl
        lea     ecx, [rdx + 2]
        mov     ebx, r9d
        shl     ebx, cl
        or      eax, r10d
        or      r11d, eax
        lea     ecx, [rdx + 3]
        mov     eax, edi
        shl     eax, cl
        or      eax, ebx
        or      eax, r11d
        add     edx, 4
        cmp     edx, 32
        jne     .LBB0_1
        pop     rbx
        ret

repeat_4(unsigned int):
        and     edi, 15
        imul    eax, edi, 286331153
        ret
```
Shipping the implementation as is makes the function borderline useless.

https://github.com/llvm/llvm-project/pull/217820


More information about the libcxx-commits mailing list