OSDN Git Service

PR debug/45015
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Jul 2010 19:11:55 +0000 (19:11 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 21 Jul 2010 19:11:55 +0000 (19:11 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162385 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/m68k/pr45015.c [new file with mode: 0644]
gcc/var-tracking.c

index 2e84ab1..222186d 100644 (file)
@@ -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
index d6b70a2..2e4919c 100644 (file)
@@ -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 (file)
index 0000000..fba9550
--- /dev/null
@@ -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;
+}
index d1c584a..3232fb7 100644 (file)
@@ -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.  */