On Wed, Jul 30, 2025 at 09:37:10AM +0200, 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.
Though that risks that the assignment __y = (x); will extend the padding bits. So maybe better: _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; volatile __typeof_unqual__ (x) __y = (x); do_copy ((void *) &__y, &(x), sizeof (__y)); do_copy (&__x, (const void *) &__y, sizeof (__x)); if (__x != __y) __builtin_abort (); If even that optimizes the extension away, we might need to use 2 shifts on the volatile __y, left followed by right, by the difference of N from typeof (x) and PROMOTED_SIZE (x) * __CHAR_BIT__. Or maybe better _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; int __y = S (x); do_copy (&__x, &(x), sizeof (__x)); if (__y < PROMOTED_SIZE (x) * __CHAR_BIT__) { int __neg = __x < 0; __x >>= PROMOTED_SIZE (x) * __CHAR_BIT__ - __y; if (__x != (__neg ? (typeof (__x)) -1 : (__typeof (__x)) 0)) __builtin_abort (); } and just no __neg and if (__x) in the unsigned case? The intent is not to invoke any UB, just have the memcpy hidden from the optimizers. Jakub