This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: patch to fix PR57604
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: Vladimir Makarov <vmakarov at redhat dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- Date: Thu, 20 Jun 2013 20:12:05 +0100
- Subject: Re: patch to fix PR57604
- References: <51C2462F dot 9040704 at redhat dot com>
Thanks Vlad.
Vladimir Makarov <vmakarov@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