]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
bitint: Make sure BEXTC checks extension when optimized
authorYang Yujie <yangyujie@loongson.cn>
Wed, 6 Aug 2025 10:02:44 +0000 (12:02 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 6 Aug 2025 10:02:44 +0000 (12:02 +0200)
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 now 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.dg/bitintext.h (BEXTC1): Define.  Convert the copied
object back to the original type before comparison.
(BEXTC): Use BEXTC1 for both the signed and the unsigned case.

gcc/testsuite/gcc.dg/bitintext.h

index d5f2689daec4f05a9a0a769d9a31c10f4f074c70..f61cf9ae2e1e5ec414f0221eeec893e48aaf4b5d 100644 (file)
@@ -25,22 +25,20 @@ 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 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)
+
 #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 ((typeof (x)) -1 < 0)   \
+      BEXTC1 ((x), signed);    \
+    else                       \
+      BEXTC1 ((x), unsigned);  \
   } while (0)
 #else
 #define BEXTC(x) do { (void) (x); } while (0)