diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-07-07 21:53:12 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2016-07-07 21:53:12 +0000 |
commit | ca07e79da58ae0d64999158cab632c6336c9a59c (patch) | |
tree | 074155dc693383513c84633e2d0d3dc0ece8ceb6 | |
parent | 09e552e6227cd9fc4e6c2ef0d6cae5c9c347c314 (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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr71626-1.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr71626-2.c | 4 |
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" |