/* Post-reload compare elimination.
   Copyright (C) 2010-2024 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* There is a set of targets whose general-purpose move or addition
   instructions clobber the flags.  These targets cannot split their
   CBRANCH/CSTORE etc patterns before reload is complete, lest reload
   itself insert these instructions in between the flags setter and user.
   Because these targets cannot split the compare from the use, they
   cannot make use of the comparison elimination offered by the combine pass.

   This is a small pass intended to provide comparison elimination similar to
   what was available via NOTICE_UPDATE_CC for cc0 targets.

   This pass assumes:

   (0) CBRANCH/CSTORE etc have been split in pass_split_after_reload.

   (1) All comparison patterns are represented as

	[(set (reg:CC) (compare:CC (reg) (reg_or_immediate)))]

   (2) All insn patterns that modify the flags are represented as

	[(set (reg) (operation)
	 (clobber (reg:CC))]

   (3) If an insn of form (2) can usefully set the flags, there is
       another pattern of the form

	[(set (reg:CCM) (compare:CCM (operation) (immediate)))
	 (set (reg) (operation)]
	 
       The mode CCM will be chosen as if by SELECT_CC_MODE.

   Note that unlike NOTICE_UPDATE_CC, we do not handle memory operands.
   This could be handled as a future enhancement.
*/

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "recog.h"
#include "emit-rtl.h"
#include "cfgrtl.h"
#include "tree-pass.h"
#include "domwalk.h"


/* These structures describe a comparison and how it is used.  */

/* The choice of maximum 3 uses comes from wanting to eliminate the two
   duplicate compares from a three-way branch on the sign of a value.
   This is also sufficient to eliminate the duplicate compare against the
   high-part of a double-word comparison.  */
#define MAX_CMP_USE 3

struct comparison_use
{
  /* The instruction in which the result of the compare is used.  */
  rtx_insn *insn;
  /* The location of the flags register within the use.  */
  rtx *loc;
  /* The comparison code applied against the flags register.  */
  enum rtx_code code;
};

struct comparison
{
  /* The comparison instruction.  */
  rtx_insn *insn;

  /* The insn prior to the comparison insn that clobbers the flags.  */
  rtx_insn *prev_clobber;

  /* The insn prior to the comparison insn that sets in_a REG.  */
  rtx_insn *in_a_setter;

  /* The two values being compared.  These will be either REGs or
     constants.  */
  rtx in_a, in_b;

  /* The REG_EH_REGION of the comparison.  */
  rtx eh_note;

  /* Information about how this comparison is used.  */
  struct comparison_use uses[MAX_CMP_USE];

  /* The original CC_MODE for this comparison.  */
  machine_mode orig_mode;

  /* The number of uses identified for this comparison.  */
  unsigned short n_uses;

  /* True if not all uses of this comparison have been identified.
     This can happen either for overflowing the array above, or if
     the flags register is used in some unusual context.  */
  bool missing_uses;

  /* True if its inputs are still valid at the end of the block.  */
  bool inputs_valid;

  /* Whether IN_A is wrapped in a NOT before being compared.  */
  bool not_in_a;
};
  
static vec<comparison *> all_compares;

/* Return whether X is a NOT unary expression.  */

static bool
is_not (rtx x)
{
  return GET_CODE (x) == NOT;
}

/* Strip a NOT unary expression around X, if any.  */

static rtx
strip_not (rtx x)
{
  if (is_not (x))
    return XEXP (x, 0);

  return x;
}

/* Look for a "conforming" comparison, as defined above.  If valid, return
   the rtx for the COMPARE itself.  */

