Thanks Vlad.

Vladimir Makarov <vmaka...@redhat.com> writes:
> Index: lra.c
> ===================================================================
> --- lra.c     (revision 200174)
> +++ lra.c     (working copy)
> @@ -242,6 +242,42 @@ lra_delete_dead_insn (rtx insn)
>    lra_set_insn_deleted (insn);
>  }
>  
> +/* Emit insn x = y + z.  Return NULL if we failed to do it.
> +   Otherwise, return the insn.  We don't use gen_add3_insn as it might
> +   clobber CC.  */
> +static rtx
> +emit_add3_insn (rtx x, rtx y, rtx z)
> +{
> +  rtx insn, last;
> +
> +  last = get_last_insn ();
> +  insn = emit_insn (gen_rtx_SET (VOIDmode, x,
> +                              gen_rtx_PLUS (GET_MODE (y), y, z)));
> +  if (recog_memoized (insn) < 0)
> +    {
> +      delete_insns_since (last);
> +      insn = NULL_RTX;
> +    }
> +  return insn;
> +}
> +
> +/* Emit insn x = x + y.  Return the insn.  We use gen_add2_insn as the
> +   last resort.  */
> +static rtx
> +emit_add2_insn (rtx x, rtx y)
> +{
> +  rtx insn;
> +
> +  insn = emit_add3_insn (x, x, y);
> +  if (insn == NULL_RTX)
> +    {
> +      insn = gen_add2_insn (x, y);
> +      if (insn != NULL_RTX)
> +     emit_insn (insn);
> +    }
> +  return insn;
> +}

Why is gen_add2_insn allowed and gen_add3_insn not?  They both use
the same add<Pmode>3 optab, so one seems just as likely as the other
to clobber the flags.

Maybe it would help to have an addptr<mode>3 optab that can only be used
for values that are known to be pointers and that is specifically not
allowed to clobber the flags.  Or an "lea<mode>2" optab that is required
to accept all "m" addresses.

> @@ -306,12 +342,14 @@ lra_emit_add (rtx x, rtx y, rtx z)
>         || (disp != NULL_RTX && ! CONSTANT_P (disp))
>         || (scale != NULL_RTX && ! CONSTANT_P (scale)))
>       {
> -       /* It is not an address generation.   Probably we have no 3 op
> -          add.  Last chance is to use 2-op add insn.  */
> +       /* Probably we have no 3 op add.  Last chance is to use 2-op
> +          add insn.  To succeed, don't move Z to X as an address
> +          segment always comes in Y.  Otherwise, we might fail when
> +          adding the address segment to register.  */

Do you mean "segment" in the x86 sense, or something else?  I still don't
really understand.

Thanks,
Richard

Reply via email to