[libcxx-commits] [libcxx] 756884c - [libc++][test] Drop _BitInt(96) byteswap padding check on 32-bit x86 (#205295)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jun 28 08:14:11 PDT 2026


Author: Xavier Roche
Date: 2026-06-28T23:14:07+08:00
New Revision: 756884ca8a90b4dfbfb71f715198ddf70cbcd819

URL: https://github.com/llvm/llvm-project/commit/756884ca8a90b4dfbfb71f715198ddf70cbcd819
DIFF: https://github.com/llvm/llvm-project/commit/756884ca8a90b4dfbfb71f715198ddf70cbcd819.diff

LOG: [libc++][test] Drop _BitInt(96) byteswap padding check on 32-bit x86 (#205295)

`byteswap.verify.cpp` (added in #203876) expects `std::byteswap(unsigned
_BitInt(96))` to be rejected for having padding bits. That holds on
x86_64, where the type is 16 bytes with 32 padding bits, but not on
32-bit x86: the i386 psABI aligns `_BitInt` to 4 bytes and packs
`_BitInt(96)` into 12 bytes with no padding, so the call is well-formed
and the expected diagnostic never fires. The Android i386 builder caught
this.

Gate `test_unsigned_96` on `!defined(__i386__)`. Every other target,
including 32-bit arm, riscv32, ppc32, mips32 and sparc32, gives
`_BitInt(96)` 16 bytes with padding, so the case still exercises the
padding-bit Mandate everywhere except 32-bit x86. `sizeof` is not
available to the preprocessor, so the guard is a target check rather
than a direct has-padding predicate.

Assisted-by: Claude (Anthropic)

---------

Co-authored-by: Claude Opus 4.6 <noreply at anthropic.com>

Added: 
    

Modified: 
    libcxx/test/std/numerics/bit/byteswap.verify.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/test/std/numerics/bit/byteswap.verify.cpp b/libcxx/test/std/numerics/bit/byteswap.verify.cpp
index 5a205d9ec5051..f9b6954f525da 100644
--- a/libcxx/test/std/numerics/bit/byteswap.verify.cpp
+++ b/libcxx/test/std/numerics/bit/byteswap.verify.cpp
@@ -68,10 +68,9 @@ void test_unsigned_65() {
 }
 #  endif
 
-// Byte-aligned widths whose value bits don't fill the object representation.
-// On platforms where sizeof(_BitInt(N)) rounds up to a power of two, these
-// types have padding bits in the high-order storage positions even though
-// their value width is a multiple of CHAR_BIT.
+// Byte-aligned widths whose value bits don't fill the object representation,
+// so the high-order storage holds padding bits even though the value width is
+// a multiple of CHAR_BIT.
 void test_unsigned_24() {
   // sizeof(_BitInt(24)) == 4 on x86_64; 8 padding bits.
   unsigned _BitInt(24) v = 0;
@@ -114,9 +113,12 @@ void test_unsigned_80() {
 }
 #    endif
 
-#    if __BITINT_MAXWIDTH__ >= 96
+// 32-bit x86 packs _BitInt(96) into 12 bytes (no padding), so std::byteswap
+// accepts it there; gate the case out. sizeof isn't available to the
+// preprocessor, so this is a target check rather than a has-padding predicate.
+#    if __BITINT_MAXWIDTH__ >= 96 && !defined(__i386__)
 void test_unsigned_96() {
-  // sizeof(_BitInt(96)) == 16 on x86_64; 32 padding bits.
+  // sizeof(_BitInt(96)) == 16 here; 32 padding bits.
   unsigned _BitInt(96) v = 0;
   // expected-error-re@*:* {{{{(std::byteswap requires T to have no padding bits|byteswap is unimplemented for integral types of this size)}}}}
   (void)std::byteswap(v);


        


More information about the libcxx-commits mailing list