static rtx
conforming_compare (rtx_insn *insn)
{
  rtx set, src, dest;

  set = single_set (insn);
  if (set == NULL)
    return NULL;

  src = SET_SRC (set);
  if (GET_CODE (src) != COMPARE)
    return NULL;

  dest = SET_DEST (set);
  if (!REG_P (dest) || REGNO (dest) != targetm.flags_regnum)
    return NULL;

  if (!REG_P (strip_not (XEXP (src, 0))))
    return NULL;

  if (CONSTANT_P (XEXP (src, 1)) || REG_P (XEXP (src, 1)))
    return src;

  if (GET_CODE (XEXP (src, 1)) == UNSPEC)
    {
      for (int i = 0; i < XVECLEN (XEXP (src, 1), 0); i++)
	if (!REG_P (XVECEXP (XEXP (src, 1), 0, i)))
	  return NULL;
      return src;
    }

  return NULL;
}

/* Look for a pattern of the "correct" form for an insn with a flags clobber
   for which we may be able to eliminate a compare later.  We're not looking
   to validate any inputs at this time, merely see that the basic shape is
   correct.  The term "arithmetic" may be somewhat misleading...  */

static bool
arithmetic_flags_clobber_p (rtx_insn *insn)
{
  rtx pat, x;

  if (!NONJUMP_INSN_P (insn))
    return false;
  pat = PATTERN (insn);
  if (asm_noperands (pat) >= 0)
    return false;

  if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) == 2)
    {
      x = XVECEXP (pat, 0, 0);
      if (GET_CODE (x) != SET)
	return false;
      x = SET_DEST (x);
      if (!REG_P (x))
	return false;

      x = XVECEXP (pat, 0, 1);
      if (GET_CODE (x) == CLOBBER)
	{
	  x = XEXP (x, 0);
	  if (REG_P (x) && REGNO (x) == targetm.flags_regnum)
	    return true;
	}
    }

  return false;
}

/* Look for uses of FLAGS in INSN.  If we find one we can analyze, record
   it in CMP; otherwise indicate that we've missed a use.  */

static void
find_flags_uses_in_insn (struct comparison *cmp, rtx_insn *insn)
{
  df_ref use;

  /* If we've already lost track of uses, don't bother collecting more.  */
  if (cmp->missing_uses)
    return;

  /* Find a USE of the flags register.  */
  FOR_EACH_INSN_USE (use, insn)
    if (DF_REF_REGNO (use) == targetm.flags_regnum)
      {
	rtx x, *loc;

	/* If this is an unusual use, quit.  */
	if (DF_REF_TYPE (use) != DF_REF_REG_USE)
	  goto fail;

	/* If we've run out of slots to record uses, quit.  */
	if (cmp->n_uses == MAX_CMP_USE)
	  goto fail;

	/* Unfortunately the location of the flags register, while present
	   in the reference structure, doesn't help.  We need to find the
	   comparison code that is outer to the actual flags use.  */
	loc = DF_REF_LOC (use);
	x = PATTERN (insn);
	if (GET_CODE (x) == PARALLEL)
	  x = XVECEXP (x, 0, 0);
	if (GET_CODE (x) == SET)
	  x = SET_SRC (x);
	if (GET_CODE (x) == IF_THEN_ELSE)
	  x = XEXP (x, 0);
	if (COMPARISON_P (x)
	    && loc == &XEXP (x, 0)
	    && XEXP (x, 1) == const0_rtx)
	  {
	    /* We've found a use of the flags that we understand.  */
	    struct comparison_use *cuse = &cmp->uses[cmp->n_uses++];
	    cuse->insn = insn;
	    cuse->loc = loc;
	    cuse->code = GET_CODE (x);
	  }
	else
	  goto fail;
      }
  return;

 fail:
  /* We failed to recognize this use of the flags register.  */
  cmp->missing_uses = true;
}

class find_comparison_dom_walker : public dom_walker
{
public:
  find_comparison_dom_walker (cdi_direction direction)
    : dom_walker (direction) {}

  edge before_dom_children (basic_block) final override;
};

/* Return true if conforming COMPARE with EH_NOTE is redundant with comparison
   CMP and can thus be eliminated.  */

