]> git.feebdaed.xyz Git - 0xmirror/gcc.git/commitdiff
c/123156 - overflow in shuffle mask for __builtin_shufflevector
authorRichard Biener <rguenther@suse.de>
Wed, 17 Dec 2025 13:38:23 +0000 (14:38 +0100)
committerRichard Biener <rguenther@suse.de>
Thu, 18 Dec 2025 08:04:36 +0000 (09:04 +0100)
At some point the permute vector element type had to match the value
elemnt in size which easily leads to overflow for char element types
as shown in the testcase.  This was relaxed for constant permute
masks, so use ssizetype.

PR c/123156
gcc/c-family/
* c-common.cc (c_build_shufflevector): Use ssizetype for the
permute vector element type.

gcc/testsuite/
* gcc.dg/torture/builtin-shufflevector-pr123156.c: New testcase.

gcc/c-family/c-common.cc
gcc/testsuite/gcc.dg/torture/builtin-shufflevector-pr123156.c [new file with mode: 0644]

index 3cec729c901ca16737aacab62ba4db09e3177663..1200a025cc97027e38177a19e4457a013364afc8 100644 (file)
@@ -1260,9 +1260,7 @@ c_build_shufflevector (location_t loc, tree v0, tree v1,
   vec_perm_indices indices (sel, 2, maskl);
 
   tree ret_type = build_vector_type (TREE_TYPE (TREE_TYPE (v0)), maskl);
-  tree mask_type = build_vector_type (build_nonstandard_integer_type
-               (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (ret_type))), 1),
-               maskl);
+  tree mask_type = build_vector_type (ssizetype, maskl);
   /* Pad out arguments to the common vector size.  */
   if (v0n < maskl)
     {
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-shufflevector-pr123156.c b/gcc/testsuite/gcc.dg/torture/builtin-shufflevector-pr123156.c
new file mode 100644 (file)
index 0000000..ec220bc
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do run } */
+
+#include <stdint.h>
+
+#define BS_VEC(type, num) type __attribute__((vector_size(num * sizeof(type))))
+#define BITCAST(T, F, arg)                                                     \
+    ((union {                                                                  \
+        F src;                                                                 \
+        T dst;                                                                 \
+    })arg)                                                                     \
+        .dst
+
+uint64_t func_1()
+{
+    BS_VEC(uint64_t, 32) BS_VAR_0;
+    BS_VAR_0 = BITCAST(
+        BS_VEC(uint64_t, 32), BS_VEC(uint8_t, 256),
+        __builtin_shufflevector(
+            (BS_VEC(uint8_t, 2)){ 2 }, (BS_VEC(uint8_t, 2)){}, 1, 0, 2, 2, 2, 3,
+            1, 2, 3, 1, 3, 3, 2, 1, 3, 0, 2, 2, 1, 2, 1, 3, 1, 1, 0, 0, 2, 0, 3,
+            2, 2, 0, 1, 3, 1, 2, 0, 2, 0, 3, 0, 0, 2, 0, 2, 1, 3, 2, 3, 2, 1, 1,
+            2, 3, 3, 3, 3, 0, 1, 2, 3, 2, 0, 2, 2, 2, 0, 3, 3, 3, 1, 3, 0, 0, 2,
+            3, 1, 1, 2, 2, 1, 2, 0, 0, 3, 2, 2, 3, 2, 2, 3, 2, 0, 2, 2, 0, 2, 1,
+            3, 1, 0, 2, 1, 3, 2, 1, 0, 2, 3, 0, 1, 3, 2, 1, 3, 1, 1, 3, 2, 2, 0,
+            3, 2, 2, 0, 3, 0, 3, 2, 3, 1, 3, 2, 3, 3, 2, 2, 0, 0, 0, 2, 1, 3, 1,
+            2, 2, 3, 0, 1, 3, 1, 1, 2, 0, 1, 2, 1, 2, 0, 2, 0, 2, 3, 3, 3, 1, 2,
+            0, 3, 1, 2, 0, 1, 0, 3, 0, 0, 3, 2, 2, 0, 3, 1, 2, 0, 1, 1, 3, 0, 1,
+            3, 1, 3, 2, 1, 3, 1, 2, 1, 1, 0, 1, 3, 3, 2, 3, 2, 2, 0, 2, 2, 2, 1,
+            1, 0, 3, 1, 3, 0, 3, 0, 0, 1, 3, 3, 1, 2, 1, 1, 3, 1, 0, 2, 1, 3, 2,
+            1, 3, 2, 2, 2, 3, 2, 0, 1, 3, 3, 3, 0, 0, 0, 1, 3, 2, 2, 1));
+    return BS_VAR_0[0];
+}
+
+int main()
+{
+    uint64_t BS_CHECKSUM = func_1();
+    if (BS_CHECKSUM != 0x0000000000000200ull)
+      __builtin_abort ();
+    return 0;
+}