backport: re PR middle-end/71626 (ICE at -O1 and above on x86_64-linux-gnu (in output_constant_pool_2, at varasm.c:3837))

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.

From-SVN: r238101
This commit is contained in:
Jakub Jelinek 2016-07-07 14:48:16 +02:00 committed by Jakub Jelinek
parent b5af6820de
commit a51922e1e6
5 changed files with 58 additions and 10 deletions

View File

@ -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

View File

@ -17599,12 +17599,29 @@ ix86_expand_vector_move (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 (SUBREG_P (op1))
{
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. */
@ -17615,13 +17632,8 @@ ix86_expand_vector_move (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);

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,4 @@
/* PR middle-end/71626 */
/* { dg-additional-options "-fpic" { target fpic } } */
#include "pr71626-1.c"