static bool
can_eliminate_compare (rtx compare, rtx eh_note, struct comparison *cmp)
{
  /* Take care that it's in the same EH region.  */
  if (cfun->can_throw_non_call_exceptions
      && !rtx_equal_p (eh_note, cmp->eh_note))
    return false;

  /* Make sure the compare is redundant with the previous.  */
  if (!rtx_equal_p (strip_not (XEXP (compare, 0)), cmp->in_a)
      || !rtx_equal_p (XEXP (compare, 1), cmp->in_b))
    return false;

  if (is_not (XEXP (compare, 0)) != cmp->not_in_a)
    return false;

  /* New mode must be compatible with the previous compare mode.  */
  machine_mode new_mode
    = targetm.cc_modes_compatible (GET_MODE (compare), cmp->orig_mode);

  if (new_mode == VOIDmode)
    return false;

  if (cmp->orig_mode != new_mode)
    {
      /* Generate new comparison for substitution.  */
      rtx flags = gen_rtx_REG (new_mode, targetm.flags_regnum);
      rtx x = gen_rtx_COMPARE (new_mode, cmp->in_a, cmp->in_b);
      x = gen_rtx_SET (flags, x);

      if (!validate_change (cmp->insn, &PATTERN (cmp->insn), x, false))
	return false;

      cmp->orig_mode = new_mode;
    }

  return true;
}

/* Identify comparison instructions within BB.  If the flags from the last
   compare in the BB is live at the end of the block, install the compare
   in BB->AUX.  Called via dom_walker.walk ().  */

