re PR target/50493 (ICE in neon_disambiguate_copy, at config/arm/arm.c:20388)

PR target/50493
* arm.c (neon_disambiguate_copy): Correctly handle partial overlap
of src and dest operands.

From-SVN: r181508
This commit is contained in:
Richard Earnshaw 2011-11-19 13:47:35 +00:00 committed by Richard Earnshaw
parent 40353fb3aa
commit 78811dd3b7
2 changed files with 26 additions and 25 deletions

View File

@ -1,3 +1,9 @@
2011-11-19 Richard Earnshaw <rearnsha@arm.com>
PR target/50493
* arm.c (neon_disambiguate_copy): Correctly handle partial overlap
of src and dest operands.
2011-11-19 Iain Sandoe <iains@gcc.gnu.org>
* config/darwin.h (ASM_DEBUG_SPEC): New.

View File

@ -20728,39 +20728,34 @@ neon_emit_pair_result_insn (enum machine_mode mode,
emit_move_insn (mem, tmp2);
}
/* Set up operands for a register copy from src to dest, taking care not to
clobber registers in the process.
FIXME: This has rather high polynomial complexity (O(n^3)?) but shouldn't
be called with a large N, so that should be OK. */
/* Set up OPERANDS for a register copy from SRC to DEST, taking care
not to early-clobber SRC registers in the process.
We assume that the operands described by SRC and DEST represent a
decomposed copy of OPERANDS[1] into OPERANDS[0]. COUNT is the
number of components into which the copy has been decomposed. */
void
neon_disambiguate_copy (rtx *operands, rtx *dest, rtx *src, unsigned int count)
{
unsigned int copied = 0, opctr = 0;
unsigned int done = (1 << count) - 1;
unsigned int i, j;
unsigned int i;
while (copied != done)
if (!reg_overlap_mentioned_p (operands[0], operands[1])
|| REGNO (operands[0]) < REGNO (operands[1]))
{
for (i = 0; i < count; i++)
{
int good = 1;
for (j = 0; good && j < count; j++)
if (i != j && (copied & (1 << j)) == 0
&& reg_overlap_mentioned_p (src[j], dest[i]))
good = 0;
if (good)
{
operands[opctr++] = dest[i];
operands[opctr++] = src[i];
copied |= 1 << i;
}
}
{
operands[2 * i] = dest[i];
operands[2 * i + 1] = src[i];
}
}
else
{
for (i = 0; i < count; i++)
{
operands[2 * i] = dest[count - i - 1];
operands[2 * i + 1] = src[count - i - 1];
}
}
gcc_assert (opctr == count * 2);
}
/* Expand an expression EXP that calls a built-in function,