This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] i386: Use TImode for BLKmode values in 2 integer registers
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Uros Bizjak <ubizjak at gmail dot com>, Jakub Jelinek <jakub at redhat dot com>
- Date: Sat, 29 Sep 2018 09:36:07 -0700
- Subject: [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