edge
find_comparison_dom_walker::before_dom_children (basic_block bb)
{
  rtx_insn *insn, *next;
  bool need_purge = false;
  rtx_insn *last_setter[FIRST_PSEUDO_REGISTER];

  /* The last comparison that was made.  Will be reset to NULL
     once the flags are clobbered.  */
  struct comparison *last_cmp = NULL;

  /* True iff the last comparison has not been clobbered, nor
     have its inputs.  Used to eliminate duplicate compares.  */
  bool last_cmp_valid = false;

  /* The last insn that clobbered the flags, if that insn is of
     a form that may be valid for eliminating a following compare.
     To be reset to NULL once the flags are set otherwise.  */
  rtx_insn *last_clobber = NULL;

  /* Propagate the last live comparison throughout the extended basic block. */
  if (single_pred_p (bb))
    {
      last_cmp = (struct comparison *) single_pred (bb)->aux;
      if (last_cmp)
	last_cmp_valid = last_cmp->inputs_valid;
    }

  memset (last_setter, 0, sizeof (last_setter));
  for (insn = BB_HEAD (bb); insn; insn = next)
    {
      rtx src;

      next = (insn == BB_END (bb) ? NULL : NEXT_INSN (insn));
      if (!NONDEBUG_INSN_P (insn))
	continue;

      src = conforming_compare (insn);
      if (src)
	{
	  rtx eh_note = NULL;

	  if (cfun->can_throw_non_call_exceptions)
	    eh_note = find_reg_note (insn, REG_EH_REGION, NULL);

	  if (last_cmp_valid && can_eliminate_compare (src, eh_note, last_cmp))
	    {
	      if (eh_note)
		need_purge = true;
	      delete_insn (insn);
	      continue;
	    }

	  last_cmp = XCNEW (struct comparison);
	  last_cmp->insn = insn;
	  last_cmp->prev_clobber = last_clobber;
	  last_cmp->in_a = strip_not (XEXP (src, 0));
	  last_cmp->in_b = XEXP (src, 1);
	  last_cmp->not_in_a = is_not (XEXP (src, 0));
	  last_cmp->eh_note = eh_note;
	  last_cmp->orig_mode = GET_MODE (src);
	  if (last_cmp->in_b == const0_rtx
	      && last_setter[REGNO (last_cmp->in_a)])
	    {
	      rtx set = single_set (last_setter[REGNO (last_cmp->in_a)]);
	      if (set && rtx_equal_p (SET_DEST (set), last_cmp->in_a))
		last_cmp->in_a_setter = last_setter[REGNO (last_cmp->in_a)];
	    }
	  all_compares.safe_push (last_cmp);

	  /* It's unusual, but be prepared for comparison patterns that
	     also clobber an input, or perhaps a scratch.  */
	  last_clobber = NULL;
	  last_cmp_valid = true;
	}

      else
	{
	  /* Notice if this instruction uses the flags register.  */
	  if (last_cmp)
	    find_flags_uses_in_insn (last_cmp, insn);

	  /* Notice if this instruction kills the flags register.  */
	  df_ref def;
	  FOR_EACH_INSN_DEF (def, insn)
	    if (DF_REF_REGNO (def) == targetm.flags_regnum)
	      {
		/* See if this insn could be the "clobber" that eliminates
		   a future comparison.   */
		last_clobber = (arithmetic_flags_clobber_p (insn)
				? insn : NULL);

		/* In either case, the previous compare is no longer valid.  */
		last_cmp = NULL;
		last_cmp_valid = false;
		break;
	      }
	}

      /* Notice if any of the inputs to the comparison have changed
	 and remember last insn that sets each register.  */
      df_ref def;
      FOR_EACH_INSN_DEF (def, insn)
	{
	  if (last_cmp_valid
	      && (DF_REF_REGNO (def) == REGNO (last_cmp->in_a)
		  || (REG_P (last_cmp->in_b)
		      && DF_REF_REGNO (def) == REGNO (last_cmp->in_b))))
	    last_cmp_valid = false;
	  last_setter[DF_REF_REGNO (def)] = insn;
	}
    }

  /* Remember the live comparison for subsequent members of
     the extended basic block.  */
  if (last_cmp)
    {
      bb->aux = last_cmp;
      last_cmp->inputs_valid = last_cmp_valid;

      /* Look to see if the flags register is live outgoing here, and
	 incoming to any successor not part of the extended basic block.  */
      if (bitmap_bit_p (df_get_live_out (bb), targetm.flags_regnum))
	{
	  edge e;
	  edge_iterator ei;

	  FOR_EACH_EDGE (e, ei, bb->succs)
	    {
	      basic_block dest = e->dest;
	      if (bitmap_bit_p (df_get_live_in (bb), targetm.flags_regnum)
		  && !single_pred_p (dest))
		{
		  last_cmp->missing_uses = true;
		  break;
		}
	    }
	}
    }

  /* If we deleted a compare with a REG_EH_REGION note, we may need to
     remove EH edges.  */
  if (need_purge)
    purge_dead_edges (bb);

  return NULL;
}

/* Find all comparisons in the function.  */

static void
find_comparisons (void)
{
  calculate_dominance_info (CDI_DOMINATORS);

  find_comparison_dom_walker (CDI_DOMINATORS)
    .walk (cfun->cfg->x_entry_block_ptr);

  clear_aux_for_blocks ();
  free_dominance_info (CDI_DOMINATORS);
}

/* Select an alternate CC_MODE for a comparison insn comparing A and B.
   Note that inputs are almost certainly different than the IN_A and IN_B
   stored in CMP -- we're called while attempting to eliminate the compare
   after all.  Return the new FLAGS rtx if successful, else return NULL.
   Note that this function may start a change group.  */

