TYPE_MODE of record and union depends on whether vector_mode_supported_p
returns true or not.  x86-64 backend uses TYPE_MODE to decide how to pass
a parameter and return a value in a function.  64-bit integer vectors
were supported only by MMX and 64-bit float vector was supported only by
3DNOW.  GCC 10 enabled 64-bit integer vectors without MMX by:

commit dfa61b9ed06d71901c4c430caa89820972ad68fe
Author: H.J. Lu <hongjiu...@intel.com>
Date:   Wed May 15 15:02:54 2019 +0000

    i386: Allow MMX register modes in SSE registers

    In 64-bit mode, SSE2 can be used to emulate MMX instructions without
    3DNOW.  We can use SSE2 to support MMX register modes.

GCC 11 enabled 64-bit float vector without 3DNOW by:

commit 7c355156aa20eaec7401d7c66f6a6cfbe597abc2
Author: Uros Bizjak <ubiz...@gmail.com>
Date:   Mon May 11 11:16:31 2020 +0200

    i386: Vectorize basic V2SFmode operations [PR94913]

    Enable V2SFmode vectorization and vectorize V2SFmode PLUS,
    MINUS, MULT, MIN and MAX operations using XMM registers.

Add ABI warnings for 64-bit integer vectors without MMX and 64-bit float
vector without 3DNOW.

gcc/

        PR target/102027
        PR target/102105
        * config/i386/i386.c (m64_mode): New function.
        (examine_argument): Add ABI warnings for 64-bit vectors.

gcc/testsuite/

        PR target/102027
        PR target/102105
        * gcc.target/i386/pr102027-1.c: New test.
        * gcc.target/i386/pr102027-2.c: Likewise.
        * gcc.target/i386/pr102027-3.c: Likewise.
        * gcc.target/i386/pr102027-4.c: Likewise.
        * gcc.target/i386/pr102105-1.c: Likewise.
        * gcc.target/i386/pr102105-2.c: Likewise.
        * gcc.target/i386/pr102105-3.c: Likewise.
        * gcc.target/i386/pr102105-4.c: Likewise.
        * gcc.target/i386/pr102105-5.c: Likewise.
        * gcc.target/i386/sse2-mmx-4.c: Add -Wno-psabi.
---
 gcc/config/i386/i386.c                     | 111 +++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr102027-1.c |  15 +++
 gcc/testsuite/gcc.target/i386/pr102027-2.c |  15 +++
 gcc/testsuite/gcc.target/i386/pr102027-3.c |  17 ++++
 gcc/testsuite/gcc.target/i386/pr102027-4.c |  17 ++++
 gcc/testsuite/gcc.target/i386/pr102105-1.c |  15 +++
 gcc/testsuite/gcc.target/i386/pr102105-2.c |  15 +++
 gcc/testsuite/gcc.target/i386/pr102105-3.c |  17 ++++
 gcc/testsuite/gcc.target/i386/pr102105-4.c |  17 ++++
 gcc/testsuite/gcc.target/i386/pr102105-5.c |  17 ++++
 gcc/testsuite/gcc.target/i386/sse2-mmx-4.c |   2 +-
 11 files changed, 257 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr102027-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr102027-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr102027-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr102027-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr102105-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr102105-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr102105-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr102105-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr102105-5.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4681b667fa2..a42c5355f6c 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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])
       {
diff --git a/gcc/testsuite/gcc.target/i386/pr102027-1.c 
b/gcc/testsuite/gcc.target/i386/pr102027-1.c
new file mode 100644
index 00000000000..f2c16771a06
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102027-1.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr102027-2.c 
b/gcc/testsuite/gcc.target/i386/pr102027-2.c
new file mode 100644
index 00000000000..53d1586a68b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102027-2.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr102027-3.c 
b/gcc/testsuite/gcc.target/i386/pr102027-3.c
new file mode 100644
index 00000000000..61e7318ec6f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102027-3.c
@@ -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" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr102027-4.c 
b/gcc/testsuite/gcc.target/i386/pr102027-4.c
new file mode 100644
index 00000000000..5677df4c99d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102027-4.c
@@ -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" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr102105-1.c 
b/gcc/testsuite/gcc.target/i386/pr102105-1.c
new file mode 100644
index 00000000000..31344147419
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102105-1.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr102105-2.c 
b/gcc/testsuite/gcc.target/i386/pr102105-2.c
new file mode 100644
index 00000000000..ab834217a24
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102105-2.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr102105-3.c 
b/gcc/testsuite/gcc.target/i386/pr102105-3.c
new file mode 100644
index 00000000000..614309579c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102105-3.c
@@ -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" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr102105-4.c 
b/gcc/testsuite/gcc.target/i386/pr102105-4.c
new file mode 100644
index 00000000000..db952e15747
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102105-4.c
@@ -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" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr102105-5.c 
b/gcc/testsuite/gcc.target/i386/pr102105-5.c
new file mode 100644
index 00000000000..54a4b6d86a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr102105-5.c
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-mmx-4.c 
b/gcc/testsuite/gcc.target/i386/sse2-mmx-4.c
index d923724fc1c..01ee8db4a4a 100644
--- a/gcc/testsuite/gcc.target/i386/sse2-mmx-4.c
+++ b/gcc/testsuite/gcc.target/i386/sse2-mmx-4.c
@@ -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"
-- 
2.31.1

Reply via email to