On Wed, Jul 30, 2025 at 09:37:10AM GMT, Jakub Jelinek wrote: > On Fri, Jul 25, 2025 at 10:53:39AM +0800, Yang Yujie wrote: > > In BEXTC, whether a _BitInt object is properly extended is examined > > by a value comparison against a copied object in a wider _BitInt > > type that utilizes all of the partial limb. > > > > Since the (implicit) conversion to the wider type may be optimized > > away and cause the result of the comparison to always be true, > > we need to cast the copied object down to the original type to > > force a extension, so that it can serve as our reference. > > > > gcc/testsuite/ChangeLog: > > > > * gcc.dg/bitintext.h (BEXTC): Convert the copied object back > > to the original type before comparison. > > This makes no sense at all, you're not testing anything then. > typeof (x) is the narrower type (smaller N). The lower bits will be always > equal. The point was to test the padding bits. > So, if the earlier patch optimizes away the extension, then you should > just use volatile. > So say > _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; > volatile __typeof_unqual__ (x) __y = (x); > do_copy (&__x, &__y, sizeof (__x)); > if (__x != __y) > __builtin_abort (); > etc. > > Jakub
This does actually work though. A comparison for smaller N is always performed between full limbs given that: - for small _BitInts, BITINT_EXTEND is optimized away during expand; - for large _BitInts, the 4th patch prevents __x being extended on load. So it would be "if (__x != (x))" that actually does nothing, and "if ((typeof (x)) __x != (x))" would force a extension on __x, which serves as the reference state of the extended bits. I'm not sure if __y being volatile actually helps removing these optimizations. But since this test is relying on an undefined behavior anyways, I think something implementation-specific (but reliable) can be accepted. Yujie