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

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

From-SVN: r99525
This commit is contained in:
Richard Henderson 2005-05-10 09:24:41 -07:00 committed by Richard Henderson
parent 8173eefc35
commit 81ba4f39ee
2 changed files with 22 additions and 9 deletions

View File

@ -1,3 +1,8 @@
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> 2005-05-10 Richard Henderson <rth@redhat.com>
* config/ia64/sync.md (sync_add<I48MODE>): Fix arguments for * config/ia64/sync.md (sync_add<I48MODE>): Fix arguments for

View 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 machine_mode mode = GET_MODE (mem);
enum insn_code icode; enum insn_code icode;
rtx label, subtarget; rtx label, cmp_reg, subtarget;
/* The loop we want to generate looks like /* The loop we want to generate looks like
old_reg = mem; cmp_reg = mem;
label: label:
old_reg = cmp_reg;
seq; seq;
old_reg = compare-and-swap(mem, old_reg, new_reg) cmp_reg = compare-and-swap(mem, old_reg, new_reg)
if (old_reg != new_reg) if (cmp_reg != old_reg)
goto label; goto label;
Note that we only do the plain load from memory once. Subsequent Note that we only do the plain load from memory once. Subsequent
iterations use the value loaded by the compare-and-swap pattern. */ iterations use the value loaded by the compare-and-swap pattern. */
label = gen_label_rtx (); 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_label (label);
emit_move_insn (old_reg, cmp_reg);
if (seq) if (seq)
emit_insn (seq); emit_insn (seq);
@ -5654,9 +5657,12 @@ expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
{ {
default: default:
subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg, subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
old_reg, icode); cmp_reg, icode);
if (subtarget != NULL_RTX) if (subtarget != NULL_RTX)
{
gcc_assert (subtarget == cmp_reg);
break; break;
}
/* FALLTHRU */ /* FALLTHRU */
case CODE_FOR_nothing: 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; return false;
subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg, subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
old_reg, icode); cmp_reg, icode);
if (subtarget == NULL_RTX) if (subtarget == NULL_RTX)
return false; 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? */ /* ??? Mark this jump predicted not taken? */