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

Reply via email to