static rtx
maybe_select_cc_mode (struct comparison *cmp, rtx a ATTRIBUTE_UNUSED,
		      rtx b ATTRIBUTE_UNUSED)
{
  machine_mode sel_mode;
  const int n = cmp->n_uses;
  rtx flags = NULL;

#ifndef SELECT_CC_MODE
  /* Minimize code differences when this target macro is undefined.  */
  return NULL;
#define SELECT_CC_MODE(A,B,C) (gcc_unreachable (), VOIDmode)
#endif

  /* If we don't have access to all of the uses, we can't validate.  */
  if (cmp->missing_uses || n == 0)
    return NULL;

  /* Find a new mode that works for all of the uses.  Special case the
     common case of exactly one use.  */
  if (n == 1)
    {
      sel_mode = SELECT_CC_MODE (cmp->uses[0].code, a, b);
      if (sel_mode != cmp->orig_mode)
	{
	  flags = gen_rtx_REG (sel_mode, targetm.flags_regnum);
	  validate_change (cmp->uses[0].insn, cmp->uses[0].loc, flags, true);
	}
    }
  else
    {
      int i;

      sel_mode = SELECT_CC_MODE (cmp->uses[0].code, a, b);
      for (i = 1; i < n; ++i)
	{
	  machine_mode new_mode = SELECT_CC_MODE (cmp->uses[i].code, a, b);
	  if (new_mode != sel_mode)
	    {
	      sel_mode = targetm.cc_modes_compatible (sel_mode, new_mode);
	      if (sel_mode == VOIDmode)
		return NULL;
	    }
	}

      if (sel_mode != cmp->orig_mode)
	{
	  flags = gen_rtx_REG (sel_mode, targetm.flags_regnum);
	  for (i = 0; i < n; ++i)
	    validate_change (cmp->uses[i].insn, cmp->uses[i].loc, flags, true);
	}
    }

  return flags;
}

/* Return a register RTX holding the same value at START as REG at END, or
   NULL_RTX if there is none.  */

static rtx
equivalent_reg_at_start (rtx reg, rtx_insn *end, rtx_insn *start)
{
  machine_mode orig_mode = GET_MODE (reg);
  rtx_insn *bb_head = BB_HEAD (BLOCK_FOR_INSN (end));

  for (rtx_insn *insn = PREV_INSN (end);
       insn != start;
       insn = PREV_INSN (insn))
    {
      const int abnormal_flags
	= (DF_REF_CONDITIONAL | DF_REF_PARTIAL | DF_REF_MAY_CLOBBER
	   | DF_REF_MUST_CLOBBER | DF_REF_SIGN_EXTRACT
	   | DF_REF_ZERO_EXTRACT | DF_REF_STRICT_LOW_PART
	   | DF_REF_PRE_POST_MODIFY);
      df_ref def;

      /* Note that the BB_HEAD is always either a note or a label, but in
	 any case it means that REG is defined outside the block.  */
      if (insn == bb_head)
	return NULL_RTX;
      if (NOTE_P (insn) || DEBUG_INSN_P (insn))
	continue;

      /* Find a possible def of REG in INSN.  */
      FOR_EACH_INSN_DEF (def, insn)
	if (DF_REF_REGNO (def) == REGNO (reg))
	  break;

      /* No definitions of REG; continue searching.  */
      if (def == NULL)
	continue;

      /* Bail if this is not a totally normal set of REG.  */
      if (DF_REF_IS_ARTIFICIAL (def))
	return NULL_RTX;
      if (DF_REF_FLAGS (def) & abnormal_flags)
	return NULL_RTX;

      /* We've found an insn between the compare and the clobber that sets
	 REG.  Given that pass_cprop_hardreg has not yet run, we still find
	 situations in which we can usefully look through a copy insn.  */
      rtx x = single_set (insn);
      if (x == NULL_RTX)
	return NULL_RTX;
      reg = SET_SRC (x);
      if (!REG_P (reg))
	return NULL_RTX;
    }

  if (GET_MODE (reg) != orig_mode)
    return NULL_RTX;

  return reg;
}

/* Return true if it is okay to merge the comparison CMP_INSN with
   the instruction ARITH_INSN.  Both instructions are assumed to be in the
   same basic block with ARITH_INSN appearing before CMP_INSN.  This checks
   that there are no uses or defs of the condition flags or control flow
   changes between the two instructions.  */

