On Tue, Aug 05, 2025 at 11:58:45AM GMT, Jakub Jelinek wrote:
> On Sat, Aug 02, 2025 at 05:14:21PM +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.
> 
> The ChangeLog doesn't describe what the patch does, e.g. the introduction of
> __BEXTC macro.
> 
> > @@ -25,22 +25,30 @@ do_copy (void *p, const void *q, __SIZE_TYPE__ r)
> >  /* Macro to test whether (on targets where psABI requires it) _BitInt
> >     with padding bits have those filled with sign or zero extension.  */
> >  #if defined(__s390x__) || defined(__arm__) || defined(__loongarch__)
> > +#define __BEXTC(x, __x, __y) \
> > +  do {                                         \
> > +    typeof (x) __z;                            \
> > +    do_copy (&(__x), &(x), sizeof (__x));   \
> > +    __z = (typeof (x)) __x;                    \
> > +    do_copy (&(__y), &__z, sizeof (__y));   \
> > +    if ((__x) != (__y))                        \
> > +      __builtin_abort ();              \
> > +  } while (0)
> 
> I'd suggest a change.  I'd just use a name of the macro
> not reserved for implementation, and instead of adding __x and __y
> arguments, let it take
> #define BEXTC1(x, uns) \
>   do {                                                        \
>     uns _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x;        \
>     do_copy (&__x, &(x), sizeof (__x));                       \
>     if ((__x) != (typeof (x)) __x)                    \
>       __builtin_abort ();                             \
>   } while (0)
> 
> and then just use BEXTC1 (x, signed); for the signed case
> and BEXTC1 (x, unsigned); for the unsigned one.
> I think the above can't be optimized away, __x is the wider type and
> after do_copy which is noipa the compiler can't know anything about
> the state of the upper bits.  So, cast from __x to typeof (x) and
> back to typeof (__x) for the comparison has to sign or zero extend
> depending on whether typeof (x) is signed or unsigned.
> 
>       Jakub

Ok. This is much simpler, I wasn't really sure what's legitimate.

Thanks for the review.

Yujie

Reply via email to