On Tue, 15 Sep 2026, Jakub Jelinek wrote:

> On Tue, Sep 15, 2026 at 02:59:53PM +0200, Richard Biener wrote:
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/vect/vect-bitint-1.c
> > @@ -0,0 +1,36 @@
> > +#include <stdint.h>
> > +#include "tree-vect.h"
> 
> Again, needs bitint effective target.
> 
> > +#pragma GCC novector
> > +  for (int i = 0; i < 32; ++i)
> > +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
> > +    *((char *)&b[i] + 3) = 0x80;
> > +#else
> > +    ;
> 
> I think it would be cleaner to do what I did in gcc.dg/bitint-142.c
> testcase,
>   z = ~0;
>   __builtin_clear_padding (&z);
>   for (unsigned i = 0; i < 16; ++i)
>     ((unsigned char *) &x[0])[i] |= ~*(unsigned char *) &z;
> there.  The first stmt sets z to all ones, the second one clears
> all padding bits.  So, accessing it now through unsigned char (note,
> in bitint-142.c it was _BitInt(7) and so fit into one byte, for
> arbitrary bitints you'd need to add a nested loop to go from
> 0 to sizeof (_BitInt(N)) - 1 and update from the ~((unsigned char *) &z)[j]
> bytes.  Anyway, in z the value bits will be 1s and padding bits will be 0s,
> so with ~ the other way around and so this sets all the padding bits to 1.

Like this?  Tested to fail without the patch and pass with it.

Thanks,
Richard.

>From 6de296f147f2e61bebf269519e3159fd3bcdff86 Mon Sep 17 00:00:00 2001
From: Richard Biener <[email protected]>
Date: Tue, 15 Sep 2026 13:22:57 +0200
Subject: [PATCH] _BitInt and conversion vectorization
To: [email protected]

The following adds a missing check to prevent vectorizing conversions
from _BitInt values which are not appropriately sign-/zero-extended
to their mode.

        * tree-vect-stmts.cc (vectorizable_conversion): Prevent
        conversions from non-mode-precision _BitInt.

        * gcc.dg/vect/vect-bitint-1.c: New testcase.
---
 gcc/testsuite/gcc.dg/vect/vect-bitint-1.c | 40 +++++++++++++++++++++++
 gcc/tree-vect-stmts.cc                    | 11 +++++++
 2 files changed, 51 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/vect/vect-bitint-1.c

diff --git a/gcc/testsuite/gcc.dg/vect/vect-bitint-1.c 
b/gcc/testsuite/gcc.dg/vect/vect-bitint-1.c
new file mode 100644
index 00000000000..106ecd500f7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-bitint-1.c
@@ -0,0 +1,40 @@
+/* { dg-require-effective-target bitint } */
+
+#include <stdint.h>
+#include "tree-vect.h"
+
+void __attribute__((noipa))
+foo (int64_t *a, signed _BitInt(17) *b)
+{
+  for (int i = 0; i < 32; i++)
+    a[i] = b[i];
+}
+
+int
+main ()
+{
+  int64_t a[32];
+  _BitInt(17) b[32];
+
+  check_vect ();
+
+#pragma GCC novector
+  for (int i = 0; i < 32; ++i)
+    b[i] = i;
+  /* Now set all padding bits in b[] to 1.  */
+  _BitInt(17) z = ~0;
+  __builtin_clear_padding (&z);
+#pragma GCC novector
+  for (int i = 0; i < 32; ++i)
+    for (int j = 0; j < sizeof (z); ++j)
+      ((char *)&b[i])[j] |= ~(((char *)&z)[j]);
+
+  foo (a, b);
+
+#pragma GCC novector
+  for (int i = 0; i < 32; ++i)
+    if (a[i] != i)
+      __builtin_abort ();
+
+  return 0;
+}
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 42c8516ea0a..36c0d34733b 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -5413,6 +5413,17 @@ vectorizable_conversion (vec_info *vinfo,
                         "type conversion to bit-precision unsupported\n");
       return false;
     }
+  /* _BitInt values are not sign-/zero-extended to mode precision.  */
+  if (!VECTOR_BOOLEAN_TYPE_P (vectype_out)
+      && TREE_CODE (rhs_type) == BITINT_TYPE
+      && !type_has_mode_precision_p (rhs_type))
+    {
+      if (dump_enabled_p ())
+       dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+                        "type conversion from _BitInt unsupported\n");
+      return false;
+    }
+
 
   if (op_type == binary_op)
     {
-- 
2.51.0

Reply via email to