This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] i386: Use TImode for BLKmode values in 2 integer registers


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]