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.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
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 | 10 +++++++++-
gcc/testsuite/g++.dg/lto/pr119067_0.C | 22 ++++++++++++++++++++++
gcc/testsuite/g++.dg/lto/pr119067_1.C | 10 ++++++++++
3 files changed, 41 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/lto/pr119067_0.C
create mode 100644 gcc/testsuite/g++.dg/lto/pr119067_1.C
diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
index c31658f57ef..532e25e87c6 100644
--- a/gcc/ipa-devirt.cc
+++ b/gcc/ipa-devirt.cc
@@ -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
index 00000000000..e0f813ceffe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr119067_0.C
@@ -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
index 00000000000..d8e2935fa24
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr119067_1.C
@@ -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;
+}
--
2.43.0