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. --- gcc/testsuite/gcc.dg/bitintext.h | 40 +++++++++++++++++++------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/gcc/testsuite/gcc.dg/bitintext.h b/gcc/testsuite/gcc.dg/bitintext.h index 522b96ed715..d9a2eba5bfd 100644 --- a/gcc/testsuite/gcc.dg/bitintext.h +++ b/gcc/testsuite/gcc.dg/bitintext.h @@ -12,7 +12,7 @@ do_copy (void *p, const void *q, __SIZE_TYPE__ r) (typeof (x)) -1, -1)) + 1 \ : __builtin_popcountg (__builtin_choose_expr ((typeof (x)) -1 < 0, \ 0U, (typeof (x)) -1))) - + #define CEIL(x,y) (((x) + (y) - 1) / (y)) /* Promote a _BitInt type to include its padding bits. */ @@ -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) + #define BEXTC(x) \ - do { \ - if ((typeof (x)) -1 < 0) \ - { \ - _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; \ - do_copy (&__x, &(x), sizeof (__x)); \ - if (__x != (x)) \ - __builtin_abort (); \ - } \ - else \ - { \ - unsigned _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x; \ - do_copy (&__x, &(x), sizeof (__x)); \ - if (__x != (x)) \ - __builtin_abort (); \ - } \ + do { \ + if (PROMOTED_SIZE (x) * __CHAR_BIT__ == S (x)) \ + break; \ + if ((typeof (x)) -1 < 0) \ + { \ + _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x, __y; \ + __BEXTC (x, __x, __y); \ + } \ + else \ + { \ + unsigned _BitInt(PROMOTED_SIZE (x) * __CHAR_BIT__) __x, __y; \ + __BEXTC (x, __x, __y); \ + } \ } while (0) #else #define BEXTC(x) do { (void) (x); } while (0) -- 2.46.0