Paul Koning <paulkon...@comcast.net> writes:
> This fixes an ICE if post-reload compare elimination is done and the
> target supports post_inc and similar modes, as pdp11 does.  The ICE is
> caused by a generated PARALLEL that has the side effect twice, which
> is not legal.
>
> (Ideally it would generate a similar RTL suitable for a matching
> constraint with the side effect omitted; I may try for that later on
> if that is still supported by the constraint machinery.)
>
> Tested against my in-progress CCmode pdp11 target.  Ok to commit?

Thanks for doing the conversion :-)

> Index: compare-elim.c
> ===================================================================
> --- compare-elim.c    (revision 261207)
> +++ compare-elim.c    (working copy)
> @@ -127,6 +127,23 @@
>    
>  static vec<comparison *> all_compares;
>  
> +/* Callback function used by addr_side_effect_p.  */
> +static int
> +addr_side_effect_check (rtx mem ATTRIBUTE_UNUSED, rtx op ATTRIBUTE_UNUSED,
> +                     rtx dest ATTRIBUTE_UNUSED, rtx src ATTRIBUTE_UNUSED,
> +                     rtx srcoff ATTRIBUTE_UNUSED, void *arg ATTRIBUTE_UNUSED)
> +{
> +  return 1;
> +}
> +
> +/* Check if addr has side effects (contains autoinc or autodec
> +   operations).  */
> +static int
> +addr_side_effect_p (rtx addr)
> +{
> +  return for_each_inc_dec (addr, addr_side_effect_check, NULL);
> +} 
> +  
>  /* Look for a "conforming" comparison, as defined above.  If valid, return
>     the rtx for the COMPARE itself.  */
>  
> @@ -690,6 +707,13 @@
>      return false;
>  
>    rtx src = SET_SRC (set);
> +
> +  /* If the source uses addressing modes with side effects, we can't
> +     do the merge because we'd end up with a PARALLEL that has two
> +     instances of that side effect in it.  */
> +  if (addr_side_effect_p (src))
> +    return false;
> +
>    rtx flags = maybe_select_cc_mode (cmp, src, CONST0_RTX (GET_MODE (src)));
>    if (!flags)
>      {
> @@ -809,6 +833,12 @@
>    else
>      return false;
>  
> +  /* If the source uses addressing modes with side effects, we can't
> +     do the merge because we'd end up with a PARALLEL that has two
> +     instances of that side effect in it.  */
> +  if (addr_side_effect_p (cmp_src))
> +    return false;
> +
>    /* Determine if we ought to use a different CC_MODE here.  */
>    flags = maybe_select_cc_mode (cmp, cmp_src, in_b);
>    if (flags == NULL)

It looks like the more general side_effects_p might be better
in both cases.  It's simpler than defining a custom function,
and I'm not convinced the pass would handle other kinds of
side-effect correctly either.

FWIW, I agree these look like good places to put the check.
They're early enough to bail out, but late enough not to slow
down the common case.

Thanks,
Richard

Reply via email to