aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-07-21 21:11:55 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2010-07-21 21:11:55 +0200
commitfcc71c6c3593f77f434fc30870f0b3b90ef5b0c9 (patch)
tree8071e2d3083da19393a44e7fac297451201b88ea /gcc
parent650b53291f0983f0af75e81729c3774b28967b69 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/m68k/pr45015.c26
-rw-r--r--gcc/var-tracking.c59
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. */