aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2018-09-29 21:59:59 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2018-09-29 14:59:59 -0700
commitbdfbaa72c5b25f273a7e40be93eb13583d310911 (patch)
treeea061bd7f0306e9f4ad21b1b0c130d68ff0226bf
parent29a94bf97da148775cedb260ca8581be9cc2bacd (diff)
downloadgcc-bdfbaa72c5b25f273a7e40be93eb13583d310911.zip
gcc-bdfbaa72c5b25f273a7e40be93eb13583d310911.tar.gz
gcc-bdfbaa72c5b25f273a7e40be93eb13583d310911.tar.bz2
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. 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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c17
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr87370.c39
4 files changed, 65 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 29f52fd..d4add9d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 176cce5..5475251 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/ChangeLog b/gcc/testsuite/ChangeLog
index 530e7de..2f021f7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c7b6295
--- /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" } } */