static bool
can_merge_compare_into_arith (rtx_insn *cmp_insn, rtx_insn *arith_insn)
{
  for (rtx_insn *insn = PREV_INSN (cmp_insn);
       insn && insn != arith_insn;
       insn = PREV_INSN (insn))
    {
      if (!NONDEBUG_INSN_P (insn))
	continue;
      /* Bail if there are jumps or calls in between.  */
      if (!NONJUMP_INSN_P (insn))
	return false;

      /* Bail on old-style asm statements because they lack
	 data flow information.  */
      if (GET_CODE (PATTERN (insn)) == ASM_INPUT)
	return false;

      df_ref ref;
      /* Find a USE of the flags register.  */
      FOR_EACH_INSN_USE (ref, insn)
	if (DF_REF_REGNO (ref) == targetm.flags_regnum)
	  return false;

      /* Find a DEF of the flags register.  */
      FOR_EACH_INSN_DEF (ref, insn)
	if (DF_REF_REGNO (ref) == targetm.flags_regnum)
	  return false;
    }
  return true;
}

/* Given two SET expressions, SET_A and SET_B determine whether they form
   a recognizable pattern when emitted in parallel.  Return that parallel
   if so.  Otherwise return NULL.  */

static rtx
try_validate_parallel (rtx set_a, rtx set_b)
{
  rtx par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set_a, set_b));
  rtx_insn *insn = make_insn_raw (par);

  if (insn_invalid_p (insn, false))
    {
      crtl->emit.x_cur_insn_uid--;
      return NULL_RTX;
    }

  SET_PREV_INSN (insn) = NULL_RTX;
  SET_NEXT_INSN (insn) = NULL_RTX;
  INSN_LOCATION (insn) = 0;
  return insn;
}

/* For a comparison instruction described by CMP check if it compares a
   register with zero i.e. it is of the form CC := CMP R1, 0.
   If it is, find the instruction defining R1 (say I1) and try to create a
   PARALLEL consisting of I1 and the comparison, representing a flag-setting
   arithmetic instruction.  Example:
   I1: R1 := R2 + R3
   <instructions that don't read the condition register>
   I2: CC := CMP R1 0
   I2 can be merged with I1 into:
   I1: { CC := CMP (R2 + R3) 0 ; R1 := R2 + R3 }
   This catches cases where R1 is used between I1 and I2 and therefore
   combine and other RTL optimisations will not try to propagate it into
   I2.  Return true if we succeeded in merging CMP.  */

static bool
try_merge_compare (struct comparison *cmp)
{
  rtx_insn *cmp_insn = cmp->insn;

  if (cmp->in_b != const0_rtx || cmp->in_a_setter == NULL)
    return false;
  rtx in_a = cmp->in_a;
  df_ref use;

  FOR_EACH_INSN_USE (use, cmp_insn)
    if (DF_REF_REGNO (use) == REGNO (in_a))
      break;
  if (!use)
    return false;

  rtx_insn *def_insn = cmp->in_a_setter;
  rtx set = single_set (def_insn);
  if (!set)
    return false;

  if (!can_merge_compare_into_arith (cmp_insn, def_insn))
    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 (side_effects_p (src))
    return false;

  rtx flags = maybe_select_cc_mode (cmp, src, CONST0_RTX (GET_MODE (src)));
  if (!flags)
    {
    /* We may already have a change group going through maybe_select_cc_mode.
       Discard it properly.  */
      cancel_changes (0);
      return false;
    }

  rtx flag_set
    = gen_rtx_SET (flags, gen_rtx_COMPARE (GET_MODE (flags),
					   copy_rtx (src),
					   CONST0_RTX (GET_MODE (src))));
  rtx arith_set = copy_rtx (PATTERN (def_insn));
  rtx par = try_validate_parallel (flag_set, arith_set);
  if (!par)
    {
      /* We may already have a change group going through maybe_select_cc_mode.
	 Discard it properly.  */
      cancel_changes (0);
      return false;
    }
  if (!apply_change_group ())
    return false;
  emit_insn_after (par, def_insn);
  delete_insn (def_insn);
  delete_insn (cmp->insn);
  return true;
}

