This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

fix compare-and-swap based atomic op expander


The test case for this is burried somewhere in libgomp.  It requires
real contention on the lock in order to show the problem.

Tested on ia64-linux; libgomp testsuite no longer hangs.



r~



        * optabs.c (expand_compare_and_swap_loop): Don't clobber old value
        before comparing it for success.

Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.277
diff -u -p -d -r1.277 optabs.c
--- optabs.c	28 Apr 2005 05:03:07 -0000	1.277
+++ optabs.c	10 May 2005 16:21:59 -0000
@@ -5625,24 +5625,27 @@ expand_compare_and_swap_loop (rtx mem, r
 {
   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, r
     {
     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, r
 	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?  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]