aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-07-07 21:53:12 +0000
committerJakub Jelinek <jakub@redhat.com>2016-07-07 21:53:12 +0000
commitca07e79da58ae0d64999158cab632c6336c9a59c (patch)
tree074155dc693383513c84633e2d0d3dc0ece8ceb6
parent09e552e6227cd9fc4e6c2ef0d6cae5c9c347c314 (diff)
Backported from mainline
2016-06-28 Jakub Jelinek <jakub@redhat.com> PR middle-end/71626 * config/i386/i386.c (ix86_expand_vector_move): For SUBREG of a constant, force its SUBREG_REG into memory or register instead of whole op1. * gcc.c-torture/execute/pr71626-1.c: New test. * gcc.c-torture/execute/pr71626-2.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@238145 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.c32
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr71626-1.c19
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr71626-2.c4
5 files changed, 58 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1fc09f34a5d..ef4bc992e3e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,13 @@
2016-07-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2016-06-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/71626
+ * config/i386/i386.c (ix86_expand_vector_move): For SUBREG of
+ a constant, force its SUBREG_REG into memory or register instead
+ of whole op1.
+
2016-06-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/71588
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 733e3bdbdf4..63af6f301e1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16918,12 +16918,29 @@ ix86_expand_vector_move (enum machine_mode mode, rtx operands[])
of the register, once we have that information we may be able
to handle some of them more efficiently. */
if (can_create_pseudo_p ()
- && register_operand (op0, mode)
&& (CONSTANT_P (op1)
|| (GET_CODE (op1) == SUBREG
&& CONSTANT_P (SUBREG_REG (op1))))
- && !standard_sse_constant_p (op1))
- op1 = validize_mem (force_const_mem (mode, op1));
+ && ((register_operand (op0, mode)
+ && !standard_sse_constant_p (op1))
+ /* ix86_expand_vector_move_misalign() does not like constants. */
+ || (SSE_REG_MODE_P (mode)
+ && MEM_P (op0)
+ && MEM_ALIGN (op0) < align)))
+ {
+ if (GET_CODE (op1) == SUBREG)
+ {
+ machine_mode imode = GET_MODE (SUBREG_REG (op1));
+ rtx r = force_const_mem (imode, SUBREG_REG (op1));
+ if (r)
+ r = validize_mem (r);
+ else
+ r = force_reg (imode, SUBREG_REG (op1));
+ op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1));
+ }
+ else
+ op1 = validize_mem (force_const_mem (mode, op1));
+ }
/* We need to check memory alignment for SSE mode since attribute
can make operands unaligned. */
@@ -16934,13 +16951,8 @@ ix86_expand_vector_move (enum machine_mode mode, rtx operands[])
{
rtx tmp[2];
- /* ix86_expand_vector_move_misalign() does not like constants ... */
- if (CONSTANT_P (op1)
- || (GET_CODE (op1) == SUBREG
- && CONSTANT_P (SUBREG_REG (op1))))
- op1 = validize_mem (force_const_mem (mode, op1));
-
- /* ... nor both arguments in memory. */
+ /* ix86_expand_vector_move_misalign() does not like both
+ arguments in memory. */
if (!register_operand (op0, mode)
&& !register_operand (op1, mode))
op1 = force_reg (mode, op1);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 89aa6084901..bf4e2596e76 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,12 @@
2016-07-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 2016-06-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/71626
+ * gcc.c-torture/execute/pr71626-1.c: New test.
+ * gcc.c-torture/execute/pr71626-2.c: New test.
+
2016-06-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/71588
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71626-1.c b/gcc/testsuite/gcc.c-torture/execute/pr71626-1.c
new file mode 100644
index 00000000000..26cfa9650e0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr71626-1.c
@@ -0,0 +1,19 @@
+/* PR middle-end/71626 */
+
+typedef __INTPTR_TYPE__ V __attribute__((__vector_size__(sizeof (__INTPTR_TYPE__))));
+
+__attribute__((noinline, noclone)) V
+foo ()
+{
+ V v = { (__INTPTR_TYPE__) foo };
+ return v;
+}
+
+int
+main ()
+{
+ V v = foo ();
+ if (v[0] != (__INTPTR_TYPE__) foo)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr71626-2.c b/gcc/testsuite/gcc.c-torture/execute/pr71626-2.c
new file mode 100644
index 00000000000..4a27c54fbf3
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr71626-2.c
@@ -0,0 +1,4 @@
+/* PR middle-end/71626 */
+/* { dg-additional-options "-fpic" { target fpic } } */
+
+#include "pr71626-1.c"