/* Attempt to replace a comparison with a prior arithmetic insn that can
   compute the same flags value as the comparison itself.  Return true if
   successful, having made all rtl modifications necessary.  */

static bool
try_eliminate_compare (struct comparison *cmp)
{
  rtx flags, in_a, in_b, cmp_a, cmp_b;

  if (try_merge_compare (cmp))
    return true;

  /* We must have found an interesting "clobber" preceding the compare.  */
  if (cmp->prev_clobber == NULL)
    return false;

  /* Verify that IN_A is not clobbered in between CMP and PREV_CLOBBER.
     Given that this target requires this pass, we can assume that most
     insns do clobber the flags, and so the distance between the compare
     and the clobber is likely to be small.  */
  /* ??? This is one point at which one could argue that DF_REF_CHAIN would
     be useful, but it is thought to be too heavy-weight a solution here.  */
  in_a = equivalent_reg_at_start (cmp->in_a, cmp->insn, cmp->prev_clobber);
  if (!in_a)
    return false;

  /* Likewise for IN_B if need be.  */
  if (CONSTANT_P (cmp->in_b))
    in_b = cmp->in_b;
  else if (REG_P (cmp->in_b))
    {
      in_b = equivalent_reg_at_start (cmp->in_b, cmp->insn, cmp->prev_clobber);
      if (!in_b)
	return false;
    }
  else if (GET_CODE (cmp->in_b) == UNSPEC)
    {
      const int len = XVECLEN (cmp->in_b, 0);
      rtvec v = rtvec_alloc (len);
      for (int i = 0; i < len; i++)
	{
	  rtx r = equivalent_reg_at_start (XVECEXP (cmp->in_b, 0, i),
					   cmp->insn, cmp->prev_clobber);
	  if (!r)
	    return false;
	  RTVEC_ELT (v, i) = r;
	}
      in_b = gen_rtx_UNSPEC (GET_MODE (cmp->in_b), v, XINT (cmp->in_b, 1));
    }
  else
    gcc_unreachable ();

  /* We've reached PREV_CLOBBER without finding a modification of IN_A.
     Validate that PREV_CLOBBER itself does in fact refer to IN_A.  Do
     recall that we've already validated the shape of PREV_CLOBBER.  */
  rtx_insn *insn = cmp->prev_clobber;

  rtx x = XVECEXP (PATTERN (insn), 0, 0);
  if (rtx_equal_p (SET_DEST (x), in_a))
    cmp_a = SET_SRC (x);

  /* Also check operations with implicit extensions, e.g.:
     [(set (reg:DI)
	   (zero_extend:DI (plus:SI (reg:SI) (reg:SI))))
      (set (reg:CCZ flags)
	   (compare:CCZ (plus:SI (reg:SI) (reg:SI))
			(const_int 0)))] */
  else if (REG_P (SET_DEST (x))
	   && REG_P (in_a)
	   && REGNO (SET_DEST (x)) == REGNO (in_a)
	   && (GET_CODE (SET_SRC (x)) == ZERO_EXTEND
	       || GET_CODE (SET_SRC (x)) == SIGN_EXTEND)
	   && GET_MODE (XEXP (SET_SRC (x), 0)) == GET_MODE (in_a))
    cmp_a = XEXP (SET_SRC (x), 0);

  /* Also check fully redundant comparisons, e.g.:
     [(set (reg:SI)
	   (minus:SI (reg:SI) (reg:SI))))
      (set (reg:CC flags)
	   (compare:CC (reg:SI) (reg:SI)))] */
  else if (REG_P (in_b)
	   && GET_CODE (SET_SRC (x)) == MINUS
	   && rtx_equal_p (XEXP (SET_SRC (x), 0), in_a)
	   && rtx_equal_p (XEXP (SET_SRC (x), 1), in_b))
    cmp_a = in_a;

  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 (side_effects_p (cmp_a))
    return false;

  if (in_a == in_b)
    cmp_b = cmp_a;
  else if (rtx_equal_p (SET_DEST (x), in_b))
    cmp_b = SET_SRC (x);
  else
    cmp_b = in_b;
  if (side_effects_p (cmp_b))
    return false;

  /* Determine if we ought to use a different CC_MODE here.  */
  flags = maybe_select_cc_mode (cmp, cmp_a, cmp_b);
  if (flags == NULL)
    flags = gen_rtx_REG (cmp->orig_mode, targetm.flags_regnum);

  /* Generate a new comparison for installation in the setter.  */
  rtx y = cmp->not_in_a
	  ? gen_rtx_NOT (GET_MODE (cmp_a), copy_rtx (cmp_a))
	  : copy_rtx (cmp_a);
  y = gen_rtx_COMPARE (GET_MODE (flags), y, copy_rtx (cmp_b));
  y = gen_rtx_SET (flags, y);

  /* Canonicalize instruction to:
     [(set (reg:CCM) (compare:CCM (operation) (immediate)))
      (set (reg) (operation)]  */

  rtvec v = rtvec_alloc (2);
  RTVEC_ELT (v, 0) = y;
  RTVEC_ELT (v, 1) = x;
  
  rtx pat = gen_rtx_PARALLEL (VOIDmode, v);
  
  /* Succeed if the new instruction is valid.  Note that we may have started
     a change group within maybe_select_cc_mode, therefore we must continue. */
  validate_change (insn, &PATTERN (insn), pat, true);
  
  if (!apply_change_group ())
    return false;

  /* Success.  Delete the compare insn...  */
  delete_insn (cmp->insn);

  /* ... and any notes that are now invalid due to multiple sets.  */
  x = find_regno_note (insn, REG_UNUSED, targetm.flags_regnum);
  if (x)
    remove_note (insn, x);
  x = find_reg_note (insn, REG_EQUAL, NULL);
  if (x)
    remove_note (insn, x);
  x = find_reg_note (insn, REG_EQUIV, NULL);
  if (x)
    remove_note (insn, x);

  return true;
}

