i386: Use TImode for BLKmode values in 2 integer registers
authorH.J. Lu <hongjiu.lu@intel.com>
Sat, 29 Sep 2018 21:59:59 +0000 (21:59 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Sat, 29 Sep 2018 21:59:59 +0000 (14:59 -0700)
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.

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.

From-SVN: r264716

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr87370.c [new file with mode: 0644]

index 29f52fd39d3b7e1a9f5a670feaad764216c6b808..d4add9d73aa5cef61e9bf5d8858ab70d30a06067 100644 (file)
@@ -1,3 +1,9 @@
+2018-09-29  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/87370
+       * config/i386/i386.c (construct_container): Use TImode for
+       BLKmode values in 2 integer registers.
+
 2018-09-29  Jeff Law  <law@redhat.com>
 
        * builtins.c (unterminated_array): Pass in c_strlen_data * to
index 176cce521b732e78d83028ceddc1b49ab43cded3..547525130767dcbb45e0e032b69c2c00999378ef 100644 (file)
@@ -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++)
index 530e7deba314f161c03e903f1f4516413270778d..2f021f78aac1ce1cada2cc2ee9ee44e8dfa3de46 100644 (file)
@@ -1,3 +1,8 @@
+2018-09-29  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/87370
+       * gcc.target/i386/pr87370.c: New test.
+
 2018-09-29  Paul Thomas  <pault@gcc.gnu.org>
 
        PR fortran/65667
diff --git a/gcc/testsuite/gcc.target/i386/pr87370.c b/gcc/testsuite/gcc.target/i386/pr87370.c
new file mode 100644 (file)
index 0000000..c7b6295
--- /dev/null
@@ -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" } } */