From 78811dd3b7d84c74392048bec3122d7222596253 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Sat, 19 Nov 2011 13:47:35 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.c | 45 ++++++++++++++++++++------------------------- 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 + + PR target/50493 + * arm.c (neon_disambiguate_copy): Correctly handle partial overlap + of src and dest operands. + 2011-11-19 Iain Sandoe * 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, -- 2.7.4