/* Main entry point to the pass.  */

static unsigned int
execute_compare_elim_after_reload (void)
{
  df_set_flags (DF_LR_RUN_DCE);
  df_analyze ();

  gcc_checking_assert (!all_compares.exists ());

  /* Locate all comparisons and their uses, and eliminate duplicates.  */
  find_comparisons ();
  if (all_compares.exists ())
    {
      struct comparison *cmp;
      size_t i;

      /* Eliminate comparisons that are redundant with flags computation.  */
      FOR_EACH_VEC_ELT (all_compares, i, cmp)
	{
	  try_eliminate_compare (cmp);
	  XDELETE (cmp);
	}

      all_compares.release ();
    }

  return 0;
}

namespace {

const pass_data pass_data_compare_elim_after_reload =
{
  RTL_PASS, /* type */
  "cmpelim", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  ( TODO_df_finish | TODO_df_verify ), /* todo_flags_finish */
};

class pass_compare_elim_after_reload : public rtl_opt_pass
{
public:
  pass_compare_elim_after_reload (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_compare_elim_after_reload, ctxt)
  {}

  /* opt_pass methods: */
  bool gate (function *) final override
    {
      /* Setting this target hook value is how a backend indicates the need.  */
      if (targetm.flags_regnum == INVALID_REGNUM)
	return false;
      return flag_compare_elim_after_reload;
    }

  unsigned int execute (function *) final override
    {
      return execute_compare_elim_after_reload ();
    }

}; // class pass_compare_elim_after_reload

} // anon namespace

rtl_opt_pass *
make_pass_compare_elim_after_reload (gcc::context *ctxt)
{
  return new pass_compare_elim_after_reload (ctxt);
}
