[libcxx-commits] [libcxx] [libc++] Optimize bitset::to_string (PR #128832)

Peng Liu via libcxx-commits libcxx-commits at lists.llvm.org
Tue Mar 11 11:26:32 PDT 2025


winner245 wrote:

> ```c++
>template <class T>
>using vec __attribute__((ext_vector_type(8))) = T;
> 
>void to_string(char* buf, unsigned char bools, char a, char b) {
>  *(vec<char>*)buf = __builtin_bit_cast(vec<bool>, bools) ? a : b;
> }
> ```
> this works on eight bits at a time. We probably want to try and write it in a way that generates code based on the `bitset` size. With AVX512 we should get some incredibly efficient code here.

I tried this idea. Since bitset's LSB starts from rightmost, while string's index 0 starts from left, I need to reverse the bit sequence. So I am doing some test as follows (https://godbolt.org/z/rh9z36Tne): 

```cpp
#include <iostream>
#include <cassert>
 
template <class T>
using vec __attribute__((ext_vector_type(8))) = T;
 
void to_string(char word, char one, char zero, char* buf) {
  word             = __builtin_bitreverse8(word);
  *(vec<char>*)buf = __builtin_bit_cast(vec<bool>, word) ? one : zero;
}

bool test() {
  char word     = 0b10100110;
  std::string s = "00000000";
  to_string(word, '1', '0', s.data());

  std::cout << "Input bits: 10100110" << std::endl;
  std::cout << "Result:     " << s << std::endl;
  assert(std::string(s) == "10100110");

  return true;
}

int main() {
  assert(test());
  
  return 0;
}
```

This only runs as expected when compiler optimization is turned on. When optimization is off, I got a strange error which I have never seen before: 

```
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-trunk-20250311/bin/clang-21 -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -dumpdir /app/output.s- -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name example.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -fno-verbose-asm -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb -fdebug-compilation-dir=/app -fcoverage-compilation-dir=/app -resource-dir /opt/compiler-explorer/clang-trunk-20250311/lib/clang/21 -internal-isystem /opt/compiler-explorer/clang-trunk-20250311/bin/../include/x86_64-unknown-linux-gnu/c++/v1 -internal-isystem /opt/compiler-explorer/clang-trunk-20250311/bin/../include/c++/v1 -internal-isystem /opt/compiler-explorer/clang-trunk-20250311/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/15.0.1/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c++23 -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -fcolor-diagnostics -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/example-291a02.o -x c++ <source>
1.	<eof> parser at end of file
2.	Code generation
3.	Running pass 'Function Pass Manager' on module '<source>'.
4.	Running pass 'X86 DAG->DAG Instruction Selection' on function '@_Z9to_stringcccPc'
```

I am not sure if I have triggered some undefined behavior. 


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


More information about the libcxx-commits mailing list