aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2011-11-19 13:47:35 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2011-11-19 13:47:35 +0000
commit78811dd3b7d84c74392048bec3122d7222596253 (patch)
tree574f7789a94ddef4c81768c221499716fb99b920 /gcc
parent40353fb3aa64e07ac3dd27fc2306b5c5010b91d2 (diff)
downloadgcc-78811dd3b7d84c74392048bec3122d7222596253.zip
gcc-78811dd3b7d84c74392048bec3122d7222596253.tar.gz
gcc-78811dd3b7d84c74392048bec3122d7222596253.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arm/arm.c45
2 files changed, 26 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 27dace6..43de112 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 4846d72..e3b0b88 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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,