[libcxx-commits] [PATCH] D114074: [libc++] Implement P1272R4 (std::byteswap)
Arthur O'Dwyer via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Nov 17 12:38:20 PST 2021
Quuxplusone added inline comments.
================
Comment at: libcxx/include/__bit/byteswap.h:25
+template <integral _Tp>
+_LIBCPP_HIDE_FROM_ABI constexpr _Tp byteswap(_Tp __val) noexcept {
+ switch (sizeof(_Tp)) {
----------------
philnik wrote:
> Quuxplusone wrote:
> > Mordante wrote:
> > > We conditionally support `__uint128_t`. This type won't work with the current implementation. I would prefer to support that type, or constrain function where `sizeof(_Tp) <= 8`. The availability is guarded by `_LIBCPP_HAS_NO_INT128`.
> > >
> > > Note that GCC already has a `__builtin_bswap128`, so maybe it's interesting to also add this to clang. I wouldn't mind looking into that myself if you don't want to.
> > IMO:
> > - Definitely add `_LIBCPP_UNREACHABLE();` at the end of this function.
> > - If both Clang and GCC support `__builtin_bswap128` then we should just do that for `case 16`.
> > - Otherwise, we should `case 16: return _Tp(byteswap(uint64_t(__val))) | (_Tp(byteswap(uint64_t(__val >> 64))) << 64); // TODO: __builtin_bswap128 when Clang supports it`.
> Right now I'll just do the two 8 byte swaps. I think I will try to add `__builtin_bswap128` in a few days, but it can't be used right now anyways if I understand correctly. Would libc++15 be the earliest revision where this could be changed, assuming clang14 gets `__builtin_bswap128`?
> Would libc++15 be the earliest revision where this could be changed, assuming clang14 gets `__builtin_bswap128`?
You could make it conditional immediately (`#if __has_builtin(__builtin_bswap128)` — and in fact perhaps that should be part of this PR!), but yeah, my understanding of the new-as-of-last-year policy is that libc++14 needs to work with both Clang14 and Clang13; libc++15 needs to work with both Clang15 and Clang14; etc.
================
Comment at: libcxx/test/std/numerics/bit/byteswap.pass.cpp:46-47
+#ifdef TEST_128BIT_INT
+ test_num<__uint128_t>(make_128bit_int<__uint128_t>(0x0123456789ABCDEF, 0xFEDCBA9876543210),
+ make_128bit_int<__uint128_t>(0x1032547698BADCFE, 0xEFCDAB8967452301));
+#endif
----------------
I'd feel better if the test case weren't constructed such that "nybble-swap each byte" was an acceptable implementation. :)
How about making the input `(0x0123456789ABCDEF, 0x13579BDF02468ACE)`?
FWIW, I also find the templated `make_128bit_int` quite verbose. I see that you're making it a template so that you don't have to hide it under an ifdef; but still, how about just this, right above the `return true`?
```
#ifndef _LIBCPP_HAS_NO_INT128
auto before = __uint128_t(0x0123456789ABCDEF) << 64 | 0x13579BDF02468ACE;
auto after = __uint128_t(0xCE8A4602DF9B5713) << 64 | 0xEFCDAB8967452301);
test_num<__uint128_t>(before, after);
test_num<__int128_t>(__int128_t(before), __int128_t(after));
#endif
```
================
Comment at: libcxx/test/std/numerics/bit/byteswap.pass.cpp:73
+ }
+#endif
+
----------------
Please add similar tests for `short, int, long, long long` and their unsigned counterparts.
(These can repeat the input data for `int{16,32,64}_t` AFAIC. We just want to make sure that we have covered whichever of `long` and `long long` is not `int64_t`.)
================
Comment at: libcxx/test/support/test_macros.h:207-209
+#if defined(_LIBCPP_VERSION) && !defined(_LIBCPP_HAS_NO_INT128)
+# define TEST_128BIT_INT
+#endif
----------------
I bet this is overkill. Are we worried that some non-libc++ vendor might fail to define `byteswap` for `__int128_t`?
If we're messing with test macros related to 128-bit support, we might want to revisit libcxx/test/libcxx/input.output/filesystems/convert_file_time.pass.cpp too, I'm not sure.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D114074/new/
https://reviews.llvm.org/D114074
More information about the libcxx-commits
mailing list