https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80080

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Dominik Vogt from comment #3)
> Most of this can be fixed in the backend, but all attempts to get rid of the
> additional load ("lr %r3,%31") in "bar" within the backend have failed. 
> This is caused by overly complicated code being generated in
> expand_compare_and_swap_loop().  I'm currently testing the patch below which
> eliminates the superfluous variable cmp_reg (and the register allocated for
> it).  Is there any chance to get something like this into Gcc7?  The patch
> could possibly also help other targets.  (Will post on gcc-patches when the
> tests are complete.)
> 
> 
> --- a/gcc/optabs.c
> +++ b/gcc/optabs.c
> @@ -5798,17 +5798,15 @@ find_cc_set (rtx x, const_rtx pat, void *data)
>  static bool
>  expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
>  {
> -  machine_mode mode = GET_MODE (mem);
>    rtx_code_label *label;
> -  rtx cmp_reg, success, oldval;
> +  rtx success, oldval;
>  
>    /* The loop we want to generate looks like
>  
> -     cmp_reg = mem;
> +     old_reg = mem;
>        label:
> -        old_reg = cmp_reg;
>       seq;
> -     (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
> +     (success, old_reg) = compare-and-swap(mem, old_reg, new_reg)
>       if (success)
>         goto label;
>  
> @@ -5816,23 +5814,21 @@ expand_compare_and_swap_loop (rtx mem, rtx old_reg,
> rtx new_reg, rtx seq)
>       iterations use the value loaded by the compare-and-swap pattern.  */
>  
>    label = gen_label_rtx ();
> -  cmp_reg = gen_reg_rtx (mode);
>  
> -  emit_move_insn (cmp_reg, mem);
> +  emit_move_insn (old_reg, mem);
>    emit_label (label);
> -  emit_move_insn (old_reg, cmp_reg);
>    if (seq)
>      emit_insn (seq);
>  
>    success = NULL_RTX;
> -  oldval = cmp_reg;
> +  oldval = old_reg;
>    if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
>                                      new_reg, false, MEMMODEL_SYNC_SEQ_CST,
>                                      MEMMODEL_RELAXED))
>      return false;
>  
> -  if (oldval != cmp_reg)
> -    emit_move_insn (cmp_reg, oldval);
> +  if (oldval != old_reg)
> +    emit_move_insn (old_reg, oldval);
>  
>    /* Mark this jump predicted not taken.  */
>    emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,

That doesn't look correct.  expand_compare_and_swap_loop is called from two
places and at least in the first case it wants old_reg to contain on success
something that is the target that will be returned.
While with your patch it might be something different.

Reply via email to