@@ -2462,6 +2462,41 @@ classify_argument (machine_mode mode, const_tree type,
}
}
+/* Return the mode of the 64-bit vector type in TYPE. */
+
+static machine_mode
+m64_mode (const_tree type)
+{
+ if ((TREE_CODE (type) == RECORD_TYPE
+ || TREE_CODE (type) == UNION_TYPE
+ || TREE_CODE (type) == QUAL_UNION_TYPE))
+ {
+ const_tree field;
+
+ for (field = TYPE_FIELDS (type);
+ field;
+ field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ const_tree field_type = TREE_TYPE (field);
+ if (field_type == error_mark_node)
+ continue;
+
+ /* Return the mode of a 64-bit vector. */
+ if (TREE_CODE (field_type) == VECTOR_TYPE
+ && VECTOR_MODE_P (TYPE_MODE (field_type))
+ && GET_MODE_SIZE (TYPE_MODE (field_type)) == 8)
+ return TYPE_MODE (field_type);
+
+ machine_mode mode = m64_mode (field_type);
+ if (mode != VOIDmode)
+ return mode;
+ }
+ }
+
+ return VOIDmode;
+}
+
/* Examine the argument and return set number of register required in each
class. Return true iff parameter should be passed in memory. */
@@ -2477,6 +2512,82 @@ examine_argument (machine_mode mode, const_tree type, int in_return,
if (!n)
return true;
+
+ if (warn_psabi
+ && n == 1
+ && regclass[0] == X86_64_SSE_CLASS
+ && (VECTOR_MODE_P (mode) || type)
+ && GET_MODE_SIZE (mode) == 8)
+ {
+ const char *url;
+ if (!VECTOR_MODE_P (mode))
+ mode = m64_mode (type);
+ if (mode == V2SFmode)
+ {
+ /* GCC 11 enables V2SFmode without TARGET_3DNOW. */
+ if (!TARGET_3DNOW)
+ {
+ url = CHANGES_ROOT_URL "gcc-11/changes.html#x86_64_m64";
+ if (in_return)
+ {
+ static bool warnedm64_ret;
+ if (!warnedm64_ret)
+ {
+ warnedm64_ret = true;
+ inform (input_location,
+ "the ABI of returning structure with "
+ "a 64-bit single precision vector has "
+ "changed in %{GCC 11.1%}", url);
+ }
+ }
+ else
+ {
+ static bool warnedm64;
+ if (!warnedm64)
+ {
+ warnedm64 = true;
+ inform (input_location,
+ "the ABI of passing structure with "
+ "a 64-bit single precision vector has "
+ "changed in %{GCC 11.1%}", url);
+ }
+ }
+ }
+ }
+ else if (VECTOR_MODE_P (mode))
+ {
+ /* GCC 10 enables other MMX modes without TARGET_MMX. */
+ if (!TARGET_MMX)
+ {
+ url = CHANGES_ROOT_URL "gcc-10/changes.html#x86_64_m64";
+ if (in_return)
+ {
+ static bool warnedm64_ret;
+ if (!warnedm64_ret)
+ {
+ warnedm64_ret = true;
+ inform (input_location,
+ "the ABI of returning structure with "
+ "a 64-bit integer vector has changed "
+ "in %{GCC 10.1%}", url);
+ }
+ }
+ else
+ {
+ static bool warnedm64;
+ if (!warnedm64)
+ {
+ warnedm64 = true;
+ inform (input_location,
+ "the ABI of passing structure with "
+ "a 64-bit integer vector has changed "
+ "in %{GCC 10.1%}", url);
+ }
+ }
+ }
+ }
+ }
+
for (n--; n >= 0; n--)
switch (regclass[n])
{
new file mode 100644
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mno-3dnow" } */
+
+struct V2SF {
+ __attribute__((__vector_size__(2 * sizeof(float)))) float v;
+};
+extern struct V2SF x;
+extern void foo (struct V2SF);
+
+struct V2SF
+bar (void)
+{ /* { dg-message "note: the ABI of returning structure with a 64-bit single precision vector has changed in GCC 11.1" } */
+ foo (x); /* { dg-message "note: the ABI of passing structure with a 64-bit single precision vector has changed in GCC 11.1" } */
+ return x;
+}
new file mode 100644
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mno-3dnow" } */
+
+union U2SF {
+ __attribute__((__vector_size__(2 * sizeof(float)))) float v;
+};
+extern union U2SF x;
+extern void foo (union U2SF);
+
+union U2SF
+bar (void)
+{ /* { dg-message "note: the ABI of returning structure with a 64-bit single precision vector has changed in GCC 11.1" } */
+ foo (x); /* { dg-message "note: the ABI of passing structure with a 64-bit single precision vector has changed in GCC 11.1" } */
+ return x;
+}
new file mode 100644
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mno-3dnow" } */
+
+struct V2SF1 {
+ __attribute__((__vector_size__(2 * sizeof(float)))) float v;
+};
+struct V2SF {
+ struct V2SF1 x;
+};
+extern struct V2SF x;
+extern void foo (struct V2SF);
+
+void
+bar (void)
+{
+ foo (x); /* { dg-message "note: the ABI of passing structure with a 64-bit single precision vector has changed in GCC 11.1" } */
+}
new file mode 100644
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mno-3dnow" } */
+
+union V2SF1 {
+ __attribute__((__vector_size__(2 * sizeof(float)))) float v;
+};
+union V2SF {
+ union V2SF1 x;
+};
+extern union V2SF x;
+extern void foo (union V2SF);
+
+void
+bar (void)
+{
+ foo (x); /* { dg-message "note: the ABI of passing structure with a 64-bit single precision vector has changed in GCC 11.1" } */
+}
new file mode 100644
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mno-mmx" } */
+
+struct V8QI {
+ __attribute__((__vector_size__(8))) char v;
+};
+extern struct V8QI x;
+extern void foo (struct V8QI);
+
+struct V8QI
+bar (void)
+{ /* { dg-message "note: the ABI of returning structure with a 64-bit integer vector has changed in GCC 10.1" } */
+ foo (x); /* { dg-message "note: the ABI of passing structure with a 64-bit integer vector has changed in GCC 10.1" } */
+ return x;
+}
new file mode 100644
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mno-mmx" } */
+
+union U8QI {
+ __attribute__((__vector_size__(8))) char v;
+};
+extern union U8QI x;
+extern void foo (union U8QI);
+
+union U8QI
+bar (void)
+{ /* { dg-message "note: the ABI of returning structure with a 64-bit integer vector has changed in GCC 10.1" } */
+ foo (x); /* { dg-message "note: the ABI of passing structure with a 64-bit integer vector has changed in GCC 10.1" } */
+ return x;
+}
new file mode 100644
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mno-mmx" } */
+
+struct V8QI1 {
+ __attribute__((__vector_size__(8))) char v;
+};
+struct V8QI {
+ struct V8QI1 x;
+};
+extern struct V8QI x;
+extern void foo (struct V8QI);
+
+void
+bar (void)
+{
+ foo (x); /* { dg-message "note: the ABI of passing structure with a 64-bit integer vector has changed in GCC 10.1" } */
+}
new file mode 100644
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mno-mmx" } */
+
+union V8QI1 {
+ __attribute__((__vector_size__(8))) char v;
+};
+union V8QI {
+ union V8QI1 x;
+};
+extern union V8QI x;
+extern void foo (union V8QI);
+
+void
+bar (void)
+{
+ foo (x); /* { dg-message "note: the ABI of passing structure with a 64-bit integer vector has changed in GCC 10.1" } */
+}
new file mode 100644
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mno-mmx" } */
+
+struct v1di
+{
+ __attribute__((__vector_size__(8))) long long ll;
+};
+extern struct v1di x;
+
+extern void foo (struct v1di);
+
+struct v1di
+bar (void)
+{ /* { dg-message "note: the ABI of returning structure with a 64-bit integer vector has changed in GCC 10.1" } */
+ foo (x); /* { dg-message "note: the ABI of passing structure with a 64-bit integer vector has changed in GCC 10.1" } */
+ return x;
+}
@@ -1,4 +1,4 @@
/* { dg-do run { target { ! ia32 } } } */
-/* { dg-options "-O2 -msse2 -mno-mmx" } */
+/* { dg-options "-O2 -msse2 -mno-mmx -Wno-psabi" } */
#include "mmx-4.c"