When passing and returning BLKmode values in 2 integer registers, use
1 TImode register instead of 2 DImode registers. Otherwise, V1TImode
may be used to move and store such BLKmode values, which prevent RTL
optimizations.

Tested on x86-64.  OK for trunk?

Thanks.

H.J.
---
gcc/

        PR target/87370
        * config/i386/i386.c (construct_container): Use TImode for
        BLKmode values in 2 integer registers.

gcc/testsuite/

        PR target/87370
        * gcc.target/i386/pr87370.c: New test.
---
 gcc/config/i386/i386.c                  | 17 +++++++++--
 gcc/testsuite/gcc.target/i386/pr87370.c | 39 +++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr87370.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 176cce521b7..54752513076 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -7914,9 +7914,22 @@ construct_container (machine_mode mode, machine_mode 
orig_mode,
   if (n == 2
       && regclass[0] == X86_64_INTEGER_CLASS
       && regclass[1] == X86_64_INTEGER_CLASS
-      && (mode == CDImode || mode == TImode)
+      && (mode == CDImode || mode == TImode || mode == BLKmode)
       && intreg[0] + 1 == intreg[1])
-    return gen_rtx_REG (mode, intreg[0]);
+    {
+      if (mode == BLKmode)
+       {
+         /* Use TImode for BLKmode values in 2 integer registers.  */
+         exp[0] = gen_rtx_EXPR_LIST (VOIDmode,
+                                     gen_rtx_REG (TImode, intreg[0]),
+                                     GEN_INT (0));
+         ret = gen_rtx_PARALLEL (mode, rtvec_alloc (1));
+         XVECEXP (ret, 0, 0) = exp[0];
+         return ret;
+       }
+      else
+       return gen_rtx_REG (mode, intreg[0]);
+    }
 
   /* Otherwise figure out the entries of the PARALLEL.  */
   for (i = 0; i < n; i++)
diff --git a/gcc/testsuite/gcc.target/i386/pr87370.c 
b/gcc/testsuite/gcc.target/i386/pr87370.c
new file mode 100644
index 00000000000..c7b6295a33b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr87370.c
@@ -0,0 +1,39 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+struct A
+{
+  int b[4];
+};
+struct B
+{
+  char a[12];
+  int b;
+};
+struct C
+{
+  char a[16];
+};
+
+struct A
+f1 (void)
+{
+  struct A x = {};
+  return x;
+}
+
+struct B
+f2 (void)
+{
+  struct B x = {};
+  return x;
+}
+
+struct C
+f3 (void)
+{
+  struct C x = {};
+  return x;
+}
+
+/* { dg-final { scan-assembler-not "xmm" } } */
-- 
2.17.1

Reply via email to