diff options
author | Jakub Jelinek <jakub@redhat.com> | 2010-07-21 21:11:55 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2010-07-21 21:11:55 +0200 |
commit | fcc71c6c3593f77f434fc30870f0b3b90ef5b0c9 (patch) | |
tree | 8071e2d3083da19393a44e7fac297451201b88ea /gcc | |
parent | 650b53291f0983f0af75e81729c3774b28967b69 (diff) | |
download | gcc-fcc71c6c3593f77f434fc30870f0b3b90ef5b0c9.zip gcc-fcc71c6c3593f77f434fc30870f0b3b90ef5b0c9.tar.gz gcc-fcc71c6c3593f77f434fc30870f0b3b90ef5b0c9.tar.bz2 |
re PR debug/45015 (ICE in cselib.c caused by fix for PR43051)
PR debug/45015
* var-tracking.c (adjust_mems): Ignore ASM_OPERANDS with non-zero
ASM_OPERANDS_OUTPUT_IDX.
(adjust_insn): For inline asm with multiple sets ensure first
ASM_OPERANDS vectors are used by all following ASM_OPERANDS in
the insn.
* gcc.target/m68k/pr45015.c: New test.
From-SVN: r162385
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/m68k/pr45015.c | 26 | ||||
-rw-r--r-- | gcc/var-tracking.c | 59 |
4 files changed, 98 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2e84ab1..222186d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-07-21 Jakub Jelinek <jakub@redhat.com> + + PR debug/45015 + * var-tracking.c (adjust_mems): Ignore ASM_OPERANDS with non-zero + ASM_OPERANDS_OUTPUT_IDX. + (adjust_insn): For inline asm with multiple sets ensure first + ASM_OPERANDS vectors are used by all following ASM_OPERANDS in + the insn. + 2010-07-21 Richard Henderson <rth@redhat.com> * config/i386/i386.c (setup_incoming_varargs_64): Emit a simple diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d6b70a2..2e4919c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-07-21 Jakub Jelinek <jakub@redhat.com> + + PR debug/45015 + * gcc.target/m68k/pr45015.c: New test. + 2010-07-21 Jeffrey Yasskin <jyasskin@google.com> PR c++/44641 diff --git a/gcc/testsuite/gcc.target/m68k/pr45015.c b/gcc/testsuite/gcc.target/m68k/pr45015.c new file mode 100644 index 0000000..fba9550 --- /dev/null +++ b/gcc/testsuite/gcc.target/m68k/pr45015.c @@ -0,0 +1,26 @@ +/* PR debug/45015 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +unsigned int +foo (unsigned int *x, const unsigned int *y, int z, unsigned int w) +{ + unsigned int a, b, c, s; + int j; + j = -z; + x -= j; + y -= j; + a = 0; + do + { + __asm__ ("move.l %2, %0; move.l %3, %1" : "=d" (b), "=d" (c) : "g<>" (y[j]), "d" (w)); + c += a; + a = (c < a) + b; + s = x[j]; + c = s + c; + a += (c < s); + x[j] = c; + } + while (++j != 0); + return a; +} diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index d1c584a..3232fb7 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -910,6 +910,16 @@ adjust_mems (rtx loc, const_rtx old_rtx, void *data) return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem), GET_MODE (SUBREG_REG (tem))); return tem; + case ASM_OPERANDS: + /* Don't do any replacements in second and following + ASM_OPERANDS of inline-asm with multiple sets. + ASM_OPERANDS_INPUT_VEC, ASM_OPERANDS_INPUT_CONSTRAINT_VEC + and ASM_OPERANDS_LABEL_VEC need to be equal between + all the ASM_OPERANDs in the insn and adjust_insn will + fix this up. */ + if (ASM_OPERANDS_OUTPUT_IDX (loc) != 0) + return loc; + break; default: break; } @@ -960,7 +970,54 @@ adjust_insn (basic_block bb, rtx insn) note_stores (PATTERN (insn), adjust_mem_stores, &amd); amd.store = false; - note_uses (&PATTERN (insn), adjust_mem_uses, &amd); + if (GET_CODE (PATTERN (insn)) == PARALLEL + && asm_noperands (PATTERN (insn)) > 0 + && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET) + { + rtx body, set0; + int i; + + /* inline-asm with multiple sets is tiny bit more complicated, + because the 3 vectors in ASM_OPERANDS need to be shared between + all ASM_OPERANDS in the instruction. adjust_mems will + not touch ASM_OPERANDS other than the first one, asm_noperands + test above needs to be called before that (otherwise it would fail) + and afterwards this code fixes it up. */ + note_uses (&PATTERN (insn), adjust_mem_uses, &amd); + body = PATTERN (insn); + set0 = XVECEXP (body, 0, 0); + gcc_checking_assert (GET_CODE (set0) == SET + && GET_CODE (SET_SRC (set0)) == ASM_OPERANDS + && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set0)) == 0); + for (i = 1; i < XVECLEN (body, 0); i++) + if (GET_CODE (XVECEXP (body, 0, i)) != SET) + break; + else + { + set = XVECEXP (body, 0, i); + gcc_checking_assert (GET_CODE (SET_SRC (set)) == ASM_OPERANDS + && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set)) + == i); + if (ASM_OPERANDS_INPUT_VEC (SET_SRC (set)) + != ASM_OPERANDS_INPUT_VEC (SET_SRC (set0)) + || ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set)) + != ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0)) + || ASM_OPERANDS_LABEL_VEC (SET_SRC (set)) + != ASM_OPERANDS_LABEL_VEC (SET_SRC (set0))) + { + rtx newsrc = shallow_copy_rtx (SET_SRC (set)); + ASM_OPERANDS_INPUT_VEC (newsrc) + = ASM_OPERANDS_INPUT_VEC (SET_SRC (set0)); + ASM_OPERANDS_INPUT_CONSTRAINT_VEC (newsrc) + = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0)); + ASM_OPERANDS_LABEL_VEC (newsrc) + = ASM_OPERANDS_LABEL_VEC (SET_SRC (set0)); + validate_change (NULL_RTX, &SET_SRC (set), newsrc, true); + } + } + } + else + note_uses (&PATTERN (insn), adjust_mem_uses, &amd); /* For read-only MEMs containing some constant, prefer those constants. */ |