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

Reply via email to