OSDN Git Service

* optabs.c (expand_compare_and_swap_loop): Don't clobber old value
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 May 2005 16:24:41 +0000 (16:24 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 May 2005 16:24:41 +0000 (16:24 +0000)
        before comparing it for success.

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

gcc/ChangeLog
gcc/optabs.c

index bf396f7..a5e907c 100644 (file)
@@ -1,5 +1,10 @@
 2005-05-10  Richard Henderson  <rth@redhat.com>
 
+       * optabs.c (expand_compare_and_swap_loop): Don't clobber old value
+       before comparing it for success.
+
+2005-05-10  Richard Henderson  <rth@redhat.com>
+
        * config/ia64/sync.md (sync_add<I48MODE>): Fix arguments for
        no return value pattern.
 
index 3b3250a..2955f7b 100644 (file)
@@ -5625,24 +5625,27 @@ expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
 {
   enum machine_mode mode = GET_MODE (mem);
   enum insn_code icode;
-  rtx label, subtarget;
+  rtx label, cmp_reg, subtarget;
 
   /* The loop we want to generate looks like
 
-       old_reg = mem;
+       cmp_reg = mem;
       label:
+        old_reg = cmp_reg;
        seq;
-       old_reg = compare-and-swap(mem, old_reg, new_reg)
-       if (old_reg != new_reg)
+       cmp_reg = compare-and-swap(mem, old_reg, new_reg)
+       if (cmp_reg != old_reg)
          goto label;
 
      Note that we only do the plain load from memory once.  Subsequent
      iterations use the value loaded by the compare-and-swap pattern.  */
 
   label = gen_label_rtx ();
+  cmp_reg = gen_reg_rtx (mode);
 
-  emit_move_insn (old_reg, mem);
+  emit_move_insn (cmp_reg, mem);
   emit_label (label);
+  emit_move_insn (old_reg, cmp_reg);
   if (seq)
     emit_insn (seq);
 
@@ -5654,9 +5657,12 @@ expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
     {
     default:
       subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
-                                                old_reg, icode);
+                                                cmp_reg, icode);
       if (subtarget != NULL_RTX)
-       break;
+       {
+         gcc_assert (subtarget == cmp_reg);
+         break;
+       }
 
       /* FALLTHRU */
     case CODE_FOR_nothing:
@@ -5665,11 +5671,13 @@ expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
        return false;
 
       subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
-                                                old_reg, icode);
+                                                cmp_reg, icode);
       if (subtarget == NULL_RTX)
        return false;
+      if (subtarget != cmp_reg)
+       emit_move_insn (cmp_reg, subtarget);
 
-      emit_cmp_insn (subtarget, old_reg, EQ, const0_rtx, mode, true);
+      emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
     }
 
   /* ??? Mark this jump predicted not taken?  */