]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa/119067 - bogus TYPE_PRECISION check on VECTOR_TYPE
authorRichard Biener <rguenther@suse.de>
Mon, 3 Mar 2025 08:54:15 +0000 (09:54 +0100)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 3 Mar 2025 10:48:42 +0000 (11:48 +0100)
odr_types_equivalent_p can end up using TYPE_PRECISION on vector
types which is a no-go.  The following instead uses TYPE_VECTOR_SUBPARTS
for vector types so we also end up comparing the number of vector elements.

PR ipa/119067
* ipa-devirt.cc (odr_types_equivalent_p): Check
TYPE_VECTOR_SUBPARTS for vectors.

* g++.dg/lto/pr119067_0.C: New testcase.
* g++.dg/lto/pr119067_1.C: Likewise.

gcc/ipa-devirt.cc
gcc/testsuite/g++.dg/lto/pr119067_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/pr119067_1.C [new file with mode: 0644]

index c31658f57ef298311a9587f2c29eb1815d9fb01f..532e25e87c60bc644f0f0c4720499c6db01b5ebd 100644 (file)
@@ -1259,13 +1259,21 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
       || TREE_CODE (t1) == OFFSET_TYPE
       || POINTER_TYPE_P (t1))
     {
-      if (TYPE_PRECISION (t1) != TYPE_PRECISION (t2))
+      if (!VECTOR_TYPE_P (t1) && TYPE_PRECISION (t1) != TYPE_PRECISION (t2))
        {
          warn_odr (t1, t2, NULL, NULL, warn, warned,
                    G_("a type with different precision is defined "
                       "in another translation unit"));
          return false;
        }
+      if (VECTOR_TYPE_P (t1)
+         && maybe_ne (TYPE_VECTOR_SUBPARTS (t1), TYPE_VECTOR_SUBPARTS (t2)))
+       {
+         warn_odr (t1, t2, NULL, NULL, warn, warned,
+                   G_("a vector type with different number of elements "
+                      "is defined in another translation unit"));
+         return false;
+       }
       if (TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
        {
          warn_odr (t1, t2, NULL, NULL, warn, warned,
diff --git a/gcc/testsuite/g++.dg/lto/pr119067_0.C b/gcc/testsuite/g++.dg/lto/pr119067_0.C
new file mode 100644 (file)
index 0000000..e0f813c
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-lto-do link } */
+/* { dg-skip-if "" { ! { x86_64-*-* i?86-*-* } } } */
+/* { dg-require-effective-target avx2 } */
+/* { dg-require-effective-target shared } */
+/* { dg-lto-options { { -O2 -fPIC -flto } } } */
+/* { dg-extra-ld-options { -shared } } */
+
+#pragma GCC push_options
+#pragma GCC target("avx2")
+typedef char __v32qi __attribute__ ((__vector_size__ (32)));
+struct ff
+{
+  __v32qi t;
+};
+__v32qi g(struct ff a);
+
+__v32qi h(__v32qi a)
+{
+  struct ff t = {a};
+  return g(t);
+}
+#pragma GCC pop_options
diff --git a/gcc/testsuite/g++.dg/lto/pr119067_1.C b/gcc/testsuite/g++.dg/lto/pr119067_1.C
new file mode 100644 (file)
index 0000000..d8e2935
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-options "-mavx2" } */
+
+typedef char __v32qi __attribute__ ((__vector_size__ (32)));
+struct ff
+{
+  __v32qi t;
+};
+__v32qi g(struct ff a) {
+ return a.t;
+}