/* Optimize by combining instructions for GNU compiler.
   Copyright (C) 1987-2019 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/>.  */

/* This module is essentially the "combiner" phase of the U. of Arizona
   Portable Optimizer, but redone to work on our list-structured
   representation for RTL instead of their string representation.

   The LOG_LINKS of each insn identify the most recent assignment
   to each REG used in the insn.  It is a list of previous insns,
   each of which contains a SET for a REG that is used in this insn
   and not used or set in between.  LOG_LINKs never cross basic blocks.
   They were set up by the preceding pass (lifetime analysis).

   We try to combine each pair of insns joined by a logical link.
   We also try to combine triplets of insns A, B and C when C has
   a link back to B and B has a link back to A.  Likewise for a
   small number of quadruplets of insns A, B, C and D for which
   there's high likelihood of success.

   LOG_LINKS does not have links for use of the CC0.  They don't
   need to, because the insn that sets the CC0 is always immediately
   before the insn that tests it.  So we always regard a branch
   insn as having a logical link to the preceding insn.  The same is true
   for an insn explicitly using CC0.

   We check (with modified_between_p) to avoid combining in such a way
   as to move a computation to a place where its value would be different.

   Combination is done by mathematically substituting the previous
   insn(s) values for the regs they set into the expressions in
   the later insns that refer to these regs.  If the result is a valid insn
   for our target machine, according to the machine description,
   we install it, delete the earlier insns, and update the data flow
   information (LOG_LINKS and REG_NOTES) for what we did.

   There are a few exceptions where the dataflow information isn't
   completely updated (however this is only a local issue since it is
   regenerated before the next pass that uses it):

   - reg_live_length is not updated
   - reg_n_refs is not adjusted in the rare case when a register is
     no longer required in a computation
   - there are extremely rare cases (see distribute_notes) when a
     REG_DEAD note is lost
   - a LOG_LINKS entry that refers to an insn with multiple SETs may be
     removed because there is no way to know which register it was
     linking

   To simplify substitution, we combine only when the earlier insn(s)
   consist of only a single assignment.  To simplify updating afterward,
   we never combine when a subroutine call appears in the middle.

   Since we do not represent assignments to CC0 explicitly except when that
   is all an insn does, there is no LOG_LINKS entry in an insn that uses
   the condition code for the insn that set the condition code.
   Fortunately, these two insns must be consecutive.
   Therefore, every JUMP_INSN is taken to have an implicit logical link
   to the preceding insn.  This is not quite right, since non-jumps can
   also use the condition code; but in practice such insns would not
   combine anyway.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "predict.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "optabs.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "cgraph.h"
#include "stor-layout.h"
#include "cfgrtl.h"
#include "cfgcleanup.h"
/* Include expr.h after insn-config.h so we get HAVE_conditional_move.  */
#include "explow.h"
#include "insn-attr.h"
#include "rtlhooks-def.h"
#include "expr.h"
#include "params.h"
#include "tree-pass.h"
#include "valtrack.h"
#include "rtl-iter.h"
#include "print-rtl.h"

/* Number of attempts to combine instructions in this function.  */

static int combine_attempts;

/* Number of attempts that got as far as substitution in this function.  */

static int combine_merges;

/* Number of instructions combined with added SETs in this function.  */

static int combine_extras;

/* Number of instructions combined in this function.  */

static int combine_successes;

/* Totals over entire compilation.  */

static int total_attempts, total_merges, total_extras, total_successes;

/* combine_instructions may try to replace the right hand side of the
   second instruction with the value of an associated REG_EQUAL note
   before throwing it at try_combine.  That is problematic when there
   is a REG_DEAD note for a register used in the old right hand side
   and can cause distribute_notes to do wrong things.  This is the
   second instruction if it has been so modified, null otherwise.  */

static rtx_insn *i2mod;

/* When I2MOD is nonnull, this is a copy of the old right hand side.  */

static rtx i2mod_old_rhs;

/* When I2MOD is nonnull, this is a copy of the new right hand side.  */

static rtx i2mod_new_rhs;

struct reg_stat_type {
  /* Record last point of death of (hard or pseudo) register n.  */
  rtx_insn			*last_death;

  /* Record last point of modification of (hard or pseudo) register n.  */
  rtx_insn			*last_set;

  /* The next group of fields allows the recording of the last value assigned
     to (hard or pseudo) register n.  We use this information to see if an
     operation being processed is redundant given a prior operation performed
     on the register.  For example, an `and' with a constant is redundant if
     all the zero bits are already known to be turned off.

     We use an approach similar to that used by cse, but change it in the
     following ways:

     (1) We do not want to reinitialize at each label.
     (2) It is useful, but not critical, to know the actual value assigned
	 to a register.  Often just its form is helpful.

     Therefore, we maintain the following fields:

     last_set_value		the last value assigned
     last_set_label		records the value of label_tick when the
				register was assigned
     last_set_table_tick	records the value of label_tick when a
				value using the register is assigned
     last_set_invalid		set to nonzero when it is not valid
				to use the value of this register in some
				register's value

     To understand the usage of these tables, it is important to understand
     the distinction between the value in last_set_value being valid and
     the register being validly contained in some other expression in the
     table.

     (The next two parameters are out of date).

     reg_stat[i].last_set_value is valid if it is nonzero, and either
     reg_n_sets[i] is 1 or reg_stat[i].last_set_label == label_tick.

     Register I may validly appear in any expression returned for the value
     of another register if reg_n_sets[i] is 1.  It may also appear in the
     value for register J if reg_stat[j].last_set_invalid is zero, or
     reg_stat[i].last_set_label < reg_stat[j].last_set_label.

     If an expression is found in the table containing a register which may
     not validly appear in an expression, the register is replaced by
     something that won't match, (clobber (const_int 0)).  */

  /* Record last value assigned to (hard or pseudo) register n.  */

  rtx				last_set_value;

  /* Record the value of label_tick when an expression involving register n
     is placed in last_set_value.  */

  int				last_set_table_tick;

  /* Record the value of label_tick when the value for register n is placed in
     last_set_value.  */

  int				last_set_label;

  /* These fields are maintained in parallel with last_set_value and are
     used to store the mode in which the register was last set, the bits
     that were known to be zero when it was last set, and the number of
     sign bits copies it was known to have when it was last set.  */

  unsigned HOST_WIDE_INT	last_set_nonzero_bits;
  char				last_set_sign_bit_copies;
  ENUM_BITFIELD(machine_mode)	last_set_mode : 8;

  /* Set nonzero if references to register n in expressions should not be
     used.  last_set_invalid is set nonzero when this register is being
     assigned to and last_set_table_tick == label_tick.  */

  char				last_set_invalid;

  /* Some registers that are set more than once and used in more than one
     basic block are nevertheless always set in similar ways.  For example,
     a QImode register may be loaded from memory in two places on a machine
     where byte loads zero extend.

     We record in the following fields if a register has some leading bits
     that are always equal to the sign bit, and what we know about the
     nonzero bits of a register, specifically which bits are known to be
     zero.

     If an entry is zero, it means that we don't know anything special.  */

  unsigned char			sign_bit_copies;

  unsigned HOST_WIDE_INT	nonzero_bits;

  /* Record the value of the label_tick when the last truncation
     happened.  The field truncated_to_mode is only valid if
     truncation_label == label_tick.  */

  int				truncation_label;

  /* Record the last truncation seen for this register.  If truncation
     is not a nop to this mode we might be able to save an explicit
     truncation if we know that value already contains a truncated
     value.  */

  ENUM_BITFIELD(machine_mode)	truncated_to_mode : 8;
};


static vec<reg_stat_type> reg_stat;

/* One plus the highest pseudo for which we track REG_N_SETS.
   regstat_init_n_sets_and_refs allocates the array for REG_N_SETS just once,
   but during combine_split_insns new pseudos can be created.  As we don't have
   updated DF information in that case, it is hard to initialize the array
   after growing.  The combiner only cares about REG_N_SETS (regno) == 1,
   so instead of growing the arrays, just assume all newly created pseudos
   during combine might be set multiple times.  */

static unsigned int reg_n_sets_max;

/* Record the luid of the last insn that invalidated memory
   (anything that writes memory, and subroutine calls, but not pushes).  */

static int mem_last_set;

/* Record the luid of the last CALL_INSN
   so we can tell whether a potential combination crosses any calls.  */

static int last_call_luid;

/* When `subst' is called, this is the insn that is being modified
   (by combining in a previous insn).  The PATTERN of this insn
   is still the old pattern partially modified and it should not be
   looked at, but this may be used to examine the successors of the insn
   to judge whether a simplification is valid.  */

static rtx_insn *subst_insn;

/* This is the lowest LUID that `subst' is currently dealing with.
   get_last_value will not return a value if the register was set at or
   after this LUID.  If not for this mechanism, we could get confused if
   I2 or I1 in try_combine were an insn that used the old value of a register
   to obtain a new value.  In that case, we might erroneously get the
   new value of the register when we wanted the old one.  */

static int subst_low_luid;

/* This contains any hard registers that are used in newpat; reg_dead_at_p
   must consider all these registers to be always live.  */

static HARD_REG_SET newpat_used_regs;

/* This is an insn to which a LOG_LINKS entry has been added.  If this
   insn is the earlier than I2 or I3, combine should rescan starting at
   that location.  */

static rtx_insn *added_links_insn;

/* And similarly, for notes.  */

static rtx_insn *added_notes_insn;

/* Basic block in which we are performing combines.  */
static basic_block this_basic_block;
static bool optimize_this_for_speed_p;


/* Length of the currently allocated uid_insn_cost array.  */

static int max_uid_known;

/* The following array records the insn_cost for every insn
   in the instruction stream.  */

static int *uid_insn_cost;

/* The following array records the LOG_LINKS for every insn in the
   instruction stream as struct insn_link pointers.  */

struct insn_link {
  rtx_insn *insn;
  unsigned int regno;
  struct insn_link *next;
};

static struct insn_link **uid_log_links;

static inline int
insn_uid_check (const_rtx insn)
{
  int uid = INSN_UID (insn);
  gcc_checking_assert (uid <= max_uid_known);
  return uid;
}

#define INSN_COST(INSN)		(uid_insn_cost[insn_uid_check (INSN)])
#define LOG_LINKS(INSN)		(uid_log_links[insn_uid_check (INSN)])

#define FOR_EACH_LOG_LINK(L, INSN)				\
  for ((L) = LOG_LINKS (INSN); (L); (L) = (L)->next)

/* Links for LOG_LINKS are allocated from this obstack.  */

static struct obstack insn_link_obstack;

/* Allocate a link.  */

static inline struct insn_link *
alloc_insn_link (rtx_insn *insn, unsigned int regno, struct insn_link *next)
{
  struct insn_link *l
    = (struct insn_link *) obstack_alloc (&insn_link_obstack,
					  sizeof (struct insn_link));
  l->insn = insn;
  l->regno = regno;
  l->next = next;
  return l;
}

/* Incremented for each basic block.  */

static int label_tick;

/* Reset to label_tick for each extended basic block in scanning order.  */

static int label_tick_ebb_start;

/* Mode used to compute significance in reg_stat[].nonzero_bits.  It is the
   largest integer mode that can fit in HOST_BITS_PER_WIDE_INT.  */

static scalar_int_mode nonzero_bits_mode;

/* Nonzero when reg_stat[].nonzero_bits and reg_stat[].sign_bit_copies can
   be safely used.  It is zero while computing them and after combine has
   completed.  This former test prevents propagating values based on
   previously set values, which can be incorrect if a variable is modified
   in a loop.  */

static int nonzero_sign_valid;


/* Record one modification to rtl structure
   to be undone by storing old_contents into *where.  */

enum undo_kind { UNDO_RTX, UNDO_INT, UNDO_MODE, UNDO_LINKS };

struct undo
{
  struct undo *next;
  enum undo_kind kind;
  union { rtx r; int i; machine_mode m; struct insn_link *l; } old_contents;
  union { rtx *r; int *i; int regno; struct insn_link **l; } where;
};

/* Record a bunch of changes to be undone, up to MAX_UNDO of them.
   num_undo says how many are currently recorded.

   other_insn is nonzero if we have modified some other insn in the process
   of working on subst_insn.  It must be verified too.  */

struct undobuf
{
  struct undo *undos;
  struct undo *frees;
  rtx_insn *other_insn;
};

static struct undobuf undobuf;

/* Number of times the pseudo being substituted for
   was found and replaced.  */

static int n_occurrences;

static rtx reg_nonzero_bits_for_combine (const_rtx, scalar_int_mode,
					 scalar_int_mode,
					 unsigned HOST_WIDE_INT *);
static rtx reg_num_sign_bit_copies_for_combine (const_rtx, scalar_int_mode,
						scalar_int_mode,
						unsigned int *);
static void do_SUBST (rtx *, rtx);
static void do_SUBST_INT (int *, int);
static void init_reg_last (void);
static void setup_incoming_promotions (rtx_insn *);
static void set_nonzero_bits_and_sign_copies (rtx, const_rtx, void *);
static int cant_combine_insn_p (rtx_insn *);
static int can_combine_p (rtx_insn *, rtx_insn *, rtx_insn *, rtx_insn *,
			  rtx_insn *, rtx_insn *, rtx *, rtx *);
static int combinable_i3pat (rtx_insn *, rtx *, rtx, rtx, rtx, int, int, rtx *);
static int contains_muldiv (rtx);
static rtx_insn *try_combine (rtx_insn *, rtx_insn *, rtx_insn *, rtx_insn *,
			      int *, rtx_insn *);
static void undo_all (void);
static void undo_commit (void);
static rtx *find_split_point (rtx *, rtx_insn *, bool);
static rtx subst (rtx, rtx, rtx, int, int, int);
static rtx combine_simplify_rtx (rtx, machine_mode, int, int);
static rtx simplify_if_then_else (rtx);
static rtx simplify_set (rtx);
static rtx simplify_logical (rtx);
static rtx expand_compound_operation (rtx);
static const_rtx expand_field_assignment (const_rtx);
static rtx make_extraction (machine_mode, rtx, HOST_WIDE_INT,
			    rtx, unsigned HOST_WIDE_INT, int, int, int);
static int get_pos_from_mask (unsigned HOST_WIDE_INT,
			      unsigned HOST_WIDE_INT *);
static rtx canon_reg_for_combine (rtx, rtx);
static rtx force_int_to_mode (rtx, scalar_int_mode, scalar_int_mode,
			      scalar_int_mode, unsigned HOST_WIDE_INT, int);
static rtx force_to_mode (rtx, machine_mode,
			  unsigned HOST_WIDE_INT, int);
static rtx if_then_else_cond (rtx, rtx *, rtx *);
static rtx known_cond (rtx, enum rtx_code, rtx, rtx);
static int rtx_equal_for_field_assignment_p (rtx, rtx, bool = false);
static rtx make_field_assignment (rtx);
static rtx apply_distributive_law (rtx);
static rtx distribute_and_simplify_rtx (rtx, int);
static rtx simplify_and_const_int_1 (scalar_int_mode, rtx,
				     unsigned HOST_WIDE_INT);
static rtx simplify_and_const_int (rtx, scalar_int_mode, rtx,
				   unsigned HOST_WIDE_INT);
static int merge_outer_ops (enum rtx_code *, HOST_WIDE_INT *, enum rtx_code,
			    HOST_WIDE_INT, machine_mode, int *);
static rtx simplify_shift_const_1 (enum rtx_code, machine_mode, rtx, int);
static rtx simplify_shift_const (rtx, enum rtx_code, machine_mode, rtx,
				 int);
static int recog_for_combine (rtx *, rtx_insn *, rtx *);
static rtx gen_lowpart_for_combine (machine_mode, rtx);
static enum rtx_code simplify_compare_const (enum rtx_code, machine_mode,
					     rtx, rtx *);
static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *);
static void update_table_tick (rtx);
static void record_value_for_reg (rtx, rtx_insn *, rtx);
static void check_promoted_subreg (rtx_insn *, rtx);
static void record_dead_and_set_regs_1 (rtx, const_rtx, void *);
static void record_dead_and_set_regs (rtx_insn *);
static int get_last_value_validate (rtx *, rtx_insn *, int, int);
static rtx get_last_value (const_rtx);
static void reg_dead_at_p_1 (rtx, const_rtx, void *);
static int reg_dead_at_p (rtx, rtx_insn *);
static void move_deaths (rtx, rtx, int, rtx_insn *, rtx *);
static int reg_bitfield_target_p (rtx, rtx);
static void distribute_notes (rtx, rtx_insn *, rtx_insn *, rtx_insn *, rtx, rtx, rtx);
static void distribute_links (struct insn_link *);
static void mark_used_regs_combine (rtx);
static void record_promoted_value (rtx_insn *, rtx);
static bool unmentioned_reg_p (rtx, rtx);
static void record_truncated_values (rtx *, void *);
static bool reg_truncated_to_mode (machine_mode, const_rtx);
static rtx gen_lowpart_or_truncate (machine_mode, rtx);


/* It is not safe to use ordinary gen_lowpart in combine.
   See comments in gen_lowpart_for_combine.  */
#undef RTL_HOOKS_GEN_LOWPART
#define RTL_HOOKS_GEN_LOWPART              gen_lowpart_for_combine

/* Our implementation of gen_lowpart never emits a new pseudo.  */
#undef RTL_HOOKS_GEN_LOWPART_NO_EMIT
#define RTL_HOOKS_GEN_LOWPART_NO_EMIT      gen_lowpart_for_combine

#undef RTL_HOOKS_REG_NONZERO_REG_BITS
#define RTL_HOOKS_REG_NONZERO_REG_BITS     reg_nonzero_bits_for_combine

#undef RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES
#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIES  reg_num_sign_bit_copies_for_combine

#undef RTL_HOOKS_REG_TRUNCATED_TO_MODE
#define RTL_HOOKS_REG_TRUNCATED_TO_MODE    reg_truncated_to_mode

static const struct rtl_hooks combine_rtl_hooks = RTL_HOOKS_INITIALIZER;


/* Convenience wrapper for the canonicalize_comparison target hook.
   Target hooks cannot use enum rtx_code.  */
static inline void
target_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1,
				bool op0_preserve_value)
{
  int code_int = (int)*code;
  targetm.canonicalize_comparison (&code_int, op0, op1, op0_preserve_value);
  *code = (enum rtx_code)code_int;
}

/* Try to split PATTERN found in INSN.  This returns NULL_RTX if
   PATTERN cannot be split.  Otherwise, it returns an insn sequence.
   This is a wrapper around split_insns which ensures that the
   reg_stat vector is made larger if the splitter creates a new
   register.  */

static rtx_insn *
combine_split_insns (rtx pattern, rtx_insn *insn)
{
  rtx_insn *ret;
  unsigned int nregs;

  ret = split_insns (pattern, insn);
  nregs = max_reg_num ();
  if (nregs > reg_stat.length ())
    reg_stat.safe_grow_cleared (nregs);
  return ret;
}

/* This is used by find_single_use to locate an rtx in LOC that
   contains exactly one use of DEST, which is typically either a REG
   or CC0.  It returns a pointer to the innermost rtx expression
   containing DEST.  Appearances of DEST that are being used to
   totally replace it are not counted.  */

static rtx *
find_single_use_1 (rtx dest, rtx *loc)
{
  rtx x = *loc;
  enum rtx_code code = GET_CODE (x);
  rtx *result = NULL;
  rtx *this_result;
  int i;
  const char *fmt;

  switch (code)
    {
    case CONST:
    case LABEL_REF:
    case SYMBOL_REF:
    CASE_CONST_ANY:
    case CLOBBER:
    case CLOBBER_HIGH:
      return 0;

    case SET:
      /* If the destination is anything other than CC0, PC, a REG or a SUBREG
	 of a REG that occupies all of the REG, the insn uses DEST if
	 it is mentioned in the destination or the source.  Otherwise, we
	 need just check the source.  */
      if (GET_CODE (SET_DEST (x)) != CC0
	  && GET_CODE (SET_DEST (x)) != PC
	  && !REG_P (SET_DEST (x))
	  && ! (GET_CODE (SET_DEST (x)) == SUBREG
		&& REG_P (SUBREG_REG (SET_DEST (x)))
		&& !read_modify_subreg_p (SET_DEST (x))))
	break;

      return find_single_use_1 (dest, &SET_SRC (x));

    case MEM:
    case SUBREG:
      return find_single_use_1 (dest, &XEXP (x, 0));

    default:
      break;
    }

  /* If it wasn't one of the common cases above, check each expression and
     vector of this code.  Look for a unique usage of DEST.  */

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	{
	  if (dest == XEXP (x, i)
	      || (REG_P (dest) && REG_P (XEXP (x, i))
		  && REGNO (dest) == REGNO (XEXP (x, i))))
	    this_result = loc;
	  else
	    this_result = find_single_use_1 (dest, &XEXP (x, i));

	  if (result == NULL)
	    result = this_result;
	  else if (this_result)
	    /* Duplicate usage.  */
	    return NULL;
	}
      else if (fmt[i] == 'E')
	{
	  int j;

	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    {
	      if (XVECEXP (x, i, j) == dest
		  || (REG_P (dest)
		      && REG_P (XVECEXP (x, i, j))
		      && REGNO (XVECEXP (x, i, j)) == REGNO (dest)))
		this_result = loc;
	      else
		this_result = find_single_use_1 (dest, &XVECEXP (x, i, j));

	      if (result == NULL)
		result = this_result;
	      else if (this_result)
		return NULL;
	    }
	}
    }

  return result;
}


/* See if DEST, produced in INSN, is used only a single time in the
   sequel.  If so, return a pointer to the innermost rtx expression in which
   it is used.

   If PLOC is nonzero, *PLOC is set to the insn containing the single use.

   If DEST is cc0_rtx, we look only at the next insn.  In that case, we don't
   care about REG_DEAD notes or LOG_LINKS.

   Otherwise, we find the single use by finding an insn that has a
   LOG_LINKS pointing at INSN and has a REG_DEAD note for DEST.  If DEST is
   only referenced once in that insn, we know that it must be the first
   and last insn referencing DEST.  */

static rtx *
find_single_use (rtx dest, rtx_insn *insn, rtx_insn **ploc)
{
  basic_block bb;
  rtx_insn *next;
  rtx *result;
  struct insn_link *link;

  if (dest == cc0_rtx)
    {
      next = NEXT_INSN (insn);
      if (next == 0
	  || (!NONJUMP_INSN_P (next) && !JUMP_P (next)))
	return 0;

      result = find_single_use_1 (dest, &PATTERN (next));
      if (result && ploc)
	*ploc = next;
      return result;
    }

  if (!REG_P (dest))
    return 0;

  bb = BLOCK_FOR_INSN (insn);
  for (next = NEXT_INSN (insn);
       next && BLOCK_FOR_INSN (next) == bb;
       next = NEXT_INSN (next))
    if (NONDEBUG_INSN_P (next) && dead_or_set_p (next, dest))
      {
	FOR_EACH_LOG_LINK (link, next)
	  if (link->insn == insn && link->regno == REGNO (dest))
	    break;

	if (link)
	  {
	    result = find_single_use_1 (dest, &PATTERN (next));
	    if (ploc)
	      *ploc = next;
	    return result;
	  }
      }

  return 0;
}

/* Substitute NEWVAL, an rtx expression, into INTO, a place in some
   insn.  The substitution can be undone by undo_all.  If INTO is already
   set to NEWVAL, do not record this change.  Because computing NEWVAL might
   also call SUBST, we have to compute it before we put anything into
   the undo table.  */

static void
do_SUBST (rtx *into, rtx newval)
{
  struct undo *buf;
  rtx oldval = *into;

  if (oldval == newval)
    return;

  /* We'd like to catch as many invalid transformations here as
     possible.  Unfortunately, there are way too many mode changes
     that are perfectly valid, so we'd waste too much effort for
     little gain doing the checks here.  Focus on catching invalid
     transformations involving integer constants.  */
  if (GET_MODE_CLASS (GET_MODE (oldval)) == MODE_INT
      && CONST_INT_P (newval))
    {
      /* Sanity check that we're replacing oldval with a CONST_INT
	 that is a valid sign-extension for the original mode.  */
      gcc_assert (INTVAL (newval)
		  == trunc_int_for_mode (INTVAL (newval), GET_MODE (oldval)));

      /* Replacing the operand of a SUBREG or a ZERO_EXTEND with a
	 CONST_INT is not valid, because after the replacement, the
	 original mode would be gone.  Unfortunately, we can't tell
	 when do_SUBST is called to replace the operand thereof, so we
	 perform this test on oldval instead, checking whether an
	 invalid replacement took place before we got here.  */
      gcc_assert (!(GET_CODE (oldval) == SUBREG
		    && CONST_INT_P (SUBREG_REG (oldval))));
      gcc_assert (!(GET_CODE (oldval) == ZERO_EXTEND
		    && CONST_INT_P (XEXP (oldval, 0))));
    }

  if (undobuf.frees)
    buf = undobuf.frees, undobuf.frees = buf->next;
  else
    buf = XNEW (struct undo);

  buf->kind = UNDO_RTX;
  buf->where.r = into;
  buf->old_contents.r = oldval;
  *into = newval;

  buf->next = undobuf.undos, undobuf.undos = buf;
}

#define SUBST(INTO, NEWVAL)	do_SUBST (&(INTO), (NEWVAL))

/* Similar to SUBST, but NEWVAL is an int expression.  Note that substitution
   for the value of a HOST_WIDE_INT value (including CONST_INT) is
   not safe.  */

static void
do_SUBST_INT (int *into, int newval)
{
  struct undo *buf;
  int oldval = *into;

  if (oldval == newval)
    return;

  if (undobuf.frees)
    buf = undobuf.frees, undobuf.frees = buf->next;
  else
    buf = XNEW (struct undo);

  buf->kind = UNDO_INT;
  buf->where.i = into;
  buf->old_contents.i = oldval;
  *into = newval;

  buf->next = undobuf.undos, undobuf.undos = buf;
}

#define SUBST_INT(INTO, NEWVAL)  do_SUBST_INT (&(INTO), (NEWVAL))

/* Similar to SUBST, but just substitute the mode.  This is used when
   changing the mode of a pseudo-register, so that any other
   references to the entry in the regno_reg_rtx array will change as
   well.  */

static void
subst_mode (int regno, machine_mode newval)
{
  struct undo *buf;
  rtx reg = regno_reg_rtx[regno];
  machine_mode oldval = GET_MODE (reg);

  if (oldval == newval)
    return;

  if (undobuf.frees)
    buf = undobuf.frees, undobuf.frees = buf->next;
  else
    buf = XNEW (struct undo);

  buf->kind = UNDO_MODE;
  buf->where.regno = regno;
  buf->old_contents.m = oldval;
  adjust_reg_mode (reg, newval);

  buf->next = undobuf.undos, undobuf.undos = buf;
}

/* Similar to SUBST, but NEWVAL is a LOG_LINKS expression.  */

static void
do_SUBST_LINK (struct insn_link **into, struct insn_link *newval)
{
  struct undo *buf;
  struct insn_link * oldval = *into;

  if (oldval == newval)
    return;

  if (undobuf.frees)
    buf = undobuf.frees, undobuf.frees = buf->next;
  else
    buf = XNEW (struct undo);

  buf->kind = UNDO_LINKS;
  buf->where.l = into;
  buf->old_contents.l = oldval;
  *into = newval;

  buf->next = undobuf.undos, undobuf.undos = buf;
}

#define SUBST_LINK(oldval, newval) do_SUBST_LINK (&oldval, newval)

/* Subroutine of try_combine.  Determine whether the replacement patterns
   NEWPAT, NEWI2PAT and NEWOTHERPAT are cheaper according to insn_cost
   than the original sequence I0, I1, I2, I3 and undobuf.other_insn.  Note
   that I0, I1 and/or NEWI2PAT may be NULL_RTX.  Similarly, NEWOTHERPAT and
   undobuf.other_insn may also both be NULL_RTX.  Return false if the cost
   of all the instructions can be estimated and the replacements are more
   expensive than the original sequence.  */

static bool
combine_validate_cost (rtx_insn *i0, rtx_insn *i1, rtx_insn *i2, rtx_insn *i3,
		       rtx newpat, rtx newi2pat, rtx newotherpat)
{
  int i0_cost, i1_cost, i2_cost, i3_cost;
  int new_i2_cost, new_i3_cost;
  int old_cost, new_cost;

  /* Lookup the original insn_costs.  */
  i2_cost = INSN_COST (i2);
  i3_cost = INSN_COST (i3);

  if (i1)
    {
      i1_cost = INSN_COST (i1);
      if (i0)
	{
	  i0_cost = INSN_COST (i0);
	  old_cost = (i0_cost > 0 && i1_cost > 0 && i2_cost > 0 && i3_cost > 0
		      ? i0_cost + i1_cost + i2_cost + i3_cost : 0);
	}
      else
	{
	  old_cost = (i1_cost > 0 && i2_cost > 0 && i3_cost > 0
		      ? i1_cost + i2_cost + i3_cost : 0);
	  i0_cost = 0;
	}
    }
  else
    {
      old_cost = (i2_cost > 0 && i3_cost > 0) ? i2_cost + i3_cost : 0;
      i1_cost = i0_cost = 0;
    }

  /* If we have split a PARALLEL I2 to I1,I2, we have counted its cost twice;
     correct that.  */
  if (old_cost && i1 && INSN_UID (i1) == INSN_UID (i2))
    old_cost -= i1_cost;


  /* Calculate the replacement insn_costs.  */
  rtx tmp = PATTERN (i3);
  PATTERN (i3) = newpat;
  int tmpi = INSN_CODE (i3);
  INSN_CODE (i3) = -1;
  new_i3_cost = insn_cost (i3, optimize_this_for_speed_p);
  PATTERN (i3) = tmp;
  INSN_CODE (i3) = tmpi;
  if (newi2pat)
    {
      tmp = PATTERN (i2);
      PATTERN (i2) = newi2pat;
      tmpi = INSN_CODE (i2);
      INSN_CODE (i2) = -1;
      new_i2_cost = insn_cost (i2, optimize_this_for_speed_p);
      PATTERN (i2) = tmp;
      INSN_CODE (i2) = tmpi;
      new_cost = (new_i2_cost > 0 && new_i3_cost > 0)
		 ? new_i2_cost + new_i3_cost : 0;
    }
  else
    {
      new_cost = new_i3_cost;
      new_i2_cost = 0;
    }

  if (undobuf.other_insn)
    {
      int old_other_cost, new_other_cost;

      old_other_cost = INSN_COST (undobuf.other_insn);
      tmp = PATTERN (undobuf.other_insn);
      PATTERN (undobuf.other_insn) = newotherpat;
      tmpi = INSN_CODE (undobuf.other_insn);
      INSN_CODE (undobuf.other_insn) = -1;
      new_other_cost = insn_cost (undobuf.other_insn,
				  optimize_this_for_speed_p);
      PATTERN (undobuf.other_insn) = tmp;
      INSN_CODE (undobuf.other_insn) = tmpi;
      if (old_other_cost > 0 && new_other_cost > 0)
	{
	  old_cost += old_other_cost;
	  new_cost += new_other_cost;
	}
      else
	old_cost = 0;
    }

  /* Disallow this combination if both new_cost and old_cost are greater than
     zero, and new_cost is greater than old cost.  */
  int reject = old_cost > 0 && new_cost > old_cost;

  if (dump_file)
    {
      fprintf (dump_file, "%s combination of insns ",
	       reject ? "rejecting" : "allowing");
      if (i0)
	fprintf (dump_file, "%d, ", INSN_UID (i0));
      if (i1 && INSN_UID (i1) != INSN_UID (i2))
	fprintf (dump_file, "%d, ", INSN_UID (i1));
      fprintf (dump_file, "%d and %d\n", INSN_UID (i2), INSN_UID (i3));

      fprintf (dump_file, "original costs ");
      if (i0)
	fprintf (dump_file, "%d + ", i0_cost);
      if (i1 && INSN_UID (i1) != INSN_UID (i2))
	fprintf (dump_file, "%d + ", i1_cost);
      fprintf (dump_file, "%d + %d = %d\n", i2_cost, i3_cost, old_cost);

      if (newi2pat)
	fprintf (dump_file, "replacement costs %d + %d = %d\n",
		 new_i2_cost, new_i3_cost, new_cost);
      else
	fprintf (dump_file, "replacement cost %d\n", new_cost);
    }

  if (reject)
    return false;

  /* Update the uid_insn_cost array with the replacement costs.  */
  INSN_COST (i2) = new_i2_cost;
  INSN_COST (i3) = new_i3_cost;
  if (i1)
    {
      INSN_COST (i1) = 0;
      if (i0)
	INSN_COST (i0) = 0;
    }

  return true;
}


/* Delete any insns that copy a register to itself.
   Return true if the CFG was changed.  */

static bool
delete_noop_moves (void)
{
  rtx_insn *insn, *next;
  basic_block bb;

  bool edges_deleted = false;

  FOR_EACH_BB_FN (bb, cfun)
    {
      for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); insn = next)
	{
	  next = NEXT_INSN (insn);
	  if (INSN_P (insn) && noop_move_p (insn))
	    {
	      if (dump_file)
		fprintf (dump_file, "deleting noop move %d\n", INSN_UID (insn));

	      edges_deleted |= delete_insn_and_edges (insn);
	    }
	}
    }

  return edges_deleted;
}


/* Return false if we do not want to (or cannot) combine DEF.  */
static bool
can_combine_def_p (df_ref def)
{
  /* Do not consider if it is pre/post modification in MEM.  */
  if (DF_REF_FLAGS (def) & DF_REF_PRE_POST_MODIFY)
    return false;

  unsigned int regno = DF_REF_REGNO (def);

  /* Do not combine frame pointer adjustments.  */
  if ((regno == FRAME_POINTER_REGNUM
       && (!reload_completed || frame_pointer_needed))
      || (!HARD_FRAME_POINTER_IS_FRAME_POINTER
	  && regno == HARD_FRAME_POINTER_REGNUM
	  && (!reload_completed || frame_pointer_needed))
      || (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	  && regno == ARG_POINTER_REGNUM && fixed_regs[regno]))
    return false;

  return true;
}

/* Return false if we do not want to (or cannot) combine USE.  */
static bool
can_combine_use_p (df_ref use)
{
  /* Do not consider the usage of the stack pointer by function call.  */
  if (DF_REF_FLAGS (use) & DF_REF_CALL_STACK_USAGE)
    return false;

  return true;
}

/* Fill in log links field for all insns.  */

static void
create_log_links (void)
{
  basic_block bb;
  rtx_insn **next_use;
  rtx_insn *insn;
  df_ref def, use;

  next_use = XCNEWVEC (rtx_insn *, max_reg_num ());

  /* Pass through each block from the end, recording the uses of each
     register and establishing log links when def is encountered.
     Note that we do not clear next_use array in order to save time,
     so we have to test whether the use is in the same basic block as def.

     There are a few cases below when we do not consider the definition or
     usage -- these are taken from original flow.c did. Don't ask me why it is
     done this way; I don't know and if it works, I don't want to know.  */

  FOR_EACH_BB_FN (bb, cfun)
    {
      FOR_BB_INSNS_REVERSE (bb, insn)
        {
          if (!NONDEBUG_INSN_P (insn))
            continue;

	  /* Log links are created only once.  */
	  gcc_assert (!LOG_LINKS (insn));

	  FOR_EACH_INSN_DEF (def, insn)
            {
              unsigned int regno = DF_REF_REGNO (def);
              rtx_insn *use_insn;

              if (!next_use[regno])
                continue;

	      if (!can_combine_def_p (def))
		continue;

	      use_insn = next_use[regno];
	      next_use[regno] = NULL;

	      if (BLOCK_FOR_INSN (use_insn) != bb)
		continue;

	      /* flow.c claimed:

		 We don't build a LOG_LINK for hard registers contained
		 in ASM_OPERANDs.  If these registers get replaced,
		 we might wind up changing the semantics of the insn,
		 even if reload can make what appear to be valid
		 assignments later.  */
	      if (regno < FIRST_PSEUDO_REGISTER
		  && asm_noperands (PATTERN (use_insn)) >= 0)
		continue;

	      /* Don't add duplicate links between instructions.  */
	      struct insn_link *links;
	      FOR_EACH_LOG_LINK (links, use_insn)
	        if (insn == links->insn && regno == links->regno)
		  break;

	      if (!links)
		LOG_LINKS (use_insn)
		  = alloc_insn_link (insn, regno, LOG_LINKS (use_insn));
            }

	  FOR_EACH_INSN_USE (use, insn)
	    if (can_combine_use_p (use))
	      next_use[DF_REF_REGNO (use)] = insn;
        }
    }

  free (next_use);
}

/* Walk the LOG_LINKS of insn B to see if we find a reference to A.  Return
   true if we found a LOG_LINK that proves that A feeds B.  This only works
   if there are no instructions between A and B which could have a link
   depending on A, since in that case we would not record a link for B.
   We also check the implicit dependency created by a cc0 setter/user
   pair.  */

static bool
insn_a_feeds_b (rtx_insn *a, rtx_insn *b)
{
  struct insn_link *links;
  FOR_EACH_LOG_LINK (links, b)
    if (links->insn == a)
      return true;
  if (HAVE_cc0 && sets_cc0_p (a))
    return true;
  return false;
}

/* Main entry point for combiner.  F is the first insn of the function.
   NREGS is the first unused pseudo-reg number.

   Return nonzero if the CFG was changed (e.g. if the combiner has
   turned an indirect jump instruction into a direct jump).  */
static int
combine_instructions (rtx_insn *f, unsigned int nregs)
{
  rtx_insn *insn, *next;
  rtx_insn *prev;
  struct insn_link *links, *nextlinks;
  rtx_insn *first;
  basic_block last_bb;

  int new_direct_jump_p = 0;

  for (first = f; first && !NONDEBUG_INSN_P (first); )
    first = NEXT_INSN (first);
  if (!first)
    return 0;

  combine_attempts = 0;
  combine_merges = 0;
  combine_extras = 0;
  combine_successes = 0;

  rtl_hooks = combine_rtl_hooks;

  reg_stat.safe_grow_cleared (nregs);

  init_recog_no_volatile ();

  /* Allocate array for insn info.  */
  max_uid_known = get_max_uid ();
  uid_log_links = XCNEWVEC (struct insn_link *, max_uid_known + 1);
  uid_insn_cost = XCNEWVEC (int, max_uid_known + 1);
  gcc_obstack_init (&insn_link_obstack);

  nonzero_bits_mode = int_mode_for_size (HOST_BITS_PER_WIDE_INT, 0).require ();

  /* Don't use reg_stat[].nonzero_bits when computing it.  This can cause
     problems when, for example, we have j <<= 1 in a loop.  */

  nonzero_sign_valid = 0;
  label_tick = label_tick_ebb_start = 1;

  /* Scan all SETs and see if we can deduce anything about what
     bits are known to be zero for some registers and how many copies
     of the sign bit are known to exist for those registers.

     Also set any known values so that we can use it while searching
     for what bits are known to be set.  */

  setup_incoming_promotions (first);
  /* Allow the entry block and the first block to fall into the same EBB.
     Conceptually the incoming promotions are assigned to the entry block.  */
  last_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);

  create_log_links ();
  FOR_EACH_BB_FN (this_basic_block, cfun)
    {
      optimize_this_for_speed_p = optimize_bb_for_speed_p (this_basic_block);
      last_call_luid = 0;
      mem_last_set = -1;

      label_tick++;
      if (!single_pred_p (this_basic_block)
	  || single_pred (this_basic_block) != last_bb)
	label_tick_ebb_start = label_tick;
      last_bb = this_basic_block;

      FOR_BB_INSNS (this_basic_block, insn)
        if (INSN_P (insn) && BLOCK_FOR_INSN (insn))
	  {
            rtx links;

            subst_low_luid = DF_INSN_LUID (insn);
            subst_insn = insn;

	    note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies,
		         insn);
	    record_dead_and_set_regs (insn);

	    if (AUTO_INC_DEC)
	      for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
		if (REG_NOTE_KIND (links) == REG_INC)
		  set_nonzero_bits_and_sign_copies (XEXP (links, 0), NULL_RTX,
						    insn);

	    /* Record the current insn_cost of this instruction.  */
	    if (NONJUMP_INSN_P (insn))
	      INSN_COST (insn) = insn_cost (insn, optimize_this_for_speed_p);
	    if (dump_file)
	      {
		fprintf (dump_file, "insn_cost %d for ", INSN_COST (insn));
		dump_insn_slim (dump_file, insn);
	      }
	  }
    }

  nonzero_sign_valid = 1;

  /* Now scan all the insns in forward order.  */
  label_tick = label_tick_ebb_start = 1;
  init_reg_last ();
  setup_incoming_promotions (first);
  last_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
  int max_combine = PARAM_VALUE (PARAM_MAX_COMBINE_INSNS);

  FOR_EACH_BB_FN (this_basic_block, cfun)
    {
      rtx_insn *last_combined_insn = NULL;

      /* Ignore instruction combination in basic blocks that are going to
	 be removed as unreachable anyway.  See PR82386.  */
      if (EDGE_COUNT (this_basic_block->preds) == 0)
	continue;

      optimize_this_for_speed_p = optimize_bb_for_speed_p (this_basic_block);
      last_call_luid = 0;
      mem_last_set = -1;

      label_tick++;
      if (!single_pred_p (this_basic_block)
	  || single_pred (this_basic_block) != last_bb)
	label_tick_ebb_start = label_tick;
      last_bb = this_basic_block;

      rtl_profile_for_bb (this_basic_block);
      for (insn = BB_HEAD (this_basic_block);
	   insn != NEXT_INSN (BB_END (this_basic_block));
	   insn = next ? next : NEXT_INSN (insn))
	{
	  next = 0;
	  if (!NONDEBUG_INSN_P (insn))
	    continue;

	  while (last_combined_insn
		 && (!NONDEBUG_INSN_P (last_combined_insn)
		     || last_combined_insn->deleted ()))
	    last_combined_insn = PREV_INSN (last_combined_insn);
	  if (last_combined_insn == NULL_RTX
	      || BLOCK_FOR_INSN (last_combined_insn) != this_basic_block
	      || DF_INSN_LUID (last_combined_insn) <= DF_INSN_LUID (insn))
	    last_combined_insn = insn;

	  /* See if we know about function return values before this
	     insn based upon SUBREG flags.  */
	  check_promoted_subreg (insn, PATTERN (insn));

	  /* See if we can find hardregs and subreg of pseudos in
	     narrower modes.  This could help turning TRUNCATEs
	     into SUBREGs.  */
	  note_uses (&PATTERN (insn), record_truncated_values, NULL);

	  /* Try this insn with each insn it links back to.  */

	  FOR_EACH_LOG_LINK (links, insn)
	    if ((next = try_combine (insn, links->insn, NULL,
				     NULL, &new_direct_jump_p,
				     last_combined_insn)) != 0)
	      {
		statistics_counter_event (cfun, "two-insn combine", 1);
		goto retry;
	      }

	  /* Try each sequence of three linked insns ending with this one.  */

	  if (max_combine >= 3)
	    FOR_EACH_LOG_LINK (links, insn)
	      {
		rtx_insn *link = links->insn;

		/* If the linked insn has been replaced by a note, then there
		   is no point in pursuing this chain any further.  */
		if (NOTE_P (link))
		  continue;

		FOR_EACH_LOG_LINK (nextlinks, link)
		  if ((next = try_combine (insn, link, nextlinks->insn,
					   NULL, &new_direct_jump_p,
					   last_combined_insn)) != 0)
		    {
		      statistics_counter_event (cfun, "three-insn combine", 1);
		      goto retry;
		    }
	      }

	  /* Try to combine a jump insn that uses CC0
	     with a preceding insn that sets CC0, and maybe with its
	     logical predecessor as well.
	     This is how we make decrement-and-branch insns.
	     We need this special code because data flow connections
	     via CC0 do not get entered in LOG_LINKS.  */

	  if (HAVE_cc0
	      && JUMP_P (insn)
	      && (prev = prev_nonnote_insn (insn)) != 0
	      && NONJUMP_INSN_P (prev)
	      && sets_cc0_p (PATTERN (prev)))
	    {
	      if ((next = try_combine (insn, prev, NULL, NULL,
				       &new_direct_jump_p,
				       last_combined_insn)) != 0)
		goto retry;

	      FOR_EACH_LOG_LINK (nextlinks, prev)
		  if ((next = try_combine (insn, prev, nextlinks->insn,
					   NULL, &new_direct_jump_p,
					   last_combined_insn)) != 0)
		    goto retry;
	    }

	  /* Do the same for an insn that explicitly references CC0.  */
	  if (HAVE_cc0 && NONJUMP_INSN_P (insn)
	      && (prev = prev_nonnote_insn (insn)) != 0
	      && NONJUMP_INSN_P (prev)
	      && sets_cc0_p (PATTERN (prev))
	      && GET_CODE (PATTERN (insn)) == SET
	      && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn))))
	    {
	      if ((next = try_combine (insn, prev, NULL, NULL,
				       &new_direct_jump_p,
				       last_combined_insn)) != 0)
		goto retry;

	      FOR_EACH_LOG_LINK (nextlinks, prev)
		  if ((next = try_combine (insn, prev, nextlinks->insn,
					   NULL, &new_direct_jump_p,
					   last_combined_insn)) != 0)
		    goto retry;
	    }

	  /* Finally, see if any of the insns that this insn links to
	     explicitly references CC0.  If so, try this insn, that insn,
	     and its predecessor if it sets CC0.  */
	  if (HAVE_cc0)
	    {
	      FOR_EACH_LOG_LINK (links, insn)
		if (NONJUMP_INSN_P (links->insn)
		    && GET_CODE (PATTERN (links->insn)) == SET
		    && reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (links->insn)))
		    && (prev = prev_nonnote_insn (links->insn)) != 0
		    && NONJUMP_INSN_P (prev)
		    && sets_cc0_p (PATTERN (prev))
		    && (next = try_combine (insn, links->insn,
					    prev, NULL, &new_direct_jump_p,
					    last_combined_insn)) != 0)
		  goto retry;
	    }

	  /* Try combining an insn with two different insns whose results it
	     uses.  */
	  if (max_combine >= 3)
	    FOR_EACH_LOG_LINK (links, insn)
	      for (nextlinks = links->next; nextlinks;
		   nextlinks = nextlinks->next)
		if ((next = try_combine (insn, links->insn,
					 nextlinks->insn, NULL,
					 &new_direct_jump_p,
					 last_combined_insn)) != 0)

		  {
		    statistics_counter_event (cfun, "three-insn combine", 1);
		    goto retry;
		  }

	  /* Try four-instruction combinations.  */
	  if (max_combine >= 4)
	    FOR_EACH_LOG_LINK (links, insn)
	      {
		struct insn_link *next1;
		rtx_insn *link = links->insn;

		/* If the linked insn has been replaced by a note, then there
		   is no point in pursuing this chain any further.  */
		if (NOTE_P (link))
		  continue;

		FOR_EACH_LOG_LINK (next1, link)
		  {
		    rtx_insn *link1 = next1->insn;
		    if (NOTE_P (link1))
		      continue;
		    /* I0 -> I1 -> I2 -> I3.  */
		    FOR_EACH_LOG_LINK (nextlinks, link1)
		      if ((next = try_combine (insn, link, link1,
					       nextlinks->insn,
					       &new_direct_jump_p,
					       last_combined_insn)) != 0)
			{
			  statistics_counter_event (cfun, "four-insn combine", 1);
			  goto retry;
			}
		    /* I0, I1 -> I2, I2 -> I3.  */
		    for (nextlinks = next1->next; nextlinks;
			 nextlinks = nextlinks->next)
		      if ((next = try_combine (insn, link, link1,
					       nextlinks->insn,
					       &new_direct_jump_p,
					       last_combined_insn)) != 0)
			{
			  statistics_counter_event (cfun, "four-insn combine", 1);
			  goto retry;
			}
		  }

		for (next1 = links->next; next1; next1 = next1->next)
		  {
		    rtx_insn *link1 = next1->insn;
		    if (NOTE_P (link1))
		      continue;
		    /* I0 -> I2; I1, I2 -> I3.  */
		    FOR_EACH_LOG_LINK (nextlinks, link)
		      if ((next = try_combine (insn, link, link1,
					       nextlinks->insn,
					       &new_direct_jump_p,
					       last_combined_insn)) != 0)
			{
			  statistics_counter_event (cfun, "four-insn combine", 1);
			  goto retry;
			}
		    /* I0 -> I1; I1, I2 -> I3.  */
		    FOR_EACH_LOG_LINK (nextlinks, link1)
		      if ((next = try_combine (insn, link, link1,
					       nextlinks->insn,
					       &new_direct_jump_p,
					       last_combined_insn)) != 0)
			{
			  statistics_counter_event (cfun, "four-insn combine", 1);
			  goto retry;
			}
		  }
	      }

	  /* Try this insn with each REG_EQUAL note it links back to.  */
	  FOR_EACH_LOG_LINK (links, insn)
	    {
	      rtx set, note;
	      rtx_insn *temp = links->insn;
	      if ((set = single_set (temp)) != 0
		  && (note = find_reg_equal_equiv_note (temp)) != 0
		  && (note = XEXP (note, 0), GET_CODE (note)) != EXPR_LIST
		  && ! side_effects_p (SET_SRC (set))
		  /* Avoid using a register that may already been marked
		     dead by an earlier instruction.  */
		  && ! unmentioned_reg_p (note, SET_SRC (set))
		  && (GET_MODE (note) == VOIDmode
		      ? SCALAR_INT_MODE_P (GET_MODE (SET_DEST (set)))
		      : (GET_MODE (SET_DEST (set)) == GET_MODE (note)
			 && (GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
			     || (GET_MODE (XEXP (SET_DEST (set), 0))
				 == GET_MODE (note))))))
		{
		  /* Temporarily replace the set's source with the
		     contents of the REG_EQUAL note.  The insn will
		     be deleted or recognized by try_combine.  */
		  rtx orig_src = SET_SRC (set);
		  rtx orig_dest = SET_DEST (set);
		  if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT)
		    SET_DEST (set) = XEXP (SET_DEST (set), 0);
		  SET_SRC (set) = note;
		  i2mod = temp;
		  i2mod_old_rhs = copy_rtx (orig_src);
		  i2mod_new_rhs = copy_rtx (note);
		  next = try_combine (insn, i2mod, NULL, NULL,
				      &new_direct_jump_p,
				      last_combined_insn);
		  i2mod = NULL;
		  if (next)
		    {
		      statistics_counter_event (cfun, "insn-with-note combine", 1);
		      goto retry;
		    }
		  SET_SRC (set) = orig_src;
		  SET_DEST (set) = orig_dest;
		}
	    }

	  if (!NOTE_P (insn))
	    record_dead_and_set_regs (insn);

retry:
	  ;
	}
    }

  default_rtl_profile ();
  clear_bb_flags ();
  new_direct_jump_p |= purge_all_dead_edges ();
  new_direct_jump_p |= delete_noop_moves ();

  /* Clean up.  */
  obstack_free (&insn_link_obstack, NULL);
  free (uid_log_links);
  free (uid_insn_cost);
  reg_stat.release ();

  {
    struct undo *undo, *next;
    for (undo = undobuf.frees; undo; undo = next)
      {
	next = undo->next;
	free (undo);
      }
    undobuf.frees = 0;
  }

  total_attempts += combine_attempts;
  total_merges += combine_merges;
  total_extras += combine_extras;
  total_successes += combine_successes;

  nonzero_sign_valid = 0;
  rtl_hooks = general_rtl_hooks;

  /* Make recognizer allow volatile MEMs again.  */
  init_recog ();

  return new_direct_jump_p;
}

/* Wipe the last_xxx fields of reg_stat in preparation for another pass.  */

static void
init_reg_last (void)
{
  unsigned int i;
  reg_stat_type *p;

  FOR_EACH_VEC_ELT (reg_stat, i, p)
    memset (p, 0, offsetof (reg_stat_type, sign_bit_copies));
}

/* Set up any promoted values for incoming argument registers.  */

static void
setup_incoming_promotions (rtx_insn *first)
{
  tree arg;
  bool strictly_local = false;

  for (arg = DECL_ARGUMENTS (current_function_decl); arg;
       arg = DECL_CHAIN (arg))
    {
      rtx x, reg = DECL_INCOMING_RTL (arg);
      int uns1, uns3;
      machine_mode mode1, mode2, mode3, mode4;

      /* Only continue if the incoming argument is in a register.  */
      if (!REG_P (reg))
	continue;

      /* Determine, if possible, whether all call sites of the current
         function lie within the current compilation unit.  (This does
	 take into account the exporting of a function via taking its
	 address, and so forth.)  */
      strictly_local = cgraph_node::local_info (current_function_decl)->local;

      /* The mode and signedness of the argument before any promotions happen
         (equal to the mode of the pseudo holding it at that stage).  */
      mode1 = TYPE_MODE (TREE_TYPE (arg));
      uns1 = TYPE_UNSIGNED (TREE_TYPE (arg));

      /* The mode and signedness of the argument after any source language and
         TARGET_PROMOTE_PROTOTYPES-driven promotions.  */
      mode2 = TYPE_MODE (DECL_ARG_TYPE (arg));
      uns3 = TYPE_UNSIGNED (DECL_ARG_TYPE (arg));

      /* The mode and signedness of the argument as it is actually passed,
         see assign_parm_setup_reg in function.c.  */
      mode3 = promote_function_mode (TREE_TYPE (arg), mode1, &uns3,
				     TREE_TYPE (cfun->decl), 0);

      /* The mode of the register in which the argument is being passed.  */
      mode4 = GET_MODE (reg);

      /* Eliminate sign extensions in the callee when:
	 (a) A mode promotion has occurred;  */
      if (mode1 == mode3)
	continue;
      /* (b) The mode of the register is the same as the mode of
	     the argument as it is passed; */
      if (mode3 != mode4)
	continue;
      /* (c) There's no language level extension;  */
      if (mode1 == mode2)
	;
      /* (c.1) All callers are from the current compilation unit.  If that's
	 the case we don't have to rely on an ABI, we only have to know
	 what we're generating right now, and we know that we will do the
	 mode1 to mode2 promotion with the given sign.  */
      else if (!strictly_local)
	continue;
      /* (c.2) The combination of the two promotions is useful.  This is
	 true when the signs match, or if the first promotion is unsigned.
	 In the later case, (sign_extend (zero_extend x)) is the same as
	 (zero_extend (zero_extend x)), so make sure to force UNS3 true.  */
      else if (uns1)
	uns3 = true;
      else if (uns3)
	continue;

      /* Record that the value was promoted from mode1 to mode3,
	 so that any sign extension at the head of the current
	 function may be eliminated.  */
      x = gen_rtx_CLOBBER (mode1, const0_rtx);
      x = gen_rtx_fmt_e ((uns3 ? ZERO_EXTEND : SIGN_EXTEND), mode3, x);
      record_value_for_reg (reg, first, x);
    }
}

/* If MODE has a precision lower than PREC and SRC is a non-negative constant
   that would appear negative in MODE, sign-extend SRC for use in nonzero_bits
   because some machines (maybe most) will actually do the sign-extension and
   this is the conservative approach.

   ??? For 2.5, try to tighten up the MD files in this regard instead of this
   kludge.  */

static rtx
sign_extend_short_imm (rtx src, machine_mode mode, unsigned int prec)
{
  scalar_int_mode int_mode;
  if (CONST_INT_P (src)
      && is_a <scalar_int_mode> (mode, &int_mode)
      && GET_MODE_PRECISION (int_mode) < prec
      && INTVAL (src) > 0
      && val_signbit_known_set_p (int_mode, INTVAL (src)))
    src = GEN_INT (INTVAL (src) | ~GET_MODE_MASK (int_mode));

  return src;
}

/* Update RSP for pseudo-register X from INSN's REG_EQUAL note (if one exists)
   and SET.  */

static void
update_rsp_from_reg_equal (reg_stat_type *rsp, rtx_insn *insn, const_rtx set,
			   rtx x)
{
  rtx reg_equal_note = insn ? find_reg_equal_equiv_note (insn) : NULL_RTX;
  unsigned HOST_WIDE_INT bits = 0;
  rtx reg_equal = NULL, src = SET_SRC (set);
  unsigned int num = 0;

  if (reg_equal_note)
    reg_equal = XEXP (reg_equal_note, 0);

  if (SHORT_IMMEDIATES_SIGN_EXTEND)
    {
      src = sign_extend_short_imm (src, GET_MODE (x), BITS_PER_WORD);
      if (reg_equal)
	reg_equal = sign_extend_short_imm (reg_equal, GET_MODE (x), BITS_PER_WORD);
    }

  /* Don't call nonzero_bits if it cannot change anything.  */
  if (rsp->nonzero_bits != HOST_WIDE_INT_M1U)
    {
      machine_mode mode = GET_MODE (x);
      if (GET_MODE_CLASS (mode) == MODE_INT
	  && HWI_COMPUTABLE_MODE_P (mode))
	mode = nonzero_bits_mode;
      bits = nonzero_bits (src, mode);
      if (reg_equal && bits)
	bits &= nonzero_bits (reg_equal, mode);
      rsp->nonzero_bits |= bits;
    }

  /* Don't call num_sign_bit_copies if it cannot change anything.  */
  if (rsp->sign_bit_copies != 1)
    {
      num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
      if (reg_equal && maybe_ne (num, GET_MODE_PRECISION (GET_MODE (x))))
	{
	  unsigned int numeq = num_sign_bit_copies (reg_equal, GET_MODE (x));
	  if (num == 0 || numeq > num)
	    num = numeq;
	}
      if (rsp->sign_bit_copies == 0 || num < rsp->sign_bit_copies)
	rsp->sign_bit_copies = num;
    }
}

/* Called via note_stores.  If X is a pseudo that is narrower than
   HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero.

   If we are setting only a portion of X and we can't figure out what
   portion, assume all bits will be used since we don't know what will
   be happening.

   Similarly, set how many bits of X are known to be copies of the sign bit
   at all locations in the function.  This is the smallest number implied
   by any set of X.  */

static void
set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
{
  rtx_insn *insn = (rtx_insn *) data;
  scalar_int_mode mode;

  if (REG_P (x)
      && REGNO (x) >= FIRST_PSEUDO_REGISTER
      /* If this register is undefined at the start of the file, we can't
	 say what its contents were.  */
      && ! REGNO_REG_SET_P
	   (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb), REGNO (x))
      && is_a <scalar_int_mode> (GET_MODE (x), &mode)
      && HWI_COMPUTABLE_MODE_P (mode))
    {
      reg_stat_type *rsp = &reg_stat[REGNO (x)];

      if (set == 0 || GET_CODE (set) == CLOBBER)
	{
	  rsp->nonzero_bits = GET_MODE_MASK (mode);
	  rsp->sign_bit_copies = 1;
	  return;
	}

      /* Should not happen as we only using pseduo registers.  */
      gcc_assert (GET_CODE (set) != CLOBBER_HIGH);

      /* If this register is being initialized using itself, and the
	 register is uninitialized in this basic block, and there are
	 no LOG_LINKS which set the register, then part of the
	 register is uninitialized.  In that case we can't assume
	 anything about the number of nonzero bits.

	 ??? We could do better if we checked this in
	 reg_{nonzero_bits,num_sign_bit_copies}_for_combine.  Then we
	 could avoid making assumptions about the insn which initially
	 sets the register, while still using the information in other
	 insns.  We would have to be careful to check every insn
	 involved in the combination.  */

      if (insn
	  && reg_referenced_p (x, PATTERN (insn))
	  && !REGNO_REG_SET_P (DF_LR_IN (BLOCK_FOR_INSN (insn)),
			       REGNO (x)))
	{
	  struct insn_link *link;

	  FOR_EACH_LOG_LINK (link, insn)
	    if (dead_or_set_p (link->insn, x))
	      break;
	  if (!link)
	    {
	      rsp->nonzero_bits = GET_MODE_MASK (mode);
	      rsp->sign_bit_copies = 1;
	      return;
	    }
	}

      /* If this is a complex assignment, see if we can convert it into a
	 simple assignment.  */
      set = expand_field_assignment (set);

      /* If this is a simple assignment, or we have a paradoxical SUBREG,
	 set what we know about X.  */

      if (SET_DEST (set) == x
	  || (paradoxical_subreg_p (SET_DEST (set))
	      && SUBREG_REG (SET_DEST (set)) == x))
	update_rsp_from_reg_equal (rsp, insn, set, x);
      else
	{
	  rsp->nonzero_bits = GET_MODE_MASK (mode);
	  rsp->sign_bit_copies = 1;
	}
    }
}

/* See if INSN can be combined into I3.  PRED, PRED2, SUCC and SUCC2 are
   optionally insns that were previously combined into I3 or that will be
   combined into the merger of INSN and I3.  The order is PRED, PRED2,
   INSN, SUCC, SUCC2, I3.

   Return 0 if the combination is not allowed for any reason.

   If the combination is allowed, *PDEST will be set to the single
   destination of INSN and *PSRC to the single source, and this function
   will return 1.  */

static int
can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED,
	       rtx_insn *pred2 ATTRIBUTE_UNUSED, rtx_insn *succ, rtx_insn *succ2,
	       rtx *pdest, rtx *psrc)
{
  int i;
  const_rtx set = 0;
  rtx src, dest;
  rtx_insn *p;
  rtx link;
  bool all_adjacent = true;
  int (*is_volatile_p) (const_rtx);

  if (succ)
    {
      if (succ2)
	{
	  if (next_active_insn (succ2) != i3)
	    all_adjacent = false;
	  if (next_active_insn (succ) != succ2)
	    all_adjacent = false;
	}
      else if (next_active_insn (succ) != i3)
	all_adjacent = false;
      if (next_active_insn (insn) != succ)
	all_adjacent = false;
    }
  else if (next_active_insn (insn) != i3)
    all_adjacent = false;
    
  /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0.
     or a PARALLEL consisting of such a SET and CLOBBERs.

     If INSN has CLOBBER parallel parts, ignore them for our processing.
     By definition, these happen during the execution of the insn.  When it
     is merged with another insn, all bets are off.  If they are, in fact,
     needed and aren't also supplied in I3, they may be added by
     recog_for_combine.  Otherwise, it won't match.

     We can also ignore a SET whose SET_DEST is mentioned in a REG_UNUSED
     note.

     Get the source and destination of INSN.  If more than one, can't
     combine.  */

  if (GET_CODE (PATTERN (insn)) == SET)
    set = PATTERN (insn);
  else if (GET_CODE (PATTERN (insn)) == PARALLEL
	   && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
    {
      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
	{
	  rtx elt = XVECEXP (PATTERN (insn), 0, i);

	  switch (GET_CODE (elt))
	    {
	    /* This is important to combine floating point insns
	       for the SH4 port.  */
	    case USE:
	      /* Combining an isolated USE doesn't make sense.
		 We depend here on combinable_i3pat to reject them.  */
	      /* The code below this loop only verifies that the inputs of
		 the SET in INSN do not change.  We call reg_set_between_p
		 to verify that the REG in the USE does not change between
		 I3 and INSN.
		 If the USE in INSN was for a pseudo register, the matching
		 insn pattern will likely match any register; combining this
		 with any other USE would only be safe if we knew that the
		 used registers have identical values, or if there was
		 something to tell them apart, e.g. different modes.  For
		 now, we forgo such complicated tests and simply disallow
		 combining of USES of pseudo registers with any other USE.  */
	      if (REG_P (XEXP (elt, 0))
		  && GET_CODE (PATTERN (i3)) == PARALLEL)
		{
		  rtx i3pat = PATTERN (i3);
		  int i = XVECLEN (i3pat, 0) - 1;
		  unsigned int regno = REGNO (XEXP (elt, 0));

		  do
		    {
		      rtx i3elt = XVECEXP (i3pat, 0, i);

		      if (GET_CODE (i3elt) == USE
			  && REG_P (XEXP (i3elt, 0))
			  && (REGNO (XEXP (i3elt, 0)) == regno
			      ? reg_set_between_p (XEXP (elt, 0),
						   PREV_INSN (insn), i3)
			      : regno >= FIRST_PSEUDO_REGISTER))
			return 0;
		    }
		  while (--i >= 0);
		}
	      break;

	      /* We can ignore CLOBBERs.  */
	    case CLOBBER:
	    case CLOBBER_HIGH:
	      break;

	    case SET:
	      /* Ignore SETs whose result isn't used but not those that
		 have side-effects.  */
	      if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt))
		  && insn_nothrow_p (insn)
		  && !side_effects_p (elt))
		break;

	      /* If we have already found a SET, this is a second one and
		 so we cannot combine with this insn.  */
	      if (set)
		return 0;

	      set = elt;
	      break;

	    default:
	      /* Anything else means we can't combine.  */
	      return 0;
	    }
	}

      if (set == 0
	  /* If SET_SRC is an ASM_OPERANDS we can't throw away these CLOBBERs,
	     so don't do anything with it.  */
	  || GET_CODE (SET_SRC (set)) == ASM_OPERANDS)
	return 0;
    }
  else
    return 0;

  if (set == 0)
    return 0;

  /* The simplification in expand_field_assignment may call back to
     get_last_value, so set safe guard here.  */
  subst_low_luid = DF_INSN_LUID (insn);

  set = expand_field_assignment (set);
  src = SET_SRC (set), dest = SET_DEST (set);

  /* Do not eliminate user-specified register if it is in an
     asm input because we may break the register asm usage defined
     in GCC manual if allow to do so.
     Be aware that this may cover more cases than we expect but this
     should be harmless.  */
  if (REG_P (dest) && REG_USERVAR_P (dest) && HARD_REGISTER_P (dest)
      && extract_asm_operands (PATTERN (i3)))
    return 0;

  /* Don't eliminate a store in the stack pointer.  */
  if (dest == stack_pointer_rtx
      /* Don't combine with an insn that sets a register to itself if it has
	 a REG_EQUAL note.  This may be part of a LIBCALL sequence.  */
      || (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX))
      /* Can't merge an ASM_OPERANDS.  */
      || GET_CODE (src) == ASM_OPERANDS
      /* Can't merge a function call.  */
      || GET_CODE (src) == CALL
      /* Don't eliminate a function call argument.  */
      || (CALL_P (i3)
	  && (find_reg_fusage (i3, USE, dest)
	      || (REG_P (dest)
		  && REGNO (dest) < FIRST_PSEUDO_REGISTER
		  && global_regs[REGNO (dest)])))
      /* Don't substitute into an incremented register.  */
      || FIND_REG_INC_NOTE (i3, dest)
      || (succ && FIND_REG_INC_NOTE (succ, dest))
      || (succ2 && FIND_REG_INC_NOTE (succ2, dest))
      /* Don't substitute into a non-local goto, this confuses CFG.  */
      || (JUMP_P (i3) && find_reg_note (i3, REG_NON_LOCAL_GOTO, NULL_RTX))
      /* Make sure that DEST is not used after INSN but before SUCC, or
	 after SUCC and before SUCC2, or after SUCC2 but before I3.  */
      || (!all_adjacent
	  && ((succ2
	       && (reg_used_between_p (dest, succ2, i3)
		   || reg_used_between_p (dest, succ, succ2)))
	      || (!succ2 && succ && reg_used_between_p (dest, succ, i3))
	      || (!succ2 && !succ && reg_used_between_p (dest, insn, i3))
	      || (succ
		  /* SUCC and SUCC2 can be split halves from a PARALLEL; in
		     that case SUCC is not in the insn stream, so use SUCC2
		     instead for this test.  */
		  && reg_used_between_p (dest, insn,
					 succ2
					 && INSN_UID (succ) == INSN_UID (succ2)
					 ? succ2 : succ))))
      /* Make sure that the value that is to be substituted for the register
	 does not use any registers whose values alter in between.  However,
	 If the insns are adjacent, a use can't cross a set even though we
	 think it might (this can happen for a sequence of insns each setting
	 the same destination; last_set of that register might point to
	 a NOTE).  If INSN has a REG_EQUIV note, the register is always
	 equivalent to the memory so the substitution is valid even if there
	 are intervening stores.  Also, don't move a volatile asm or
	 UNSPEC_VOLATILE across any other insns.  */
      || (! all_adjacent
	  && (((!MEM_P (src)
		|| ! find_reg_note (insn, REG_EQUIV, src))
	       && modified_between_p (src, insn, i3))
	      || (GET_CODE (src) == ASM_OPERANDS && MEM_VOLATILE_P (src))
	      || GET_CODE (src) == UNSPEC_VOLATILE))
      /* Don't combine across a CALL_INSN, because that would possibly
	 change whether the life span of some REGs crosses calls or not,
	 and it is a pain to update that information.
	 Exception: if source is a constant, moving it later can't hurt.
	 Accept that as a special case.  */
      || (DF_INSN_LUID (insn) < last_call_luid && ! CONSTANT_P (src)))
    return 0;

  /* DEST must either be a REG or CC0.  */
  if (REG_P (dest))
    {
      /* If register alignment is being enforced for multi-word items in all
	 cases except for parameters, it is possible to have a register copy
	 insn referencing a hard register that is not allowed to contain the
	 mode being copied and which would not be valid as an operand of most
	 insns.  Eliminate this problem by not combining with such an insn.

	 Also, on some machines we don't want to extend the life of a hard
	 register.  */

      if (REG_P (src)
	  && ((REGNO (dest) < FIRST_PSEUDO_REGISTER
	       && !targetm.hard_regno_mode_ok (REGNO (dest), GET_MODE (dest)))
	      /* Don't extend the life of a hard register unless it is
		 user variable (if we have few registers) or it can't
		 fit into the desired register (meaning something special
		 is going on).
		 Also avoid substituting a return register into I3, because
		 reload can't handle a conflict with constraints of other
		 inputs.  */
	      || (REGNO (src) < FIRST_PSEUDO_REGISTER
		  && !targetm.hard_regno_mode_ok (REGNO (src),
						  GET_MODE (src)))))
	return 0;
    }
  else if (GET_CODE (dest) != CC0)
    return 0;


  if (GET_CODE (PATTERN (i3)) == PARALLEL)
    for (i = XVECLEN (PATTERN (i3), 0) - 1; i >= 0; i--)
      if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER)
	{
	  rtx reg = XEXP (XVECEXP (PATTERN (i3), 0, i), 0);

	  /* If the clobber represents an earlyclobber operand, we must not
	     substitute an expression containing the clobbered register.
	     As we do not analyze the constraint strings here, we have to
	     make the conservative assumption.  However, if the register is
	     a fixed hard reg, the clobber cannot represent any operand;
	     we leave it up to the machine description to either accept or
	     reject use-and-clobber patterns.  */
	  if (!REG_P (reg)
	      || REGNO (reg) >= FIRST_PSEUDO_REGISTER
	      || !fixed_regs[REGNO (reg)])
	    if (reg_overlap_mentioned_p (reg, src))
	      return 0;
	}

  /* If INSN contains anything volatile, or is an `asm' (whether volatile
     or not), reject, unless nothing volatile comes between it and I3 */

  if (GET_CODE (src) == ASM_OPERANDS || volatile_refs_p (src))
    {
      /* Make sure neither succ nor succ2 contains a volatile reference.  */
      if (succ2 != 0 && volatile_refs_p (PATTERN (succ2)))
	return 0;
      if (succ != 0 && volatile_refs_p (PATTERN (succ)))
	return 0;
      /* We'll check insns between INSN and I3 below.  */
    }

  /* If INSN is an asm, and DEST is a hard register, reject, since it has
     to be an explicit register variable, and was chosen for a reason.  */

  if (GET_CODE (src) == ASM_OPERANDS
      && REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER)
    return 0;

  /* If INSN contains volatile references (specifically volatile MEMs),
     we cannot combine across any other volatile references.
     Even if INSN doesn't contain volatile references, any intervening
     volatile insn might affect machine state.  */

  is_volatile_p = volatile_refs_p (PATTERN (insn))
    ? volatile_refs_p
    : volatile_insn_p;
    
  for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
    if (INSN_P (p) && p != succ && p != succ2 && is_volatile_p (PATTERN (p)))
      return 0;

  /* If INSN contains an autoincrement or autodecrement, make sure that
     register is not used between there and I3, and not already used in
     I3 either.  Neither must it be used in PRED or SUCC, if they exist.
     Also insist that I3 not be a jump; if it were one
     and the incremented register were spilled, we would lose.  */

  if (AUTO_INC_DEC)
    for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
      if (REG_NOTE_KIND (link) == REG_INC
	  && (JUMP_P (i3)
	      || reg_used_between_p (XEXP (link, 0), insn, i3)
	      || (pred != NULL_RTX
		  && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (pred)))
	      || (pred2 != NULL_RTX
		  && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (pred2)))
	      || (succ != NULL_RTX
		  && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (succ)))
	      || (succ2 != NULL_RTX
		  && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (succ2)))
	      || reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i3))))
	return 0;

  /* Don't combine an insn that follows a CC0-setting insn.
     An insn that uses CC0 must not be separated from the one that sets it.
     We do, however, allow I2 to follow a CC0-setting insn if that insn
     is passed as I1; in that case it will be deleted also.
     We also allow combining in this case if all the insns are adjacent
     because that would leave the two CC0 insns adjacent as well.
     It would be more logical to test whether CC0 occurs inside I1 or I2,
     but that would be much slower, and this ought to be equivalent.  */

  if (HAVE_cc0)
    {
      p = prev_nonnote_insn (insn);
      if (p && p != pred && NONJUMP_INSN_P (p) && sets_cc0_p (PATTERN (p))
	  && ! all_adjacent)
	return 0;
    }

  /* If we get here, we have passed all the tests and the combination is
     to be allowed.  */

  *pdest = dest;
  *psrc = src;

  return 1;
}

/* LOC is the location within I3 that contains its pattern or the component
   of a PARALLEL of the pattern.  We validate that it is valid for combining.

   One problem is if I3 modifies its output, as opposed to replacing it
   entirely, we can't allow the output to contain I2DEST, I1DEST or I0DEST as
   doing so would produce an insn that is not equivalent to the original insns.

   Consider:

	 (set (reg:DI 101) (reg:DI 100))
	 (set (subreg:SI (reg:DI 101) 0) <foo>)

   This is NOT equivalent to:

	 (parallel [(set (subreg:SI (reg:DI 100) 0) <foo>)
		    (set (reg:DI 101) (reg:DI 100))])

   Not only does this modify 100 (in which case it might still be valid
   if 100 were dead in I2), it sets 101 to the ORIGINAL value of 100.

   We can also run into a problem if I2 sets a register that I1
   uses and I1 gets directly substituted into I3 (not via I2).  In that
   case, we would be getting the wrong value of I2DEST into I3, so we
   must reject the combination.  This case occurs when I2 and I1 both
   feed into I3, rather than when I1 feeds into I2, which feeds into I3.
   If I1_NOT_IN_SRC is nonzero, it means that finding I1 in the source
   of a SET must prevent combination from occurring.  The same situation
   can occur for I0, in which case I0_NOT_IN_SRC is set.

   Before doing the above check, we first try to expand a field assignment
   into a set of logical operations.

   If PI3_DEST_KILLED is nonzero, it is a pointer to a location in which
   we place a register that is both set and used within I3.  If more than one
   such register is detected, we fail.

   Return 1 if the combination is valid, zero otherwise.  */

static int
combinable_i3pat (rtx_insn *i3, rtx *loc, rtx i2dest, rtx i1dest, rtx i0dest,
		  int i1_not_in_src, int i0_not_in_src, rtx *pi3dest_killed)
{
  rtx x = *loc;

  if (GET_CODE (x) == SET)
    {
      rtx set = x ;
      rtx dest = SET_DEST (set);
      rtx src = SET_SRC (set);
      rtx inner_dest = dest;
      rtx subdest;

      while (GET_CODE (inner_dest) == STRICT_LOW_PART
	     || GET_CODE (inner_dest) == SUBREG
	     || GET_CODE (inner_dest) == ZERO_EXTRACT)
	inner_dest = XEXP (inner_dest, 0);

      /* Check for the case where I3 modifies its output, as discussed
	 above.  We don't want to prevent pseudos from being combined
	 into the address of a MEM, so only prevent the combination if
	 i1 or i2 set the same MEM.  */
      if ((inner_dest != dest &&
	   (!MEM_P (inner_dest)
	    || rtx_equal_p (i2dest, inner_dest)
	    || (i1dest && rtx_equal_p (i1dest, inner_dest))
	    || (i0dest && rtx_equal_p (i0dest, inner_dest)))
	   && (reg_overlap_mentioned_p (i2dest, inner_dest)
	       || (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest))
	       || (i0dest && reg_overlap_mentioned_p (i0dest, inner_dest))))

	  /* This is the same test done in can_combine_p except we can't test
	     all_adjacent; we don't have to, since this instruction will stay
	     in place, thus we are not considering increasing the lifetime of
	     INNER_DEST.

	     Also, if this insn sets a function argument, combining it with
	     something that might need a spill could clobber a previous
	     function argument; the all_adjacent test in can_combine_p also
	     checks this; here, we do a more specific test for this case.  */

	  || (REG_P (inner_dest)
	      && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
	      && !targetm.hard_regno_mode_ok (REGNO (inner_dest),
					      GET_MODE (inner_dest)))
	  || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src))
	  || (i0_not_in_src && reg_overlap_mentioned_p (i0dest, src)))
	return 0;

      /* If DEST is used in I3, it is being killed in this insn, so
	 record that for later.  We have to consider paradoxical
	 subregs here, since they kill the whole register, but we
	 ignore partial subregs, STRICT_LOW_PART, etc.
	 Never add REG_DEAD notes for the FRAME_POINTER_REGNUM or the
	 STACK_POINTER_REGNUM, since these are always considered to be
	 live.  Similarly for ARG_POINTER_REGNUM if it is fixed.  */
      subdest = dest;
      if (GET_CODE (subdest) == SUBREG && !partial_subreg_p (subdest))
	subdest = SUBREG_REG (subdest);
      if (pi3dest_killed
	  && REG_P (subdest)
	  && reg_referenced_p (subdest, PATTERN (i3))
	  && REGNO (subdest) != FRAME_POINTER_REGNUM
	  && (HARD_FRAME_POINTER_IS_FRAME_POINTER
	      || REGNO (subdest) != HARD_FRAME_POINTER_REGNUM)
	  && (FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM
	      || (REGNO (subdest) != ARG_POINTER_REGNUM
		  || ! fixed_regs [REGNO (subdest)]))
	  && REGNO (subdest) != STACK_POINTER_REGNUM)
	{
	  if (*pi3dest_killed)
	    return 0;

	  *pi3dest_killed = subdest;
	}
    }

  else if (GET_CODE (x) == PARALLEL)
    {
      int i;

      for (i = 0; i < XVECLEN (x, 0); i++)
	if (! combinable_i3pat (i3, &XVECEXP (x, 0, i), i2dest, i1dest, i0dest,
				i1_not_in_src, i0_not_in_src, pi3dest_killed))
	  return 0;
    }

  return 1;
}

/* Return 1 if X is an arithmetic expression that contains a multiplication
   and division.  We don't count multiplications by powers of two here.  */

static int
contains_muldiv (rtx x)
{
  switch (GET_CODE (x))
    {
    case MOD:  case DIV:  case UMOD:  case UDIV:
      return 1;

    case MULT:
      return ! (CONST_INT_P (XEXP (x, 1))
		&& pow2p_hwi (UINTVAL (XEXP (x, 1))));
    default:
      if (BINARY_P (x))
	return contains_muldiv (XEXP (x, 0))
	    || contains_muldiv (XEXP (x, 1));

      if (UNARY_P (x))
	return contains_muldiv (XEXP (x, 0));

      return 0;
    }
}

/* Determine whether INSN can be used in a combination.  Return nonzero if
   not.  This is used in try_combine to detect early some cases where we
   can't perform combinations.  */

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

  /* If this isn't really an insn, we can't do anything.
     This can occur when flow deletes an insn that it has merged into an
     auto-increment address.  */
  if (!NONDEBUG_INSN_P (insn))
    return 1;

  /* Never combine loads and stores involving hard regs that are likely
     to be spilled.  The register allocator can usually handle such
     reg-reg moves by tying.  If we allow the combiner to make
     substitutions of likely-spilled regs, reload might die.
     As an exception, we allow combinations involving fixed regs; these are
     not available to the register allocator so there's no risk involved.  */

  set = single_set (insn);
  if (! set)
    return 0;
  src = SET_SRC (set);
  dest = SET_DEST (set);
  if (GET_CODE (src) == SUBREG)
    src = SUBREG_REG (src);
  if (GET_CODE (dest) == SUBREG)
    dest = SUBREG_REG (dest);
  if (REG_P (src) && REG_P (dest)
      && ((HARD_REGISTER_P (src)
	   && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (src))
#ifdef LEAF_REGISTERS
	   && ! LEAF_REGISTERS [REGNO (src)])
#else
	   )
#endif
	  || (HARD_REGISTER_P (dest)
	      && ! TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dest))
	      && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dest))))))
    return 1;

  return 0;
}

struct likely_spilled_retval_info
{
  unsigned regno, nregs;
  unsigned mask;
};

/* Called via note_stores by likely_spilled_retval_p.  Remove from info->mask
   hard registers that are known to be written to / clobbered in full.  */
static void
likely_spilled_retval_1 (rtx x, const_rtx set, void *data)
{
  struct likely_spilled_retval_info *const info =
    (struct likely_spilled_retval_info *) data;
  unsigned regno, nregs;
  unsigned new_mask;

  if (!REG_P (XEXP (set, 0)))
    return;
  regno = REGNO (x);
  if (regno >= info->regno + info->nregs)
    return;
  nregs = REG_NREGS (x);
  if (regno + nregs <= info->regno)
    return;
  new_mask = (2U << (nregs - 1)) - 1;
  if (regno < info->regno)
    new_mask >>= info->regno - regno;
  else
    new_mask <<= regno - info->regno;
  info->mask &= ~new_mask;
}

/* Return nonzero iff part of the return value is live during INSN, and
   it is likely spilled.  This can happen when more than one insn is needed
   to copy the return value, e.g. when we consider to combine into the
   second copy insn for a complex value.  */

static int
likely_spilled_retval_p (rtx_insn *insn)
{
  rtx_insn *use = BB_END (this_basic_block);
  rtx reg;
  rtx_insn *p;
  unsigned regno, nregs;
  /* We assume here that no machine mode needs more than
     32 hard registers when the value overlaps with a register
     for which TARGET_FUNCTION_VALUE_REGNO_P is true.  */
  unsigned mask;
  struct likely_spilled_retval_info info;

  if (!NONJUMP_INSN_P (use) || GET_CODE (PATTERN (use)) != USE || insn == use)
    return 0;
  reg = XEXP (PATTERN (use), 0);
  if (!REG_P (reg) || !targetm.calls.function_value_regno_p (REGNO (reg)))
    return 0;
  regno = REGNO (reg);
  nregs = REG_NREGS (reg);
  if (nregs == 1)
    return 0;
  mask = (2U << (nregs - 1)) - 1;

  /* Disregard parts of the return value that are set later.  */
  info.regno = regno;
  info.nregs = nregs;
  info.mask = mask;
  for (p = PREV_INSN (use); info.mask && p != insn; p = PREV_INSN (p))
    if (INSN_P (p))
      note_stores (PATTERN (p), likely_spilled_retval_1, &info);
  mask = info.mask;

  /* Check if any of the (probably) live return value registers is
     likely spilled.  */
  nregs --;
  do
    {
      if ((mask & 1 << nregs)
	  && targetm.class_likely_spilled_p (REGNO_REG_CLASS (regno + nregs)))
	return 1;
    } while (nregs--);
  return 0;
}

/* Adjust INSN after we made a change to its destination.

   Changing the destination can invalidate notes that say something about
   the results of the insn and a LOG_LINK pointing to the insn.  */

static void
adjust_for_new_dest (rtx_insn *insn)
{
  /* For notes, be conservative and simply remove them.  */
  remove_reg_equal_equiv_notes (insn);

  /* The new insn will have a destination that was previously the destination
     of an insn just above it.  Call distribute_links to make a LOG_LINK from
     the next use of that destination.  */

  rtx set = single_set (insn);
  gcc_assert (set);

  rtx reg = SET_DEST (set);

  while (GET_CODE (reg) == ZERO_EXTRACT
	 || GET_CODE (reg) == STRICT_LOW_PART
	 || GET_CODE (reg) == SUBREG)
    reg = XEXP (reg, 0);
  gcc_assert (REG_P (reg));

  distribute_links (alloc_insn_link (insn, REGNO (reg), NULL));

  df_insn_rescan (insn);
}

/* Return TRUE if combine can reuse reg X in mode MODE.
   ADDED_SETS is nonzero if the original set is still required.  */
static bool
can_change_dest_mode (rtx x, int added_sets, machine_mode mode)
{
  unsigned int regno;

  if (!REG_P (x))
    return false;

  /* Don't change between modes with different underlying register sizes,
     since this could lead to invalid subregs.  */
  if (maybe_ne (REGMODE_NATURAL_SIZE (mode),
		REGMODE_NATURAL_SIZE (GET_MODE (x))))
    return false;

  regno = REGNO (x);
  /* Allow hard registers if the new mode is legal, and occupies no more
     registers than the old mode.  */
  if (regno < FIRST_PSEUDO_REGISTER)
    return (targetm.hard_regno_mode_ok (regno, mode)
	    && REG_NREGS (x) >= hard_regno_nregs (regno, mode));

  /* Or a pseudo that is only used once.  */
  return (regno < reg_n_sets_max
	  && REG_N_SETS (regno) == 1
	  && !added_sets
	  && !REG_USERVAR_P (x));
}


/* Check whether X, the destination of a set, refers to part of
   the register specified by REG.  */

static bool
reg_subword_p (rtx x, rtx reg)
{
  /* Check that reg is an integer mode register.  */
  if (!REG_P (reg) || GET_MODE_CLASS (GET_MODE (reg)) != MODE_INT)
    return false;

  if (GET_CODE (x) == STRICT_LOW_PART
      || GET_CODE (x) == ZERO_EXTRACT)
    x = XEXP (x, 0);

  return GET_CODE (x) == SUBREG
	 && SUBREG_REG (x) == reg
	 && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT;
}

/* Delete the unconditional jump INSN and adjust the CFG correspondingly.
   Note that the INSN should be deleted *after* removing dead edges, so
   that the kept edge is the fallthrough edge for a (set (pc) (pc))
   but not for a (set (pc) (label_ref FOO)).  */

static void
update_cfg_for_uncondjump (rtx_insn *insn)
{
  basic_block bb = BLOCK_FOR_INSN (insn);
  gcc_assert (BB_END (bb) == insn);

  purge_dead_edges (bb);

  delete_insn (insn);
  if (EDGE_COUNT (bb->succs) == 1)
    {
      rtx_insn *insn;

      single_succ_edge (bb)->flags |= EDGE_FALLTHRU;

      /* Remove barriers from the footer if there are any.  */
      for (insn = BB_FOOTER (bb); insn; insn = NEXT_INSN (insn))
	if (BARRIER_P (insn))
	  {
	    if (PREV_INSN (insn))
	      SET_NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
	    else
	      BB_FOOTER (bb) = NEXT_INSN (insn);
	    if (NEXT_INSN (insn))
	      SET_PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
	  }
	else if (LABEL_P (insn))
	  break;
    }
}

/* Return whether PAT is a PARALLEL of exactly N register SETs followed
   by an arbitrary number of CLOBBERs.  */
static bool
is_parallel_of_n_reg_sets (rtx pat, int n)
{
  if (GET_CODE (pat) != PARALLEL)
    return false;

  int len = XVECLEN (pat, 0);
  if (len < n)
    return false;

  int i;
  for (i = 0; i < n; i++)
    if (GET_CODE (XVECEXP (pat, 0, i)) != SET
	|| !REG_P (SET_DEST (XVECEXP (pat, 0, i))))
      return false;
  for ( ; i < len; i++)
    switch (GET_CODE (XVECEXP (pat, 0, i)))
      {
      case CLOBBER:
	if (XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
	  return false;
	break;
      case CLOBBER_HIGH:
	break;
      default:
	return false;
      }
  return true;
}

/* Return whether INSN, a PARALLEL of N register SETs (and maybe some
   CLOBBERs), can be split into individual SETs in that order, without
   changing semantics.  */
static bool
can_split_parallel_of_n_reg_sets (rtx_insn *insn, int n)
{
  if (!insn_nothrow_p (insn))
    return false;

  rtx pat = PATTERN (insn);

  int i, j;
  for (i = 0; i < n; i++)
    {
      if (side_effects_p (SET_SRC (XVECEXP (pat, 0, i))))
	return false;

      rtx reg = SET_DEST (XVECEXP (pat, 0, i));

      for (j = i + 1; j < n; j++)
	if (reg_referenced_p (reg, XVECEXP (pat, 0, j)))
	  return false;
    }

  return true;
}

/* Return whether X is just a single set, with the source
   a general_operand.  */
static bool
is_just_move (rtx x)
{
  if (INSN_P (x))
    x = PATTERN (x);

  return (GET_CODE (x) == SET && general_operand (SET_SRC (x), VOIDmode));
}

/* Callback function to count autoincs.  */

static int
count_auto_inc (rtx, rtx, rtx, rtx, rtx, void *arg)
{
  (*((int *) arg))++;

  return 0;
}

/* Try to combine the insns I0, I1 and I2 into I3.
   Here I0, I1 and I2 appear earlier than I3.
   I0 and I1 can be zero; then we combine just I2 into I3, or I1 and I2 into
   I3.

   If we are combining more than two insns and the resulting insn is not
   recognized, try splitting it into two insns.  If that happens, I2 and I3
   are retained and I1/I0 are pseudo-deleted by turning them into a NOTE.
   Otherwise, I0, I1 and I2 are pseudo-deleted.

   Return 0 if the combination does not work.  Then nothing is changed.
   If we did the combination, return the insn at which combine should
   resume scanning.

   Set NEW_DIRECT_JUMP_P to a nonzero value if try_combine creates a
   new direct jump instruction.

   LAST_COMBINED_INSN is either I3, or some insn after I3 that has
   been I3 passed to an earlier try_combine within the same basic
   block.  */

static rtx_insn *
try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
	     int *new_direct_jump_p, rtx_insn *last_combined_insn)
{
  /* New patterns for I3 and I2, respectively.  */
  rtx newpat, newi2pat = 0;
  rtvec newpat_vec_with_clobbers = 0;
  int substed_i2 = 0, substed_i1 = 0, substed_i0 = 0;
  /* Indicates need to preserve SET in I0, I1 or I2 in I3 if it is not
     dead.  */
  int added_sets_0, added_sets_1, added_sets_2;
  /* Total number of SETs to put into I3.  */
  int total_sets;
  /* Nonzero if I2's or I1's body now appears in I3.  */
  int i2_is_used = 0, i1_is_used = 0;
  /* INSN_CODEs for new I3, new I2, and user of condition code.  */
  int insn_code_number, i2_code_number = 0, other_code_number = 0;
  /* Contains I3 if the destination of I3 is used in its source, which means
     that the old life of I3 is being killed.  If that usage is placed into
     I2 and not in I3, a REG_DEAD note must be made.  */
  rtx i3dest_killed = 0;
  /* SET_DEST and SET_SRC of I2, I1 and I0.  */
  rtx i2dest = 0, i2src = 0, i1dest = 0, i1src = 0, i0dest = 0, i0src = 0;
  /* Copy of SET_SRC of I1 and I0, if needed.  */
  rtx i1src_copy = 0, i0src_copy = 0, i0src_copy2 = 0;
  /* Set if I2DEST was reused as a scratch register.  */
  bool i2scratch = false;
  /* The PATTERNs of I0, I1, and I2, or a copy of them in certain cases.  */
  rtx i0pat = 0, i1pat = 0, i2pat = 0;
  /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC.  */
  int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0;
  int i0dest_in_i0src = 0, i1dest_in_i0src = 0, i2dest_in_i0src = 0;
  int i2dest_killed = 0, i1dest_killed = 0, i0dest_killed = 0;
  int i1_feeds_i2_n = 0, i0_feeds_i2_n = 0, i0_feeds_i1_n = 0;
  /* Notes that must be added to REG_NOTES in I3 and I2.  */
  rtx new_i3_notes, new_i2_notes;
  /* Notes that we substituted I3 into I2 instead of the normal case.  */
  int i3_subst_into_i2 = 0;
  /* Notes that I1, I2 or I3 is a MULT operation.  */
  int have_mult = 0;
  int swap_i2i3 = 0;
  int split_i2i3 = 0;
  int changed_i3_dest = 0;
  bool i2_was_move = false, i3_was_move = false;
  int n_auto_inc = 0;

  int maxreg;
  rtx_insn *temp_insn;
  rtx temp_expr;
  struct insn_link *link;
  rtx other_pat = 0;
  rtx new_other_notes;
  int i;
  scalar_int_mode dest_mode, temp_mode;

  /* Immediately return if any of I0,I1,I2 are the same insn (I3 can
     never be).  */
  if (i1 == i2 || i0 == i2 || (i0 && i0 == i1))
    return 0;

  /* Only try four-insn combinations when there's high likelihood of
     success.  Look for simple insns, such as loads of constants or
     binary operations involving a constant.  */
  if (i0)
    {
      int i;
      int ngood = 0;
      int nshift = 0;
      rtx set0, set3;

      if (!flag_expensive_optimizations)
	return 0;

      for (i = 0; i < 4; i++)
	{
	  rtx_insn *insn = i == 0 ? i0 : i == 1 ? i1 : i == 2 ? i2 : i3;
	  rtx set = single_set (insn);
	  rtx src;
	  if (!set)
	    continue;
	  src = SET_SRC (set);
	  if (CONSTANT_P (src))
	    {
	      ngood += 2;
	      break;
	    }
	  else if (BINARY_P (src) && CONSTANT_P (XEXP (src, 1)))
	    ngood++;
	  else if (GET_CODE (src) == ASHIFT || GET_CODE (src) == ASHIFTRT
		   || GET_CODE (src) == LSHIFTRT)
	    nshift++;
	}

      /* If I0 loads a memory and I3 sets the same memory, then I1 and I2
	 are likely manipulating its value.  Ideally we'll be able to combine
	 all four insns into a bitfield insertion of some kind. 

	 Note the source in I0 might be inside a sign/zero extension and the
	 memory modes in I0 and I3 might be different.  So extract the address
	 from the destination of I3 and search for it in the source of I0.

	 In the event that there's a match but the source/dest do not actually
	 refer to the same memory, the worst that happens is we try some
	 combinations that we wouldn't have otherwise.  */
      if ((set0 = single_set (i0))
	  /* Ensure the source of SET0 is a MEM, possibly buried inside
	     an extension.  */
	  && (GET_CODE (SET_SRC (set0)) == MEM
	      || ((GET_CODE (SET_SRC (set0)) == ZERO_EXTEND
		   || GET_CODE (SET_SRC (set0)) == SIGN_EXTEND)
		  && GET_CODE (XEXP (SET_SRC (set0), 0)) == MEM))
	  && (set3 = single_set (i3))
	  /* Ensure the destination of SET3 is a MEM.  */
	  && GET_CODE (SET_DEST (set3)) == MEM
	  /* Would it be better to extract the base address for the MEM
	     in SET3 and look for that?  I don't have cases where it matters
	     but I could envision such cases.  */
	  && rtx_referenced_p (XEXP (SET_DEST (set3), 0), SET_SRC (set0)))
	ngood += 2;

      if (ngood < 2 && nshift < 2)
	return 0;
    }

  /* Exit early if one of the insns involved can't be used for
     combinations.  */
  if (CALL_P (i2)
      || (i1 && CALL_P (i1))
      || (i0 && CALL_P (i0))
      || cant_combine_insn_p (i3)
      || cant_combine_insn_p (i2)
      || (i1 && cant_combine_insn_p (i1))
      || (i0 && cant_combine_insn_p (i0))
      || likely_spilled_retval_p (i3))
    return 0;

  combine_attempts++;
  undobuf.other_insn = 0;

  /* Reset the hard register usage information.  */
  CLEAR_HARD_REG_SET (newpat_used_regs);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      if (i0)
	fprintf (dump_file, "\nTrying %d, %d, %d -> %d:\n",
		 INSN_UID (i0), INSN_UID (i1), INSN_UID (i2), INSN_UID (i3));
      else if (i1)
	fprintf (dump_file, "\nTrying %d, %d -> %d:\n",
		 INSN_UID (i1), INSN_UID (i2), INSN_UID (i3));
      else
	fprintf (dump_file, "\nTrying %d -> %d:\n",
		 INSN_UID (i2), INSN_UID (i3));

      if (i0)
	dump_insn_slim (dump_file, i0);
      if (i1)
	dump_insn_slim (dump_file, i1);
      dump_insn_slim (dump_file, i2);
      dump_insn_slim (dump_file, i3);
    }

  /* If multiple insns feed into one of I2 or I3, they can be in any
     order.  To simplify the code below, reorder them in sequence.  */
  if (i0 && DF_INSN_LUID (i0) > DF_INSN_LUID (i2))
    std::swap (i0, i2);
  if (i0 && DF_INSN_LUID (i0) > DF_INSN_LUID (i1))
    std::swap (i0, i1);
  if (i1 && DF_INSN_LUID (i1) > DF_INSN_LUID (i2))
    std::swap (i1, i2);

  added_links_insn = 0;
  added_notes_insn = 0;

  /* First check for one important special case that the code below will
     not handle.  Namely, the case where I1 is zero, I2 is a PARALLEL
     and I3 is a SET whose SET_SRC is a SET_DEST in I2.  In that case,
     we may be able to replace that destination with the destination of I3.
     This occurs in the common code where we compute both a quotient and
     remainder into a structure, in which case we want to do the computation
     directly into the structure to avoid register-register copies.

     Note that this case handles both multiple sets in I2 and also cases
     where I2 has a number of CLOBBERs inside the PARALLEL.

     We make very conservative checks below and only try to handle the
     most common cases of this.  For example, we only handle the case
     where I2 and I3 are adjacent to avoid making difficult register
     usage tests.  */

  if (i1 == 0 && NONJUMP_INSN_P (i3) && GET_CODE (PATTERN (i3)) == SET
      && REG_P (SET_SRC (PATTERN (i3)))
      && REGNO (SET_SRC (PATTERN (i3))) >= FIRST_PSEUDO_REGISTER
      && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3)))
      && GET_CODE (PATTERN (i2)) == PARALLEL
      && ! side_effects_p (SET_DEST (PATTERN (i3)))
      /* If the dest of I3 is a ZERO_EXTRACT or STRICT_LOW_PART, the code
	 below would need to check what is inside (and reg_overlap_mentioned_p
	 doesn't support those codes anyway).  Don't allow those destinations;
	 the resulting insn isn't likely to be recognized anyway.  */
      && GET_CODE (SET_DEST (PATTERN (i3))) != ZERO_EXTRACT
      && GET_CODE (SET_DEST (PATTERN (i3))) != STRICT_LOW_PART
      && ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3)),
				    SET_DEST (PATTERN (i3)))
      && next_active_insn (i2) == i3)
    {
      rtx p2 = PATTERN (i2);

      /* Make sure that the destination of I3,
	 which we are going to substitute into one output of I2,
	 is not used within another output of I2.  We must avoid making this:
	 (parallel [(set (mem (reg 69)) ...)
		    (set (reg 69) ...)])
	 which is not well-defined as to order of actions.
	 (Besides, reload can't handle output reloads for this.)

	 The problem can also happen if the dest of I3 is a memory ref,
	 if another dest in I2 is an indirect memory ref.

	 Neither can this PARALLEL be an asm.  We do not allow combining
	 that usually (see can_combine_p), so do not here either.  */
      bool ok = true;
      for (i = 0; ok && i < XVECLEN (p2, 0); i++)
	{
	  if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
	       || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER
	       || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER_HIGH)
	      && reg_overlap_mentioned_p (SET_DEST (PATTERN (i3)),
					  SET_DEST (XVECEXP (p2, 0, i))))
	    ok = false;
	  else if (GET_CODE (XVECEXP (p2, 0, i)) == SET
		   && GET_CODE (SET_SRC (XVECEXP (p2, 0, i))) == ASM_OPERANDS)
	    ok = false;
	}

      if (ok)
	for (i = 0; i < XVECLEN (p2, 0); i++)
	  if (GET_CODE (XVECEXP (p2, 0, i)) == SET
	      && SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3)))
	    {
	      combine_merges++;

	      subst_insn = i3;
	      subst_low_luid = DF_INSN_LUID (i2);

	      added_sets_2 = added_sets_1 = added_sets_0 = 0;
	      i2src = SET_SRC (XVECEXP (p2, 0, i));
	      i2dest = SET_DEST (XVECEXP (p2, 0, i));
	      i2dest_killed = dead_or_set_p (i2, i2dest);

	      /* Replace the dest in I2 with our dest and make the resulting
		 insn the new pattern for I3.  Then skip to where we validate
		 the pattern.  Everything was set up above.  */
	      SUBST (SET_DEST (XVECEXP (p2, 0, i)), SET_DEST (PATTERN (i3)));
	      newpat = p2;
	      i3_subst_into_i2 = 1;
	      goto validate_replacement;
	    }
    }

  /* If I2 is setting a pseudo to a constant and I3 is setting some
     sub-part of it to another constant, merge them by making a new
     constant.  */
  if (i1 == 0
      && (temp_expr = single_set (i2)) != 0
      && is_a <scalar_int_mode> (GET_MODE (SET_DEST (temp_expr)), &temp_mode)
      && CONST_SCALAR_INT_P (SET_SRC (temp_expr))
      && GET_CODE (PATTERN (i3)) == SET
      && CONST_SCALAR_INT_P (SET_SRC (PATTERN (i3)))
      && reg_subword_p (SET_DEST (PATTERN (i3)), SET_DEST (temp_expr)))
    {
      rtx dest = SET_DEST (PATTERN (i3));
      rtx temp_dest = SET_DEST (temp_expr);
      int offset = -1;
      int width = 0;

      if (GET_CODE (dest) == ZERO_EXTRACT)
	{
	  if (CONST_INT_P (XEXP (dest, 1))
	      && CONST_INT_P (XEXP (dest, 2))
	      && is_a <scalar_int_mode> (GET_MODE (XEXP (dest, 0)),
					 &dest_mode))
	    {
	      width = INTVAL (XEXP (dest, 1));
	      offset = INTVAL (XEXP (dest, 2));
	      dest = XEXP (dest, 0);
	      if (BITS_BIG_ENDIAN)
		offset = GET_MODE_PRECISION (dest_mode) - width - offset;
	    }
	}
      else
	{
	  if (GET_CODE (dest) == STRICT_LOW_PART)
	    dest = XEXP (dest, 0);
	  if (is_a <scalar_int_mode> (GET_MODE (dest), &dest_mode))
	    {
	      width = GET_MODE_PRECISION (dest_mode);
	      offset = 0;
	    }
	}

      if (offset >= 0)
	{
	  /* If this is the low part, we're done.  */
	  if (subreg_lowpart_p (dest))
	    ;
	  /* Handle the case where inner is twice the size of outer.  */
	  else if (GET_MODE_PRECISION (temp_mode)
		   == 2 * GET_MODE_PRECISION (dest_mode))
	    offset += GET_MODE_PRECISION (dest_mode);
	  /* Otherwise give up for now.  */
	  else
	    offset = -1;
	}

      if (offset >= 0)
	{
	  rtx inner = SET_SRC (PATTERN (i3));
	  rtx outer = SET_SRC (temp_expr);

	  wide_int o = wi::insert (rtx_mode_t (outer, temp_mode),
				   rtx_mode_t (inner, dest_mode),
				   offset, width);

	  combine_merges++;
	  subst_insn = i3;
	  subst_low_luid = DF_INSN_LUID (i2);
	  added_sets_2 = added_sets_1 = added_sets_0 = 0;
	  i2dest = temp_dest;
	  i2dest_killed = dead_or_set_p (i2, i2dest);

	  /* Replace the source in I2 with the new constant and make the
	     resulting insn the new pattern for I3.  Then skip to where we
	     validate the pattern.  Everything was set up above.  */
	  SUBST (SET_SRC (temp_expr),
		 immed_wide_int_const (o, temp_mode));

	  newpat = PATTERN (i2);

          /* The dest of I3 has been replaced with the dest of I2.  */
          changed_i3_dest = 1;
	  goto validate_replacement;
	}
    }

  /* If we have no I1 and I2 looks like:
	(parallel [(set (reg:CC X) (compare:CC OP (const_int 0)))
		   (set Y OP)])
     make up a dummy I1 that is
	(set Y OP)
     and change I2 to be
	(set (reg:CC X) (compare:CC Y (const_int 0)))

     (We can ignore any trailing CLOBBERs.)

     This undoes a previous combination and allows us to match a branch-and-
     decrement insn.  */

  if (!HAVE_cc0 && i1 == 0
      && is_parallel_of_n_reg_sets (PATTERN (i2), 2)
      && (GET_MODE_CLASS (GET_MODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 0))))
	  == MODE_CC)
      && GET_CODE (SET_SRC (XVECEXP (PATTERN (i2), 0, 0))) == COMPARE
      && XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 1) == const0_rtx
      && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 0),
		      SET_SRC (XVECEXP (PATTERN (i2), 0, 1)))
      && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 0)), i2, i3)
      && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1)), i2, i3))
    {
      /* We make I1 with the same INSN_UID as I2.  This gives it
	 the same DF_INSN_LUID for value tracking.  Our fake I1 will
	 never appear in the insn stream so giving it the same INSN_UID
	 as I2 will not cause a problem.  */

      i1 = gen_rtx_INSN (VOIDmode, NULL, i2, BLOCK_FOR_INSN (i2),
			 XVECEXP (PATTERN (i2), 0, 1), INSN_LOCATION (i2),
			 -1, NULL_RTX);
      INSN_UID (i1) = INSN_UID (i2);

      SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
      SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
	     SET_DEST (PATTERN (i1)));
      unsigned int regno = REGNO (SET_DEST (PATTERN (i1)));
      SUBST_LINK (LOG_LINKS (i2),
		  alloc_insn_link (i1, regno, LOG_LINKS (i2)));
    }

  /* If I2 is a PARALLEL of two SETs of REGs (and perhaps some CLOBBERs),
     make those two SETs separate I1 and I2 insns, and make an I0 that is
     the original I1.  */
  if (!HAVE_cc0 && i0 == 0
      && is_parallel_of_n_reg_sets (PATTERN (i2), 2)
      && can_split_parallel_of_n_reg_sets (i2, 2)
      && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 0)), i2, i3)
      && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1)), i2, i3)
      && !reg_set_between_p  (SET_DEST (XVECEXP (PATTERN (i2), 0, 0)), i2, i3)
      && !reg_set_between_p  (SET_DEST (XVECEXP (PATTERN (i2), 0, 1)), i2, i3))
    {
      /* If there is no I1, there is no I0 either.  */
      i0 = i1;

      /* We make I1 with the same INSN_UID as I2.  This gives it
	 the same DF_INSN_LUID for value tracking.  Our fake I1 will
	 never appear in the insn stream so giving it the same INSN_UID
	 as I2 will not cause a problem.  */

      i1 = gen_rtx_INSN (VOIDmode, NULL, i2, BLOCK_FOR_INSN (i2),
			 XVECEXP (PATTERN (i2), 0, 0), INSN_LOCATION (i2),
			 -1, NULL_RTX);
      INSN_UID (i1) = INSN_UID (i2);

      SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 1));
    }

  /* Verify that I2 and maybe I1 and I0 can be combined into I3.  */
  if (!can_combine_p (i2, i3, i0, i1, NULL, NULL, &i2dest, &i2src))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Can't combine i2 into i3\n");
      undo_all ();
      return 0;
    }
  if (i1 && !can_combine_p (i1, i3, i0, NULL, i2, NULL, &i1dest, &i1src))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Can't combine i1 into i3\n");
      undo_all ();
      return 0;
    }
  if (i0 && !can_combine_p (i0, i3, NULL, NULL, i1, i2, &i0dest, &i0src))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file, "Can't combine i0 into i3\n");
      undo_all ();
      return 0;
    }

  /* Record whether i2 and i3 are trivial moves.  */
  i2_was_move = is_just_move (i2);
  i3_was_move = is_just_move (i3);

  /* Record whether I2DEST is used in I2SRC and similarly for the other
     cases.  Knowing this will help in register status updating below.  */
  i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
  i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src);
  i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src);
  i0dest_in_i0src = i0 && reg_overlap_mentioned_p (i0dest, i0src);
  i1dest_in_i0src = i0 && reg_overlap_mentioned_p (i1dest, i0src);
  i2dest_in_i0src = i0 && reg_overlap_mentioned_p (i2dest, i0src);
  i2dest_killed = dead_or_set_p (i2, i2dest);
  i1dest_killed = i1 && dead_or_set_p (i1, i1dest);
  i0dest_killed = i0 && dead_or_set_p (i0, i0dest);

  /* For the earlier insns, determine which of the subsequent ones they
     feed.  */
  i1_feeds_i2_n = i1 && insn_a_feeds_b (i1, i2);
  i0_feeds_i1_n = i0 && insn_a_feeds_b (i0, i1);
  i0_feeds_i2_n = (i0 && (!i0_feeds_i1_n ? insn_a_feeds_b (i0, i2)
			  : (!reg_overlap_mentioned_p (i1dest, i0dest)
			     && reg_overlap_mentioned_p (i0dest, i2src))));

  /* Ensure that I3's pattern can be the destination of combines.  */
  if (! combinable_i3pat (i3, &PATTERN (i3), i2dest, i1dest, i0dest,
			  i1 && i2dest_in_i1src && !i1_feeds_i2_n,
			  i0 && ((i2dest_in_i0src && !i0_feeds_i2_n)
				 || (i1dest_in_i0src && !i0_feeds_i1_n)),
			  &i3dest_killed))
    {
      undo_all ();
      return 0;
    }

  /* See if any of the insns is a MULT operation.  Unless one is, we will
     reject a combination that is, since it must be slower.  Be conservative
     here.  */
  if (GET_CODE (i2src) == MULT
      || (i1 != 0 && GET_CODE (i1src) == MULT)
      || (i0 != 0 && GET_CODE (i0src) == MULT)
      || (GET_CODE (PATTERN (i3)) == SET
	  && GET_CODE (SET_SRC (PATTERN (i3))) == MULT))
    have_mult = 1;

  /* If I3 has an inc, then give up if I1 or I2 uses the reg that is inc'd.
     We used to do this EXCEPT in one case: I3 has a post-inc in an
     output operand.  However, that exception can give rise to insns like
	mov r3,(r3)+
     which is a famous insn on the PDP-11 where the value of r3 used as the
     source was model-dependent.  Avoid this sort of thing.  */

#if 0
  if (!(GET_CODE (PATTERN (i3)) == SET
	&& REG_P (SET_SRC (PATTERN (i3)))
	&& MEM_P (SET_DEST (PATTERN (i3)))
	&& (GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_INC
	    || GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_DEC)))
    /* It's not the exception.  */
#endif
    if (AUTO_INC_DEC)
      {
	rtx link;
	for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
	  if (REG_NOTE_KIND (link) == REG_INC
	      && (reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i2))
		  || (i1 != 0
		      && reg_overlap_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
	    {
	      undo_all ();
	      return 0;
	    }
      }

  /* See if the SETs in I1 or I2 need to be kept around in the merged
     instruction: whenever the value set there is still needed past I3.
     For the SET in I2, this is easy: we see if I2DEST dies or is set in I3.

     For the SET in I1, we have two cases: if I1 and I2 independently feed
     into I3, the set in I1 needs to be kept around unless I1DEST dies
     or is set in I3.  Otherwise (if I1 feeds I2 which feeds I3), the set
     in I1 needs to be kept around unless I1DEST dies or is set in either
     I2 or I3.  The same considerations apply to I0.  */

  added_sets_2 = !dead_or_set_p (i3, i2dest);

  if (i1)
    added_sets_1 = !(dead_or_set_p (i3, i1dest)
		     || (i1_feeds_i2_n && dead_or_set_p (i2, i1dest)));
  else
    added_sets_1 = 0;

  if (i0)
    added_sets_0 =  !(dead_or_set_p (i3, i0dest)
		      || (i0_feeds_i1_n && dead_or_set_p (i1, i0dest))
		      || ((i0_feeds_i2_n || (i0_feeds_i1_n && i1_feeds_i2_n))
			  && dead_or_set_p (i2, i0dest)));
  else
    added_sets_0 = 0;

  /* We are about to copy insns for the case where they need to be kept
     around.  Check that they can be copied in the merged instruction.  */

  if (targetm.cannot_copy_insn_p
      && ((added_sets_2 && targetm.cannot_copy_insn_p (i2))
	  || (i1 && added_sets_1 && targetm.cannot_copy_insn_p (i1))
	  || (i0 && added_sets_0 && targetm.cannot_copy_insn_p (i0))))
    {
      undo_all ();
      return 0;
    }

  /* We cannot safely duplicate volatile references in any case.  */

  if ((added_sets_2 && volatile_refs_p (PATTERN (i2)))
      || (added_sets_1 && volatile_refs_p (PATTERN (i1)))
      || (added_sets_0 && volatile_refs_p (PATTERN (i0))))
    {
      undo_all ();
      return 0;
    }

  /* Count how many auto_inc expressions there were in the original insns;
     we need to have the same number in the resulting patterns.  */

  if (i0)
    for_each_inc_dec (PATTERN (i0), count_auto_inc, &n_auto_inc);
  if (i1)
    for_each_inc_dec (PATTERN (i1), count_auto_inc, &n_auto_inc);
  for_each_inc_dec (PATTERN (i2), count_auto_inc, &n_auto_inc);
  for_each_inc_dec (PATTERN (i3), count_auto_inc, &n_auto_inc);

  /* If the set in I2 needs to be kept around, we must make a copy of
     PATTERN (I2), so that when we substitute I1SRC for I1DEST in
     PATTERN (I2), we are only substituting for the original I1DEST, not into
     an already-substituted copy.  This also prevents making self-referential
     rtx.  If I2 is a PARALLEL, we just need the piece that assigns I2SRC to
     I2DEST.  */

  if (added_sets_2)
    {
      if (GET_CODE (PATTERN (i2)) == PARALLEL)
	i2pat = gen_rtx_SET (i2dest, copy_rtx (i2src));
      else
	i2pat = copy_rtx (PATTERN (i2));
    }

  if (added_sets_1)
    {
      if (GET_CODE (PATTERN (i1)) == PARALLEL)
	i1pat = gen_rtx_SET (i1dest, copy_rtx (i1src));
      else
	i1pat = copy_rtx (PATTERN (i1));
    }

  if (added_sets_0)
    {
      if (GET_CODE (PATTERN (i0)) == PARALLEL)
	i0pat = gen_rtx_SET (i0dest, copy_rtx (i0src));
      else
	i0pat = copy_rtx (PATTERN (i0));
    }

  combine_merges++;

  /* Substitute in the latest insn for the regs set by the earlier ones.  */

  maxreg = max_reg_num ();

  subst_insn = i3;

  /* Many machines that don't use CC0 have insns that can both perform an
     arithmetic operation and set the condition code.  These operations will
     be represented as a PARALLEL with the first element of the vector
     being a COMPARE of an arithmetic operation with the constant zero.
     The second element of the vector will set some pseudo to the result
     of the same arithmetic operation.  If we simplify the COMPARE, we won't
     match such a pattern and so will generate an extra insn.   Here we test
     for this case, where both the comparison and the operation result are
     needed, and make the PARALLEL by just replacing I2DEST in I3SRC with
     I2SRC.  Later we will make the PARALLEL that contains I2.  */

  if (!HAVE_cc0 && i1 == 0 && added_sets_2 && GET_CODE (PATTERN (i3)) == SET
      && GET_CODE (SET_SRC (PATTERN (i3))) == COMPARE
      && CONST_INT_P (XEXP (SET_SRC (PATTERN (i3)), 1))
      && rtx_equal_p (XEXP (SET_SRC (PATTERN (i3)), 0), i2dest))
    {
      rtx newpat_dest;
      rtx *cc_use_loc = NULL;
      rtx_insn *cc_use_insn = NULL;
      rtx op0 = i2src, op1 = XEXP (SET_SRC (PATTERN (i3)), 1);
      machine_mode compare_mode, orig_compare_mode;
      enum rtx_code compare_code = UNKNOWN, orig_compare_code = UNKNOWN;
      scalar_int_mode mode;

      newpat = PATTERN (i3);
      newpat_dest = SET_DEST (newpat);
      compare_mode = orig_compare_mode = GET_MODE (newpat_dest);

      if (undobuf.other_insn == 0
	  && (cc_use_loc = find_single_use (SET_DEST (newpat), i3,
					    &cc_use_insn)))
	{
	  compare_code = orig_compare_code = GET_CODE (*cc_use_loc);
	  if (is_a <scalar_int_mode> (GET_MODE (i2dest), &mode))
	    compare_code = simplify_compare_const (compare_code, mode,
						   op0, &op1);
	  target_canonicalize_comparison (&compare_code, &op0, &op1, 1);
	}

      /* Do the rest only if op1 is const0_rtx, which may be the
	 result of simplification.  */
      if (op1 == const0_rtx)
	{
	  /* If a single use of the CC is found, prepare to modify it
	     when SELECT_CC_MODE returns a new CC-class mode, or when
	     the above simplify_compare_const() returned a new comparison
	     operator.  undobuf.other_insn is assigned the CC use insn
	     when modifying it.  */
	  if (cc_use_loc)
	    {
#ifdef SELECT_CC_MODE
	      machine_mode new_mode
		= SELECT_CC_MODE (compare_code, op0, op1);
	      if (new_mode != orig_compare_mode
		  && can_change_dest_mode (SET_DEST (newpat),
					   added_sets_2, new_mode))
		{
		  unsigned int regno = REGNO (newpat_dest);
		  compare_mode = new_mode;
		  if (regno < FIRST_PSEUDO_REGISTER)
		    newpat_dest = gen_rtx_REG (compare_mode, regno);
		  else
		    {
		      subst_mode (regno, compare_mode);
		      newpat_dest = regno_reg_rtx[regno];
		    }
		}
#endif
	      /* Cases for modifying the CC-using comparison.  */
	      if (compare_code != orig_compare_code
		  /* ??? Do we need to verify the zero rtx?  */
		  && XEXP (*cc_use_loc, 1) == const0_rtx)
		{
		  /* Replace cc_use_loc with entire new RTX.  */
		  SUBST (*cc_use_loc,
			 gen_rtx_fmt_ee (compare_code, GET_MODE (*cc_use_loc),
					 newpat_dest, const0_rtx));
		  undobuf.other_insn = cc_use_insn;
		}
	      else if (compare_mode != orig_compare_mode)
		{
		  /* Just replace the CC reg with a new mode.  */
		  SUBST (XEXP (*cc_use_loc, 0), newpat_dest);
		  undobuf.other_insn = cc_use_insn;
		}
	    }

	  /* Now we modify the current newpat:
	     First, SET_DEST(newpat) is updated if the CC mode has been
	     altered. For targets without SELECT_CC_MODE, this should be
	     optimized away.  */
	  if (compare_mode != orig_compare_mode)
	    SUBST (SET_DEST (newpat), newpat_dest);
	  /* This is always done to propagate i2src into newpat.  */
	  SUBST (SET_SRC (newpat),
		 gen_rtx_COMPARE (compare_mode, op0, op1));
	  /* Create new version of i2pat if needed; the below PARALLEL
	     creation needs this to work correctly.  */
	  if (! rtx_equal_p (i2src, op0))
	    i2pat = gen_rtx_SET (i2dest, op0);
	  i2_is_used = 1;
	}
    }

  if (i2_is_used == 0)
    {
      /* It is possible that the source of I2 or I1 may be performing
	 an unneeded operation, such as a ZERO_EXTEND of something
	 that is known to have the high part zero.  Handle that case
	 by letting subst look at the inner insns.

	 Another way to do this would be to have a function that tries
	 to simplify a single insn instead of merging two or more
	 insns.  We don't do this because of the potential of infinite
	 loops and because of the potential extra memory required.
	 However, doing it the way we are is a bit of a kludge and
	 doesn't catch all cases.

	 But only do this if -fexpensive-optimizations since it slows
	 things down and doesn't usually win.

	 This is not done in the COMPARE case above because the
	 unmodified I2PAT is used in the PARALLEL and so a pattern
	 with a modified I2SRC would not match.  */

      if (flag_expensive_optimizations)
	{
	  /* Pass pc_rtx so no substitutions are done, just
	     simplifications.  */
	  if (i1)
	    {
	      subst_low_luid = DF_INSN_LUID (i1);
	      i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0, 0);
	    }

	  subst_low_luid = DF_INSN_LUID (i2);
	  i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0, 0);
	}

      n_occurrences = 0;		/* `subst' counts here */
      subst_low_luid = DF_INSN_LUID (i2);

      /* If I1 feeds into I2 and I1DEST is in I1SRC, we need to make a unique
	 copy of I2SRC each time we substitute it, in order to avoid creating
	 self-referential RTL when we will be substituting I1SRC for I1DEST
	 later.  Likewise if I0 feeds into I2, either directly or indirectly
	 through I1, and I0DEST is in I0SRC.  */
      newpat = subst (PATTERN (i3), i2dest, i2src, 0, 0,
		      (i1_feeds_i2_n && i1dest_in_i1src)
		      || ((i0_feeds_i2_n || (i0_feeds_i1_n && i1_feeds_i2_n))
			  && i0dest_in_i0src));
      substed_i2 = 1;

      /* Record whether I2's body now appears within I3's body.  */
      i2_is_used = n_occurrences;
    }

  /* If we already got a failure, don't try to do more.  Otherwise, try to
     substitute I1 if we have it.  */

  if (i1 && GET_CODE (newpat) != CLOBBER)
    {
      /* Before we can do this substitution, we must redo the test done
	 above (see detailed comments there) that ensures I1DEST isn't
	 mentioned in any SETs in NEWPAT that are field assignments.  */
      if (!combinable_i3pat (NULL, &newpat, i1dest, NULL_RTX, NULL_RTX,
			     0, 0, 0))
	{
	  undo_all ();
	  return 0;
	}

      n_occurrences = 0;
      subst_low_luid = DF_INSN_LUID (i1);

      /* If the following substitution will modify I1SRC, make a copy of it
	 for the case where it is substituted for I1DEST in I2PAT later.  */
      if (added_sets_2 && i1_feeds_i2_n)
	i1src_copy = copy_rtx (i1src);

      /* If I0 feeds into I1 and I0DEST is in I0SRC, we need to make a unique
	 copy of I1SRC each time we substitute it, in order to avoid creating
	 self-referential RTL when we will be substituting I0SRC for I0DEST
	 later.  */
      newpat = subst (newpat, i1dest, i1src, 0, 0,
		      i0_feeds_i1_n && i0dest_in_i0src);
      substed_i1 = 1;

      /* Record whether I1's body now appears within I3's body.  */
      i1_is_used = n_occurrences;
    }

  /* Likewise for I0 if we have it.  */

  if (i0 && GET_CODE (newpat) != CLOBBER)
    {
      if (!combinable_i3pat (NULL, &newpat, i0dest, NULL_RTX, NULL_RTX,
			     0, 0, 0))
	{
	  undo_all ();
	  return 0;
	}

      /* If the following substitution will modify I0SRC, make a copy of it
	 for the case where it is substituted for I0DEST in I1PAT later.  */
      if (added_sets_1 && i0_feeds_i1_n)
	i0src_copy = copy_rtx (i0src);
      /* And a copy for I0DEST in I2PAT substitution.  */
      if (added_sets_2 && ((i0_feeds_i1_n && i1_feeds_i2_n)
			   || (i0_feeds_i2_n)))
	i0src_copy2 = copy_rtx (i0src);

      n_occurrences = 0;
      subst_low_luid = DF_INSN_LUID (i0);
      newpat = subst (newpat, i0dest, i0src, 0, 0, 0);
      substed_i0 = 1;
    }

  if (n_auto_inc)
    {
      int new_n_auto_inc = 0;
      for_each_inc_dec (newpat, count_auto_inc, &new_n_auto_inc);

      if (n_auto_inc != new_n_auto_inc)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fprintf (dump_file, "Number of auto_inc expressions changed\n");
	  undo_all ();
	  return 0;
	}
    }

  /* Fail if an autoincrement side-effect has been duplicated.  Be careful
     to count all the ways that I2SRC and I1SRC can be used.  */
  if ((FIND_REG_INC_NOTE (i2, NULL_RTX) != 0
       && i2_is_used + added_sets_2 > 1)
      || (i1 != 0 && FIND_REG_INC_NOTE (i1, NULL_RTX) != 0
	  && (i1_is_used + added_sets_1 + (added_sets_2 && i1_feeds_i2_n)
	      > 1))
      || (i0 != 0 && FIND_REG_INC_NOTE (i0, NULL_RTX) != 0
	  && (n_occurrences + added_sets_0
	      + (added_sets_1 && i0_feeds_i1_n)
	      + (added_sets_2 && i0_feeds_i2_n)
	      > 1))
      /* Fail if we tried to make a new register.  */
      || max_reg_num () != maxreg
      /* Fail if we couldn't do something and have a CLOBBER.  */
      || GET_CODE (newpat) == CLOBBER
      /* Fail if this new pattern is a MULT and we didn't have one before
	 at the outer level.  */
      || (GET_CODE (newpat) == SET && GET_CODE (SET_SRC (newpat)) == MULT
	  && ! have_mult))
    {
      undo_all ();
      return 0;
    }

  /* If the actions of the earlier insns must be kept
     in addition to substituting them into the latest one,
     we must make a new PARALLEL for the latest insn
     to hold additional the SETs.  */

  if (added_sets_0 || added_sets_1 || added_sets_2)
    {
      int extra_sets = added_sets_0 + added_sets_1 + added_sets_2;
      combine_extras++;

      if (GET_CODE (newpat) == PARALLEL)
	{
	  rtvec old = XVEC (newpat, 0);
	  total_sets = XVECLEN (newpat, 0) + extra_sets;
	  newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
	  memcpy (XVEC (newpat, 0)->elem, &old->elem[0],
		  sizeof (old->elem[0]) * old->num_elem);
	}
      else
	{
	  rtx old = newpat;
	  total_sets = 1 + extra_sets;
	  newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets));
	  XVECEXP (newpat, 0, 0) = old;
	}

      if (added_sets_0)
	XVECEXP (newpat, 0, --total_sets) = i0pat;

      if (added_sets_1)
	{
	  rtx t = i1pat;
	  if (i0_feeds_i1_n)
	    t = subst (t, i0dest, i0src_copy ? i0src_copy : i0src, 0, 0, 0);

	  XVECEXP (newpat, 0, --total_sets) = t;
	}
      if (added_sets_2)
	{
	  rtx t = i2pat;
	  if (i1_feeds_i2_n)
	    t = subst (t, i1dest, i1src_copy ? i1src_copy : i1src, 0, 0,
		       i0_feeds_i1_n && i0dest_in_i0src);
	  if ((i0_feeds_i1_n && i1_feeds_i2_n) || i0_feeds_i2_n)
	    t = subst (t, i0dest, i0src_copy2 ? i0src_copy2 : i0src, 0, 0, 0);

	  XVECEXP (newpat, 0, --total_sets) = t;
	}
    }

 validate_replacement:

  /* Note which hard regs this insn has as inputs.  */
  mark_used_regs_combine (newpat);

  /* If recog_for_combine fails, it strips existing clobbers.  If we'll
     consider splitting this pattern, we might need these clobbers.  */
  if (i1 && GET_CODE (newpat) == PARALLEL
      && GET_CODE (XVECEXP (newpat, 0, XVECLEN (newpat, 0) - 1)) == CLOBBER)
    {
      int len = XVECLEN (newpat, 0);

      newpat_vec_with_clobbers = rtvec_alloc (len);
      for (i = 0; i < len; i++)
	RTVEC_ELT (newpat_vec_with_clobbers, i) = XVECEXP (newpat, 0, i);
    }

  /* We have recognized nothing yet.  */
  insn_code_number = -1;

  /* See if this is a PARALLEL of two SETs where one SET's destination is
     a register that is unused and this isn't marked as an instruction that
     might trap in an EH region.  In that case, we just need the other SET.
     We prefer this over the PARALLEL.

     This can occur when simplifying a divmod insn.  We *must* test for this
     case here because the code below that splits two independent SETs doesn't
     handle this case correctly when it updates the register status.

     It's pointless doing this if we originally had two sets, one from
     i3, and one from i2.  Combining then splitting the parallel results
     in the original i2 again plus an invalid insn (which we delete).
     The net effect is only to move instructions around, which makes
     debug info less accurate.

     If the remaining SET came from I2 its destination should not be used
     between I2 and I3.  See PR82024.  */

  if (!(added_sets_2 && i1 == 0)
      && is_parallel_of_n_reg_sets (newpat, 2)
      && asm_noperands (newpat) < 0)
    {
      rtx set0 = XVECEXP (newpat, 0, 0);
      rtx set1 = XVECEXP (newpat, 0, 1);
      rtx oldpat = newpat;

      if (((REG_P (SET_DEST (set1))
	    && find_reg_note (i3, REG_UNUSED, SET_DEST (set1)))
	   || (GET_CODE (SET_DEST (set1)) == SUBREG
	       && find_reg_note (i3, REG_UNUSED, SUBREG_REG (SET_DEST (set1)))))
	  && insn_nothrow_p (i3)
	  && !side_effects_p (SET_SRC (set1)))
	{
	  newpat = set0;
	  insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
	}

      else if (((REG_P (SET_DEST (set0))
		 && find_reg_note (i3, REG_UNUSED, SET_DEST (set0)))
		|| (GET_CODE (SET_DEST (set0)) == SUBREG
		    && find_reg_note (i3, REG_UNUSED,
				      SUBREG_REG (SET_DEST (set0)))))
	       && insn_nothrow_p (i3)
	       && !side_effects_p (SET_SRC (set0)))
	{
	  rtx dest = SET_DEST (set1);
	  if (GET_CODE (dest) == SUBREG)
	    dest = SUBREG_REG (dest);
	  if (!reg_used_between_p (dest, i2, i3))
	    {
	      newpat = set1;
	      insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);

	      if (insn_code_number >= 0)
		changed_i3_dest = 1;
	    }
	}

      if (insn_code_number < 0)
	newpat = oldpat;
    }

  /* Is the result of combination a valid instruction?  */
  if (insn_code_number < 0)
    insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);

  /* If we were combining three insns and the result is a simple SET
     with no ASM_OPERANDS that wasn't recognized, try to split it into two
     insns.  There are two ways to do this.  It can be split using a
     machine-specific method (like when you have an addition of a large
     constant) or by combine in the function find_split_point.  */

  if (i1 && insn_code_number < 0 && GET_CODE (newpat) == SET
      && asm_noperands (newpat) < 0)
    {
      rtx parallel, *split;
      rtx_insn *m_split_insn;

      /* See if the MD file can split NEWPAT.  If it can't, see if letting it
	 use I2DEST as a scratch register will help.  In the latter case,
	 convert I2DEST to the mode of the source of NEWPAT if we can.  */

      m_split_insn = combine_split_insns (newpat, i3);

      /* We can only use I2DEST as a scratch reg if it doesn't overlap any
	 inputs of NEWPAT.  */

      /* ??? If I2DEST is not safe, and I1DEST exists, then it would be
	 possible to try that as a scratch reg.  This would require adding
	 more code to make it work though.  */

      if (m_split_insn == 0 && ! reg_overlap_mentioned_p (i2dest, newpat))
	{
	  machine_mode new_mode = GET_MODE (SET_DEST (newpat));

	  /* ??? Reusing i2dest without resetting the reg_stat entry for it
	     (temporarily, until we are committed to this instruction
	     combination) does not work: for example, any call to nonzero_bits
	     on the register (from a splitter in the MD file, for example)
	     will get the old information, which is invalid.

	     Since nowadays we can create registers during combine just fine,
	     we should just create a new one here, not reuse i2dest.  */

	  /* First try to split using the original register as a
	     scratch register.  */
	  parallel = gen_rtx_PARALLEL (VOIDmode,
				       gen_rtvec (2, newpat,
						  gen_rtx_CLOBBER (VOIDmode,
								   i2dest)));
	  m_split_insn = combine_split_insns (parallel, i3);

	  /* If that didn't work, try changing the mode of I2DEST if
	     we can.  */
	  if (m_split_insn == 0
	      && new_mode != GET_MODE (i2dest)
	      && new_mode != VOIDmode
	      && can_change_dest_mode (i2dest, added_sets_2, new_mode))
	    {
	      machine_mode old_mode = GET_MODE (i2dest);
	      rtx ni2dest;

	      if (REGNO (i2dest) < FIRST_PSEUDO_REGISTER)
		ni2dest = gen_rtx_REG (new_mode, REGNO (i2dest));
	      else
		{
		  subst_mode (REGNO (i2dest), new_mode);
		  ni2dest = regno_reg_rtx[REGNO (i2dest)];
		}

	      parallel = (gen_rtx_PARALLEL
			  (VOIDmode,
			   gen_rtvec (2, newpat,
				      gen_rtx_CLOBBER (VOIDmode,
						       ni2dest))));
	      m_split_insn = combine_split_insns (parallel, i3);

	      if (m_split_insn == 0
		  && REGNO (i2dest) >= FIRST_PSEUDO_REGISTER)
		{
		  struct undo *buf;

		  adjust_reg_mode (regno_reg_rtx[REGNO (i2dest)], old_mode);
		  buf = undobuf.undos;
		  undobuf.undos = buf->next;
		  buf->next = undobuf.frees;
		  undobuf.frees = buf;
		}
	    }

	  i2scratch = m_split_insn != 0;
	}

      /* If recog_for_combine has discarded clobbers, try to use them
	 again for the split.  */
      if (m_split_insn == 0 && newpat_vec_with_clobbers)
	{
	  parallel = gen_rtx_PARALLEL (VOIDmode, newpat_vec_with_clobbers);
	  m_split_insn = combine_split_insns (parallel, i3);
	}

      if (m_split_insn && NEXT_INSN (m_split_insn) == NULL_RTX)
	{
	  rtx m_split_pat = PATTERN (m_split_insn);
	  insn_code_number = recog_for_combine (&m_split_pat, i3, &new_i3_notes);
	  if (insn_code_number >= 0)
	    newpat = m_split_pat;
	}
      else if (m_split_insn && NEXT_INSN (NEXT_INSN (m_split_insn)) == NULL_RTX
	       && (next_nonnote_nondebug_insn (i2) == i3
		   || !modified_between_p (PATTERN (m_split_insn), i2, i3)))
	{
	  rtx i2set, i3set;
	  rtx newi3pat = PATTERN (NEXT_INSN (m_split_insn));
	  newi2pat = PATTERN (m_split_insn);

	  i3set = single_set (NEXT_INSN (m_split_insn));
	  i2set = single_set (m_split_insn);

	  i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);

	  /* If I2 or I3 has multiple SETs, we won't know how to track
	     register status, so don't use these insns.  If I2's destination
	     is used between I2 and I3, we also can't use these insns.  */

	  if (i2_code_number >= 0 && i2set && i3set
	      && (next_nonnote_nondebug_insn (i2) == i3
		  || ! reg_used_between_p (SET_DEST (i2set), i2, i3)))
	    insn_code_number = recog_for_combine (&newi3pat, i3,
						  &new_i3_notes);
	  if (insn_code_number >= 0)
	    newpat = newi3pat;

	  /* It is possible that both insns now set the destination of I3.
	     If so, we must show an extra use of it.  */

	  if (insn_code_number >= 0)
	    {
	      rtx new_i3_dest = SET_DEST (i3set);
	      rtx new_i2_dest = SET_DEST (i2set);

	      while (GET_CODE (new_i3_dest) == ZERO_EXTRACT
		     || GET_CODE (new_i3_dest) == STRICT_LOW_PART
		     || GET_CODE (new_i3_dest) == SUBREG)
		new_i3_dest = XEXP (new_i3_dest, 0);

	      while (GET_CODE (new_i2_dest) == ZERO_EXTRACT
		     || GET_CODE (new_i2_dest) == STRICT_LOW_PART
		     || GET_CODE (new_i2_dest) == SUBREG)
		new_i2_dest = XEXP (new_i2_dest, 0);

	      if (REG_P (new_i3_dest)
		  && REG_P (new_i2_dest)
		  && REGNO (new_i3_dest) == REGNO (new_i2_dest)
		  && REGNO (new_i2_dest) < reg_n_sets_max)
		INC_REG_N_SETS (REGNO (new_i2_dest), 1);
	    }
	}

      /* If we can split it and use I2DEST, go ahead and see if that
	 helps things be recognized.  Verify that none of the registers
	 are set between I2 and I3.  */
      if (insn_code_number < 0
          && (split = find_split_point (&newpat, i3, false)) != 0
	  && (!HAVE_cc0 || REG_P (i2dest))
	  /* We need I2DEST in the proper mode.  If it is a hard register
	     or the only use of a pseudo, we can change its mode.
	     Make sure we don't change a hard register to have a mode that
	     isn't valid for it, or change the number of registers.  */
	  && (GET_MODE (*split) == GET_MODE (i2dest)
	      || GET_MODE (*split) == VOIDmode
	      || can_change_dest_mode (i2dest, added_sets_2,
				       GET_MODE (*split)))
	  && (next_nonnote_nondebug_insn (i2) == i3
	      || !modified_between_p (*split, i2, i3))
	  /* We can't overwrite I2DEST if its value is still used by
	     NEWPAT.  */
	  && ! reg_referenced_p (i2dest, newpat))
	{
	  rtx newdest = i2dest;
	  enum rtx_code split_code = GET_CODE (*split);
	  machine_mode split_mode = GET_MODE (*split);
	  bool subst_done = false;
	  newi2pat = NULL_RTX;

	  i2scratch = true;

	  /* *SPLIT may be part of I2SRC, so make sure we have the
	     original expression around for later debug processing.
	     We should not need I2SRC any more in other cases.  */
	  if (MAY_HAVE_DEBUG_BIND_INSNS)
	    i2src = copy_rtx (i2src);
	  else
	    i2src = NULL;

	  /* Get NEWDEST as a register in the proper mode.  We have already
	     validated that we can do this.  */
	  if (GET_MODE (i2dest) != split_mode && split_mode != VOIDmode)
	    {
	      if (REGNO (i2dest) < FIRST_PSEUDO_REGISTER)
		newdest = gen_rtx_REG (split_mode, REGNO (i2dest));
	      else
		{
		  subst_mode (REGNO (i2dest), split_mode);
		  newdest = regno_reg_rtx[REGNO (i2dest)];
		}
	    }

	  /* If *SPLIT is a (mult FOO (const_int pow2)), convert it to
	     an ASHIFT.  This can occur if it was inside a PLUS and hence
	     appeared to be a memory address.  This is a kludge.  */
	  if (split_code == MULT
	      && CONST_INT_P (XEXP (*split, 1))
	      && INTVAL (XEXP (*split, 1)) > 0
	      && (i = exact_log2 (UINTVAL (XEXP (*split, 1)))) >= 0)
	    {
	      rtx i_rtx = gen_int_shift_amount (split_mode, i);
	      SUBST (*split, gen_rtx_ASHIFT (split_mode,
					     XEXP (*split, 0), i_rtx));
	      /* Update split_code because we may not have a multiply
		 anymore.  */
	      split_code = GET_CODE (*split);
	    }

	  /* Similarly for (plus (mult FOO (const_int pow2))).  */
	  if (split_code == PLUS
	      && GET_CODE (XEXP (*split, 0)) == MULT
	      && CONST_INT_P (XEXP (XEXP (*split, 0), 1))
	      && INTVAL (XEXP (XEXP (*split, 0), 1)) > 0
	      && (i = exact_log2 (UINTVAL (XEXP (XEXP (*split, 0), 1)))) >= 0)
	    {
	      rtx nsplit = XEXP (*split, 0);
	      rtx i_rtx = gen_int_shift_amount (GET_MODE (nsplit), i);
	      SUBST (XEXP (*split, 0), gen_rtx_ASHIFT (GET_MODE (nsplit),
						       XEXP (nsplit, 0),
						       i_rtx));
	      /* Update split_code because we may not have a multiply
		 anymore.  */
	      split_code = GET_CODE (*split);
	    }

#ifdef INSN_SCHEDULING
	  /* If *SPLIT is a paradoxical SUBREG, when we split it, it should
	     be written as a ZERO_EXTEND.  */
	  if (split_code == SUBREG && MEM_P (SUBREG_REG (*split)))
	    {
	      /* Or as a SIGN_EXTEND if LOAD_EXTEND_OP says that that's
		 what it really is.  */
	      if (load_extend_op (GET_MODE (SUBREG_REG (*split)))
		  == SIGN_EXTEND)
		SUBST (*split, gen_rtx_SIGN_EXTEND (split_mode,
						    SUBREG_REG (*split)));
	      else
		SUBST (*split, gen_rtx_ZERO_EXTEND (split_mode,
						    SUBREG_REG (*split)));
	    }
#endif

	  /* Attempt to split binary operators using arithmetic identities.  */
	  if (BINARY_P (SET_SRC (newpat))
	      && split_mode == GET_MODE (SET_SRC (newpat))
	      && ! side_effects_p (SET_SRC (newpat)))
	    {
	      rtx setsrc = SET_SRC (newpat);
	      machine_mode mode = GET_MODE (setsrc);
	      enum rtx_code code = GET_CODE (setsrc);
	      rtx src_op0 = XEXP (setsrc, 0);
	      rtx src_op1 = XEXP (setsrc, 1);

	      /* Split "X = Y op Y" as "Z = Y; X = Z op Z".  */
	      if (rtx_equal_p (src_op0, src_op1))
		{
		  newi2pat = gen_rtx_SET (newdest, src_op0);
		  SUBST (XEXP (setsrc, 0), newdest);
		  SUBST (XEXP (setsrc, 1), newdest);
		  subst_done = true;
		}
	      /* Split "((P op Q) op R) op S" where op is PLUS or MULT.  */
	      else if ((code == PLUS || code == MULT)
		       && GET_CODE (src_op0) == code
		       && GET_CODE (XEXP (src_op0, 0)) == code
		       && (INTEGRAL_MODE_P (mode)
			   || (FLOAT_MODE_P (mode)
			       && flag_unsafe_math_optimizations)))
		{
		  rtx p = XEXP (XEXP (src_op0, 0), 0);
		  rtx q = XEXP (XEXP (src_op0, 0), 1);
		  rtx r = XEXP (src_op0, 1);
		  rtx s = src_op1;

		  /* Split both "((X op Y) op X) op Y" and
		     "((X op Y) op Y) op X" as "T op T" where T is
		     "X op Y".  */
		  if ((rtx_equal_p (p,r) && rtx_equal_p (q,s))
		       || (rtx_equal_p (p,s) && rtx_equal_p (q,r)))
		    {
		      newi2pat = gen_rtx_SET (newdest, XEXP (src_op0, 0));
		      SUBST (XEXP (setsrc, 0), newdest);
		      SUBST (XEXP (setsrc, 1), newdest);
		      subst_done = true;
		    }
		  /* Split "((X op X) op Y) op Y)" as "T op T" where
		     T is "X op Y".  */
		  else if (rtx_equal_p (p,q) && rtx_equal_p (r,s))
		    {
		      rtx tmp = simplify_gen_binary (code, mode, p, r);
		      newi2pat = gen_rtx_SET (newdest, tmp);
		      SUBST (XEXP (setsrc, 0), newdest);
		      SUBST (XEXP (setsrc, 1), newdest);
		      subst_done = true;
		    }
		}
	    }

	  if (!subst_done)
	    {
	      newi2pat = gen_rtx_SET (newdest, *split);
	      SUBST (*split, newdest);
	    }

	  i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);

	  /* recog_for_combine might have added CLOBBERs to newi2pat.
	     Make sure NEWPAT does not depend on the clobbered regs.  */
	  if (GET_CODE (newi2pat) == PARALLEL)
	    for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--)
	      if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER)
		{
		  rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0);
		  if (reg_overlap_mentioned_p (reg, newpat))
		    {
		      undo_all ();
		      return 0;
		    }
		}

	  /* If the split point was a MULT and we didn't have one before,
	     don't use one now.  */
	  if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult))
	    insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
	}
    }

  /* Check for a case where we loaded from memory in a narrow mode and
     then sign extended it, but we need both registers.  In that case,
     we have a PARALLEL with both loads from the same memory location.
     We can split this into a load from memory followed by a register-register
     copy.  This saves at least one insn, more if register allocation can
     eliminate the copy.

     We cannot do this if the destination of the first assignment is a
     condition code register or cc0.  We eliminate this case by making sure
     the SET_DEST and SET_SRC have the same mode.

     We cannot do this if the destination of the second assignment is
     a register that we have already assumed is zero-extended.  Similarly
     for a SUBREG of such a register.  */

  else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
	   && GET_CODE (newpat) == PARALLEL
	   && XVECLEN (newpat, 0) == 2
	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
	   && GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0))) == SIGN_EXTEND
	   && (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0)))
	       == GET_MODE (SET_SRC (XVECEXP (newpat, 0, 0))))
	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
	   && rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1)),
			   XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0))
	   && !modified_between_p (SET_SRC (XVECEXP (newpat, 0, 1)), i2, i3)
	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
	   && ! (temp_expr = SET_DEST (XVECEXP (newpat, 0, 1)),
		 (REG_P (temp_expr)
		  && reg_stat[REGNO (temp_expr)].nonzero_bits != 0
		  && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)),
			       BITS_PER_WORD)
		  && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)),
			       HOST_BITS_PER_INT)
		  && (reg_stat[REGNO (temp_expr)].nonzero_bits
		      != GET_MODE_MASK (word_mode))))
	   && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == SUBREG
		 && (temp_expr = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1))),
		     (REG_P (temp_expr)
		      && reg_stat[REGNO (temp_expr)].nonzero_bits != 0
		      && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)),
				   BITS_PER_WORD)
		      && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)),
				   HOST_BITS_PER_INT)
		      && (reg_stat[REGNO (temp_expr)].nonzero_bits
			  != GET_MODE_MASK (word_mode)))))
	   && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1)),
					 SET_SRC (XVECEXP (newpat, 0, 1)))
	   && ! find_reg_note (i3, REG_UNUSED,
			       SET_DEST (XVECEXP (newpat, 0, 0))))
    {
      rtx ni2dest;

      newi2pat = XVECEXP (newpat, 0, 0);
      ni2dest = SET_DEST (XVECEXP (newpat, 0, 0));
      newpat = XVECEXP (newpat, 0, 1);
      SUBST (SET_SRC (newpat),
	     gen_lowpart (GET_MODE (SET_SRC (newpat)), ni2dest));
      i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);

      if (i2_code_number >= 0)
	insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);

      if (insn_code_number >= 0)
	swap_i2i3 = 1;
    }

  /* Similarly, check for a case where we have a PARALLEL of two independent
     SETs but we started with three insns.  In this case, we can do the sets
     as two separate insns.  This case occurs when some SET allows two
     other insns to combine, but the destination of that SET is still live.

     Also do this if we started with two insns and (at least) one of the
     resulting sets is a noop; this noop will be deleted later.

     Also do this if we started with two insns neither of which was a simple
     move.  */

  else if (insn_code_number < 0 && asm_noperands (newpat) < 0
	   && GET_CODE (newpat) == PARALLEL
	   && XVECLEN (newpat, 0) == 2
	   && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
	   && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
	   && (i1
	       || set_noop_p (XVECEXP (newpat, 0, 0))
	       || set_noop_p (XVECEXP (newpat, 0, 1))
	       || (!i2_was_move && !i3_was_move))
	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != ZERO_EXTRACT
	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) != STRICT_LOW_PART
	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != ZERO_EXTRACT
	   && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) != STRICT_LOW_PART
	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1)),
				  XVECEXP (newpat, 0, 0))
	   && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0)),
				  XVECEXP (newpat, 0, 1))
	   && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0)))
		 && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1)))))
    {
      rtx set0 = XVECEXP (newpat, 0, 0);
      rtx set1 = XVECEXP (newpat, 0, 1);

      /* Normally, it doesn't matter which of the two is done first,
	 but the one that references cc0 can't be the second, and
	 one which uses any regs/memory set in between i2 and i3 can't
	 be first.  The PARALLEL might also have been pre-existing in i3,
	 so we need to make sure that we won't wrongly hoist a SET to i2
	 that would conflict with a death note present in there, or would
	 have its dest modified between i2 and i3.  */
      if (!modified_between_p (SET_SRC (set1), i2, i3)
	  && !(REG_P (SET_DEST (set1))
	       && find_reg_note (i2, REG_DEAD, SET_DEST (set1)))
	  && !(GET_CODE (SET_DEST (set1)) == SUBREG
	       && find_reg_note (i2, REG_DEAD,
				 SUBREG_REG (SET_DEST (set1))))
	  && !modified_between_p (SET_DEST (set1), i2, i3)
	  && (!HAVE_cc0 || !reg_referenced_p (cc0_rtx, set0))
	  /* If I3 is a jump, ensure that set0 is a jump so that
	     we do not create invalid RTL.  */
	  && (!JUMP_P (i3) || SET_DEST (set0) == pc_rtx)
	 )
	{
	  newi2pat = set1;
	  newpat = set0;
	}
      else if (!modified_between_p (SET_SRC (set0), i2, i3)
	       && !(REG_P (SET_DEST (set0))
		    && find_reg_note (i2, REG_DEAD, SET_DEST (set0)))
	       && !(GET_CODE (SET_DEST (set0)) == SUBREG
		    && find_reg_note (i2, REG_DEAD,
				      SUBREG_REG (SET_DEST (set0))))
	       && !modified_between_p (SET_DEST (set0), i2, i3)
	       && (!HAVE_cc0 || !reg_referenced_p (cc0_rtx, set1))
	       /* If I3 is a jump, ensure that set1 is a jump so that
		  we do not create invalid RTL.  */
	       && (!JUMP_P (i3) || SET_DEST (set1) == pc_rtx)
	      )
	{
	  newi2pat = set0;
	  newpat = set1;
	}
      else
	{
	  undo_all ();
	  return 0;
	}

      i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);

      if (i2_code_number >= 0)
	{
	  /* recog_for_combine might have added CLOBBERs to newi2pat.
	     Make sure NEWPAT does not depend on the clobbered regs.  */
	  if (GET_CODE (newi2pat) == PARALLEL)
	    {
	      for (i = XVECLEN (newi2pat, 0) - 1; i >= 0; i--)
		if (GET_CODE (XVECEXP (newi2pat, 0, i)) == CLOBBER)
		  {
		    rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0);
		    if (reg_overlap_mentioned_p (reg, newpat))
		      {
			undo_all ();
			return 0;
		      }
		  }
	    }

	  insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);

	  if (insn_code_number >= 0)
	    split_i2i3 = 1;
	}
    }

  /* If it still isn't recognized, fail and change things back the way they
     were.  */
  if ((insn_code_number < 0
       /* Is the result a reasonable ASM_OPERANDS?  */
       && (! check_asm_operands (newpat) || added_sets_1 || added_sets_2)))
    {
      undo_all ();
      return 0;
    }

  /* If we had to change another insn, make sure it is valid also.  */
  if (undobuf.other_insn)
    {
      CLEAR_HARD_REG_SET (newpat_used_regs);

      other_pat = PATTERN (undobuf.other_insn);
      other_code_number = recog_for_combine (&other_pat, undobuf.other_insn,
					     &new_other_notes);

      if (other_code_number < 0 && ! check_asm_operands (other_pat))
	{
	  undo_all ();
	  return 0;
	}
    }

  /* If I2 is the CC0 setter and I3 is the CC0 user then check whether
     they are adjacent to each other or not.  */
  if (HAVE_cc0)
    {
      rtx_insn *p = prev_nonnote_insn (i3);
      if (p && p != i2 && NONJUMP_INSN_P (p) && newi2pat
	  && sets_cc0_p (newi2pat))
	{
	  undo_all ();
	  return 0;
	}
    }

  /* Only allow this combination if insn_cost reports that the
     replacement instructions are cheaper than the originals.  */
  if (!combine_validate_cost (i0, i1, i2, i3, newpat, newi2pat, other_pat))
    {
      undo_all ();
      return 0;
    }

  if (MAY_HAVE_DEBUG_BIND_INSNS)
    {
      struct undo *undo;

      for (undo = undobuf.undos; undo; undo = undo->next)
	if (undo->kind == UNDO_MODE)
	  {
	    rtx reg = regno_reg_rtx[undo->where.regno];
	    machine_mode new_mode = GET_MODE (reg);
	    machine_mode old_mode = undo->old_contents.m;

	    /* Temporarily revert mode back.  */
	    adjust_reg_mode (reg, old_mode);

	    if (reg == i2dest && i2scratch)
	      {
		/* If we used i2dest as a scratch register with a
		   different mode, substitute it for the original
		   i2src while its original mode is temporarily
		   restored, and then clear i2scratch so that we don't
		   do it again later.  */
		propagate_for_debug (i2, last_combined_insn, reg, i2src,
				     this_basic_block);
		i2scratch = false;
		/* Put back the new mode.  */
		adjust_reg_mode (reg, new_mode);
	      }
	    else
	      {
		rtx tempreg = gen_raw_REG (old_mode, REGNO (reg));
		rtx_insn *first, *last;

		if (reg == i2dest)
		  {
		    first = i2;
		    last = last_combined_insn;
		  }
		else
		  {
		    first = i3;
		    last = undobuf.other_insn;
		    gcc_assert (last);
		    if (DF_INSN_LUID (last)
			< DF_INSN_LUID (last_combined_insn))
		      last = last_combined_insn;
		  }

		/* We're dealing with a reg that changed mode but not
		   meaning, so we want to turn it into a subreg for
		   the new mode.  However, because of REG sharing and
		   because its mode had already changed, we have to do
		   it in two steps.  First, replace any debug uses of
		   reg, with its original mode temporarily restored,
		   with this copy we have created; then, replace the
		   copy with the SUBREG of the original shared reg,
		   once again changed to the new mode.  */
		propagate_for_debug (first, last, reg, tempreg,
				     this_basic_block);
		adjust_reg_mode (reg, new_mode);
		propagate_for_debug (first, last, tempreg,
				     lowpart_subreg (old_mode, reg, new_mode),
				     this_basic_block);
	      }
	  }
    }

  /* If we will be able to accept this, we have made a
     change to the destination of I3.  This requires us to
     do a few adjustments.  */

  if (changed_i3_dest)
    {
      PATTERN (i3) = newpat;
      adjust_for_new_dest (i3);
    }

  /* We now know that we can do this combination.  Merge the insns and
     update the status of registers and LOG_LINKS.  */

  if (undobuf.other_insn)
    {
      rtx note, next;

      PATTERN (undobuf.other_insn) = other_pat;

      /* If any of the notes in OTHER_INSN were REG_DEAD or REG_UNUSED,
	 ensure that they are still valid.  Then add any non-duplicate
	 notes added by recog_for_combine.  */
      for (note = REG_NOTES (undobuf.other_insn); note; note = next)
	{
	  next = XEXP (note, 1);

	  if ((REG_NOTE_KIND (note) == REG_DEAD
	       && !reg_referenced_p (XEXP (note, 0),
				     PATTERN (undobuf.other_insn)))
	      ||(REG_NOTE_KIND (note) == REG_UNUSED
		 && !reg_set_p (XEXP (note, 0),
				PATTERN (undobuf.other_insn)))
	      /* Simply drop equal note since it may be no longer valid
		 for other_insn.  It may be possible to record that CC
		 register is changed and only discard those notes, but
		 in practice it's unnecessary complication and doesn't
		 give any meaningful improvement.

		 See PR78559.  */
	      || REG_NOTE_KIND (note) == REG_EQUAL
	      || REG_NOTE_KIND (note) == REG_EQUIV)
	    remove_note (undobuf.other_insn, note);
	}

      distribute_notes  (new_other_notes, undobuf.other_insn,
			undobuf.other_insn, NULL, NULL_RTX, NULL_RTX,
			NULL_RTX);
    }

  if (swap_i2i3)
    {
      /* I3 now uses what used to be its destination and which is now
	 I2's destination.  This requires us to do a few adjustments.  */
      PATTERN (i3) = newpat;
      adjust_for_new_dest (i3);
    }

  if (swap_i2i3 || split_i2i3)
    {
      /* We might need a LOG_LINK from I3 to I2.  But then we used to
	 have one, so we still will.

	 However, some later insn might be using I2's dest and have
	 a LOG_LINK pointing at I3.  We should change it to point at
	 I2 instead.  */

      /* newi2pat is usually a SET here; however, recog_for_combine might
	 have added some clobbers.  */
      rtx x = newi2pat;
      if (GET_CODE (x) == PARALLEL)
	x = XVECEXP (newi2pat, 0, 0);

      /* It can only be a SET of a REG or of a SUBREG of a REG.  */
      unsigned int regno = reg_or_subregno (SET_DEST (x));

      bool done = false;
      for (rtx_insn *insn = NEXT_INSN (i3);
	   !done
	   && insn
	   && NONDEBUG_INSN_P (insn)
	   && BLOCK_FOR_INSN (insn) == this_basic_block;
	   insn = NEXT_INSN (insn))
	{
	  struct insn_link *link;
	  FOR_EACH_LOG_LINK (link, insn)
	    if (link->insn == i3 && link->regno == regno)
	      {
		link->insn = i2;
		done = true;
		break;
	      }
	}
    }

  {
    rtx i3notes, i2notes, i1notes = 0, i0notes = 0;
    struct insn_link *i3links, *i2links, *i1links = 0, *i0links = 0;
    rtx midnotes = 0;
    int from_luid;
    /* Compute which registers we expect to eliminate.  newi2pat may be setting
       either i3dest or i2dest, so we must check it.  */
    rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
		   || i2dest_in_i2src || i2dest_in_i1src || i2dest_in_i0src
		   || !i2dest_killed
		   ? 0 : i2dest);
    /* For i1, we need to compute both local elimination and global
       elimination information with respect to newi2pat because i1dest
       may be the same as i3dest, in which case newi2pat may be setting
       i1dest.  Global information is used when distributing REG_DEAD
       note for i2 and i3, in which case it does matter if newi2pat sets
       i1dest or not.

       Local information is used when distributing REG_DEAD note for i1,
       in which case it doesn't matter if newi2pat sets i1dest or not.
       See PR62151, if we have four insns combination:
	   i0: r0 <- i0src
	   i1: r1 <- i1src (using r0)
		     REG_DEAD (r0)
	   i2: r0 <- i2src (using r1)
	   i3: r3 <- i3src (using r0)
	   ix: using r0
       From i1's point of view, r0 is eliminated, no matter if it is set
       by newi2pat or not.  In other words, REG_DEAD info for r0 in i1
       should be discarded.

       Note local information only affects cases in forms like "I1->I2->I3",
       "I0->I1->I2->I3" or "I0&I1->I2, I2->I3".  For other cases like
       "I0->I1, I1&I2->I3" or "I1&I2->I3", newi2pat won't set i1dest or
       i0dest anyway.  */
    rtx local_elim_i1 = (i1 == 0 || i1dest_in_i1src || i1dest_in_i0src
			 || !i1dest_killed
			 ? 0 : i1dest);
    rtx elim_i1 = (local_elim_i1 == 0
		   || (newi2pat && reg_set_p (i1dest, newi2pat))
		   ? 0 : i1dest);
    /* Same case as i1.  */
    rtx local_elim_i0 = (i0 == 0 || i0dest_in_i0src || !i0dest_killed
			 ? 0 : i0dest);
    rtx elim_i0 = (local_elim_i0 == 0
		   || (newi2pat && reg_set_p (i0dest, newi2pat))
		   ? 0 : i0dest);

    /* Get the old REG_NOTES and LOG_LINKS from all our insns and
       clear them.  */
    i3notes = REG_NOTES (i3), i3links = LOG_LINKS (i3);
    i2notes = REG_NOTES (i2), i2links = LOG_LINKS (i2);
    if (i1)
      i1notes = REG_NOTES (i1), i1links = LOG_LINKS (i1);
    if (i0)
      i0notes = REG_NOTES (i0), i0links = LOG_LINKS (i0);

    /* Ensure that we do not have something that should not be shared but
       occurs multiple times in the new insns.  Check this by first
       resetting all the `used' flags and then copying anything is shared.  */

    reset_used_flags (i3notes);
    reset_used_flags (i2notes);
    reset_used_flags (i1notes);
    reset_used_flags (i0notes);
    reset_used_flags (newpat);
    reset_used_flags (newi2pat);
    if (undobuf.other_insn)
      reset_used_flags (PATTERN (undobuf.other_insn));

    i3notes = copy_rtx_if_shared (i3notes);
    i2notes = copy_rtx_if_shared (i2notes);
    i1notes = copy_rtx_if_shared (i1notes);
    i0notes = copy_rtx_if_shared (i0notes);
    newpat = copy_rtx_if_shared (newpat);
    newi2pat = copy_rtx_if_shared (newi2pat);
    if (undobuf.other_insn)
      reset_used_flags (PATTERN (undobuf.other_insn));

    INSN_CODE (i3) = insn_code_number;
    PATTERN (i3) = newpat;

    if (CALL_P (i3) && CALL_INSN_FUNCTION_USAGE (i3))
      {
	for (rtx link = CALL_INSN_FUNCTION_USAGE (i3); link;
	     link = XEXP (link, 1))
	  {
	    if (substed_i2)
	      {
		/* I2SRC must still be meaningful at this point.  Some
		   splitting operations can invalidate I2SRC, but those
		   operations do not apply to calls.  */
		gcc_assert (i2src);
		XEXP (link, 0) = simplify_replace_rtx (XEXP (link, 0),
						       i2dest, i2src);
	      }
	    if (substed_i1)
	      XEXP (link, 0) = simplify_replace_rtx (XEXP (link, 0),
						     i1dest, i1src);
	    if (substed_i0)
	      XEXP (link, 0) = simplify_replace_rtx (XEXP (link, 0),
						     i0dest, i0src);
	  }
      }

    if (undobuf.other_insn)
      INSN_CODE (undobuf.other_insn) = other_code_number;

    /* We had one special case above where I2 had more than one set and
       we replaced a destination of one of those sets with the destination
       of I3.  In that case, we have to update LOG_LINKS of insns later
       in this basic block.  Note that this (expensive) case is rare.

       Also, in this case, we must pretend that all REG_NOTEs for I2
       actually came from I3, so that REG_UNUSED notes from I2 will be
       properly handled.  */

    if (i3_subst_into_i2)
      {
	for (i = 0; i < XVECLEN (PATTERN (i2), 0); i++)
	  if ((GET_CODE (XVECEXP (PATTERN (i2), 0, i)) == SET
	       || GET_CODE (XVECEXP (PATTERN (i2), 0, i)) == CLOBBER)
	      && REG_P (SET_DEST (XVECEXP (PATTERN (i2), 0, i)))
	      && SET_DEST (XVECEXP (PATTERN (i2), 0, i)) != i2dest
	      && ! find_reg_note (i2, REG_UNUSED,
				  SET_DEST (XVECEXP (PATTERN (i2), 0, i))))
	    for (temp_insn = NEXT_INSN (i2);
		 temp_insn
		 && (this_basic_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
		     || BB_HEAD (this_basic_block) != temp_insn);
		 temp_insn = NEXT_INSN (temp_insn))
	      if (temp_insn != i3 && NONDEBUG_INSN_P (temp_insn))
		FOR_EACH_LOG_LINK (link, temp_insn)
		  if (link->insn == i2)
		    link->insn = i3;

	if (i3notes)
	  {
	    rtx link = i3notes;
	    while (XEXP (link, 1))
	      link = XEXP (link, 1);
	    XEXP (link, 1) = i2notes;
	  }
	else
	  i3notes = i2notes;
	i2notes = 0;
      }

    LOG_LINKS (i3) = NULL;
    REG_NOTES (i3) = 0;
    LOG_LINKS (i2) = NULL;
    REG_NOTES (i2) = 0;

    if (newi2pat)
      {
	if (MAY_HAVE_DEBUG_BIND_INSNS && i2scratch)
	  propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
			       this_basic_block);
	INSN_CODE (i2) = i2_code_number;
	PATTERN (i2) = newi2pat;
      }
    else
      {
	if (MAY_HAVE_DEBUG_BIND_INSNS && i2src)
	  propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
			       this_basic_block);
	SET_INSN_DELETED (i2);
      }

    if (i1)
      {
	LOG_LINKS (i1) = NULL;
	REG_NOTES (i1) = 0;
	if (MAY_HAVE_DEBUG_BIND_INSNS)
	  propagate_for_debug (i1, last_combined_insn, i1dest, i1src,
			       this_basic_block);
	SET_INSN_DELETED (i1);
      }

    if (i0)
      {
	LOG_LINKS (i0) = NULL;
	REG_NOTES (i0) = 0;
	if (MAY_HAVE_DEBUG_BIND_INSNS)
	  propagate_for_debug (i0, last_combined_insn, i0dest, i0src,
			       this_basic_block);
	SET_INSN_DELETED (i0);
      }

    /* Get death notes for everything that is now used in either I3 or
       I2 and used to die in a previous insn.  If we built two new
       patterns, move from I1 to I2 then I2 to I3 so that we get the
       proper movement on registers that I2 modifies.  */

    if (i0)
      from_luid = DF_INSN_LUID (i0);
    else if (i1)
      from_luid = DF_INSN_LUID (i1);
    else
      from_luid = DF_INSN_LUID (i2);
    if (newi2pat)
      move_deaths (newi2pat, NULL_RTX, from_luid, i2, &midnotes);
    move_deaths (newpat, newi2pat, from_luid, i3, &midnotes);

    /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3.  */
    if (i3notes)
      distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL,
			elim_i2, elim_i1, elim_i0);
    if (i2notes)
      distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL,
			elim_i2, elim_i1, elim_i0);
    if (i1notes)
      distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL,
			elim_i2, local_elim_i1, local_elim_i0);
    if (i0notes)
      distribute_notes (i0notes, i0, i3, newi2pat ? i2 : NULL,
			elim_i2, elim_i1, local_elim_i0);
    if (midnotes)
      distribute_notes (midnotes, NULL, i3, newi2pat ? i2 : NULL,
			elim_i2, elim_i1, elim_i0);

    /* Distribute any notes added to I2 or I3 by recog_for_combine.  We
       know these are REG_UNUSED and want them to go to the desired insn,
       so we always pass it as i3.  */

    if (newi2pat && new_i2_notes)
      distribute_notes (new_i2_notes, i2, i2, NULL, NULL_RTX, NULL_RTX,
			NULL_RTX);

    if (new_i3_notes)
      distribute_notes (new_i3_notes, i3, i3, NULL, NULL_RTX, NULL_RTX,
			NULL_RTX);

    /* If I3DEST was used in I3SRC, it really died in I3.  We may need to
       put a REG_DEAD note for it somewhere.  If NEWI2PAT exists and sets
       I3DEST, the death must be somewhere before I2, not I3.  If we passed I3
       in that case, it might delete I2.  Similarly for I2 and I1.
       Show an additional death due to the REG_DEAD note we make here.  If
       we discard it in distribute_notes, we will decrement it again.  */

    if (i3dest_killed)
      {
	rtx new_note = alloc_reg_note (REG_DEAD, i3dest_killed, NULL_RTX);
	if (newi2pat && reg_set_p (i3dest_killed, newi2pat))
	  distribute_notes (new_note, NULL, i2, NULL, elim_i2,
			    elim_i1, elim_i0);
	else
	  distribute_notes (new_note, NULL, i3, newi2pat ? i2 : NULL,
			    elim_i2, elim_i1, elim_i0);
      }

    if (i2dest_in_i2src)
      {
	rtx new_note = alloc_reg_note (REG_DEAD, i2dest, NULL_RTX);
	if (newi2pat && reg_set_p (i2dest, newi2pat))
	  distribute_notes (new_note,  NULL, i2, NULL, NULL_RTX,
			    NULL_RTX, NULL_RTX);
	else
	  distribute_notes (new_note, NULL, i3, newi2pat ? i2 : NULL,
			    NULL_RTX, NULL_RTX, NULL_RTX);
      }

    if (i1dest_in_i1src)
      {
	rtx new_note = alloc_reg_note (REG_DEAD, i1dest, NULL_RTX);
	if (newi2pat && reg_set_p (i1dest, newi2pat))
	  distribute_notes (new_note, NULL, i2, NULL, NULL_RTX,
			    NULL_RTX, NULL_RTX);
	else
	  distribute_notes (new_note, NULL, i3, newi2pat ? i2 : NULL,
			    NULL_RTX, NULL_RTX, NULL_RTX);
      }

    if (i0dest_in_i0src)
      {
	rtx new_note = alloc_reg_note (REG_DEAD, i0dest, NULL_RTX);
	if (newi2pat && reg_set_p (i0dest, newi2pat))
	  distribute_notes (new_note, NULL, i2, NULL, NULL_RTX,
			    NULL_RTX, NULL_RTX);
	else
	  distribute_notes (new_note, NULL, i3, newi2pat ? i2 : NULL,
			    NULL_RTX, NULL_RTX, NULL_RTX);
      }

    distribute_links (i3links);
    distribute_links (i2links);
    distribute_links (i1links);
    distribute_links (i0links);

    if (REG_P (i2dest))
      {
	struct insn_link *link;
	rtx_insn *i2_insn = 0;
	rtx i2_val = 0, set;

	/* The insn that used to set this register doesn't exist, and
	   this life of the register may not exist either.  See if one of
	   I3's links points to an insn that sets I2DEST.  If it does,
	   that is now the last known value for I2DEST. If we don't update
	   this and I2 set the register to a value that depended on its old
	   contents, we will get confused.  If this insn is used, thing
	   will be set correctly in combine_instructions.  */
	FOR_EACH_LOG_LINK (link, i3)
	  if ((set = single_set (link->insn)) != 0
	      && rtx_equal_p (i2dest, SET_DEST (set)))
	    i2_insn = link->insn, i2_val = SET_SRC (set);

	record_value_for_reg (i2dest, i2_insn, i2_val);

	/* If the reg formerly set in I2 died only once and that was in I3,
	   zero its use count so it won't make `reload' do any work.  */
	if (! added_sets_2
	    && (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat))
	    && ! i2dest_in_i2src
	    && REGNO (i2dest) < reg_n_sets_max)
	  INC_REG_N_SETS (REGNO (i2dest), -1);
      }

    if (i1 && REG_P (i1dest))
      {
	struct insn_link *link;
	rtx_insn *i1_insn = 0;
	rtx i1_val = 0, set;

	FOR_EACH_LOG_LINK (link, i3)
	  if ((set = single_set (link->insn)) != 0
	      && rtx_equal_p (i1dest, SET_DEST (set)))
	    i1_insn = link->insn, i1_val = SET_SRC (set);

	record_value_for_reg (i1dest, i1_insn, i1_val);

	if (! added_sets_1
	    && ! i1dest_in_i1src
	    && REGNO (i1dest) < reg_n_sets_max)
	  INC_REG_N_SETS (REGNO (i1dest), -1);
      }

    if (i0 && REG_P (i0dest))
      {
	struct insn_link *link;
	rtx_insn *i0_insn = 0;
	rtx i0_val = 0, set;

	FOR_EACH_LOG_LINK (link, i3)
	  if ((set = single_set (link->insn)) != 0
	      && rtx_equal_p (i0dest, SET_DEST (set)))
	    i0_insn = link->insn, i0_val = SET_SRC (set);

	record_value_for_reg (i0dest, i0_insn, i0_val);

	if (! added_sets_0
	    && ! i0dest_in_i0src
	    && REGNO (i0dest) < reg_n_sets_max)
	  INC_REG_N_SETS (REGNO (i0dest), -1);
      }

    /* Update reg_stat[].nonzero_bits et al for any changes that may have
       been made to this insn.  The order is important, because newi2pat
       can affect nonzero_bits of newpat.  */
    if (newi2pat)
      note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
    note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
  }

  if (undobuf.other_insn != NULL_RTX)
    {
      if (dump_file)
	{
	  fprintf (dump_file, "modifying other_insn ");
	  dump_insn_slim (dump_file, undobuf.other_insn);
	}
      df_insn_rescan (undobuf.other_insn);
    }

  if (i0 && !(NOTE_P (i0) && (NOTE_KIND (i0) == NOTE_INSN_DELETED)))
    {
      if (dump_file)
	{
	  fprintf (dump_file, "modifying insn i0 ");
	  dump_insn_slim (dump_file, i0);
	}
      df_insn_rescan (i0);
    }

  if (i1 && !(NOTE_P (i1) && (NOTE_KIND (i1) == NOTE_INSN_DELETED)))
    {
      if (dump_file)
	{
	  fprintf (dump_file, "modifying insn i1 ");
	  dump_insn_slim (dump_file, i1);
	}
      df_insn_rescan (i1);
    }

  if (i2 && !(NOTE_P (i2) && (NOTE_KIND (i2) == NOTE_INSN_DELETED)))
    {
      if (dump_file)
	{
	  fprintf (dump_file, "modifying insn i2 ");
	  dump_insn_slim (dump_file, i2);
	}
      df_insn_rescan (i2);
    }

  if (i3 && !(NOTE_P (i3) && (NOTE_KIND (i3) == NOTE_INSN_DELETED)))
    {
      if (dump_file)
	{
	  fprintf (dump_file, "modifying insn i3 ");
	  dump_insn_slim (dump_file, i3);
	}
      df_insn_rescan (i3);
    }

  /* Set new_direct_jump_p if a new return or simple jump instruction
     has been created.  Adjust the CFG accordingly.  */
  if (returnjump_p (i3) || any_uncondjump_p (i3))
    {
      *new_direct_jump_p = 1;
      mark_jump_label (PATTERN (i3), i3, 0);
      update_cfg_for_uncondjump (i3);
    }

  if (undobuf.other_insn != NULL_RTX
      && (returnjump_p (undobuf.other_insn)
	  || any_uncondjump_p (undobuf.other_insn)))
    {
      *new_direct_jump_p = 1;
      update_cfg_for_uncondjump (undobuf.other_insn);
    }

  if (GET_CODE (PATTERN (i3)) == TRAP_IF
      && XEXP (PATTERN (i3), 0) == const1_rtx)
    {
      basic_block bb = BLOCK_FOR_INSN (i3);
      gcc_assert (bb);
      remove_edge (split_block (bb, i3));
      emit_barrier_after_bb (bb);
      *new_direct_jump_p = 1;
    }

  if (undobuf.other_insn
      && GET_CODE (PATTERN (undobuf.other_insn)) == TRAP_IF
      && XEXP (PATTERN (undobuf.other_insn), 0) == const1_rtx)
    {
      basic_block bb = BLOCK_FOR_INSN (undobuf.other_insn);
      gcc_assert (bb);
      remove_edge (split_block (bb, undobuf.other_insn));
      emit_barrier_after_bb (bb);
      *new_direct_jump_p = 1;
    }

  /* A noop might also need cleaning up of CFG, if it comes from the
     simplification of a jump.  */
  if (JUMP_P (i3)
      && GET_CODE (newpat) == SET
      && SET_SRC (newpat) == pc_rtx
      && SET_DEST (newpat) == pc_rtx)
    {
      *new_direct_jump_p = 1;
      update_cfg_for_uncondjump (i3);
    }

  if (undobuf.other_insn != NULL_RTX
      && JUMP_P (undobuf.other_insn)
      && GET_CODE (PATTERN (undobuf.other_insn)) == SET
      && SET_SRC (PATTERN (undobuf.other_insn)) == pc_rtx
      && SET_DEST (PATTERN (undobuf.other_insn)) == pc_rtx)
    {
      *new_direct_jump_p = 1;
      update_cfg_for_uncondjump (undobuf.other_insn);
    }

  combine_successes++;
  undo_commit ();

  rtx_insn *ret = newi2pat ? i2 : i3;
  if (added_links_insn && DF_INSN_LUID (added_links_insn) < DF_INSN_LUID (ret))
    ret = added_links_insn;
  if (added_notes_insn && DF_INSN_LUID (added_notes_insn) < DF_INSN_LUID (ret))
    ret = added_notes_insn;

  return ret;
}

/* Get a marker for undoing to the current state.  */

static void *
get_undo_marker (void)
{
  return undobuf.undos;
}

/* Undo the modifications up to the marker.  */

static void
undo_to_marker (void *marker)
{
  struct undo *undo, *next;

  for (undo = undobuf.undos; undo != marker; undo = next)
    {
      gcc_assert (undo);

      next = undo->next;
      switch (undo->kind)
	{
	case UNDO_RTX:
	  *undo->where.r = undo->old_contents.r;
	  break;
	case UNDO_INT:
	  *undo->where.i = undo->old_contents.i;
	  break;
	case UNDO_MODE:
	  adjust_reg_mode (regno_reg_rtx[undo->where.regno],
			   undo->old_contents.m);
	  break;
	case UNDO_LINKS:
	  *undo->where.l = undo->old_contents.l;
	  break;
	default:
	  gcc_unreachable ();
	}

      undo->next = undobuf.frees;
      undobuf.frees = undo;
    }

  undobuf.undos = (struct undo *) marker;
}

/* Undo all the modifications recorded in undobuf.  */

static void
undo_all (void)
{
  undo_to_marker (0);
}

/* We've committed to accepting the changes we made.  Move all
   of the undos to the free list.  */

static void
undo_commit (void)
{
  struct undo *undo, *next;

  for (undo = undobuf.undos; undo; undo = next)
    {
      next = undo->next;
      undo->next = undobuf.frees;
      undobuf.frees = undo;
    }
  undobuf.undos = 0;
}

/* Find the innermost point within the rtx at LOC, possibly LOC itself,
   where we have an arithmetic expression and return that point.  LOC will
   be inside INSN.

   try_combine will call this function to see if an insn can be split into
   two insns.  */

static rtx *
find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
{
  rtx x = *loc;
  enum rtx_code code = GET_CODE (x);
  rtx *split;
  unsigned HOST_WIDE_INT len = 0;
  HOST_WIDE_INT pos = 0;
  int unsignedp = 0;
  rtx inner = NULL_RTX;
  scalar_int_mode mode, inner_mode;

  /* First special-case some codes.  */
  switch (code)
    {
    case SUBREG:
#ifdef INSN_SCHEDULING
      /* If we are making a paradoxical SUBREG invalid, it becomes a split
	 point.  */
      if (MEM_P (SUBREG_REG (x)))
	return loc;
#endif
      return find_split_point (&SUBREG_REG (x), insn, false);

    case MEM:
      /* If we have (mem (const ..)) or (mem (symbol_ref ...)), split it
	 using LO_SUM and HIGH.  */
      if (HAVE_lo_sum && (GET_CODE (XEXP (x, 0)) == CONST
			  || GET_CODE (XEXP (x, 0)) == SYMBOL_REF))
	{
	  machine_mode address_mode = get_address_mode (x);

	  SUBST (XEXP (x, 0),
		 gen_rtx_LO_SUM (address_mode,
				 gen_rtx_HIGH (address_mode, XEXP (x, 0)),
				 XEXP (x, 0)));
	  return &XEXP (XEXP (x, 0), 0);
	}

      /* If we have a PLUS whose second operand is a constant and the
	 address is not valid, perhaps we can split it up using
	 the machine-specific way to split large constants.  We use
	 the first pseudo-reg (one of the virtual regs) as a placeholder;
	 it will not remain in the result.  */
      if (GET_CODE (XEXP (x, 0)) == PLUS
	  && CONST_INT_P (XEXP (XEXP (x, 0), 1))
	  && ! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
					    MEM_ADDR_SPACE (x)))
	{
	  rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
	  rtx_insn *seq = combine_split_insns (gen_rtx_SET (reg, XEXP (x, 0)),
					       subst_insn);

	  /* This should have produced two insns, each of which sets our
	     placeholder.  If the source of the second is a valid address,
	     we can put both sources together and make a split point
	     in the middle.  */

	  if (seq
	      && NEXT_INSN (seq) != NULL_RTX
	      && NEXT_INSN (NEXT_INSN (seq)) == NULL_RTX
	      && NONJUMP_INSN_P (seq)
	      && GET_CODE (PATTERN (seq)) == SET
	      && SET_DEST (PATTERN (seq)) == reg
	      && ! reg_mentioned_p (reg,
				    SET_SRC (PATTERN (seq)))
	      && NONJUMP_INSN_P (NEXT_INSN (seq))
	      && GET_CODE (PATTERN (NEXT_INSN (seq))) == SET
	      && SET_DEST (PATTERN (NEXT_INSN (seq))) == reg
	      && memory_address_addr_space_p
		   (GET_MODE (x), SET_SRC (PATTERN (NEXT_INSN (seq))),
		    MEM_ADDR_SPACE (x)))
	    {
	      rtx src1 = SET_SRC (PATTERN (seq));
	      rtx src2 = SET_SRC (PATTERN (NEXT_INSN (seq)));

	      /* Replace the placeholder in SRC2 with SRC1.  If we can
		 find where in SRC2 it was placed, that can become our
		 split point and we can replace this address with SRC2.
		 Just try two obvious places.  */

	      src2 = replace_rtx (src2, reg, src1);
	      split = 0;
	      if (XEXP (src2, 0) == src1)
		split = &XEXP (src2, 0);
	      else if (GET_RTX_FORMAT (GET_CODE (XEXP (src2, 0)))[0] == 'e'
		       && XEXP (XEXP (src2, 0), 0) == src1)
		split = &XEXP (XEXP (src2, 0), 0);

	      if (split)
		{
		  SUBST (XEXP (x, 0), src2);
		  return split;
		}
	    }

	  /* If that didn't work and we have a nested plus, like:
	     ((REG1 * CONST1) + REG2) + CONST2 and (REG1 + REG2) + CONST2
	     is valid address, try to split (REG1 * CONST1).  */
	  if (GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
	      && !OBJECT_P (XEXP (XEXP (XEXP (x, 0), 0), 0))
	      && OBJECT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
	      && ! (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SUBREG
		    && OBJECT_P (SUBREG_REG (XEXP (XEXP (XEXP (x, 0),
							 0), 0)))))
	    {
	      rtx tem = XEXP (XEXP (XEXP (x, 0), 0), 0);
	      XEXP (XEXP (XEXP (x, 0), 0), 0) = reg;
	      if (memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
					       MEM_ADDR_SPACE (x)))
		{
		  XEXP (XEXP (XEXP (x, 0), 0), 0) = tem;
		  return &XEXP (XEXP (XEXP (x, 0), 0), 0);
		}
	      XEXP (XEXP (XEXP (x, 0), 0), 0) = tem;
	    }
	  else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
		   && OBJECT_P (XEXP (XEXP (XEXP (x, 0), 0), 0))
		   && !OBJECT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
		   && ! (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == SUBREG
			 && OBJECT_P (SUBREG_REG (XEXP (XEXP (XEXP (x, 0),
							      0), 1)))))
	    {
	      rtx tem = XEXP (XEXP (XEXP (x, 0), 0), 1);
	      XEXP (XEXP (XEXP (x, 0), 0), 1) = reg;
	      if (memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
					       MEM_ADDR_SPACE (x)))
		{
		  XEXP (XEXP (XEXP (x, 0), 0), 1) = tem;
		  return &XEXP (XEXP (XEXP (x, 0), 0), 1);
		}
	      XEXP (XEXP (XEXP (x, 0), 0), 1) = tem;
	    }

	  /* If that didn't work, perhaps the first operand is complex and
	     needs to be computed separately, so make a split point there.
	     This will occur on machines that just support REG + CONST
	     and have a constant moved through some previous computation.  */
	  if (!OBJECT_P (XEXP (XEXP (x, 0), 0))
	      && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG
		    && OBJECT_P (SUBREG_REG (XEXP (XEXP (x, 0), 0)))))
	    return &XEXP (XEXP (x, 0), 0);
	}

      /* If we have a PLUS whose first operand is complex, try computing it
         separately by making a split there.  */
      if (GET_CODE (XEXP (x, 0)) == PLUS
          && ! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
					    MEM_ADDR_SPACE (x))
          && ! OBJECT_P (XEXP (XEXP (x, 0), 0))
          && ! (GET_CODE (XEXP (XEXP (x, 0), 0)) == SUBREG
                && OBJECT_P (SUBREG_REG (XEXP (XEXP (x, 0), 0)))))
        return &XEXP (XEXP (x, 0), 0);
      break;

    case SET:
      /* If SET_DEST is CC0 and SET_SRC is not an operand, a COMPARE, or a
	 ZERO_EXTRACT, the most likely reason why this doesn't match is that
	 we need to put the operand into a register.  So split at that
	 point.  */

      if (SET_DEST (x) == cc0_rtx
	  && GET_CODE (SET_SRC (x)) != COMPARE
	  && GET_CODE (SET_SRC (x)) != ZERO_EXTRACT
	  && !OBJECT_P (SET_SRC (x))
	  && ! (GET_CODE (SET_SRC (x)) == SUBREG
		&& OBJECT_P (SUBREG_REG (SET_SRC (x)))))
	return &SET_SRC (x);

      /* See if we can split SET_SRC as it stands.  */
      split = find_split_point (&SET_SRC (x), insn, true);
      if (split && split != &SET_SRC (x))
	return split;

      /* See if we can split SET_DEST as it stands.  */
      split = find_split_point (&SET_DEST (x), insn, false);
      if (split && split != &SET_DEST (x))
	return split;

      /* See if this is a bitfield assignment with everything constant.  If
	 so, this is an IOR of an AND, so split it into that.  */
      if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
	  && is_a <scalar_int_mode> (GET_MODE (XEXP (SET_DEST (x), 0)),
				     &inner_mode)
	  && HWI_COMPUTABLE_MODE_P (inner_mode)
	  && CONST_INT_P (XEXP (SET_DEST (x), 1))
	  && CONST_INT_P (XEXP (SET_DEST (x), 2))
	  && CONST_INT_P (SET_SRC (x))
	  && ((INTVAL (XEXP (SET_DEST (x), 1))
	       + INTVAL (XEXP (SET_DEST (x), 2)))
	      <= GET_MODE_PRECISION (inner_mode))
	  && ! side_effects_p (XEXP (SET_DEST (x), 0)))
	{
	  HOST_WIDE_INT pos = INTVAL (XEXP (SET_DEST (x), 2));
	  unsigned HOST_WIDE_INT len = INTVAL (XEXP (SET_DEST (x), 1));
	  rtx dest = XEXP (SET_DEST (x), 0);
	  unsigned HOST_WIDE_INT mask = (HOST_WIDE_INT_1U << len) - 1;
	  unsigned HOST_WIDE_INT src = INTVAL (SET_SRC (x)) & mask;
	  rtx or_mask;

	  if (BITS_BIG_ENDIAN)
	    pos = GET_MODE_PRECISION (inner_mode) - len - pos;

	  or_mask = gen_int_mode (src << pos, inner_mode);
	  if (src == mask)
	    SUBST (SET_SRC (x),
		   simplify_gen_binary (IOR, inner_mode, dest, or_mask));
	  else
	    {
	      rtx negmask = gen_int_mode (~(mask << pos), inner_mode);
	      SUBST (SET_SRC (x),
		     simplify_gen_binary (IOR, inner_mode,
					  simplify_gen_binary (AND, inner_mode,
							       dest, negmask),
					  or_mask));
	    }

	  SUBST (SET_DEST (x), dest);

	  split = find_split_point (&SET_SRC (x), insn, true);
	  if (split && split != &SET_SRC (x))
	    return split;
	}

      /* Otherwise, see if this is an operation that we can split into two.
	 If so, try to split that.  */
      code = GET_CODE (SET_SRC (x));

      switch (code)
	{
	case AND:
	  /* If we are AND'ing with a large constant that is only a single
	     bit and the result is only being used in a context where we
	     need to know if it is zero or nonzero, replace it with a bit
	     extraction.  This will avoid the large constant, which might
	     have taken more than one insn to make.  If the constant were
	     not a valid argument to the AND but took only one insn to make,
	     this is no worse, but if it took more than one insn, it will
	     be better.  */

	  if (CONST_INT_P (XEXP (SET_SRC (x), 1))
	      && REG_P (XEXP (SET_SRC (x), 0))
	      && (pos = exact_log2 (UINTVAL (XEXP (SET_SRC (x), 1)))) >= 7
	      && REG_P (SET_DEST (x))
	      && (split = find_single_use (SET_DEST (x), insn, NULL)) != 0
	      && (GET_CODE (*split) == EQ || GET_CODE (*split) == NE)
	      && XEXP (*split, 0) == SET_DEST (x)
	      && XEXP (*split, 1) == const0_rtx)
	    {
	      rtx extraction = make_extraction (GET_MODE (SET_DEST (x)),
						XEXP (SET_SRC (x), 0),
						pos, NULL_RTX, 1, 1, 0, 0);
	      if (extraction != 0)
		{
		  SUBST (SET_SRC (x), extraction);
		  return find_split_point (loc, insn, false);
		}
	    }
	  break;

	case NE:
	  /* If STORE_FLAG_VALUE is -1, this is (NE X 0) and only one bit of X
	     is known to be on, this can be converted into a NEG of a shift.  */
	  if (STORE_FLAG_VALUE == -1 && XEXP (SET_SRC (x), 1) == const0_rtx
	      && GET_MODE (SET_SRC (x)) == GET_MODE (XEXP (SET_SRC (x), 0))
	      && ((pos = exact_log2 (nonzero_bits (XEXP (SET_SRC (x), 0),
						   GET_MODE (XEXP (SET_SRC (x),
							     0))))) >= 1))
	    {
	      machine_mode mode = GET_MODE (XEXP (SET_SRC (x), 0));
	      rtx pos_rtx = gen_int_shift_amount (mode, pos);
	      SUBST (SET_SRC (x),
		     gen_rtx_NEG (mode,
				  gen_rtx_LSHIFTRT (mode,
						    XEXP (SET_SRC (x), 0),
						    pos_rtx)));

	      split = find_split_point (&SET_SRC (x), insn, true);
	      if (split && split != &SET_SRC (x))
		return split;
	    }
	  break;

	case SIGN_EXTEND:
	  inner = XEXP (SET_SRC (x), 0);

	  /* We can't optimize if either mode is a partial integer
	     mode as we don't know how many bits are significant
	     in those modes.  */
	  if (!is_int_mode (GET_MODE (inner), &inner_mode)
	      || GET_MODE_CLASS (GET_MODE (SET_SRC (x))) == MODE_PARTIAL_INT)
	    break;

	  pos = 0;
	  len = GET_MODE_PRECISION (inner_mode);
	  unsignedp = 0;
	  break;

	case SIGN_EXTRACT:
	case ZERO_EXTRACT:
	  if (is_a <scalar_int_mode> (GET_MODE (XEXP (SET_SRC (x), 0)),
				      &inner_mode)
	      && CONST_INT_P (XEXP (SET_SRC (x), 1))
	      && CONST_INT_P (XEXP (SET_SRC (x), 2)))
	    {
	      inner = XEXP (SET_SRC (x), 0);
	      len = INTVAL (XEXP (SET_SRC (x), 1));
	      pos = INTVAL (XEXP (SET_SRC (x), 2));

	      if (BITS_BIG_ENDIAN)
		pos = GET_MODE_PRECISION (inner_mode) - len - pos;
	      unsignedp = (code == ZERO_EXTRACT);
	    }
	  break;

	default:
	  break;
	}

      if (len
	  && known_subrange_p (pos, len,
			       0, GET_MODE_PRECISION (GET_MODE (inner)))
	  && is_a <scalar_int_mode> (GET_MODE (SET_SRC (x)), &mode))
	{
	  /* For unsigned, we have a choice of a shift followed by an
	     AND or two shifts.  Use two shifts for field sizes where the
	     constant might be too large.  We assume here that we can
	     always at least get 8-bit constants in an AND insn, which is
	     true for every current RISC.  */

	  if (unsignedp && len <= 8)
	    {
	      unsigned HOST_WIDE_INT mask
		= (HOST_WIDE_INT_1U << len) - 1;
	      rtx pos_rtx = gen_int_shift_amount (mode, pos);
	      SUBST (SET_SRC (x),
		     gen_rtx_AND (mode,
				  gen_rtx_LSHIFTRT
				  (mode, gen_lowpart (mode, inner), pos_rtx),
				  gen_int_mode (mask, mode)));

	      split = find_split_point (&SET_SRC (x), insn, true);
	      if (split && split != &SET_SRC (x))
		return split;
	    }
	  else
	    {
	      int left_bits = GET_MODE_PRECISION (mode) - len - pos;
	      int right_bits = GET_MODE_PRECISION (mode) - len;
	      SUBST (SET_SRC (x),
		     gen_rtx_fmt_ee
		     (unsignedp ? LSHIFTRT : ASHIFTRT, mode,
		      gen_rtx_ASHIFT (mode,
				      gen_lowpart (mode, inner),
				      gen_int_shift_amount (mode, left_bits)),
		      gen_int_shift_amount (mode, right_bits)));

	      split = find_split_point (&SET_SRC (x), insn, true);
	      if (split && split != &SET_SRC (x))
		return split;
	    }
	}

      /* See if this is a simple operation with a constant as the second
	 operand.  It might be that this constant is out of range and hence
	 could be used as a split point.  */
      if (BINARY_P (SET_SRC (x))
	  && CONSTANT_P (XEXP (SET_SRC (x), 1))
	  && (OBJECT_P (XEXP (SET_SRC (x), 0))
	      || (GET_CODE (XEXP (SET_SRC (x), 0)) == SUBREG
		  && OBJECT_P (SUBREG_REG (XEXP (SET_SRC (x), 0))))))
	return &XEXP (SET_SRC (x), 1);

      /* Finally, see if this is a simple operation with its first operand
	 not in a register.  The operation might require this operand in a
	 register, so return it as a split point.  We can always do this
	 because if the first operand were another operation, we would have
	 already found it as a split point.  */
      if ((BINARY_P (SET_SRC (x)) || UNARY_P (SET_SRC (x)))
	  && ! register_operand (XEXP (SET_SRC (x), 0), VOIDmode))
	return &XEXP (SET_SRC (x), 0);

      return 0;

    case AND:
    case IOR:
      /* We write NOR as (and (not A) (not B)), but if we don't have a NOR,
	 it is better to write this as (not (ior A B)) so we can split it.
	 Similarly for IOR.  */
      if (GET_CODE (XEXP (x, 0)) == NOT && GET_CODE (XEXP (x, 1)) == NOT)
	{
	  SUBST (*loc,
		 gen_rtx_NOT (GET_MODE (x),
			      gen_rtx_fmt_ee (code == IOR ? AND : IOR,
					      GET_MODE (x),
					      XEXP (XEXP (x, 0), 0),
					      XEXP (XEXP (x, 1), 0))));
	  return find_split_point (loc, insn, set_src);
	}

      /* Many RISC machines have a large set of logical insns.  If the
	 second operand is a NOT, put it first so we will try to split the
	 other operand first.  */
      if (GET_CODE (XEXP (x, 1)) == NOT)
	{
	  rtx tem = XEXP (x, 0);
	  SUBST (XEXP (x, 0), XEXP (x, 1));
	  SUBST (XEXP (x, 1), tem);
	}
      break;

    case PLUS:
    case MINUS:
      /* Canonicalization can produce (minus A (mult B C)), where C is a
	 constant.  It may be better to try splitting (plus (mult B -C) A)
	 instead if this isn't a multiply by a power of two.  */
      if (set_src && code == MINUS && GET_CODE (XEXP (x, 1)) == MULT
	  && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
	  && !pow2p_hwi (INTVAL (XEXP (XEXP (x, 1), 1))))
	{
	  machine_mode mode = GET_MODE (x);
	  unsigned HOST_WIDE_INT this_int = INTVAL (XEXP (XEXP (x, 1), 1));
	  HOST_WIDE_INT other_int = trunc_int_for_mode (-this_int, mode);
	  SUBST (*loc, gen_rtx_PLUS (mode,
				     gen_rtx_MULT (mode,
						   XEXP (XEXP (x, 1), 0),
						   gen_int_mode (other_int,
								 mode)),
				     XEXP (x, 0)));
	  return find_split_point (loc, insn, set_src);
	}

      /* Split at a multiply-accumulate instruction.  However if this is
         the SET_SRC, we likely do not have such an instruction and it's
         worthless to try this split.  */
      if (!set_src
	  && (GET_CODE (XEXP (x, 0)) == MULT
	      || (GET_CODE (XEXP (x, 0)) == ASHIFT
		  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
        return loc;

    default:
      break;
    }

  /* Otherwise, select our actions depending on our rtx class.  */
  switch (GET_RTX_CLASS (code))
    {
    case RTX_BITFIELD_OPS:		/* This is ZERO_EXTRACT and SIGN_EXTRACT.  */
    case RTX_TERNARY:
      split = find_split_point (&XEXP (x, 2), insn, false);
      if (split)
	return split;
      /* fall through */
    case RTX_BIN_ARITH:
    case RTX_COMM_ARITH:
    case RTX_COMPARE:
    case RTX_COMM_COMPARE:
      split = find_split_point (&XEXP (x, 1), insn, false);
      if (split)
	return split;
      /* fall through */
    case RTX_UNARY:
      /* Some machines have (and (shift ...) ...) insns.  If X is not
	 an AND, but XEXP (X, 0) is, use it as our split point.  */
      if (GET_CODE (x) != AND && GET_CODE (XEXP (x, 0)) == AND)
	return &XEXP (x, 0);

      split = find_split_point (&XEXP (x, 0), insn, false);
      if (split)
	return split;
      return loc;

    default:
      /* Otherwise, we don't have a split point.  */
      return 0;
    }
}

/* Throughout X, replace FROM with TO, and return the result.
   The result is TO if X is FROM;
   otherwise the result is X, but its contents may have been modified.
   If they were modified, a record was made in undobuf so that
   undo_all will (among other things) return X to its original state.

   If the number of changes necessary is too much to record to undo,
   the excess changes are not made, so the result is invalid.
   The changes already made can still be undone.
   undobuf.num_undo is incremented for such changes, so by testing that
   the caller can tell whether the result is valid.

   `n_occurrences' is incremented each time FROM is replaced.

   IN_DEST is nonzero if we are processing the SET_DEST of a SET.

   IN_COND is nonzero if we are at the top level of a condition.

   UNIQUE_COPY is nonzero if each substitution must be unique.  We do this
   by copying if `n_occurrences' is nonzero.  */

static rtx
subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy)
{
  enum rtx_code code = GET_CODE (x);
  machine_mode op0_mode = VOIDmode;
  const char *fmt;
  int len, i;
  rtx new_rtx;

/* Two expressions are equal if they are identical copies of a shared
   RTX or if they are both registers with the same register number
   and mode.  */

#define COMBINE_RTX_EQUAL_P(X,Y)			\
  ((X) == (Y)						\
   || (REG_P (X) && REG_P (Y)	\
       && REGNO (X) == REGNO (Y) && GET_MODE (X) == GET_MODE (Y)))

  /* Do not substitute into clobbers of regs -- this will never result in
     valid RTL.  */
  if (GET_CODE (x) == CLOBBER && REG_P (XEXP (x, 0)))
    return x;

  if (! in_dest && COMBINE_RTX_EQUAL_P (x, from))
    {
      n_occurrences++;
      return (unique_copy && n_occurrences > 1 ? copy_rtx (to) : to);
    }

  /* If X and FROM are the same register but different modes, they
     will not have been seen as equal above.  However, the log links code
     will make a LOG_LINKS entry for that case.  If we do nothing, we
     will try to rerecognize our original insn and, when it succeeds,
     we will delete the feeding insn, which is incorrect.

     So force this insn not to match in this (rare) case.  */
  if (! in_dest && code == REG && REG_P (from)
      && reg_overlap_mentioned_p (x, from))
    return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);

  /* If this is an object, we are done unless it is a MEM or LO_SUM, both
     of which may contain things that can be combined.  */
  if (code != MEM && code != LO_SUM && OBJECT_P (x))
    return x;

  /* It is possible to have a subexpression appear twice in the insn.
     Suppose that FROM is a register that appears within TO.
     Then, after that subexpression has been scanned once by `subst',
     the second time it is scanned, TO may be found.  If we were
     to scan TO here, we would find FROM within it and create a
     self-referent rtl structure which is completely wrong.  */
  if (COMBINE_RTX_EQUAL_P (x, to))
    return to;

  /* Parallel asm_operands need special attention because all of the
     inputs are shared across the arms.  Furthermore, unsharing the
     rtl results in recognition failures.  Failure to handle this case
     specially can result in circular rtl.

     Solve this by doing a normal pass across the first entry of the
     parallel, and only processing the SET_DESTs of the subsequent
     entries.  Ug.  */

  if (code == PARALLEL
      && GET_CODE (XVECEXP (x, 0, 0)) == SET
      && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
    {
      new_rtx = subst (XVECEXP (x, 0, 0), from, to, 0, 0, unique_copy);

      /* If this substitution failed, this whole thing fails.  */
      if (GET_CODE (new_rtx) == CLOBBER
	  && XEXP (new_rtx, 0) == const0_rtx)
	return new_rtx;

      SUBST (XVECEXP (x, 0, 0), new_rtx);

      for (i = XVECLEN (x, 0) - 1; i >= 1; i--)
	{
	  rtx dest = SET_DEST (XVECEXP (x, 0, i));

	  if (!REG_P (dest)
	      && GET_CODE (dest) != CC0
	      && GET_CODE (dest) != PC)
	    {
	      new_rtx = subst (dest, from, to, 0, 0, unique_copy);

	      /* If this substitution failed, this whole thing fails.  */
	      if (GET_CODE (new_rtx) == CLOBBER
		  && XEXP (new_rtx, 0) == const0_rtx)
		return new_rtx;

	      SUBST (SET_DEST (XVECEXP (x, 0, i)), new_rtx);
	    }
	}
    }
  else
    {
      len = GET_RTX_LENGTH (code);
      fmt = GET_RTX_FORMAT (code);

      /* We don't need to process a SET_DEST that is a register, CC0,
	 or PC, so set up to skip this common case.  All other cases
	 where we want to suppress replacing something inside a
	 SET_SRC are handled via the IN_DEST operand.  */
      if (code == SET
	  && (REG_P (SET_DEST (x))
	      || GET_CODE (SET_DEST (x)) == CC0
	      || GET_CODE (SET_DEST (x)) == PC))
	fmt = "ie";

      /* Trying to simplify the operands of a widening MULT is not likely
	 to create RTL matching a machine insn.  */
      if (code == MULT
	  && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
	      || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
	  && (GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
	      || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND)
	  && REG_P (XEXP (XEXP (x, 0), 0))
	  && REG_P (XEXP (XEXP (x, 1), 0))
	  && from == to)
	return x;


      /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a
	 constant.  */
      if (fmt[0] == 'e')
	op0_mode = GET_MODE (XEXP (x, 0));

      for (i = 0; i < len; i++)
	{
	  if (fmt[i] == 'E')
	    {
	      int j;
	      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
		{
		  if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from))
		    {
		      new_rtx = (unique_copy && n_occurrences
			     ? copy_rtx (to) : to);
		      n_occurrences++;
		    }
		  else
		    {
		      new_rtx = subst (XVECEXP (x, i, j), from, to, 0, 0,
				       unique_copy);

		      /* If this substitution failed, this whole thing
			 fails.  */
		      if (GET_CODE (new_rtx) == CLOBBER
			  && XEXP (new_rtx, 0) == const0_rtx)
			return new_rtx;
		    }

		  SUBST (XVECEXP (x, i, j), new_rtx);
		}
	    }
	  else if (fmt[i] == 'e')
	    {
	      /* If this is a register being set, ignore it.  */
	      new_rtx = XEXP (x, i);
	      if (in_dest
		  && i == 0
		  && (((code == SUBREG || code == ZERO_EXTRACT)
		       && REG_P (new_rtx))
		      || code == STRICT_LOW_PART))
		;

	      else if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from))
		{
		  /* In general, don't install a subreg involving two
		     modes not tieable.  It can worsen register
		     allocation, and can even make invalid reload
		     insns, since the reg inside may need to be copied
		     from in the outside mode, and that may be invalid
		     if it is an fp reg copied in integer mode.

		     We allow two exceptions to this: It is valid if
		     it is inside another SUBREG and the mode of that
		     SUBREG and the mode of the inside of TO is
		     tieable and it is valid if X is a SET that copies
		     FROM to CC0.  */

		  if (GET_CODE (to) == SUBREG
		      && !targetm.modes_tieable_p (GET_MODE (to),
						   GET_MODE (SUBREG_REG (to)))
		      && ! (code == SUBREG
			    && (targetm.modes_tieable_p
				(GET_MODE (x), GET_MODE (SUBREG_REG (to)))))
		      && (!HAVE_cc0
			  || (! (code == SET
				 && i == 1
				 && XEXP (x, 0) == cc0_rtx))))
		    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);

		  if (code == SUBREG
		      && REG_P (to)
		      && REGNO (to) < FIRST_PSEUDO_REGISTER
		      && simplify_subreg_regno (REGNO (to), GET_MODE (to),
						SUBREG_BYTE (x),
						GET_MODE (x)) < 0)
		    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);

		  new_rtx = (unique_copy && n_occurrences ? copy_rtx (to) : to);
		  n_occurrences++;
		}
	      else
		/* If we are in a SET_DEST, suppress most cases unless we
		   have gone inside a MEM, in which case we want to
		   simplify the address.  We assume here that things that
		   are actually part of the destination have their inner
		   parts in the first expression.  This is true for SUBREG,
		   STRICT_LOW_PART, and ZERO_EXTRACT, which are the only
		   things aside from REG and MEM that should appear in a
		   SET_DEST.  */
		new_rtx = subst (XEXP (x, i), from, to,
			     (((in_dest
				&& (code == SUBREG || code == STRICT_LOW_PART
				    || code == ZERO_EXTRACT))
			       || code == SET)
			      && i == 0),
				 code == IF_THEN_ELSE && i == 0,
				 unique_copy);

	      /* If we found that we will have to reject this combination,
		 indicate that by returning the CLOBBER ourselves, rather than
		 an expression containing it.  This will speed things up as
		 well as prevent accidents where two CLOBBERs are considered
		 to be equal, thus producing an incorrect simplification.  */

	      if (GET_CODE (new_rtx) == CLOBBER && XEXP (new_rtx, 0) == const0_rtx)
		return new_rtx;

	      if (GET_CODE (x) == SUBREG && CONST_SCALAR_INT_P (new_rtx))
		{
		  machine_mode mode = GET_MODE (x);

		  x = simplify_subreg (GET_MODE (x), new_rtx,
				       GET_MODE (SUBREG_REG (x)),
				       SUBREG_BYTE (x));
		  if (! x)
		    x = gen_rtx_CLOBBER (mode, const0_rtx);
		}
	      else if (CONST_SCALAR_INT_P (new_rtx)
		       && (GET_CODE (x) == ZERO_EXTEND
			   || GET_CODE (x) == FLOAT
			   || GET_CODE (x) == UNSIGNED_FLOAT))
		{
		  x = simplify_unary_operation (GET_CODE (x), GET_MODE (x),
						new_rtx,
						GET_MODE (XEXP (x, 0)));
		  if (!x)
		    return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
		}
	      /* CONST_INTs shouldn't be substituted into PRE_DEC, PRE_MODIFY
		 etc. arguments, otherwise we can ICE before trying to recog
		 it.  See PR104446.  */
	      else if (CONST_SCALAR_INT_P (new_rtx)
		       && GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC)
		return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
	      else
		SUBST (XEXP (x, i), new_rtx);
	    }
	}
    }

  /* Check if we are loading something from the constant pool via float
     extension; in this case we would undo compress_float_constant
     optimization and degenerate constant load to an immediate value.  */
  if (GET_CODE (x) == FLOAT_EXTEND
      && MEM_P (XEXP (x, 0))
      && MEM_READONLY_P (XEXP (x, 0)))
    {
      rtx tmp = avoid_constant_pool_reference (x);
      if (x != tmp)
        return x;
    }

  /* Try to simplify X.  If the simplification changed the code, it is likely
     that further simplification will help, so loop, but limit the number
     of repetitions that will be performed.  */

  for (i = 0; i < 4; i++)
    {
      /* If X is sufficiently simple, don't bother trying to do anything
	 with it.  */
      if (code != CONST_INT && code != REG && code != CLOBBER)
	x = combine_simplify_rtx (x, op0_mode, in_dest, in_cond);

      if (GET_CODE (x) == code)
	break;

      code = GET_CODE (x);

      /* We no longer know the original mode of operand 0 since we
	 have changed the form of X)  */
      op0_mode = VOIDmode;
    }

  return x;
}

/* If X is a commutative operation whose operands are not in the canonical
   order, use substitutions to swap them.  */

static void
maybe_swap_commutative_operands (rtx x)
{
  if (COMMUTATIVE_ARITH_P (x)
      && swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
    {
      rtx temp = XEXP (x, 0);
      SUBST (XEXP (x, 0), XEXP (x, 1));
      SUBST (XEXP (x, 1), temp);
    }
}

/* Simplify X, a piece of RTL.  We just operate on the expression at the
   outer level; call `subst' to simplify recursively.  Return the new
   expression.

   OP0_MODE is the original mode of XEXP (x, 0).  IN_DEST is nonzero
   if we are inside a SET_DEST.  IN_COND is nonzero if we are at the top level
   of a condition.  */

static rtx
combine_simplify_rtx (rtx x, machine_mode op0_mode, int in_dest,
		      int in_cond)
{
  enum rtx_code code = GET_CODE (x);
  machine_mode mode = GET_MODE (x);
  scalar_int_mode int_mode;
  rtx temp;
  int i;

  /* If this is a commutative operation, put a constant last and a complex
     expression first.  We don't need to do this for comparisons here.  */
  maybe_swap_commutative_operands (x);

  /* Try to fold this expression in case we have constants that weren't
     present before.  */
  temp = 0;
  switch (GET_RTX_CLASS (code))
    {
    case RTX_UNARY:
      if (op0_mode == VOIDmode)
	op0_mode = GET_MODE (XEXP (x, 0));
      temp = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
      break;
    case RTX_COMPARE:
    case RTX_COMM_COMPARE:
      {
	machine_mode cmp_mode = GET_MODE (XEXP (x, 0));
	if (cmp_mode == VOIDmode)
	  {
	    cmp_mode = GET_MODE (XEXP (x, 1));
	    if (cmp_mode == VOIDmode)
	      cmp_mode = op0_mode;
	  }
	temp = simplify_relational_operation (code, mode, cmp_mode,
					      XEXP (x, 0), XEXP (x, 1));
      }
      break;
    case RTX_COMM_ARITH:
    case RTX_BIN_ARITH:
      temp = simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
      break;
    case RTX_BITFIELD_OPS:
    case RTX_TERNARY:
      temp = simplify_ternary_operation (code, mode, op0_mode, XEXP (x, 0),
					 XEXP (x, 1), XEXP (x, 2));
      break;
    default:
      break;
    }

  if (temp)
    {
      x = temp;
      code = GET_CODE (temp);
      op0_mode = VOIDmode;
      mode = GET_MODE (temp);
    }

  /* If this is a simple operation applied to an IF_THEN_ELSE, try
     applying it to the arms of the IF_THEN_ELSE.  This often simplifies
     things.  Check for cases where both arms are testing the same
     condition.

     Don't do anything if all operands are very simple.  */

  if ((BINARY_P (x)
       && ((!OBJECT_P (XEXP (x, 0))
	    && ! (GET_CODE (XEXP (x, 0)) == SUBREG
		  && OBJECT_P (SUBREG_REG (XEXP (x, 0)))))
	   || (!OBJECT_P (XEXP (x, 1))
	       && ! (GET_CODE (XEXP (x, 1)) == SUBREG
		     && OBJECT_P (SUBREG_REG (XEXP (x, 1)))))))
      || (UNARY_P (x)
	  && (!OBJECT_P (XEXP (x, 0))
	       && ! (GET_CODE (XEXP (x, 0)) == SUBREG
		     && OBJECT_P (SUBREG_REG (XEXP (x, 0)))))))
    {
      rtx cond, true_rtx, false_rtx;

      cond = if_then_else_cond (x, &true_rtx, &false_rtx);
      if (cond != 0
	  /* If everything is a comparison, what we have is highly unlikely
	     to be simpler, so don't use it.  */
	  && ! (COMPARISON_P (x)
		&& (COMPARISON_P (true_rtx) || COMPARISON_P (false_rtx)))
	  /* Similarly, if we end up with one of the expressions the same
	     as the original, it is certainly not simpler.  */
	  && ! rtx_equal_p (x, true_rtx)
	  && ! rtx_equal_p (x, false_rtx))
	{
	  rtx cop1 = const0_rtx;
	  enum rtx_code cond_code = simplify_comparison (NE, &cond, &cop1);

	  if (cond_code == NE && COMPARISON_P (cond))
	    return x;

	  /* Simplify the alternative arms; this may collapse the true and
	     false arms to store-flag values.  Be careful to use copy_rtx
	     here since true_rtx or false_rtx might share RTL with x as a
	     result of the if_then_else_cond call above.  */
	  true_rtx = subst (copy_rtx (true_rtx), pc_rtx, pc_rtx, 0, 0, 0);
	  false_rtx = subst (copy_rtx (false_rtx), pc_rtx, pc_rtx, 0, 0, 0);

	  /* If true_rtx and false_rtx are not general_operands, an if_then_else
	     is unlikely to be simpler.  */
	  if (general_operand (true_rtx, VOIDmode)
	      && general_operand (false_rtx, VOIDmode))
	    {
	      enum rtx_code reversed;

	      /* Restarting if we generate a store-flag expression will cause
		 us to loop.  Just drop through in this case.  */

	      /* If the result values are STORE_FLAG_VALUE and zero, we can
		 just make the comparison operation.  */
	      if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
		x = simplify_gen_relational (cond_code, mode, VOIDmode,
					     cond, cop1);
	      else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
		       && ((reversed = reversed_comparison_code_parts
					(cond_code, cond, cop1, NULL))
			   != UNKNOWN))
		x = simplify_gen_relational (reversed, mode, VOIDmode,
					     cond, cop1);

	      /* Likewise, we can make the negate of a comparison operation
		 if the result values are - STORE_FLAG_VALUE and zero.  */
	      else if (CONST_INT_P (true_rtx)
		       && INTVAL (true_rtx) == - STORE_FLAG_VALUE
		       && false_rtx == const0_rtx)
		x = simplify_gen_unary (NEG, mode,
					simplify_gen_relational (cond_code,
								 mode, VOIDmode,
								 cond, cop1),
					mode);
	      else if (CONST_INT_P (false_rtx)
		       && INTVAL (false_rtx) == - STORE_FLAG_VALUE
		       && true_rtx == const0_rtx
		       && ((reversed = reversed_comparison_code_parts
					(cond_code, cond, cop1, NULL))
			   != UNKNOWN))
		x = simplify_gen_unary (NEG, mode,
					simplify_gen_relational (reversed,
								 mode, VOIDmode,
								 cond, cop1),
					mode);
	      else
		return gen_rtx_IF_THEN_ELSE (mode,
					     simplify_gen_relational (cond_code,
								      mode,
								      VOIDmode,
								      cond,
								      cop1),
					     true_rtx, false_rtx);

	      code = GET_CODE (x);
	      op0_mode = VOIDmode;
	    }
	}
    }

  /* First see if we can apply the inverse distributive law.  */
  if (code == PLUS || code == MINUS
      || code == AND || code == IOR || code == XOR)
    {
      x = apply_distributive_law (x);
      code = GET_CODE (x);
      op0_mode = VOIDmode;
    }

  /* If CODE is an associative operation not otherwise handled, see if we
     can associate some operands.  This can win if they are constants or
     if they are logically related (i.e. (a & b) & a).  */
  if ((code == PLUS || code == MINUS || code == MULT || code == DIV
       || code == AND || code == IOR || code == XOR
       || code == SMAX || code == SMIN || code == UMAX || code == UMIN)
      && ((INTEGRAL_MODE_P (mode) && code != DIV)
	  || (flag_associative_math && FLOAT_MODE_P (mode))))
    {
      if (GET_CODE (XEXP (x, 0)) == code)
	{
	  rtx other = XEXP (XEXP (x, 0), 0);
	  rtx inner_op0 = XEXP (XEXP (x, 0), 1);
	  rtx inner_op1 = XEXP (x, 1);
	  rtx inner;

	  /* Make sure we pass the constant operand if any as the second
	     one if this is a commutative operation.  */
	  if (CONSTANT_P (inner_op0) && COMMUTATIVE_ARITH_P (x))
	    std::swap (inner_op0, inner_op1);
	  inner = simplify_binary_operation (code == MINUS ? PLUS
					     : code == DIV ? MULT
					     : code,
					     mode, inner_op0, inner_op1);

	  /* For commutative operations, try the other pair if that one
	     didn't simplify.  */
	  if (inner == 0 && COMMUTATIVE_ARITH_P (x))
	    {
	      other = XEXP (XEXP (x, 0), 1);
	      inner = simplify_binary_operation (code, mode,
						 XEXP (XEXP (x, 0), 0),
						 XEXP (x, 1));
	    }

	  if (inner)
	    return simplify_gen_binary (code, mode, other, inner);
	}
    }

  /* A little bit of algebraic simplification here.  */
  switch (code)
    {
    case MEM:
      /* Ensure that our address has any ASHIFTs converted to MULT in case
	 address-recognizing predicates are called later.  */
      temp = make_compound_operation (XEXP (x, 0), MEM);
      SUBST (XEXP (x, 0), temp);
      break;

    case SUBREG:
      if (op0_mode == VOIDmode)
	op0_mode = GET_MODE (SUBREG_REG (x));

      /* See if this can be moved to simplify_subreg.  */
      if (CONSTANT_P (SUBREG_REG (x))
	  && known_eq (subreg_lowpart_offset (mode, op0_mode), SUBREG_BYTE (x))
	     /* Don't call gen_lowpart if the inner mode
		is VOIDmode and we cannot simplify it, as SUBREG without
		inner mode is invalid.  */
	  && (GET_MODE (SUBREG_REG (x)) != VOIDmode
	      || gen_lowpart_common (mode, SUBREG_REG (x))))
	return gen_lowpart (mode, SUBREG_REG (x));

      if (GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_CC)
	break;
      {
	rtx temp;
	temp = simplify_subreg (mode, SUBREG_REG (x), op0_mode,
				SUBREG_BYTE (x));
	if (temp)
	  return temp;

	/* If op is known to have all lower bits zero, the result is zero.  */
	scalar_int_mode int_mode, int_op0_mode;
	if (!in_dest
	    && is_a <scalar_int_mode> (mode, &int_mode)
	    && is_a <scalar_int_mode> (op0_mode, &int_op0_mode)
	    && (GET_MODE_PRECISION (int_mode)
		< GET_MODE_PRECISION (int_op0_mode))
	    && known_eq (subreg_lowpart_offset (int_mode, int_op0_mode),
			 SUBREG_BYTE (x))
	    && HWI_COMPUTABLE_MODE_P (int_op0_mode)
	    && ((nonzero_bits (SUBREG_REG (x), int_op0_mode)
		 & GET_MODE_MASK (int_mode)) == 0)
	    && !side_effects_p (SUBREG_REG (x)))
	  return CONST0_RTX (int_mode);
      }

      /* Don't change the mode of the MEM if that would change the meaning
	 of the address.  */
      if (MEM_P (SUBREG_REG (x))
	  && (MEM_VOLATILE_P (SUBREG_REG (x))
	      || mode_dependent_address_p (XEXP (SUBREG_REG (x), 0),
					   MEM_ADDR_SPACE (SUBREG_REG (x)))))
	return gen_rtx_CLOBBER (mode, const0_rtx);

      /* Note that we cannot do any narrowing for non-constants since
	 we might have been counting on using the fact that some bits were
	 zero.  We now do this in the SET.  */

      break;

    case NEG:
      temp = expand_compound_operation (XEXP (x, 0));

      /* For C equal to the width of MODE minus 1, (neg (ashiftrt X C)) can be
	 replaced by (lshiftrt X C).  This will convert
	 (neg (sign_extract X 1 Y)) to (zero_extract X 1 Y).  */

      if (GET_CODE (temp) == ASHIFTRT
	  && CONST_INT_P (XEXP (temp, 1))
	  && INTVAL (XEXP (temp, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
	return simplify_shift_const (NULL_RTX, LSHIFTRT, mode, XEXP (temp, 0),
				     INTVAL (XEXP (temp, 1)));

      /* If X has only a single bit that might be nonzero, say, bit I, convert
	 (neg X) to (ashiftrt (ashift X C-I) C-I) where C is the bitsize of
	 MODE minus 1.  This will convert (neg (zero_extract X 1 Y)) to
	 (sign_extract X 1 Y).  But only do this if TEMP isn't a register
	 or a SUBREG of one since we'd be making the expression more
	 complex if it was just a register.  */

      if (!REG_P (temp)
	  && ! (GET_CODE (temp) == SUBREG
		&& REG_P (SUBREG_REG (temp)))
	  && is_a <scalar_int_mode> (mode, &int_mode)
	  && (i = exact_log2 (nonzero_bits (temp, int_mode))) >= 0)
	{
	  rtx temp1 = simplify_shift_const
	    (NULL_RTX, ASHIFTRT, int_mode,
	     simplify_shift_const (NULL_RTX, ASHIFT, int_mode, temp,
				   GET_MODE_PRECISION (int_mode) - 1 - i),
	     GET_MODE_PRECISION (int_mode) - 1 - i);

	  /* If all we did was surround TEMP with the two shifts, we
	     haven't improved anything, so don't use it.  Otherwise,
	     we are better off with TEMP1.  */
	  if (GET_CODE (temp1) != ASHIFTRT
	      || GET_CODE (XEXP (temp1, 0)) != ASHIFT
	      || XEXP (XEXP (temp1, 0), 0) != temp)
	    return temp1;
	}
      break;

    case TRUNCATE:
      /* We can't handle truncation to a partial integer mode here
	 because we don't know the real bitsize of the partial
	 integer mode.  */
      if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
	break;

      if (HWI_COMPUTABLE_MODE_P (mode))
	SUBST (XEXP (x, 0),
	       force_to_mode (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
			      GET_MODE_MASK (mode), 0));

      /* We can truncate a constant value and return it.  */
      {
	poly_int64 c;
	if (poly_int_rtx_p (XEXP (x, 0), &c))
	  return gen_int_mode (c, mode);
      }

      /* Similarly to what we do in simplify-rtx.c, a truncate of a register
	 whose value is a comparison can be replaced with a subreg if
	 STORE_FLAG_VALUE permits.  */
      if (HWI_COMPUTABLE_MODE_P (mode)
	  && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
	  && (temp = get_last_value (XEXP (x, 0)))
	  && COMPARISON_P (temp))
	return gen_lowpart (mode, XEXP (x, 0));
      break;

    case CONST:
      /* (const (const X)) can become (const X).  Do it this way rather than
	 returning the inner CONST since CONST can be shared with a
	 REG_EQUAL note.  */
      if (GET_CODE (XEXP (x, 0)) == CONST)
	SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
      break;

    case LO_SUM:
      /* Convert (lo_sum (high FOO) FOO) to FOO.  This is necessary so we
	 can add in an offset.  find_split_point will split this address up
	 again if it doesn't match.  */
      if (HAVE_lo_sum && GET_CODE (XEXP (x, 0)) == HIGH
	  && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
	return XEXP (x, 1);
      break;

    case PLUS:
      /* (plus (xor (and <foo> (const_int pow2 - 1)) <c>) <-c>)
	 when c is (const_int (pow2 + 1) / 2) is a sign extension of a
	 bit-field and can be replaced by either a sign_extend or a
	 sign_extract.  The `and' may be a zero_extend and the two
	 <c>, -<c> constants may be reversed.  */
      if (GET_CODE (XEXP (x, 0)) == XOR
	  && is_a <scalar_int_mode> (mode, &int_mode)
	  && CONST_INT_P (XEXP (x, 1))
	  && CONST_INT_P (XEXP (XEXP (x, 0), 1))
	  && INTVAL (XEXP (x, 1)) == -INTVAL (XEXP (XEXP (x, 0), 1))
	  && ((i = exact_log2 (UINTVAL (XEXP (XEXP (x, 0), 1)))) >= 0
	      || (i = exact_log2 (UINTVAL (XEXP (x, 1)))) >= 0)
	  && HWI_COMPUTABLE_MODE_P (int_mode)
	  && ((GET_CODE (XEXP (XEXP (x, 0), 0)) == AND
	       && CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
	       && (UINTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))
		   == (HOST_WIDE_INT_1U << (i + 1)) - 1))
	      || (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
		  && known_eq ((GET_MODE_PRECISION
				(GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)))),
			       (unsigned int) i + 1))))
	return simplify_shift_const
	  (NULL_RTX, ASHIFTRT, int_mode,
	   simplify_shift_const (NULL_RTX, ASHIFT, int_mode,
				 XEXP (XEXP (XEXP (x, 0), 0), 0),
				 GET_MODE_PRECISION (int_mode) - (i + 1)),
	   GET_MODE_PRECISION (int_mode) - (i + 1));

      /* If only the low-order bit of X is possibly nonzero, (plus x -1)
	 can become (ashiftrt (ashift (xor x 1) C) C) where C is
	 the bitsize of the mode - 1.  This allows simplification of
	 "a = (b & 8) == 0;"  */
      if (XEXP (x, 1) == constm1_rtx
	  && !REG_P (XEXP (x, 0))
	  && ! (GET_CODE (XEXP (x, 0)) == SUBREG
		&& REG_P (SUBREG_REG (XEXP (x, 0))))
	  && is_a <scalar_int_mode> (mode, &int_mode)
	  && nonzero_bits (XEXP (x, 0), int_mode) == 1)
	return simplify_shift_const
	  (NULL_RTX, ASHIFTRT, int_mode,
	   simplify_shift_const (NULL_RTX, ASHIFT, int_mode,
				 gen_rtx_XOR (int_mode, XEXP (x, 0),
					      const1_rtx),
				 GET_MODE_PRECISION (int_mode) - 1),
	   GET_MODE_PRECISION (int_mode) - 1);

      /* If we are adding two things that have no bits in common, convert
	 the addition into an IOR.  This will often be further simplified,
	 for example in cases like ((a & 1) + (a & 2)), which can
	 become a & 3.  */

      if (HWI_COMPUTABLE_MODE_P (mode)
	  && (nonzero_bits (XEXP (x, 0), mode)
	      & nonzero_bits (XEXP (x, 1), mode)) == 0)
	{
	  /* Try to simplify the expression further.  */
	  rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
	  temp = combine_simplify_rtx (tor, VOIDmode, in_dest, 0);

	  /* If we could, great.  If not, do not go ahead with the IOR
	     replacement, since PLUS appears in many special purpose
	     address arithmetic instructions.  */
	  if (GET_CODE (temp) != CLOBBER
	      && (GET_CODE (temp) != IOR
		  || ((XEXP (temp, 0) != XEXP (x, 0)
		       || XEXP (temp, 1) != XEXP (x, 1))
		      && (XEXP (temp, 0) != XEXP (x, 1)
			  || XEXP (temp, 1) != XEXP (x, 0)))))
	    return temp;
	}

      /* Canonicalize x + x into x << 1.  */
      if (GET_MODE_CLASS (mode) == MODE_INT
	  && rtx_equal_p (XEXP (x, 0), XEXP (x, 1))
	  && !side_effects_p (XEXP (x, 0)))
	return simplify_gen_binary (ASHIFT, mode, XEXP (x, 0), const1_rtx);

      break;

    case MINUS:
      /* (minus <foo> (and <foo> (const_int -pow2))) becomes
	 (and <foo> (const_int pow2-1))  */
      if (is_a <scalar_int_mode> (mode, &int_mode)
	  && GET_CODE (XEXP (x, 1)) == AND
	  && CONST_INT_P (XEXP (XEXP (x, 1), 1))
	  && pow2p_hwi (-UINTVAL (XEXP (XEXP (x, 1), 1)))
	  && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
	return simplify_and_const_int (NULL_RTX, int_mode, XEXP (x, 0),
				       -INTVAL (XEXP (XEXP (x, 1), 1)) - 1);
      break;

    case MULT:
      /* If we have (mult (plus A B) C), apply the distributive law and then
	 the inverse distributive law to see if things simplify.  This
	 occurs mostly in addresses, often when unrolling loops.  */

      if (GET_CODE (XEXP (x, 0)) == PLUS)
	{
	  rtx result = distribute_and_simplify_rtx (x, 0);
	  if (result)
	    return result;
	}

      /* Try simplify a*(b/c) as (a*b)/c.  */
      if (FLOAT_MODE_P (mode) && flag_associative_math
	  && GET_CODE (XEXP (x, 0)) == DIV)
	{
	  rtx tem = simplify_binary_operation (MULT, mode,
					       XEXP (XEXP (x, 0), 0),
					       XEXP (x, 1));
	  if (tem)
	    return simplify_gen_binary (DIV, mode, tem, XEXP (XEXP (x, 0), 1));
	}
      break;

    case UDIV:
      /* If this is a divide by a power of two, treat it as a shift if
	 its first operand is a shift.  */
      if (is_a <scalar_int_mode> (mode, &int_mode)
	  && CONST_INT_P (XEXP (x, 1))
	  && (i = exact_log2 (UINTVAL (XEXP (x, 1)))) >= 0
	  && (GET_CODE (XEXP (x, 0)) == ASHIFT
	      || GET_CODE (XEXP (x, 0)) == LSHIFTRT
	      || GET_CODE (XEXP (x, 0)) == ASHIFTRT
	      || GET_CODE (XEXP (x, 0)) == ROTATE
	      || GET_CODE (XEXP (x, 0)) == ROTATERT))
	return simplify_shift_const (NULL_RTX, LSHIFTRT, int_mode,
				     XEXP (x, 0), i);
      break;

    case EQ:  case NE:
    case GT:  case GTU:  case GE:  case GEU:
    case LT:  case LTU:  case LE:  case LEU:
    case UNEQ:  case LTGT:
    case UNGT:  case UNGE:
    case UNLT:  case UNLE:
    case UNORDERED: case ORDERED:
      /* If the first operand is a condition code, we can't do anything
	 with it.  */
      if (GET_CODE (XEXP (x, 0)) == COMPARE
	  || (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_CC
	      && ! CC0_P (XEXP (x, 0))))
	{
	  rtx op0 = XEXP (x, 0);
	  rtx op1 = XEXP (x, 1);
	  enum rtx_code new_code;

	  if (GET_CODE (op0) == COMPARE)
	    op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);

	  /* Simplify our comparison, if possible.  */
	  new_code = simplify_comparison (code, &op0, &op1);

	  /* If STORE_FLAG_VALUE is 1, we can convert (ne x 0) to simply X
	     if only the low-order bit is possibly nonzero in X (such as when
	     X is a ZERO_EXTRACT of one bit).  Similarly, we can convert EQ to
	     (xor X 1) or (minus 1 X); we use the former.  Finally, if X is
	     known to be either 0 or -1, NE becomes a NEG and EQ becomes
	     (plus X 1).

	     Remove any ZERO_EXTRACT we made when thinking this was a
	     comparison.  It may now be simpler to use, e.g., an AND.  If a
	     ZERO_EXTRACT is indeed appropriate, it will be placed back by
	     the call to make_compound_operation in the SET case.

	     Don't apply these optimizations if the caller would
	     prefer a comparison rather than a value.
	     E.g., for the condition in an IF_THEN_ELSE most targets need
	     an explicit comparison.  */

	  if (in_cond)
	    ;

	  else if (STORE_FLAG_VALUE == 1
		   && new_code == NE
		   && is_int_mode (mode, &int_mode)
		   && op1 == const0_rtx
		   && int_mode == GET_MODE (op0)
		   && nonzero_bits (op0, int_mode) == 1)
	    return gen_lowpart (int_mode,
				expand_compound_operation (op0));

	  else if (STORE_FLAG_VALUE == 1
		   && new_code == NE
		   && is_int_mode (mode, &int_mode)
		   && op1 == const0_rtx
		   && int_mode == GET_MODE (op0)
		   && (num_sign_bit_copies (op0, int_mode)
		       == GET_MODE_PRECISION (int_mode)))
	    {
	      op0 = expand_compound_operation (op0);
	      return simplify_gen_unary (NEG, int_mode,
					 gen_lowpart (int_mode, op0),
					 int_mode);
	    }

	  else if (STORE_FLAG_VALUE == 1
		   && new_code == EQ
		   && is_int_mode (mode, &int_mode)
		   && op1 == const0_rtx
		   && int_mode == GET_MODE (op0)
		   && nonzero_bits (op0, int_mode) == 1)
	    {
	      op0 = expand_compound_operation (op0);
	      return simplify_gen_binary (XOR, int_mode,
					  gen_lowpart (int_mode, op0),
					  const1_rtx);
	    }

	  else if (STORE_FLAG_VALUE == 1
		   && new_code == EQ
		   && is_int_mode (mode, &int_mode)
		   && op1 == const0_rtx
		   && int_mode == GET_MODE (op0)
		   && (num_sign_bit_copies (op0, int_mode)
		       == GET_MODE_PRECISION (int_mode)))
	    {
	      op0 = expand_compound_operation (op0);
	      return plus_constant (int_mode, gen_lowpart (int_mode, op0), 1);
	    }

	  /* If STORE_FLAG_VALUE is -1, we have cases similar to
	     those above.  */
	  if (in_cond)
	    ;

	  else if (STORE_FLAG_VALUE == -1
		   && new_code == NE
		   && is_int_mode (mode, &int_mode)
		   && op1 == const0_rtx
		   && int_mode == GET_MODE (op0)
		   && (num_sign_bit_copies (op0, int_mode)
		       == GET_MODE_PRECISION (int_mode)))
	    return gen_lowpart (int_mode, expand_compound_operation (op0));

	  else if (STORE_FLAG_VALUE == -1
		   && new_code == NE
		   && is_int_mode (mode, &int_mode)
		   && op1 == const0_rtx
		   && int_mode == GET_MODE (op0)
		   && nonzero_bits (op0, int_mode) == 1)
	    {
	      op0 = expand_compound_operation (op0);
	      return simplify_gen_unary (NEG, int_mode,
					 gen_lowpart (int_mode, op0),
					 int_mode);
	    }

	  else if (STORE_FLAG_VALUE == -1
		   && new_code == EQ
		   && is_int_mode (mode, &int_mode)
		   && op1 == const0_rtx
		   && int_mode == GET_MODE (op0)
		   && (num_sign_bit_copies (op0, int_mode)
		       == GET_MODE_PRECISION (int_mode)))
	    {
	      op0 = expand_compound_operation (op0);
	      return simplify_gen_unary (NOT, int_mode,
					 gen_lowpart (int_mode, op0),
					 int_mode);
	    }

	  /* If X is 0/1, (eq X 0) is X-1.  */
	  else if (STORE_FLAG_VALUE == -1
		   && new_code == EQ
		   && is_int_mode (mode, &int_mode)
		   && op1 == const0_rtx
		   && int_mode == GET_MODE (op0)
		   && nonzero_bits (op0, int_mode) == 1)
	    {
	      op0 = expand_compound_operation (op0);
	      return plus_constant (int_mode, gen_lowpart (int_mode, op0), -1);
	    }

	  /* If STORE_FLAG_VALUE says to just test the sign bit and X has just
	     one bit that might be nonzero, we can convert (ne x 0) to
	     (ashift x c) where C puts the bit in the sign bit.  Remove any
	     AND with STORE_FLAG_VALUE when we are done, since we are only
	     going to test the sign bit.  */
	  if (new_code == NE
	      && is_int_mode (mode, &int_mode)
	      && HWI_COMPUTABLE_MODE_P (int_mode)
	      && val_signbit_p (int_mode, STORE_FLAG_VALUE)
	      && op1 == const0_rtx
	      && int_mode == GET_MODE (op0)
	      && (i = exact_log2 (nonzero_bits (op0, int_mode))) >= 0)
	    {
	      x = simplify_shift_const (NULL_RTX, ASHIFT, int_mode,
					expand_compound_operation (op0),
					GET_MODE_PRECISION (int_mode) - 1 - i);
	      if (GET_CODE (x) == AND && XEXP (x, 1) == const_true_rtx)
		return XEXP (x, 0);
	      else
		return x;
	    }

	  /* If the code changed, return a whole new comparison.
	     We also need to avoid using SUBST in cases where
	     simplify_comparison has widened a comparison with a CONST_INT,
	     since in that case the wider CONST_INT may fail the sanity
	     checks in do_SUBST.  */
	  if (new_code != code
	      || (CONST_INT_P (op1)
		  && GET_MODE (op0) != GET_MODE (XEXP (x, 0))
		  && GET_MODE (op0) != GET_MODE (XEXP (x, 1))))
	    return gen_rtx_fmt_ee (new_code, mode, op0, op1);

	  /* Otherwise, keep this operation, but maybe change its operands.
	     This also converts (ne (compare FOO BAR) 0) to (ne FOO BAR).  */
	  SUBST (XEXP (x, 0), op0);
	  SUBST (XEXP (x, 1), op1);
	}
      break;

    case IF_THEN_ELSE:
      return simplify_if_then_else (x);

    case ZERO_EXTRACT:
    case SIGN_EXTRACT:
    case ZERO_EXTEND:
    case SIGN_EXTEND:
      /* If we are processing SET_DEST, we are done.  */
      if (in_dest)
	return x;

      return expand_compound_operation (x);

    case SET:
      return simplify_set (x);

    case AND:
    case IOR:
      return simplify_logical (x);

    case ASHIFT:
    case LSHIFTRT:
    case ASHIFTRT:
    case ROTATE:
    case ROTATERT:
      /* If this is a shift by a constant amount, simplify it.  */
      if (CONST_INT_P (XEXP (x, 1)))
	return simplify_shift_const (x, code, mode, XEXP (x, 0),
				     INTVAL (XEXP (x, 1)));

      else if (SHIFT_COUNT_TRUNCATED && !REG_P (XEXP (x, 1)))
	SUBST (XEXP (x, 1),
	       force_to_mode (XEXP (x, 1), GET_MODE (XEXP (x, 1)),
			      (HOST_WIDE_INT_1U
			       << exact_log2 (GET_MODE_UNIT_BITSIZE
					      (GET_MODE (x))))
			      - 1,
			      0));
      break;

    default:
      break;
    }

  return x;
}

/* Simplify X, an IF_THEN_ELSE expression.  Return the new expression.  */

static rtx
simplify_if_then_else (rtx x)
{
  machine_mode mode = GET_MODE (x);
  rtx cond = XEXP (x, 0);
  rtx true_rtx = XEXP (x, 1);
  rtx false_rtx = XEXP (x, 2);
  enum rtx_code true_code = GET_CODE (cond);
  int comparison_p = COMPARISON_P (cond);
  rtx temp;
  int i;
  enum rtx_code false_code;
  rtx reversed;
  scalar_int_mode int_mode, inner_mode;

  /* Simplify storing of the truth value.  */
  if (comparison_p && true_rtx == const_true_rtx && false_rtx == const0_rtx)
    return simplify_gen_relational (true_code, mode, VOIDmode,
				    XEXP (cond, 0), XEXP (cond, 1));

  /* Also when the truth value has to be reversed.  */
  if (comparison_p
      && true_rtx == const0_rtx && false_rtx == const_true_rtx
      && (reversed = reversed_comparison (cond, mode)))
    return reversed;

  /* Sometimes we can simplify the arm of an IF_THEN_ELSE if a register used
     in it is being compared against certain values.  Get the true and false
     comparisons and see if that says anything about the value of each arm.  */

  if (comparison_p
      && ((false_code = reversed_comparison_code (cond, NULL))
	  != UNKNOWN)
      && REG_P (XEXP (cond, 0)))
    {
      HOST_WIDE_INT nzb;
      rtx from = XEXP (cond, 0);
      rtx true_val = XEXP (cond, 1);
      rtx false_val = true_val;
      int swapped = 0;

      /* If FALSE_CODE is EQ, swap the codes and arms.  */

      if (false_code == EQ)
	{
	  swapped = 1, true_code = EQ, false_code = NE;
	  std::swap (true_rtx, false_rtx);
	}

      scalar_int_mode from_mode;
      if (is_a <scalar_int_mode> (GET_MODE (from), &from_mode))
	{
	  /* If we are comparing against zero and the expression being
	     tested has only a single bit that might be nonzero, that is
	     its value when it is not equal to zero.  Similarly if it is
	     known to be -1 or 0.  */
	  if (true_code == EQ
	      && true_val == const0_rtx
	      && pow2p_hwi (nzb = nonzero_bits (from, from_mode)))
	    {
	      false_code = EQ;
	      false_val = gen_int_mode (nzb, from_mode);
	    }
	  else if (true_code == EQ
		   && true_val == const0_rtx
		   && (num_sign_bit_copies (from, from_mode)
		       == GET_MODE_PRECISION (from_mode)))
	    {
	      false_code = EQ;
	      false_val = constm1_rtx;
	    }
	}

      /* Now simplify an arm if we know the value of the register in the
	 branch and it is used in the arm.  Be careful due to the potential
	 of locally-shared RTL.  */

      if (reg_mentioned_p (from, true_rtx))
	true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code,
				      from, true_val),
			  pc_rtx, pc_rtx, 0, 0, 0);
      if (reg_mentioned_p (from, false_rtx))
	false_rtx = subst (known_cond (copy_rtx (false_rtx), false_code,
				       from, false_val),
			   pc_rtx, pc_rtx, 0, 0, 0);

      SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx);
      SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx);

      true_rtx = XEXP (x, 1);
      false_rtx = XEXP (x, 2);
      true_code = GET_CODE (cond);
    }

  /* If we have (if_then_else FOO (pc) (label_ref BAR)) and FOO can be
     reversed, do so to avoid needing two sets of patterns for
     subtract-and-branch insns.  Similarly if we have a constant in the true
     arm, the false arm is the same as the first operand of the comparison, or
     the false arm is more complicated than the true arm.  */

  if (comparison_p
      && reversed_comparison_code (cond, NULL) != UNKNOWN
      && (true_rtx == pc_rtx
	  || (CONSTANT_P (true_rtx)
	      && !CONST_INT_P (false_rtx) && false_rtx != pc_rtx)
	  || true_rtx == const0_rtx
	  || (OBJECT_P (true_rtx) && !OBJECT_P (false_rtx))
	  || (GET_CODE (true_rtx) == SUBREG && OBJECT_P (SUBREG_REG (true_rtx))
	      && !OBJECT_P (false_rtx))
	  || reg_mentioned_p (true_rtx, false_rtx)
	  || rtx_equal_p (false_rtx, XEXP (cond, 0))))
    {
      true_code = reversed_comparison_code (cond, NULL);
      SUBST (XEXP (x, 0), reversed_comparison (cond, GET_MODE (cond)));
      SUBST (XEXP (x, 1), false_rtx);
      SUBST (XEXP (x, 2), true_rtx);

      std::swap (true_rtx, false_rtx);
      cond = XEXP (x, 0);

      /* It is possible that the conditional has been simplified out.  */
      true_code = GET_CODE (cond);
      comparison_p = COMPARISON_P (cond);
    }

  /* If the two arms are identical, we don't need the comparison.  */

  if (rtx_equal_p (true_rtx, false_rtx) && ! side_effects_p (cond))
    return true_rtx;

  /* Convert a == b ? b : a to "a".  */
  if (true_code == EQ && ! side_effects_p (cond)
      && !HONOR_NANS (mode)
      && rtx_equal_p (XEXP (cond, 0), false_rtx)
      && rtx_equal_p (XEXP (cond, 1), true_rtx))
    return false_rtx;
  else if (true_code == NE && ! side_effects_p (cond)
	   && !HONOR_NANS (mode)
	   && rtx_equal_p (XEXP (cond, 0), true_rtx)
	   && rtx_equal_p (XEXP (cond, 1), false_rtx))
    return true_rtx;

  /* Look for cases where we have (abs x) or (neg (abs X)).  */

  if (GET_MODE_CLASS (mode) == MODE_INT
      && comparison_p
      && XEXP (cond, 1) == const0_rtx
      && GET_CODE (false_rtx) == NEG
      && rtx_equal_p (true_rtx, XEXP (false_rtx, 0))
      && rtx_equal_p (true_rtx, XEXP (cond, 0))
      && ! side_effects_p (true_rtx))
    switch (true_code)
      {
      case GT:
      case GE:
	return simplify_gen_unary (ABS, mode, true_rtx, mode);
      case LT:
      case LE:
	return
	  simplify_gen_unary (NEG, mode,
			      simplify_gen_unary (ABS, mode, true_rtx, mode),
			      mode);
      default:
	break;
      }

  /* Look for MIN or MAX.  */

  if ((! FLOAT_MODE_P (mode) || flag_unsafe_math_optimizations)
      && comparison_p
      && rtx_equal_p (XEXP (cond, 0), true_rtx)
      && rtx_equal_p (XEXP (cond, 1), false_rtx)
      && ! side_effects_p (cond))
    switch (true_code)
      {
      case GE:
      case GT:
	return simplify_gen_binary (SMAX, mode, true_rtx, false_rtx);
      case LE:
      case LT:
	return simplify_gen_binary (SMIN, mode, true_rtx, false_rtx);
      case GEU:
      case GTU:
	return simplify_gen_binary (UMAX, mode, true_rtx, false_rtx);
      case LEU:
      case LTU:
	return simplify_gen_binary (UMIN, mode, true_rtx, false_rtx);
      default:
	break;
      }

  /* If we have (if_then_else COND (OP Z C1) Z) and OP is an identity when its
     second operand is zero, this can be done as (OP Z (mult COND C2)) where
     C2 = C1 * STORE_FLAG_VALUE. Similarly if OP has an outer ZERO_EXTEND or
     SIGN_EXTEND as long as Z is already extended (so we don't destroy it).
     We can do this kind of thing in some cases when STORE_FLAG_VALUE is
     neither 1 or -1, but it isn't worth checking for.  */

  if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
      && comparison_p
      && is_int_mode (mode, &int_mode)
      && ! side_effects_p (x))
    {
      rtx t = make_compound_operation (true_rtx, SET);
      rtx f = make_compound_operation (false_rtx, SET);
      rtx cond_op0 = XEXP (cond, 0);
      rtx cond_op1 = XEXP (cond, 1);
      enum rtx_code op = UNKNOWN, extend_op = UNKNOWN;
      scalar_int_mode m = int_mode;
      rtx z = 0, c1 = NULL_RTX;

      if ((GET_CODE (t) == PLUS || GET_CODE (t) == MINUS
	   || GET_CODE (t) == IOR || GET_CODE (t) == XOR
	   || GET_CODE (t) == ASHIFT
	   || GET_CODE (t) == LSHIFTRT || GET_CODE (t) == ASHIFTRT)
	  && rtx_equal_p (XEXP (t, 0), f))
	c1 = XEXP (t, 1), op = GET_CODE (t), z = f;

      /* If an identity-zero op is commutative, check whether there
	 would be a match if we swapped the operands.  */
      else if ((GET_CODE (t) == PLUS || GET_CODE (t) == IOR
		|| GET_CODE (t) == XOR)
	       && rtx_equal_p (XEXP (t, 1), f))
	c1 = XEXP (t, 0), op = GET_CODE (t), z = f;
      else if (GET_CODE (t) == SIGN_EXTEND
	       && is_a <scalar_int_mode> (GET_MODE (XEXP (t, 0)), &inner_mode)
	       && (GET_CODE (XEXP (t, 0)) == PLUS
		   || GET_CODE (XEXP (t, 0)) == MINUS
		   || GET_CODE (XEXP (t, 0)) == IOR
		   || GET_CODE (XEXP (t, 0)) == XOR
		   || GET_CODE (XEXP (t, 0)) == ASHIFT
		   || GET_CODE (XEXP (t, 0)) == LSHIFTRT
		   || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
	       && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
	       && (num_sign_bit_copies (f, GET_MODE (f))
		   > (unsigned int)
		     (GET_MODE_PRECISION (int_mode)
		      - GET_MODE_PRECISION (inner_mode))))
	{
	  c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
	  extend_op = SIGN_EXTEND;
	  m = inner_mode;
	}
      else if (GET_CODE (t) == SIGN_EXTEND
	       && is_a <scalar_int_mode> (GET_MODE (XEXP (t, 0)), &inner_mode)
	       && (GET_CODE (XEXP (t, 0)) == PLUS
		   || GET_CODE (XEXP (t, 0)) == IOR
		   || GET_CODE (XEXP (t, 0)) == XOR)
	       && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
	       && (num_sign_bit_copies (f, GET_MODE (f))
		   > (unsigned int)
		     (GET_MODE_PRECISION (int_mode)
		      - GET_MODE_PRECISION (inner_mode))))
	{
	  c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
	  extend_op = SIGN_EXTEND;
	  m = inner_mode;
	}
      else if (GET_CODE (t) == ZERO_EXTEND
	       && is_a <scalar_int_mode> (GET_MODE (XEXP (t, 0)), &inner_mode)
	       && (GET_CODE (XEXP (t, 0)) == PLUS
		   || GET_CODE (XEXP (t, 0)) == MINUS
		   || GET_CODE (XEXP (t, 0)) == IOR
		   || GET_CODE (XEXP (t, 0)) == XOR
		   || GET_CODE (XEXP (t, 0)) == ASHIFT
		   || GET_CODE (XEXP (t, 0)) == LSHIFTRT
		   || GET_CODE (XEXP (t, 0)) == ASHIFTRT)
	       && GET_CODE (XEXP (XEXP (t, 0), 0)) == SUBREG
	       && HWI_COMPUTABLE_MODE_P (int_mode)
	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 0))
	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 0)), f)
	       && ((nonzero_bits (f, GET_MODE (f))
		    & ~GET_MODE_MASK (inner_mode))
		   == 0))
	{
	  c1 = XEXP (XEXP (t, 0), 1); z = f; op = GET_CODE (XEXP (t, 0));
	  extend_op = ZERO_EXTEND;
	  m = inner_mode;
	}
      else if (GET_CODE (t) == ZERO_EXTEND
	       && is_a <scalar_int_mode> (GET_MODE (XEXP (t, 0)), &inner_mode)
	       && (GET_CODE (XEXP (t, 0)) == PLUS
		   || GET_CODE (XEXP (t, 0)) == IOR
		   || GET_CODE (XEXP (t, 0)) == XOR)
	       && GET_CODE (XEXP (XEXP (t, 0), 1)) == SUBREG
	       && HWI_COMPUTABLE_MODE_P (int_mode)
	       && subreg_lowpart_p (XEXP (XEXP (t, 0), 1))
	       && rtx_equal_p (SUBREG_REG (XEXP (XEXP (t, 0), 1)), f)
	       && ((nonzero_bits (f, GET_MODE (f))
		    & ~GET_MODE_MASK (inner_mode))
		   == 0))
	{
	  c1 = XEXP (XEXP (t, 0), 0); z = f; op = GET_CODE (XEXP (t, 0));
	  extend_op = ZERO_EXTEND;
	  m = inner_mode;
	}

      if (z)
	{
	  machine_mode cm = m;
	  if ((op == ASHIFT || op == LSHIFTRT || op == ASHIFTRT)
	      && GET_MODE (c1) != VOIDmode)
	    cm = GET_MODE (c1);
	  temp = subst (simplify_gen_relational (true_code, cm, VOIDmode,
						 cond_op0, cond_op1),
			pc_rtx, pc_rtx, 0, 0, 0);
	  temp = simplify_gen_binary (MULT, cm, temp,
				      simplify_gen_binary (MULT, cm, c1,
							   const_true_rtx));
	  temp = subst (temp, pc_rtx, pc_rtx, 0, 0, 0);
	  temp = simplify_gen_binary (op, m, gen_lowpart (m, z), temp);

	  if (extend_op != UNKNOWN)
	    temp = simplify_gen_unary (extend_op, int_mode, temp, m);

	  return temp;
	}
    }

  /* If we have (if_then_else (ne A 0) C1 0) and either A is known to be 0 or
     1 and C1 is a single bit or A is known to be 0 or -1 and C1 is the
     negation of a single bit, we can convert this operation to a shift.  We
     can actually do this more generally, but it doesn't seem worth it.  */

  if (true_code == NE
      && is_a <scalar_int_mode> (mode, &int_mode)
      && XEXP (cond, 1) == const0_rtx
      && false_rtx == const0_rtx
      && CONST_INT_P (true_rtx)
      && ((nonzero_bits (XEXP (cond, 0), int_mode) == 1
	   && (i = exact_log2 (UINTVAL (true_rtx))) >= 0)
	  || ((num_sign_bit_copies (XEXP (cond, 0), int_mode)
	       == GET_MODE_PRECISION (int_mode))
	      && (i = exact_log2 (-UINTVAL (true_rtx))) >= 0)))
    return
      simplify_shift_const (NULL_RTX, ASHIFT, int_mode,
			    gen_lowpart (int_mode, XEXP (cond, 0)), i);

  /* (IF_THEN_ELSE (NE A 0) C1 0) is A or a zero-extend of A if the only
     non-zero bit in A is C1.  */
  if (true_code == NE && XEXP (cond, 1) == const0_rtx
      && false_rtx == const0_rtx && CONST_INT_P (true_rtx)
      && is_a <scalar_int_mode> (mode, &int_mode)
      && is_a <scalar_int_mode> (GET_MODE (XEXP (cond, 0)), &inner_mode)
      && (UINTVAL (true_rtx) & GET_MODE_MASK (int_mode))
	  == nonzero_bits (XEXP (cond, 0), inner_mode)
      && (i = exact_log2 (UINTVAL (true_rtx) & GET_MODE_MASK (int_mode))) >= 0)
    {
      rtx val = XEXP (cond, 0);
      if (inner_mode == int_mode)
        return val;
      else if (GET_MODE_PRECISION (inner_mode) < GET_MODE_PRECISION (int_mode))
        return simplify_gen_unary (ZERO_EXTEND, int_mode, val, inner_mode);
    }

  return x;
}

/* Simplify X, a SET expression.  Return the new expression.  */

static rtx
simplify_set (rtx x)
{
  rtx src = SET_SRC (x);
  rtx dest = SET_DEST (x);
  machine_mode mode
    = GET_MODE (src) != VOIDmode ? GET_MODE (src) : GET_MODE (dest);
  rtx_insn *other_insn;
  rtx *cc_use;
  scalar_int_mode int_mode;

  /* (set (pc) (return)) gets written as (return).  */
  if (GET_CODE (dest) == PC && ANY_RETURN_P (src))
    return src;

  /* Now that we know for sure which bits of SRC we are using, see if we can
     simplify the expression for the object knowing that we only need the
     low-order bits.  */

  if (GET_MODE_CLASS (mode) == MODE_INT && HWI_COMPUTABLE_MODE_P (mode))
    {
      src = force_to_mode (src, mode, HOST_WIDE_INT_M1U, 0);
      SUBST (SET_SRC (x), src);
    }

  /* If we are setting CC0 or if the source is a COMPARE, look for the use of
     the comparison result and try to simplify it unless we already have used
     undobuf.other_insn.  */
  if ((GET_MODE_CLASS (mode) == MODE_CC
       || GET_CODE (src) == COMPARE
       || CC0_P (dest))
      && (cc_use = find_single_use (dest, subst_insn, &other_insn)) != 0
      && (undobuf.other_insn == 0 || other_insn == undobuf.other_insn)
      && COMPARISON_P (*cc_use)
      && rtx_equal_p (XEXP (*cc_use, 0), dest))
    {
      enum rtx_code old_code = GET_CODE (*cc_use);
      enum rtx_code new_code;
      rtx op0, op1, tmp;
      int other_changed = 0;
      rtx inner_compare = NULL_RTX;
      machine_mode compare_mode = GET_MODE (dest);

      if (GET_CODE (src) == COMPARE)
	{
	  op0 = XEXP (src, 0), op1 = XEXP (src, 1);
	  if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
	    {
	      inner_compare = op0;
	      op0 = XEXP (inner_compare, 0), op1 = XEXP (inner_compare, 1);
	    }
	}
      else
	op0 = src, op1 = CONST0_RTX (GET_MODE (src));

      tmp = simplify_relational_operation (old_code, compare_mode, VOIDmode,
					   op0, op1);
      if (!tmp)
	new_code = old_code;
      else if (!CONSTANT_P (tmp))
	{
	  new_code = GET_CODE (tmp);
	  op0 = XEXP (tmp, 0);
	  op1 = XEXP (tmp, 1);
	}
      else
	{
	  rtx pat = PATTERN (other_insn);
	  undobuf.other_insn = other_insn;
	  SUBST (*cc_use, tmp);

	  /* Attempt to simplify CC user.  */
	  if (GET_CODE (pat) == SET)
	    {
	      rtx new_rtx = simplify_rtx (SET_SRC (pat));
	      if (new_rtx != NULL_RTX)
		SUBST (SET_SRC (pat), new_rtx);
	    }

	  /* Convert X into a no-op move.  */
	  SUBST (SET_DEST (x), pc_rtx);
	  SUBST (SET_SRC (x), pc_rtx);
	  return x;
	}

      /* Simplify our comparison, if possible.  */
      new_code = simplify_comparison (new_code, &op0, &op1);

#ifdef SELECT_CC_MODE
      /* If this machine has CC modes other than CCmode, check to see if we
	 need to use a different CC mode here.  */
      if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
	compare_mode = GET_MODE (op0);
      else if (inner_compare
	       && GET_MODE_CLASS (GET_MODE (inner_compare)) == MODE_CC
	       && new_code == old_code
	       && op0 == XEXP (inner_compare, 0)
	       && op1 == XEXP (inner_compare, 1))
	compare_mode = GET_MODE (inner_compare);
      else
	compare_mode = SELECT_CC_MODE (new_code, op0, op1);

      /* If the mode changed, we have to change SET_DEST, the mode in the
	 compare, and the mode in the place SET_DEST is used.  If SET_DEST is
	 a hard register, just build new versions with the proper mode.  If it
	 is a pseudo, we lose unless it is only time we set the pseudo, in
	 which case we can safely change its mode.  */
      if (!HAVE_cc0 && compare_mode != GET_MODE (dest))
	{
	  if (can_change_dest_mode (dest, 0, compare_mode))
	    {
	      unsigned int regno = REGNO (dest);
	      rtx new_dest;

	      if (regno < FIRST_PSEUDO_REGISTER)
		new_dest = gen_rtx_REG (compare_mode, regno);
	      else
		{
		  subst_mode (regno, compare_mode);
		  new_dest = regno_reg_rtx[regno];
		}

	      SUBST (SET_DEST (x), new_dest);
	      SUBST (XEXP (*cc_use, 0), new_dest);
	      other_changed = 1;

	      dest = new_dest;
	    }
	}
#endif  /* SELECT_CC_MODE */

      /* If the code changed, we have to build a new comparison in
	 undobuf.other_insn.  */
      if (new_code != old_code)
	{
	  int other_changed_previously = other_changed;
	  unsigned HOST_WIDE_INT mask;
	  rtx old_cc_use = *cc_use;

	  SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use),
					  dest, const0_rtx));
	  other_changed = 1;

	  /* If the only change we made was to change an EQ into an NE or
	     vice versa, OP0 has only one bit that might be nonzero, and OP1
	     is zero, check if changing the user of the condition code will
	     produce a valid insn.  If it won't, we can keep the original code
	     in that insn by surrounding our operation with an XOR.  */

	  if (((old_code == NE && new_code == EQ)
	       || (old_code == EQ && new_code == NE))
	      && ! other_changed_previously && op1 == const0_rtx
	      && HWI_COMPUTABLE_MODE_P (GET_MODE (op0))
	      && pow2p_hwi (mask = nonzero_bits (op0, GET_MODE (op0))))
	    {
	      rtx pat = PATTERN (other_insn), note = 0;

	      if ((recog_for_combine (&pat, other_insn, &note) < 0
		   && ! check_asm_operands (pat)))
		{
		  *cc_use = old_cc_use;
		  other_changed = 0;

		  op0 = simplify_gen_binary (XOR, GET_MODE (op0), op0,
					     gen_int_mode (mask,
							   GET_MODE (op0)));
		}
	    }
	}

      if (other_changed)
	undobuf.other_insn = other_insn;

      /* Don't generate a compare of a CC with 0, just use that CC.  */
      if (GET_MODE (op0) == compare_mode && op1 == const0_rtx)
	{
	  SUBST (SET_SRC (x), op0);
	  src = SET_SRC (x);
	}
      /* Otherwise, if we didn't previously have the same COMPARE we
	 want, create it from scratch.  */
      else if (GET_CODE (src) != COMPARE || GET_MODE (src) != compare_mode
	       || XEXP (src, 0) != op0 || XEXP (src, 1) != op1)
	{
	  SUBST (SET_SRC (x), gen_rtx_COMPARE (compare_mode, op0, op1));
	  src = SET_SRC (x);
	}
    }
  else
    {
      /* Get SET_SRC in a form where we have placed back any
	 compound expressions.  Then do the checks below.  */
      src = make_compound_operation (src, SET);
      SUBST (SET_SRC (x), src);
    }

  /* If we have (set x (subreg:m1 (op:m2 ...) 0)) with OP being some operation,
     and X being a REG or (subreg (reg)), we may be able to convert this to
     (set (subreg:m2 x) (op)).

     We can always do this if M1 is narrower than M2 because that means that
     we only care about the low bits of the result.

     However, on machines without WORD_REGISTER_OPERATIONS defined, we cannot
     perform a narrower operation than requested since the high-order bits will
     be undefined.  On machine where it is defined, this transformation is safe
     as long as M1 and M2 have the same number of words.  */

  if (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)
      && !OBJECT_P (SUBREG_REG (src))
      && (known_equal_after_align_up
	  (GET_MODE_SIZE (GET_MODE (src)),
	   GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))),
	   UNITS_PER_WORD))
      && (WORD_REGISTER_OPERATIONS || !paradoxical_subreg_p (src))
      && ! (REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER
	    && !REG_CAN_CHANGE_MODE_P (REGNO (dest),
				       GET_MODE (SUBREG_REG (src)),
				       GET_MODE (src)))
      && (REG_P (dest)
	  || (GET_CODE (dest) == SUBREG
	      && REG_P (SUBREG_REG (dest)))))
    {
      SUBST (SET_DEST (x),
	     gen_lowpart (GET_MODE (SUBREG_REG (src)),
				      dest));
      SUBST (SET_SRC (x), SUBREG_REG (src));

      src = SET_SRC (x), dest = SET_DEST (x);
    }

  /* If we have (set (cc0) (subreg ...)), we try to remove the subreg
     in SRC.  */
  if (dest == cc0_rtx
      && partial_subreg_p (src)
      && subreg_lowpart_p (src))
    {
      rtx inner = SUBREG_REG (src);
      machine_mode inner_mode = GET_MODE (inner);

      /* Here we make sure that we don't have a sign bit on.  */
      if (val_signbit_known_clear_p (GET_MODE (src),
				     nonzero_bits (inner, inner_mode)))
	{
	  SUBST (SET_SRC (x), inner);
	  src = SET_SRC (x);
	}
    }

  /* If we have (set FOO (subreg:M (mem:N BAR) 0)) with M wider than N, this
     would require a paradoxical subreg.  Replace the subreg with a
     zero_extend to avoid the reload that would otherwise be required.
     Don't do this unless we have a scalar integer mode, otherwise the
     transformation is incorrect.  */

  enum rtx_code extend_op;
  if (paradoxical_subreg_p (src)
      && MEM_P (SUBREG_REG (src))
      && SCALAR_INT_MODE_P (GET_MODE (src))
      && (extend_op = load_extend_op (GET_MODE (SUBREG_REG (src)))) != UNKNOWN)
    {
      SUBST (SET_SRC (x),
	     gen_rtx_fmt_e (extend_op, GET_MODE (src), SUBREG_REG (src)));

      src = SET_SRC (x);
    }

  /* If we don't have a conditional move, SET_SRC is an IF_THEN_ELSE, and we
     are comparing an item known to be 0 or -1 against 0, use a logical
     operation instead. Check for one of the arms being an IOR of the other
     arm with some value.  We compute three terms to be IOR'ed together.  In
     practice, at most two will be nonzero.  Then we do the IOR's.  */

  if (GET_CODE (dest) != PC
      && GET_CODE (src) == IF_THEN_ELSE
      && is_int_mode (GET_MODE (src), &int_mode)
      && (GET_CODE (XEXP (src, 0)) == EQ || GET_CODE (XEXP (src, 0)) == NE)
      && XEXP (XEXP (src, 0), 1) == const0_rtx
      && int_mode == GET_MODE (XEXP (XEXP (src, 0), 0))
      && (!HAVE_conditional_move
	  || ! can_conditionally_move_p (int_mode))
      && (num_sign_bit_copies (XEXP (XEXP (src, 0), 0), int_mode)
	  == GET_MODE_PRECISION (int_mode))
      && ! side_effects_p (src))
    {
      rtx true_rtx = (GET_CODE (XEXP (src, 0)) == NE
		      ? XEXP (src, 1) : XEXP (src, 2));
      rtx false_rtx = (GET_CODE (XEXP (src, 0)) == NE
		   ? XEXP (src, 2) : XEXP (src, 1));
      rtx term1 = const0_rtx, term2, term3;

      if (GET_CODE (true_rtx) == IOR
	  && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
	term1 = false_rtx, true_rtx = XEXP (true_rtx, 1), false_rtx = const0_rtx;
      else if (GET_CODE (true_rtx) == IOR
	       && rtx_equal_p (XEXP (true_rtx, 1), false_rtx))
	term1 = false_rtx, true_rtx = XEXP (true_rtx, 0), false_rtx = const0_rtx;
      else if (GET_CODE (false_rtx) == IOR
	       && rtx_equal_p (XEXP (false_rtx, 0), true_rtx))
	term1 = true_rtx, false_rtx = XEXP (false_rtx, 1), true_rtx = const0_rtx;
      else if (GET_CODE (false_rtx) == IOR
	       && rtx_equal_p (XEXP (false_rtx, 1), true_rtx))
	term1 = true_rtx, false_rtx = XEXP (false_rtx, 0), true_rtx = const0_rtx;

      term2 = simplify_gen_binary (AND, int_mode,
				   XEXP (XEXP (src, 0), 0), true_rtx);
      term3 = simplify_gen_binary (AND, int_mode,
				   simplify_gen_unary (NOT, int_mode,
						       XEXP (XEXP (src, 0), 0),
						       int_mode),
				   false_rtx);

      SUBST (SET_SRC (x),
	     simplify_gen_binary (IOR, int_mode,
				  simplify_gen_binary (IOR, int_mode,
						       term1, term2),
				  term3));

      src = SET_SRC (x);
    }

  /* If either SRC or DEST is a CLOBBER of (const_int 0), make this
     whole thing fail.  */
  if (GET_CODE (src) == CLOBBER && XEXP (src, 0) == const0_rtx)
    return src;
  else if (GET_CODE (dest) == CLOBBER && XEXP (dest, 0) == const0_rtx)
    return dest;
  else
    /* Convert this into a field assignment operation, if possible.  */
    return make_field_assignment (x);
}

/* Simplify, X, and AND, IOR, or XOR operation, and return the simplified
   result.  */

static rtx
simplify_logical (rtx x)
{
  rtx op0 = XEXP (x, 0);
  rtx op1 = XEXP (x, 1);
  scalar_int_mode mode;

  switch (GET_CODE (x))
    {
    case AND:
      /* We can call simplify_and_const_int only if we don't lose
	 any (sign) bits when converting INTVAL (op1) to
	 "unsigned HOST_WIDE_INT".  */
      if (is_a <scalar_int_mode> (GET_MODE (x), &mode)
	  && CONST_INT_P (op1)
	  && (HWI_COMPUTABLE_MODE_P (mode)
	      || INTVAL (op1) > 0))
	{
	  x = simplify_and_const_int (x, mode, op0, INTVAL (op1));
	  if (GET_CODE (x) != AND)
	    return x;

	  op0 = XEXP (x, 0);
	  op1 = XEXP (x, 1);
	}

      /* If we have any of (and (ior A B) C) or (and (xor A B) C),
	 apply the distributive law and then the inverse distributive
	 law to see if things simplify.  */
      if (GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
	{
	  rtx result = distribute_and_simplify_rtx (x, 0);
	  if (result)
	    return result;
	}
      if (GET_CODE (op1) == IOR || GET_CODE (op1) == XOR)
	{
	  rtx result = distribute_and_simplify_rtx (x, 1);
	  if (result)
	    return result;
	}
      break;

    case IOR:
      /* If we have (ior (and A B) C), apply the distributive law and then
	 the inverse distributive law to see if things simplify.  */

      if (GET_CODE (op0) == AND)
	{
	  rtx result = distribute_and_simplify_rtx (x, 0);
	  if (result)
	    return result;
	}

      if (GET_CODE (op1) == AND)
	{
	  rtx result = distribute_and_simplify_rtx (x, 1);
	  if (result)
	    return result;
	}
      break;

    default:
      gcc_unreachable ();
    }

  return x;
}

/* We consider ZERO_EXTRACT, SIGN_EXTRACT, and SIGN_EXTEND as "compound
   operations" because they can be replaced with two more basic operations.
   ZERO_EXTEND is also considered "compound" because it can be replaced with
   an AND operation, which is simpler, though only one operation.

   The function expand_compound_operation is called with an rtx expression
   and will convert it to the appropriate shifts and AND operations,
   simplifying at each stage.

   The function make_compound_operation is called to convert an expression
   consisting of shifts and ANDs into the equivalent compound expression.
   It is the inverse of this function, loosely speaking.  */

static rtx
expand_compound_operation (rtx x)
{
  unsigned HOST_WIDE_INT pos = 0, len;
  int unsignedp = 0;
  unsigned int modewidth;
  rtx tem;
  scalar_int_mode inner_mode;

  switch (GET_CODE (x))
    {
    case ZERO_EXTEND:
      unsignedp = 1;
      /* FALLTHRU */
    case SIGN_EXTEND:
      /* We can't necessarily use a const_int for a multiword mode;
	 it depends on implicitly extending the value.
	 Since we don't know the right way to extend it,
	 we can't tell whether the implicit way is right.

	 Even for a mode that is no wider than a const_int,
	 we can't win, because we need to sign extend one of its bits through
	 the rest of it, and we don't know which bit.  */
      if (CONST_INT_P (XEXP (x, 0)))
	return x;

      /* Reject modes that aren't scalar integers because turning vector
	 or complex modes into shifts causes problems.  */
      if (!is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &inner_mode))
	return x;

      /* Return if (subreg:MODE FROM 0) is not a safe replacement for
	 (zero_extend:MODE FROM) or (sign_extend:MODE FROM).  It is for any MEM
	 because (SUBREG (MEM...)) is guaranteed to cause the MEM to be
	 reloaded. If not for that, MEM's would very rarely be safe.

	 Reject modes bigger than a word, because we might not be able
	 to reference a two-register group starting with an arbitrary register
	 (and currently gen_lowpart might crash for a SUBREG).  */

      if (GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
	return x;

      len = GET_MODE_PRECISION (inner_mode);
      /* If the inner object has VOIDmode (the only way this can happen
	 is if it is an ASM_OPERANDS), we can't do anything since we don't
	 know how much masking to do.  */
      if (len == 0)
	return x;

      break;

    case ZERO_EXTRACT:
      unsignedp = 1;

      /* fall through */

    case SIGN_EXTRACT:
      /* If the operand is a CLOBBER, just return it.  */
      if (GET_CODE (XEXP (x, 0)) == CLOBBER)
	return XEXP (x, 0);

      if (!CONST_INT_P (XEXP (x, 1))
	  || !CONST_INT_P (XEXP (x, 2)))
	return x;

      /* Reject modes that aren't scalar integers because turning vector
	 or complex modes into shifts causes problems.  */
      if (!is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &inner_mode))
	return x;

      len = INTVAL (XEXP (x, 1));
      pos = INTVAL (XEXP (x, 2));

      /* This should stay within the object being extracted, fail otherwise.  */
      if (len + pos > GET_MODE_PRECISION (inner_mode))
	return x;

      if (BITS_BIG_ENDIAN)
	pos = GET_MODE_PRECISION (inner_mode) - len - pos;

      break;

    default:
      return x;
    }

  /* We've rejected non-scalar operations by now.  */
  scalar_int_mode mode = as_a <scalar_int_mode> (GET_MODE (x));

  /* Convert sign extension to zero extension, if we know that the high
     bit is not set, as this is easier to optimize.  It will be converted
     back to cheaper alternative in make_extraction.  */
  if (GET_CODE (x) == SIGN_EXTEND
      && HWI_COMPUTABLE_MODE_P (mode)
      && ((nonzero_bits (XEXP (x, 0), inner_mode)
	   & ~(((unsigned HOST_WIDE_INT) GET_MODE_MASK (inner_mode)) >> 1))
	  == 0))
    {
      rtx temp = gen_rtx_ZERO_EXTEND (mode, XEXP (x, 0));
      rtx temp2 = expand_compound_operation (temp);

      /* Make sure this is a profitable operation.  */
      if (set_src_cost (x, mode, optimize_this_for_speed_p)
          > set_src_cost (temp2, mode, optimize_this_for_speed_p))
       return temp2;
      else if (set_src_cost (x, mode, optimize_this_for_speed_p)
               > set_src_cost (temp, mode, optimize_this_for_speed_p))
       return temp;
      else
       return x;
    }

  /* We can optimize some special cases of ZERO_EXTEND.  */
  if (GET_CODE (x) == ZERO_EXTEND)
    {
      /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI if we
	 know that the last value didn't have any inappropriate bits
	 set.  */
      if (GET_CODE (XEXP (x, 0)) == TRUNCATE
	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode
	  && HWI_COMPUTABLE_MODE_P (mode)
	  && (nonzero_bits (XEXP (XEXP (x, 0), 0), mode)
	      & ~GET_MODE_MASK (inner_mode)) == 0)
	return XEXP (XEXP (x, 0), 0);

      /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
      if (GET_CODE (XEXP (x, 0)) == SUBREG
	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == mode
	  && subreg_lowpart_p (XEXP (x, 0))
	  && HWI_COMPUTABLE_MODE_P (mode)
	  && (nonzero_bits (SUBREG_REG (XEXP (x, 0)), mode)
	      & ~GET_MODE_MASK (inner_mode)) == 0)
	return SUBREG_REG (XEXP (x, 0));

      /* (zero_extend:DI (truncate:SI foo:DI)) is just foo:DI when foo
	 is a comparison and STORE_FLAG_VALUE permits.  This is like
	 the first case, but it works even when MODE is larger
	 than HOST_WIDE_INT.  */
      if (GET_CODE (XEXP (x, 0)) == TRUNCATE
	  && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode
	  && COMPARISON_P (XEXP (XEXP (x, 0), 0))
	  && GET_MODE_PRECISION (inner_mode) <= HOST_BITS_PER_WIDE_INT
	  && (STORE_FLAG_VALUE & ~GET_MODE_MASK (inner_mode)) == 0)
	return XEXP (XEXP (x, 0), 0);

      /* Likewise for (zero_extend:DI (subreg:SI foo:DI 0)).  */
      if (GET_CODE (XEXP (x, 0)) == SUBREG
	  && GET_MODE (SUBREG_REG (XEXP (x, 0))) == mode
	  && subreg_lowpart_p (XEXP (x, 0))
	  && COMPARISON_P (SUBREG_REG (XEXP (x, 0)))
	  && GET_MODE_PRECISION (inner_mode) <= HOST_BITS_PER_WIDE_INT
	  && (STORE_FLAG_VALUE & ~GET_MODE_MASK (inner_mode)) == 0)
	return SUBREG_REG (XEXP (x, 0));

    }

  /* If we reach here, we want to return a pair of shifts.  The inner
     shift is a left shift of BITSIZE - POS - LEN bits.  The outer
     shift is a right shift of BITSIZE - LEN bits.  It is arithmetic or
     logical depending on the value of UNSIGNEDP.

     If this was a ZERO_EXTEND or ZERO_EXTRACT, this pair of shifts will be
     converted into an AND of a shift.

     We must check for the case where the left shift would have a negative
     count.  This can happen in a case like (x >> 31) & 255 on machines
     that can't shift by a constant.  On those machines, we would first
     combine the shift with the AND to produce a variable-position
     extraction.  Then the constant of 31 would be substituted in
     to produce such a position.  */

  modewidth = GET_MODE_PRECISION (mode);
  if (modewidth >= pos + len)
    {
      tem = gen_lowpart (mode, XEXP (x, 0));
      if (!tem || GET_CODE (tem) == CLOBBER)
	return x;
      tem = simplify_shift_const (NULL_RTX, ASHIFT, mode,
				  tem, modewidth - pos - len);
      tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT : ASHIFTRT,
				  mode, tem, modewidth - len);
    }
  else if (unsignedp && len < HOST_BITS_PER_WIDE_INT)
    {
      tem = simplify_shift_const (NULL_RTX, LSHIFTRT, inner_mode,
				  XEXP (x, 0), pos);
      tem = gen_lowpart (mode, tem);
      if (!tem || GET_CODE (tem) == CLOBBER)
	return x;
      tem = simplify_and_const_int (NULL_RTX, mode, tem,
				    (HOST_WIDE_INT_1U << len) - 1);
    }
  else
    /* Any other cases we can't handle.  */
    return x;

  /* If we couldn't do this for some reason, return the original
     expression.  */
  if (GET_CODE (tem) == CLOBBER)
    return x;

  return tem;
}

/* X is a SET which contains an assignment of one object into
   a part of another (such as a bit-field assignment, STRICT_LOW_PART,
   or certain SUBREGS). If possible, convert it into a series of
   logical operations.

   We half-heartedly support variable positions, but do not at all
   support variable lengths.  */

static const_rtx
expand_field_assignment (const_rtx x)
{
  rtx inner;
  rtx pos;			/* Always counts from low bit.  */
  int len, inner_len;
  rtx mask, cleared, masked;
  scalar_int_mode compute_mode;

  /* Loop until we find something we can't simplify.  */
  while (1)
    {
      if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
	  && GET_CODE (XEXP (SET_DEST (x), 0)) == SUBREG)
	{
	  rtx x0 = XEXP (SET_DEST (x), 0);
	  if (!GET_MODE_PRECISION (GET_MODE (x0)).is_constant (&len))
	    break;
	  inner = SUBREG_REG (XEXP (SET_DEST (x), 0));
	  pos = gen_int_mode (subreg_lsb (XEXP (SET_DEST (x), 0)),
			      MAX_MODE_INT);
	}
      else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
	       && CONST_INT_P (XEXP (SET_DEST (x), 1)))
	{
	  inner = XEXP (SET_DEST (x), 0);
	  if (!GET_MODE_PRECISION (GET_MODE (inner)).is_constant (&inner_len))
	    break;

	  len = INTVAL (XEXP (SET_DEST (x), 1));
	  pos = XEXP (SET_DEST (x), 2);

	  /* A constant position should stay within the width of INNER.  */
	  if (CONST_INT_P (pos) && INTVAL (pos) + len > inner_len)
	    break;

	  if (BITS_BIG_ENDIAN)
	    {
	      if (CONST_INT_P (pos))
		pos = GEN_INT (inner_len - len - INTVAL (pos));
	      else if (GET_CODE (pos) == MINUS
		       && CONST_INT_P (XEXP (pos, 1))
		       && INTVAL (XEXP (pos, 1)) == inner_len - len)
		/* If position is ADJUST - X, new position is X.  */
		pos = XEXP (pos, 0);
	      else
		pos = simplify_gen_binary (MINUS, GET_MODE (pos),
					   gen_int_mode (inner_len - len,
							 GET_MODE (pos)),
					   pos);
	    }
	}

      /* If the destination is a subreg that overwrites the whole of the inner
	 register, we can move the subreg to the source.  */
      else if (GET_CODE (SET_DEST (x)) == SUBREG
	       /* We need SUBREGs to compute nonzero_bits properly.  */
	       && nonzero_sign_valid
	       && !read_modify_subreg_p (SET_DEST (x)))
	{
	  x = gen_rtx_SET (SUBREG_REG (SET_DEST (x)),
			   gen_lowpart
			   (GET_MODE (SUBREG_REG (SET_DEST (x))),
			    SET_SRC (x)));
	  continue;
	}
      else
	break;

      while (GET_CODE (inner) == SUBREG && subreg_lowpart_p (inner))
	inner = SUBREG_REG (inner);

      /* Don't attempt bitwise arithmetic on non scalar integer modes.  */
      if (!is_a <scalar_int_mode> (GET_MODE (inner), &compute_mode))
	{
	  /* Don't do anything for vector or complex integral types.  */
	  if (! FLOAT_MODE_P (GET_MODE (inner)))
	    break;

	  /* Try to find an integral mode to pun with.  */
	  if (!int_mode_for_size (GET_MODE_BITSIZE (GET_MODE (inner)), 0)
	      .exists (&compute_mode))
	    break;

	  inner = gen_lowpart (compute_mode, inner);
	}

      /* Compute a mask of LEN bits, if we can do this on the host machine.  */
      if (len >= HOST_BITS_PER_WIDE_INT)
	break;

      /* Don't try to compute in too wide unsupported modes.  */
      if (!targetm.scalar_mode_supported_p (compute_mode))
	break;

      /* Now compute the equivalent expression.  Make a copy of INNER
	 for the SET_DEST in case it is a MEM into which we will substitute;
	 we don't want shared RTL in that case.  */
      mask = gen_int_mode ((HOST_WIDE_INT_1U << len) - 1,
			   compute_mode);
      cleared = simplify_gen_binary (AND, compute_mode,
				     simplify_gen_unary (NOT, compute_mode,
				       simplify_gen_binary (ASHIFT,
							    compute_mode,
							    mask, pos),
				       compute_mode),
				     inner);
      masked = simplify_gen_binary (ASHIFT, compute_mode,
				    simplify_gen_binary (
				      AND, compute_mode,
				      gen_lowpart (compute_mode, SET_SRC (x)),
				      mask),
				    pos);

      x = gen_rtx_SET (copy_rtx (inner),
		       simplify_gen_binary (IOR, compute_mode,
					    cleared, masked));
    }

  return x;
}

/* Return an RTX for a reference to LEN bits of INNER.  If POS_RTX is nonzero,
   it is an RTX that represents the (variable) starting position; otherwise,
   POS is the (constant) starting bit position.  Both are counted from the LSB.

   UNSIGNEDP is nonzero for an unsigned reference and zero for a signed one.

   IN_DEST is nonzero if this is a reference in the destination of a SET.
   This is used when a ZERO_ or SIGN_EXTRACT isn't needed.  If nonzero,
   a STRICT_LOW_PART will be used, if zero, ZERO_EXTEND or SIGN_EXTEND will
   be used.

   IN_COMPARE is nonzero if we are in a COMPARE.  This means that a
   ZERO_EXTRACT should be built even for bits starting at bit 0.

   MODE is the desired mode of the result (if IN_DEST == 0).

   The result is an RTX for the extraction or NULL_RTX if the target
   can't handle it.  */

static rtx
make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
		 rtx pos_rtx, unsigned HOST_WIDE_INT len, int unsignedp,
		 int in_dest, int in_compare)
{
  /* This mode describes the size of the storage area
     to fetch the overall value from.  Within that, we
     ignore the POS lowest bits, etc.  */
  machine_mode is_mode = GET_MODE (inner);
  machine_mode inner_mode;
  scalar_int_mode wanted_inner_mode;
  scalar_int_mode wanted_inner_reg_mode = word_mode;
  scalar_int_mode pos_mode = word_mode;
  machine_mode extraction_mode = word_mode;
  rtx new_rtx = 0;
  rtx orig_pos_rtx = pos_rtx;
  HOST_WIDE_INT orig_pos;

  if (pos_rtx && CONST_INT_P (pos_rtx))
    pos = INTVAL (pos_rtx), pos_rtx = 0;

  if (GET_CODE (inner) == SUBREG
      && subreg_lowpart_p (inner)
      && (paradoxical_subreg_p (inner)
	  /* If trying or potentionally trying to extract
	     bits outside of is_mode, don't look through
	     non-paradoxical SUBREGs.  See PR82192.  */
	  || (pos_rtx == NULL_RTX
	      && known_le (pos + len, GET_MODE_PRECISION (is_mode)))))
    {
      /* If going from (subreg:SI (mem:QI ...)) to (mem:QI ...),
	 consider just the QI as the memory to extract from.
	 The subreg adds or removes high bits; its mode is
	 irrelevant to the meaning of this extraction,
	 since POS and LEN count from the lsb.  */
      if (MEM_P (SUBREG_REG (inner)))
	is_mode = GET_MODE (SUBREG_REG (inner));
      inner = SUBREG_REG (inner);
    }
  else if (GET_CODE (inner) == ASHIFT
	   && CONST_INT_P (XEXP (inner, 1))
	   && pos_rtx == 0 && pos == 0
	   && len > UINTVAL (XEXP (inner, 1)))
    {
      /* We're extracting the least significant bits of an rtx
	 (ashift X (const_int C)), where LEN > C.  Extract the
	 least significant (LEN - C) bits of X, giving an rtx
	 whose mode is MODE, then shift it left C times.  */
      new_rtx = make_extraction (mode, XEXP (inner, 0),
			     0, 0, len - INTVAL (XEXP (inner, 1)),
			     unsignedp, in_dest, in_compare);
      if (new_rtx != 0)
	return gen_rtx_ASHIFT (mode, new_rtx, XEXP (inner, 1));
    }
  else if (GET_CODE (inner) == TRUNCATE
	   /* If trying or potentionally trying to extract
	      bits outside of is_mode, don't look through
	      TRUNCATE.  See PR82192.  */
	   && pos_rtx == NULL_RTX
	   && known_le (pos + len, GET_MODE_PRECISION (is_mode)))
    inner = XEXP (inner, 0);

  inner_mode = GET_MODE (inner);

  /* See if this can be done without an extraction.  We never can if the
     width of the field is not the same as that of some integer mode. For
     registers, we can only avoid the extraction if the position is at the
     low-order bit and this is either not in the destination or we have the
     appropriate STRICT_LOW_PART operation available.

     For MEM, we can avoid an extract if the field starts on an appropriate
     boundary and we can change the mode of the memory reference.  */

  scalar_int_mode tmode;
  if (int_mode_for_size (len, 1).exists (&tmode)
      && ((pos_rtx == 0 && (pos % BITS_PER_WORD) == 0
	   && !MEM_P (inner)
	   && (pos == 0 || REG_P (inner))
	   && (inner_mode == tmode
	       || !REG_P (inner)
	       || TRULY_NOOP_TRUNCATION_MODES_P (tmode, inner_mode)
	       || reg_truncated_to_mode (tmode, inner))
	   && (! in_dest
	       || (REG_P (inner)
		   && have_insn_for (STRICT_LOW_PART, tmode))))
	  || (MEM_P (inner) && pos_rtx == 0
	      && (pos
		  % (STRICT_ALIGNMENT ? GET_MODE_ALIGNMENT (tmode)
		     : BITS_PER_UNIT)) == 0
	      /* We can't do this if we are widening INNER_MODE (it
		 may not be aligned, for one thing).  */
	      && !paradoxical_subreg_p (tmode, inner_mode)
	      && known_le (pos + len, GET_MODE_PRECISION (is_mode))
	      && (inner_mode == tmode
		  || (! mode_dependent_address_p (XEXP (inner, 0),
						  MEM_ADDR_SPACE (inner))
		      && ! MEM_VOLATILE_P (inner))))))
    {
      /* If INNER is a MEM, make a new MEM that encompasses just the desired
	 field.  If the original and current mode are the same, we need not
	 adjust the offset.  Otherwise, we do if bytes big endian.

	 If INNER is not a MEM, get a piece consisting of just the field
	 of interest (in this case POS % BITS_PER_WORD must be 0).  */

      if (MEM_P (inner))
	{
	  poly_int64 offset;

	  /* POS counts from lsb, but make OFFSET count in memory order.  */
	  if (BYTES_BIG_ENDIAN)
	    offset = bits_to_bytes_round_down (GET_MODE_PRECISION (is_mode)
					       - len - pos);
	  else
	    offset = pos / BITS_PER_UNIT;

	  new_rtx = adjust_address_nv (inner, tmode, offset);
	}
      else if (REG_P (inner))
	{
	  if (tmode != inner_mode)
	    {
	      /* We can't call gen_lowpart in a DEST since we
		 always want a SUBREG (see below) and it would sometimes
		 return a new hard register.  */
	      if (pos || in_dest)
		{
		  poly_uint64 offset
		    = subreg_offset_from_lsb (tmode, inner_mode, pos);

		  /* Avoid creating invalid subregs, for example when
		     simplifying (x>>32)&255.  */
		  if (!validate_subreg (tmode, inner_mode, inner, offset))
		    return NULL_RTX;

		  new_rtx = gen_rtx_SUBREG (tmode, inner, offset);
		}
	      else
		new_rtx = gen_lowpart (tmode, inner);
	    }
	  else
	    new_rtx = inner;
	}
      else
	new_rtx = force_to_mode (inner, tmode,
				 len >= HOST_BITS_PER_WIDE_INT
				 ? HOST_WIDE_INT_M1U
				 : (HOST_WIDE_INT_1U << len) - 1, 0);

      /* If this extraction is going into the destination of a SET,
	 make a STRICT_LOW_PART unless we made a MEM.  */

      if (in_dest)
	return (MEM_P (new_rtx) ? new_rtx
		: (GET_CODE (new_rtx) != SUBREG
		   ? gen_rtx_CLOBBER (tmode, const0_rtx)
		   : gen_rtx_STRICT_LOW_PART (VOIDmode, new_rtx)));

      if (mode == tmode)
	return new_rtx;

      if (CONST_SCALAR_INT_P (new_rtx))
	return simplify_unary_operation (unsignedp ? ZERO_EXTEND : SIGN_EXTEND,
					 mode, new_rtx, tmode);

      /* If we know that no extraneous bits are set, and that the high
	 bit is not set, convert the extraction to the cheaper of
	 sign and zero extension, that are equivalent in these cases.  */
      if (flag_expensive_optimizations
	  && (HWI_COMPUTABLE_MODE_P (tmode)
	      && ((nonzero_bits (new_rtx, tmode)
		   & ~(((unsigned HOST_WIDE_INT)GET_MODE_MASK (tmode)) >> 1))
		  == 0)))
	{
	  rtx temp = gen_rtx_ZERO_EXTEND (mode, new_rtx);
	  rtx temp1 = gen_rtx_SIGN_EXTEND (mode, new_rtx);

	  /* Prefer ZERO_EXTENSION, since it gives more information to
	     backends.  */
	  if (set_src_cost (temp, mode, optimize_this_for_speed_p)
	      <= set_src_cost (temp1, mode, optimize_this_for_speed_p))
	    return temp;
	  return temp1;
	}

      /* Otherwise, sign- or zero-extend unless we already are in the
	 proper mode.  */

      return (gen_rtx_fmt_e (unsignedp ? ZERO_EXTEND : SIGN_EXTEND,
			     mode, new_rtx));
    }

  /* Unless this is a COMPARE or we have a funny memory reference,
     don't do anything with zero-extending field extracts starting at
     the low-order bit since they are simple AND operations.  */
  if (pos_rtx == 0 && pos == 0 && ! in_dest
      && ! in_compare && unsignedp)
    return 0;

  /* Unless INNER is not MEM, reject this if we would be spanning bytes or
     if the position is not a constant and the length is not 1.  In all
     other cases, we would only be going outside our object in cases when
     an original shift would have been undefined.  */
  if (MEM_P (inner)
      && ((pos_rtx == 0 && maybe_gt (pos + len, GET_MODE_PRECISION (is_mode)))
	  || (pos_rtx != 0 && len != 1)))
    return 0;

  enum extraction_pattern pattern = (in_dest ? EP_insv
				     : unsignedp ? EP_extzv : EP_extv);

  /* If INNER is not from memory, we want it to have the mode of a register
     extraction pattern's structure operand, or word_mode if there is no
     such pattern.  The same applies to extraction_mode and pos_mode
     and their respective operands.

     For memory, assume that the desired extraction_mode and pos_mode
     are the same as for a register operation, since at present we don't
     have named patterns for aligned memory structures.  */
  struct extraction_insn insn;
  unsigned int inner_size;
  if (GET_MODE_BITSIZE (inner_mode).is_constant (&inner_size)
      && get_best_reg_extraction_insn (&insn, pattern, inner_size, mode))
    {
      wanted_inner_reg_mode = insn.struct_mode.require ();
      pos_mode = insn.pos_mode;
      extraction_mode = insn.field_mode;
    }

  /* Never narrow an object, since that might not be safe.  */

  if (mode != VOIDmode
      && partial_subreg_p (extraction_mode, mode))
    extraction_mode = mode;

  /* Punt if len is too large for extraction_mode.  */
  if (maybe_gt (len, GET_MODE_PRECISION (extraction_mode)))
    return NULL_RTX;

  if (!MEM_P (inner))
    wanted_inner_mode = wanted_inner_reg_mode;
  else
    {
      /* Be careful not to go beyond the extracted object and maintain the
	 natural alignment of the memory.  */
      wanted_inner_mode = smallest_int_mode_for_size (len);
      while (pos % GET_MODE_BITSIZE (wanted_inner_mode) + len
	     > GET_MODE_BITSIZE (wanted_inner_mode))
	wanted_inner_mode = GET_MODE_WIDER_MODE (wanted_inner_mode).require ();
    }

  orig_pos = pos;

  if (BITS_BIG_ENDIAN)
    {
      /* POS is passed as if BITS_BIG_ENDIAN == 0, so we need to convert it to
	 BITS_BIG_ENDIAN style.  If position is constant, compute new
	 position.  Otherwise, build subtraction.
	 Note that POS is relative to the mode of the original argument.
	 If it's a MEM we need to recompute POS relative to that.
	 However, if we're extracting from (or inserting into) a register,
	 we want to recompute POS relative to wanted_inner_mode.  */
      int width;
      if (!MEM_P (inner))
	width = GET_MODE_BITSIZE (wanted_inner_mode);
      else if (!GET_MODE_BITSIZE (is_mode).is_constant (&width))
	return NULL_RTX;

      if (pos_rtx == 0)
	pos = width - len - pos;
      else
	pos_rtx
	  = gen_rtx_MINUS (GET_MODE (pos_rtx),
			   gen_int_mode (width - len, GET_MODE (pos_rtx)),
			   pos_rtx);
      /* POS may be less than 0 now, but we check for that below.
	 Note that it can only be less than 0 if !MEM_P (inner).  */
    }

  /* If INNER has a wider mode, and this is a constant extraction, try to
     make it smaller and adjust the byte to point to the byte containing
     the value.  */
  if (wanted_inner_mode != VOIDmode
      && inner_mode != wanted_inner_mode
      && ! pos_rtx
      && partial_subreg_p (wanted_inner_mode, is_mode)
      && MEM_P (inner)
      && ! mode_dependent_address_p (XEXP (inner, 0), MEM_ADDR_SPACE (inner))
      && ! MEM_VOLATILE_P (inner))
    {
      poly_int64 offset = 0;

      /* The computations below will be correct if the machine is big
	 endian in both bits and bytes or little endian in bits and bytes.
	 If it is mixed, we must adjust.  */

      /* If bytes are big endian and we had a paradoxical SUBREG, we must
	 adjust OFFSET to compensate.  */
      if (BYTES_BIG_ENDIAN
	  && paradoxical_subreg_p (is_mode, inner_mode))
	offset -= GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (inner_mode);

      /* We can now move to the desired byte.  */
      offset += (pos / GET_MODE_BITSIZE (wanted_inner_mode))
		* GET_MODE_SIZE (wanted_inner_mode);
      pos %= GET_MODE_BITSIZE (wanted_inner_mode);

      if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN
	  && is_mode != wanted_inner_mode)
	offset = (GET_MODE_SIZE (is_mode)
		  - GET_MODE_SIZE (wanted_inner_mode) - offset);

      inner = adjust_address_nv (inner, wanted_inner_mode, offset);
    }

  /* If INNER is not memory, get it into the proper mode.  If we are changing
     its mode, POS must be a constant and smaller than the size of the new
     mode.  */
  else if (!MEM_P (inner))
    {
      /* On the LHS, don't create paradoxical subregs implicitely truncating
	 the register unless TARGET_TRULY_NOOP_TRUNCATION.  */
      if (in_dest
	  && !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (inner),
					     wanted_inner_mode))
	return NULL_RTX;

      if (GET_MODE (inner) != wanted_inner_mode
	  && (pos_rtx != 0
	      || orig_pos + len > GET_MODE_BITSIZE (wanted_inner_mode)))
	return NULL_RTX;

      if (orig_pos < 0)
	return NULL_RTX;

      inner = force_to_mode (inner, wanted_inner_mode,
			     pos_rtx
			     || len + orig_pos >= HOST_BITS_PER_WIDE_INT
			     ? HOST_WIDE_INT_M1U
			     : (((HOST_WIDE_INT_1U << len) - 1)
				<< orig_pos),
			     0);
    }

  /* Adjust mode of POS_RTX, if needed.  If we want a wider mode, we
     have to zero extend.  Otherwise, we can just use a SUBREG.

     We dealt with constant rtxes earlier, so pos_rtx cannot
     have VOIDmode at this point.  */
  if (pos_rtx != 0
      && (GET_MODE_SIZE (pos_mode)
	  > GET_MODE_SIZE (as_a <scalar_int_mode> (GET_MODE (pos_rtx)))))
    {
      rtx temp = simplify_gen_unary (ZERO_EXTEND, pos_mode, pos_rtx,
				     GET_MODE (pos_rtx));

      /* If we know that no extraneous bits are set, and that the high
	 bit is not set, convert extraction to cheaper one - either
	 SIGN_EXTENSION or ZERO_EXTENSION, that are equivalent in these
	 cases.  */
      if (flag_expensive_optimizations
	  && (HWI_COMPUTABLE_MODE_P (GET_MODE (pos_rtx))
	      && ((nonzero_bits (pos_rtx, GET_MODE (pos_rtx))
		   & ~(((unsigned HOST_WIDE_INT)
			GET_MODE_MASK (GET_MODE (pos_rtx)))
		       >> 1))
		  == 0)))
	{
	  rtx temp1 = simplify_gen_unary (SIGN_EXTEND, pos_mode, pos_rtx,
					  GET_MODE (pos_rtx));

	  /* Prefer ZERO_EXTENSION, since it gives more information to
	     backends.  */
	  if (set_src_cost (temp1, pos_mode, optimize_this_for_speed_p)
	      < set_src_cost (temp, pos_mode, optimize_this_for_speed_p))
	    temp = temp1;
	}
      pos_rtx = temp;
    }

  /* Make POS_RTX unless we already have it and it is correct.  If we don't
     have a POS_RTX but we do have an ORIG_POS_RTX, the latter must
     be a CONST_INT.  */
  if (pos_rtx == 0 && orig_pos_rtx != 0 && INTVAL (orig_pos_rtx) == pos)
    pos_rtx = orig_pos_rtx;

  else if (pos_rtx == 0)
    pos_rtx = GEN_INT (pos);

  /* Make the required operation.  See if we can use existing rtx.  */
  new_rtx = gen_rtx_fmt_eee (unsignedp ? ZERO_EXTRACT : SIGN_EXTRACT,
			 extraction_mode, inner, GEN_INT (len), pos_rtx);
  if (! in_dest)
    new_rtx = gen_lowpart (mode, new_rtx);

  return new_rtx;
}

/* See if X (of mode MODE) contains an ASHIFT of COUNT or more bits that
   can be commuted with any other operations in X.  Return X without
   that shift if so.  */

static rtx
extract_left_shift (scalar_int_mode mode, rtx x, int count)
{
  enum rtx_code code = GET_CODE (x);
  rtx tem;

  switch (code)
    {
    case ASHIFT:
      /* This is the shift itself.  If it is wide enough, we will return
	 either the value being shifted if the shift count is equal to
	 COUNT or a shift for the difference.  */
      if (CONST_INT_P (XEXP (x, 1))
	  && INTVAL (XEXP (x, 1)) >= count)
	return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (x, 0),
				     INTVAL (XEXP (x, 1)) - count);
      break;

    case NEG:  case NOT:
      if ((tem = extract_left_shift (mode, XEXP (x, 0), count)) != 0)
	return simplify_gen_unary (code, mode, tem, mode);

      break;

    case PLUS:  case IOR:  case XOR:  case AND:
      /* If we can safely shift this constant and we find the inner shift,
	 make a new operation.  */
      if (CONST_INT_P (XEXP (x, 1))
	  && (UINTVAL (XEXP (x, 1))
	      & (((HOST_WIDE_INT_1U << count)) - 1)) == 0
	  && (tem = extract_left_shift (mode, XEXP (x, 0), count)) != 0)
	{
	  HOST_WIDE_INT val = INTVAL (XEXP (x, 1)) >> count;
	  return simplify_gen_binary (code, mode, tem,
				      gen_int_mode (val, mode));
	}
      break;

    default:
      break;
    }

  return 0;
}

/* Subroutine of make_compound_operation.  *X_PTR is the rtx at the current
   level of the expression and MODE is its mode.  IN_CODE is as for
   make_compound_operation.  *NEXT_CODE_PTR is the value of IN_CODE
   that should be used when recursing on operands of *X_PTR.

   There are two possible actions:

   - Return null.  This tells the caller to recurse on *X_PTR with IN_CODE
     equal to *NEXT_CODE_PTR, after which *X_PTR holds the final value.

   - Return a new rtx, which the caller returns directly.  */

static rtx
make_compound_operation_int (scalar_int_mode mode, rtx *x_ptr,
			     enum rtx_code in_code,
			     enum rtx_code *next_code_ptr)
{
  rtx x = *x_ptr;
  enum rtx_code next_code = *next_code_ptr;
  enum rtx_code code = GET_CODE (x);
  int mode_width = GET_MODE_PRECISION (mode);
  rtx rhs, lhs;
  rtx new_rtx = 0;
  int i;
  rtx tem;
  scalar_int_mode inner_mode;
  bool equality_comparison = false;

  if (in_code == EQ)
    {
      equality_comparison = true;
      in_code = COMPARE;
    }

  /* Process depending on the code of this operation.  If NEW is set
     nonzero, it will be returned.  */

  switch (code)
    {
    case ASHIFT:
      /* Convert shifts by constants into multiplications if inside
	 an address.  */
      if (in_code == MEM && CONST_INT_P (XEXP (x, 1))
	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
	  && INTVAL (XEXP (x, 1)) >= 0)
	{
	  HOST_WIDE_INT count = INTVAL (XEXP (x, 1));
	  HOST_WIDE_INT multval = HOST_WIDE_INT_1 << count;

	  new_rtx = make_compound_operation (XEXP (x, 0), next_code);
	  if (GET_CODE (new_rtx) == NEG)
	    {
	      new_rtx = XEXP (new_rtx, 0);
	      multval = -multval;
	    }
	  multval = trunc_int_for_mode (multval, mode);
	  new_rtx = gen_rtx_MULT (mode, new_rtx, gen_int_mode (multval, mode));
	}
      break;

    case PLUS:
      lhs = XEXP (x, 0);
      rhs = XEXP (x, 1);
      lhs = make_compound_operation (lhs, next_code);
      rhs = make_compound_operation (rhs, next_code);
      if (GET_CODE (lhs) == MULT && GET_CODE (XEXP (lhs, 0)) == NEG)
	{
	  tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (lhs, 0), 0),
				     XEXP (lhs, 1));
	  new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem);
	}
      else if (GET_CODE (lhs) == MULT
	       && (CONST_INT_P (XEXP (lhs, 1)) && INTVAL (XEXP (lhs, 1)) < 0))
	{
	  tem = simplify_gen_binary (MULT, mode, XEXP (lhs, 0),
				     simplify_gen_unary (NEG, mode,
							 XEXP (lhs, 1),
							 mode));
	  new_rtx = simplify_gen_binary (MINUS, mode, rhs, tem);
	}
      else
	{
	  SUBST (XEXP (x, 0), lhs);
	  SUBST (XEXP (x, 1), rhs);
	}
      maybe_swap_commutative_operands (x);
      return x;

    case MINUS:
      lhs = XEXP (x, 0);
      rhs = XEXP (x, 1);
      lhs = make_compound_operation (lhs, next_code);
      rhs = make_compound_operation (rhs, next_code);
      if (GET_CODE (rhs) == MULT && GET_CODE (XEXP (rhs, 0)) == NEG)
	{
	  tem = simplify_gen_binary (MULT, mode, XEXP (XEXP (rhs, 0), 0),
				     XEXP (rhs, 1));
	  return simplify_gen_binary (PLUS, mode, tem, lhs);
	}
      else if (GET_CODE (rhs) == MULT
	       && (CONST_INT_P (XEXP (rhs, 1)) && INTVAL (XEXP (rhs, 1)) < 0))
	{
	  tem = simplify_gen_binary (MULT, mode, XEXP (rhs, 0),
				     simplify_gen_unary (NEG, mode,
							 XEXP (rhs, 1),
							 mode));
	  return simplify_gen_binary (PLUS, mode, tem, lhs);
	}
      else
	{
	  SUBST (XEXP (x, 0), lhs);
	  SUBST (XEXP (x, 1), rhs);
	  return x;
	}

    case AND:
      /* If the second operand is not a constant, we can't do anything
	 with it.  */
      if (!CONST_INT_P (XEXP (x, 1)))
	break;

      /* If the constant is a power of two minus one and the first operand
	 is a logical right shift, make an extraction.  */
      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
	  && (i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0)
	{
	  new_rtx = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
	  new_rtx = make_extraction (mode, new_rtx, 0, XEXP (XEXP (x, 0), 1),
				     i, 1, 0, in_code == COMPARE);
	}

      /* Same as previous, but for (subreg (lshiftrt ...)) in first op.  */
      else if (GET_CODE (XEXP (x, 0)) == SUBREG
	       && subreg_lowpart_p (XEXP (x, 0))
	       && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (XEXP (x, 0))),
					  &inner_mode)
	       && GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
	       && (i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0)
	{
	  rtx inner_x0 = SUBREG_REG (XEXP (x, 0));
	  new_rtx = make_compound_operation (XEXP (inner_x0, 0), next_code);
	  new_rtx = make_extraction (inner_mode, new_rtx, 0,
				     XEXP (inner_x0, 1),
				     i, 1, 0, in_code == COMPARE);

	  /* If we narrowed the mode when dropping the subreg, then we lose.  */
	  if (GET_MODE_SIZE (inner_mode) < GET_MODE_SIZE (mode))
	    new_rtx = NULL;

	  /* If that didn't give anything, see if the AND simplifies on
	     its own.  */
	  if (!new_rtx && i >= 0)
	    {
	      new_rtx = make_compound_operation (XEXP (x, 0), next_code);
	      new_rtx = make_extraction (mode, new_rtx, 0, NULL_RTX, i, 1,
					 0, in_code == COMPARE);
	    }
	}
      /* Same as previous, but for (xor/ior (lshiftrt...) (lshiftrt...)).  */
      else if ((GET_CODE (XEXP (x, 0)) == XOR
		|| GET_CODE (XEXP (x, 0)) == IOR)
	       && GET_CODE (XEXP (XEXP (x, 0), 0)) == LSHIFTRT
	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == LSHIFTRT
	       && (i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0)
	{
	  /* Apply the distributive law, and then try to make extractions.  */
	  new_rtx = gen_rtx_fmt_ee (GET_CODE (XEXP (x, 0)), mode,
				    gen_rtx_AND (mode, XEXP (XEXP (x, 0), 0),
						 XEXP (x, 1)),
				    gen_rtx_AND (mode, XEXP (XEXP (x, 0), 1),
						 XEXP (x, 1)));
	  new_rtx = make_compound_operation (new_rtx, in_code);
	}

      /* If we are have (and (rotate X C) M) and C is larger than the number
	 of bits in M, this is an extraction.  */

      else if (GET_CODE (XEXP (x, 0)) == ROTATE
	       && CONST_INT_P (XEXP (XEXP (x, 0), 1))
	       && (i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0
	       && i <= INTVAL (XEXP (XEXP (x, 0), 1)))
	{
	  new_rtx = make_compound_operation (XEXP (XEXP (x, 0), 0), next_code);
	  new_rtx = make_extraction (mode, new_rtx,
				     (GET_MODE_PRECISION (mode)
				      - INTVAL (XEXP (XEXP (x, 0), 1))),
				     NULL_RTX, i, 1, 0, in_code == COMPARE);
	}

      /* On machines without logical shifts, if the operand of the AND is
	 a logical shift and our mask turns off all the propagated sign
	 bits, we can replace the logical shift with an arithmetic shift.  */
      else if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
	       && !have_insn_for (LSHIFTRT, mode)
	       && have_insn_for (ASHIFTRT, mode)
	       && CONST_INT_P (XEXP (XEXP (x, 0), 1))
	       && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
	       && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
	       && mode_width <= HOST_BITS_PER_WIDE_INT)
	{
	  unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);

	  mask >>= INTVAL (XEXP (XEXP (x, 0), 1));
	  if ((INTVAL (XEXP (x, 1)) & ~mask) == 0)
	    SUBST (XEXP (x, 0),
		   gen_rtx_ASHIFTRT (mode,
				     make_compound_operation (XEXP (XEXP (x,
									  0),
								    0),
							      next_code),
				     XEXP (XEXP (x, 0), 1)));
	}

      /* If the constant is one less than a power of two, this might be
	 representable by an extraction even if no shift is present.
	 If it doesn't end up being a ZERO_EXTEND, we will ignore it unless
	 we are in a COMPARE.  */
      else if ((i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0)
	new_rtx = make_extraction (mode,
				   make_compound_operation (XEXP (x, 0),
							    next_code),
				   0, NULL_RTX, i, 1, 0, in_code == COMPARE);

      /* If we are in a comparison and this is an AND with a power of two,
	 convert this into the appropriate bit extract.  */
      else if (in_code == COMPARE
	       && (i = exact_log2 (UINTVAL (XEXP (x, 1)))) >= 0
	       && (equality_comparison || i < GET_MODE_PRECISION (mode) - 1))
	new_rtx = make_extraction (mode,
				   make_compound_operation (XEXP (x, 0),
							    next_code),
				   i, NULL_RTX, 1, 1, 0, 1);

      /* If the one operand is a paradoxical subreg of a register or memory and
	 the constant (limited to the smaller mode) has only zero bits where
	 the sub expression has known zero bits, this can be expressed as
	 a zero_extend.  */
      else if (GET_CODE (XEXP (x, 0)) == SUBREG)
	{
	  rtx sub;

	  sub = XEXP (XEXP (x, 0), 0);
	  machine_mode sub_mode = GET_MODE (sub);
	  int sub_width;
	  if ((REG_P (sub) || MEM_P (sub))
	      && GET_MODE_PRECISION (sub_mode).is_constant (&sub_width)
	      && sub_width < mode_width)
	    {
	      unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (sub_mode);
	      unsigned HOST_WIDE_INT mask;

	      /* original AND constant with all the known zero bits set */
	      mask = UINTVAL (XEXP (x, 1)) | (~nonzero_bits (sub, sub_mode));
	      if ((mask & mode_mask) == mode_mask)
		{
		  new_rtx = make_compound_operation (sub, next_code);
		  new_rtx = make_extraction (mode, new_rtx, 0, 0, sub_width,
					     1, 0, in_code == COMPARE);
		}
	    }
	}

      break;

    case LSHIFTRT:
      /* If the sign bit is known to be zero, replace this with an
	 arithmetic shift.  */
      if (have_insn_for (ASHIFTRT, mode)
	  && ! have_insn_for (LSHIFTRT, mode)
	  && mode_width <= HOST_BITS_PER_WIDE_INT
	  && (nonzero_bits (XEXP (x, 0), mode) & (1 << (mode_width - 1))) == 0)
	{
	  new_rtx = gen_rtx_ASHIFTRT (mode,
				      make_compound_operation (XEXP (x, 0),
							       next_code),
				      XEXP (x, 1));
	  break;
	}

      /* fall through */

    case ASHIFTRT:
      lhs = XEXP (x, 0);
      rhs = XEXP (x, 1);

      /* If we have (ashiftrt (ashift foo C1) C2) with C2 >= C1,
	 this is a SIGN_EXTRACT.  */
      if (CONST_INT_P (rhs)
	  && GET_CODE (lhs) == ASHIFT
	  && CONST_INT_P (XEXP (lhs, 1))
	  && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1))
	  && INTVAL (XEXP (lhs, 1)) >= 0
	  && INTVAL (rhs) < mode_width)
	{
	  new_rtx = make_compound_operation (XEXP (lhs, 0), next_code);
	  new_rtx = make_extraction (mode, new_rtx,
				     INTVAL (rhs) - INTVAL (XEXP (lhs, 1)),
				     NULL_RTX, mode_width - INTVAL (rhs),
				     code == LSHIFTRT, 0, in_code == COMPARE);
	  break;
	}

      /* See if we have operations between an ASHIFTRT and an ASHIFT.
	 If so, try to merge the shifts into a SIGN_EXTEND.  We could
	 also do this for some cases of SIGN_EXTRACT, but it doesn't
	 seem worth the effort; the case checked for occurs on Alpha.  */

      if (!OBJECT_P (lhs)
	  && ! (GET_CODE (lhs) == SUBREG
		&& (OBJECT_P (SUBREG_REG (lhs))))
	  && CONST_INT_P (rhs)
	  && INTVAL (rhs) >= 0
	  && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
	  && INTVAL (rhs) < mode_width
	  && (new_rtx = extract_left_shift (mode, lhs, INTVAL (rhs))) != 0)
	new_rtx = make_extraction (mode, make_compound_operation (new_rtx,
								  next_code),
				   0, NULL_RTX, mode_width - INTVAL (rhs),
				   code == LSHIFTRT, 0, in_code == COMPARE);

      break;

    case SUBREG:
      /* Call ourselves recursively on the inner expression.  If we are
	 narrowing the object and it has a different RTL code from
	 what it originally did, do this SUBREG as a force_to_mode.  */
      {
	rtx inner = SUBREG_REG (x), simplified;
	enum rtx_code subreg_code = in_code;

	/* If the SUBREG is masking of a logical right shift,
	   make an extraction.  */
	if (GET_CODE (inner) == LSHIFTRT
	    && is_a <scalar_int_mode> (GET_MODE (inner), &inner_mode)
	    && GET_MODE_SIZE (mode) < GET_MODE_SIZE (inner_mode)
	    && CONST_INT_P (XEXP (inner, 1))
	    && UINTVAL (XEXP (inner, 1)) < GET_MODE_PRECISION (inner_mode)
	    && subreg_lowpart_p (x))
	  {
	    new_rtx = make_compound_operation (XEXP (inner, 0), next_code);
	    int width = GET_MODE_PRECISION (inner_mode)
			- INTVAL (XEXP (inner, 1));
	    if (width > mode_width)
	      width = mode_width;
	    new_rtx = make_extraction (mode, new_rtx, 0, XEXP (inner, 1),
				       width, 1, 0, in_code == COMPARE);
	    break;
	  }

	/* If in_code is COMPARE, it isn't always safe to pass it through
	   to the recursive make_compound_operation call.  */
	if (subreg_code == COMPARE
	    && (!subreg_lowpart_p (x)
		|| GET_CODE (inner) == SUBREG
		/* (subreg:SI (and:DI (reg:DI) (const_int 0x800000000)) 0)
		   is (const_int 0), rather than
		   (subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0).
		   Similarly (subreg:QI (and:SI (reg:SI) (const_int 0x80)) 0)
		   for non-equality comparisons against 0 is not equivalent
		   to (subreg:QI (lshiftrt:SI (reg:SI) (const_int 7)) 0).  */
		|| (GET_CODE (inner) == AND
		    && CONST_INT_P (XEXP (inner, 1))
		    && partial_subreg_p (x)
		    && exact_log2 (UINTVAL (XEXP (inner, 1)))
		       >= GET_MODE_BITSIZE (mode) - 1)))
	  subreg_code = SET;

	tem = make_compound_operation (inner, subreg_code);

	simplified
	  = simplify_subreg (mode, tem, GET_MODE (inner), SUBREG_BYTE (x));
	if (simplified)
	  tem = simplified;

	if (GET_CODE (tem) != GET_CODE (inner)
	    && partial_subreg_p (x)
	    && subreg_lowpart_p (x))
	  {
	    rtx newer
	      = force_to_mode (tem, mode, HOST_WIDE_INT_M1U, 0);

	    /* If we have something other than a SUBREG, we might have
	       done an expansion, so rerun ourselves.  */
	    if (GET_CODE (newer) != SUBREG)
	      newer = make_compound_operation (newer, in_code);

	    /* force_to_mode can expand compounds.  If it just re-expanded
	       the compound, use gen_lowpart to convert to the desired
	       mode.  */
	    if (rtx_equal_p (newer, x)
		/* Likewise if it re-expanded the compound only partially.
		   This happens for SUBREG of ZERO_EXTRACT if they extract
		   the same number of bits.  */
		|| (GET_CODE (newer) == SUBREG
		    && (GET_CODE (SUBREG_REG (newer)) == LSHIFTRT
			|| GET_CODE (SUBREG_REG (newer)) == ASHIFTRT)
		    && GET_CODE (inner) == AND
		    && rtx_equal_p (SUBREG_REG (newer), XEXP (inner, 0))))
	      return gen_lowpart (GET_MODE (x), tem);

	    return newer;
	  }

	if (simplified)
	  return tem;
      }
      break;

    default:
      break;
    }

  if (new_rtx)
    *x_ptr = gen_lowpart (mode, new_rtx);
  *next_code_ptr = next_code;
  return NULL_RTX;
}

/* Look at the expression rooted at X.  Look for expressions
   equivalent to ZERO_EXTRACT, SIGN_EXTRACT, ZERO_EXTEND, SIGN_EXTEND.
   Form these expressions.

   Return the new rtx, usually just X.

   Also, for machines like the VAX that don't have logical shift insns,
   try to convert logical to arithmetic shift operations in cases where
   they are equivalent.  This undoes the canonicalizations to logical
   shifts done elsewhere.

   We try, as much as possible, to re-use rtl expressions to save memory.

   IN_CODE says what kind of expression we are processing.  Normally, it is
   SET.  In a memory address it is MEM.  When processing the arguments of
   a comparison or a COMPARE against zero, it is COMPARE, or EQ if more
   precisely it is an equality comparison against zero.  */

rtx
make_compound_operation (rtx x, enum rtx_code in_code)
{
  enum rtx_code code = GET_CODE (x);
  const char *fmt;
  int i, j;
  enum rtx_code next_code;
  rtx new_rtx, tem;

  /* Select the code to be used in recursive calls.  Once we are inside an
     address, we stay there.  If we have a comparison, set to COMPARE,
     but once inside, go back to our default of SET.  */

  next_code = (code == MEM ? MEM
	       : ((code == COMPARE || COMPARISON_P (x))
		  && XEXP (x, 1) == const0_rtx) ? COMPARE
	       : in_code == COMPARE || in_code == EQ ? SET : in_code);

  scalar_int_mode mode;
  if (is_a <scalar_int_mode> (GET_MODE (x), &mode))
    {
      rtx new_rtx = make_compound_operation_int (mode, &x, in_code,
						 &next_code);
      if (new_rtx)
	return new_rtx;
      code = GET_CODE (x);
    }

  /* Now recursively process each operand of this operation.  We need to
     handle ZERO_EXTEND specially so that we don't lose track of the
     inner mode.  */
  if (code == ZERO_EXTEND)
    {
      new_rtx = make_compound_operation (XEXP (x, 0), next_code);
      tem = simplify_const_unary_operation (ZERO_EXTEND, GET_MODE (x),
					    new_rtx, GET_MODE (XEXP (x, 0)));
      if (tem)
	return tem;
      SUBST (XEXP (x, 0), new_rtx);
      return x;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = 0; i < GET_RTX_LENGTH (code); i++)
    if (fmt[i] == 'e')
      {
	new_rtx = make_compound_operation (XEXP (x, i), next_code);
	SUBST (XEXP (x, i), new_rtx);
      }
    else if (fmt[i] == 'E')
      for (j = 0; j < XVECLEN (x, i); j++)
	{
	  new_rtx = make_compound_operation (XVECEXP (x, i, j), next_code);
	  SUBST (XVECEXP (x, i, j), new_rtx);
	}

  maybe_swap_commutative_operands (x);
  return x;
}

/* Given M see if it is a value that would select a field of bits
   within an item, but not the entire word.  Return -1 if not.
   Otherwise, return the starting position of the field, where 0 is the
   low-order bit.

   *PLEN is set to the length of the field.  */

static int
get_pos_from_mask (unsigned HOST_WIDE_INT m, unsigned HOST_WIDE_INT *plen)
{
  /* Get the bit number of the first 1 bit from the right, -1 if none.  */
  int pos = m ? ctz_hwi (m) : -1;
  int len = 0;

  if (pos >= 0)
    /* Now shift off the low-order zero bits and see if we have a
       power of two minus 1.  */
    len = exact_log2 ((m >> pos) + 1);

  if (len <= 0)
    pos = -1;

  *plen = len;
  return pos;
}

/* If X refers to a register that equals REG in value, replace these
   references with REG.  */
static rtx
canon_reg_for_combine (rtx x, rtx reg)
{
  rtx op0, op1, op2;
  const char *fmt;
  int i;
  bool copied;

  enum rtx_code code = GET_CODE (x);
  switch (GET_RTX_CLASS (code))
    {
    case RTX_UNARY:
      op0 = canon_reg_for_combine (XEXP (x, 0), reg);
      if (op0 != XEXP (x, 0))
	return simplify_gen_unary (GET_CODE (x), GET_MODE (x), op0,
				   GET_MODE (reg));
      break;

    case RTX_BIN_ARITH:
    case RTX_COMM_ARITH:
      op0 = canon_reg_for_combine (XEXP (x, 0), reg);
      op1 = canon_reg_for_combine (XEXP (x, 1), reg);
      if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
	return simplify_gen_binary (GET_CODE (x), GET_MODE (x), op0, op1);
      break;

    case RTX_COMPARE:
    case RTX_COMM_COMPARE:
      op0 = canon_reg_for_combine (XEXP (x, 0), reg);
      op1 = canon_reg_for_combine (XEXP (x, 1), reg);
      if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
	return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
					GET_MODE (op0), op0, op1);
      break;

    case RTX_TERNARY:
    case RTX_BITFIELD_OPS:
      op0 = canon_reg_for_combine (XEXP (x, 0), reg);
      op1 = canon_reg_for_combine (XEXP (x, 1), reg);
      op2 = canon_reg_for_combine (XEXP (x, 2), reg);
      if (op0 != XEXP (x, 0) || op1 != XEXP (x, 1) || op2 != XEXP (x, 2))
	return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
				     GET_MODE (op0), op0, op1, op2);
      /* FALLTHRU */

    case RTX_OBJ:
      if (REG_P (x))
	{
	  if (rtx_equal_p (get_last_value (reg), x)
	      || rtx_equal_p (reg, get_last_value (x)))
	    return reg;
	  else
	    break;
	}

      /* fall through */

    default:
      fmt = GET_RTX_FORMAT (code);
      copied = false;
      for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
	if (fmt[i] == 'e')
	  {
	    rtx op = canon_reg_for_combine (XEXP (x, i), reg);
	    if (op != XEXP (x, i))
	      {
		if (!copied)
		  {
		    copied = true;
		    x = copy_rtx (x);
		  }
		XEXP (x, i) = op;
	      }
	  }
	else if (fmt[i] == 'E')
	  {
	    int j;
	    for (j = 0; j < XVECLEN (x, i); j++)
	      {
		rtx op = canon_reg_for_combine (XVECEXP (x, i, j), reg);
		if (op != XVECEXP (x, i, j))
		  {
		    if (!copied)
		      {
			copied = true;
			x = copy_rtx (x);
		      }
		    XVECEXP (x, i, j) = op;
		  }
	      }
	  }

      break;
    }

  return x;
}

/* Return X converted to MODE.  If the value is already truncated to
   MODE we can just return a subreg even though in the general case we
   would need an explicit truncation.  */

static rtx
gen_lowpart_or_truncate (machine_mode mode, rtx x)
{
  if (!CONST_INT_P (x)
      && partial_subreg_p (mode, GET_MODE (x))
      && !TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (x))
      && !(REG_P (x) && reg_truncated_to_mode (mode, x)))
    {
      /* Bit-cast X into an integer mode.  */
      if (!SCALAR_INT_MODE_P (GET_MODE (x)))
	x = gen_lowpart (int_mode_for_mode (GET_MODE (x)).require (), x);
      x = simplify_gen_unary (TRUNCATE, int_mode_for_mode (mode).require (),
			      x, GET_MODE (x));
    }

  return gen_lowpart (mode, x);
}

/* See if X can be simplified knowing that we will only refer to it in
   MODE and will only refer to those bits that are nonzero in MASK.
   If other bits are being computed or if masking operations are done
   that select a superset of the bits in MASK, they can sometimes be
   ignored.

   Return a possibly simplified expression, but always convert X to
   MODE.  If X is a CONST_INT, AND the CONST_INT with MASK.

   If JUST_SELECT is nonzero, don't optimize by noticing that bits in MASK
   are all off in X.  This is used when X will be complemented, by either
   NOT, NEG, or XOR.  */

static rtx
force_to_mode (rtx x, machine_mode mode, unsigned HOST_WIDE_INT mask,
	       int just_select)
{
  enum rtx_code code = GET_CODE (x);
  int next_select = just_select || code == XOR || code == NOT || code == NEG;
  machine_mode op_mode;
  unsigned HOST_WIDE_INT nonzero;

  /* If this is a CALL or ASM_OPERANDS, don't do anything.  Some of the
     code below will do the wrong thing since the mode of such an
     expression is VOIDmode.

     Also do nothing if X is a CLOBBER; this can happen if X was
     the return value from a call to gen_lowpart.  */
  if (code == CALL || code == ASM_OPERANDS || code == CLOBBER)
    return x;

  /* We want to perform the operation in its present mode unless we know
     that the operation is valid in MODE, in which case we do the operation
     in MODE.  */
  op_mode = ((GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (x))
	      && have_insn_for (code, mode))
	     ? mode : GET_MODE (x));

  /* It is not valid to do a right-shift in a narrower mode
     than the one it came in with.  */
  if ((code == LSHIFTRT || code == ASHIFTRT)
      && partial_subreg_p (mode, GET_MODE (x)))
    op_mode = GET_MODE (x);

  /* Truncate MASK to fit OP_MODE.  */
  if (op_mode)
    mask &= GET_MODE_MASK (op_mode);

  /* Determine what bits of X are guaranteed to be (non)zero.  */
  nonzero = nonzero_bits (x, mode);

  /* If none of the bits in X are needed, return a zero.  */
  if (!just_select && (nonzero & mask) == 0 && !side_effects_p (x))
    x = const0_rtx;

  /* If X is a CONST_INT, return a new one.  Do this here since the
     test below will fail.  */
  if (CONST_INT_P (x))
    {
      if (SCALAR_INT_MODE_P (mode))
	return gen_int_mode (INTVAL (x) & mask, mode);
      else
	{
	  x = GEN_INT (INTVAL (x) & mask);
	  return gen_lowpart_common (mode, x);
	}
    }

  /* If X is narrower than MODE and we want all the bits in X's mode, just
     get X in the proper mode.  */
  if (paradoxical_subreg_p (mode, GET_MODE (x))
      && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
    return gen_lowpart (mode, x);

  /* We can ignore the effect of a SUBREG if it narrows the mode or
     if the constant masks to zero all the bits the mode doesn't have.  */
  if (GET_CODE (x) == SUBREG
      && subreg_lowpart_p (x)
      && (partial_subreg_p (x)
	  || (mask
	      & GET_MODE_MASK (GET_MODE (x))
	      & ~GET_MODE_MASK (GET_MODE (SUBREG_REG (x)))) == 0))
    return force_to_mode (SUBREG_REG (x), mode, mask, next_select);

  scalar_int_mode int_mode, xmode;
  if (is_a <scalar_int_mode> (mode, &int_mode)
      && is_a <scalar_int_mode> (GET_MODE (x), &xmode))
    /* OP_MODE is either MODE or XMODE, so it must be a scalar
       integer too.  */
    return force_int_to_mode (x, int_mode, xmode,
			      as_a <scalar_int_mode> (op_mode),
			      mask, just_select);

  return gen_lowpart_or_truncate (mode, x);
}

/* Subroutine of force_to_mode that handles cases in which both X and
   the result are scalar integers.  MODE is the mode of the result,
   XMODE is the mode of X, and OP_MODE says which of MODE or XMODE
   is preferred for simplified versions of X.  The other arguments
   are as for force_to_mode.  */

static rtx
force_int_to_mode (rtx x, scalar_int_mode mode, scalar_int_mode xmode,
		   scalar_int_mode op_mode, unsigned HOST_WIDE_INT mask,
		   int just_select)
{
  enum rtx_code code = GET_CODE (x);
  int next_select = just_select || code == XOR || code == NOT || code == NEG;
  unsigned HOST_WIDE_INT fuller_mask;
  rtx op0, op1, temp;
  poly_int64 const_op0;

  /* When we have an arithmetic operation, or a shift whose count we
     do not know, we need to assume that all bits up to the highest-order
     bit in MASK will be needed.  This is how we form such a mask.  */
  if (mask & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1)))
    fuller_mask = HOST_WIDE_INT_M1U;
  else
    fuller_mask = ((HOST_WIDE_INT_1U << (floor_log2 (mask) + 1))
		   - 1);

  switch (code)
    {
    case CLOBBER:
      /* If X is a (clobber (const_int)), return it since we know we are
	 generating something that won't match.  */
      return x;

    case SIGN_EXTEND:
    case ZERO_EXTEND:
    case ZERO_EXTRACT:
    case SIGN_EXTRACT:
      x = expand_compound_operation (x);
      if (GET_CODE (x) != code)
	return force_to_mode (x, mode, mask, next_select);
      break;

    case TRUNCATE:
      /* Similarly for a truncate.  */
      return force_to_mode (XEXP (x, 0), mode, mask, next_select);

    case AND:
      /* If this is an AND with a constant, convert it into an AND
	 whose constant is the AND of that constant with MASK.  If it
	 remains an AND of MASK, delete it since it is redundant.  */

      if (CONST_INT_P (XEXP (x, 1)))
	{
	  x = simplify_and_const_int (x, op_mode, XEXP (x, 0),
				      mask & INTVAL (XEXP (x, 1)));
	  xmode = op_mode;

	  /* If X is still an AND, see if it is an AND with a mask that
	     is just some low-order bits.  If so, and it is MASK, we don't
	     need it.  */

	  if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1))
	      && (INTVAL (XEXP (x, 1)) & GET_MODE_MASK (xmode)) == mask)
	    x = XEXP (x, 0);

	  /* If it remains an AND, try making another AND with the bits
	     in the mode mask that aren't in MASK turned on.  If the
	     constant in the AND is wide enough, this might make a
	     cheaper constant.  */

	  if (GET_CODE (x) == AND && CONST_INT_P (XEXP (x, 1))
	      && GET_MODE_MASK (xmode) != mask
	      && HWI_COMPUTABLE_MODE_P (xmode))
	    {
	      unsigned HOST_WIDE_INT cval
		= UINTVAL (XEXP (x, 1)) | (GET_MODE_MASK (xmode) & ~mask);
	      rtx y;

	      y = simplify_gen_binary (AND, xmode, XEXP (x, 0),
				       gen_int_mode (cval, xmode));
	      if (set_src_cost (y, xmode, optimize_this_for_speed_p)
		  < set_src_cost (x, xmode, optimize_this_for_speed_p))
		x = y;
	    }

	  break;
	}

      goto binop;

    case PLUS:
      /* In (and (plus FOO C1) M), if M is a mask that just turns off
	 low-order bits (as in an alignment operation) and FOO is already
	 aligned to that boundary, mask C1 to that boundary as well.
	 This may eliminate that PLUS and, later, the AND.  */

      {
	unsigned int width = GET_MODE_PRECISION (mode);
	unsigned HOST_WIDE_INT smask = mask;

	/* If MODE is narrower than HOST_WIDE_INT and mask is a negative
	   number, sign extend it.  */

	if (width < HOST_BITS_PER_WIDE_INT
	    && (smask & (HOST_WIDE_INT_1U << (width - 1))) != 0)
	  smask |= HOST_WIDE_INT_M1U << width;

	if (CONST_INT_P (XEXP (x, 1))
	    && pow2p_hwi (- smask)
	    && (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
	    && (INTVAL (XEXP (x, 1)) & ~smask) != 0)
	  return force_to_mode (plus_constant (xmode, XEXP (x, 0),
					       (INTVAL (XEXP (x, 1)) & smask)),
				mode, smask, next_select);
      }

      /* fall through */

    case MULT:
      /* Substituting into the operands of a widening MULT is not likely to
	 create RTL matching a machine insn.  */
      if (code == MULT
	  && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
	      || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
	  && (GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
	      || GET_CODE (XEXP (x, 1)) == SIGN_EXTEND)
	  && REG_P (XEXP (XEXP (x, 0), 0))
	  && REG_P (XEXP (XEXP (x, 1), 0)))
	return gen_lowpart_or_truncate (mode, x);

      /* For PLUS, MINUS and MULT, we need any bits less significant than the
	 most significant bit in MASK since carries from those bits will
	 affect the bits we are interested in.  */
      mask = fuller_mask;
      goto binop;

    case MINUS:
      /* If X is (minus C Y) where C's least set bit is larger than any bit
	 in the mask, then we may replace with (neg Y).  */
      if (poly_int_rtx_p (XEXP (x, 0), &const_op0)
	  && known_alignment (poly_uint64 (const_op0)) > mask)
	{
	  x = simplify_gen_unary (NEG, xmode, XEXP (x, 1), xmode);
	  return force_to_mode (x, mode, mask, next_select);
	}

      /* Similarly, if C contains every bit in the fuller_mask, then we may
	 replace with (not Y).  */
      if (CONST_INT_P (XEXP (x, 0))
	  && ((UINTVAL (XEXP (x, 0)) | fuller_mask) == UINTVAL (XEXP (x, 0))))
	{
	  x = simplify_gen_unary (NOT, xmode, XEXP (x, 1), xmode);
	  return force_to_mode (x, mode, mask, next_select);
	}

      mask = fuller_mask;
      goto binop;

    case IOR:
    case XOR:
      /* If X is (ior (lshiftrt FOO C1) C2), try to commute the IOR and
	 LSHIFTRT so we end up with an (and (lshiftrt (ior ...) ...) ...)
	 operation which may be a bitfield extraction.  Ensure that the
	 constant we form is not wider than the mode of X.  */

      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
	  && CONST_INT_P (XEXP (XEXP (x, 0), 1))
	  && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
	  && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT
	  && CONST_INT_P (XEXP (x, 1))
	  && ((INTVAL (XEXP (XEXP (x, 0), 1))
	       + floor_log2 (INTVAL (XEXP (x, 1))))
	      < GET_MODE_PRECISION (xmode))
	  && (UINTVAL (XEXP (x, 1))
	      & ~nonzero_bits (XEXP (x, 0), xmode)) == 0)
	{
	  temp = gen_int_mode ((INTVAL (XEXP (x, 1)) & mask)
			       << INTVAL (XEXP (XEXP (x, 0), 1)),
			       xmode);
	  temp = simplify_gen_binary (GET_CODE (x), xmode,
				      XEXP (XEXP (x, 0), 0), temp);
	  x = simplify_gen_binary (LSHIFTRT, xmode, temp,
				   XEXP (XEXP (x, 0), 1));
	  return force_to_mode (x, mode, mask, next_select);
	}

    binop:
      /* For most binary operations, just propagate into the operation and
	 change the mode if we have an operation of that mode.  */

      op0 = force_to_mode (XEXP (x, 0), mode, mask, next_select);
      op1 = force_to_mode (XEXP (x, 1), mode, mask, next_select);

      /* If we ended up truncating both operands, truncate the result of the
	 operation instead.  */
      if (GET_CODE (op0) == TRUNCATE
	  && GET_CODE (op1) == TRUNCATE)
	{
	  op0 = XEXP (op0, 0);
	  op1 = XEXP (op1, 0);
	}

      op0 = gen_lowpart_or_truncate (op_mode, op0);
      op1 = gen_lowpart_or_truncate (op_mode, op1);

      if (op_mode != xmode || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
	{
	  x = simplify_gen_binary (code, op_mode, op0, op1);
	  xmode = op_mode;
	}
      break;

    case ASHIFT:
      /* For left shifts, do the same, but just for the first operand.
	 However, we cannot do anything with shifts where we cannot
	 guarantee that the counts are smaller than the size of the mode
	 because such a count will have a different meaning in a
	 wider mode.  */

      if (! (CONST_INT_P (XEXP (x, 1))
	     && INTVAL (XEXP (x, 1)) >= 0
	     && INTVAL (XEXP (x, 1)) < GET_MODE_PRECISION (mode))
	  && ! (GET_MODE (XEXP (x, 1)) != VOIDmode
		&& (nonzero_bits (XEXP (x, 1), GET_MODE (XEXP (x, 1)))
		    < (unsigned HOST_WIDE_INT) GET_MODE_PRECISION (mode))))
	break;

      /* If the shift count is a constant and we can do arithmetic in
	 the mode of the shift, refine which bits we need.  Otherwise, use the
	 conservative form of the mask.  */
      if (CONST_INT_P (XEXP (x, 1))
	  && INTVAL (XEXP (x, 1)) >= 0
	  && INTVAL (XEXP (x, 1)) < GET_MODE_PRECISION (op_mode)
	  && HWI_COMPUTABLE_MODE_P (op_mode))
	mask >>= INTVAL (XEXP (x, 1));
      else
	mask = fuller_mask;

      op0 = gen_lowpart_or_truncate (op_mode,
				     force_to_mode (XEXP (x, 0), mode,
						    mask, next_select));

      if (op_mode != xmode || op0 != XEXP (x, 0))
	{
	  x = simplify_gen_binary (code, op_mode, op0, XEXP (x, 1));
	  xmode = op_mode;
	}
      break;

    case LSHIFTRT:
      /* Here we can only do something if the shift count is a constant,
	 this shift constant is valid for the host, and we can do arithmetic
	 in OP_MODE.  */

      if (CONST_INT_P (XEXP (x, 1))
	  && INTVAL (XEXP (x, 1)) >= 0
	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
	  && HWI_COMPUTABLE_MODE_P (op_mode))
	{
	  rtx inner = XEXP (x, 0);
	  unsigned HOST_WIDE_INT inner_mask;

	  /* Select the mask of the bits we need for the shift operand.  */
	  inner_mask = mask << INTVAL (XEXP (x, 1));

	  /* We can only change the mode of the shift if we can do arithmetic
	     in the mode of the shift and INNER_MASK is no wider than the
	     width of X's mode.  */
	  if ((inner_mask & ~GET_MODE_MASK (xmode)) != 0)
	    op_mode = xmode;

	  inner = force_to_mode (inner, op_mode, inner_mask, next_select);

	  if (xmode != op_mode || inner != XEXP (x, 0))
	    {
	      x = simplify_gen_binary (LSHIFTRT, op_mode, inner, XEXP (x, 1));
	      xmode = op_mode;
	    }
	}

      /* If we have (and (lshiftrt FOO C1) C2) where the combination of the
	 shift and AND produces only copies of the sign bit (C2 is one less
	 than a power of two), we can do this with just a shift.  */

      if (GET_CODE (x) == LSHIFTRT
	  && CONST_INT_P (XEXP (x, 1))
	  /* The shift puts one of the sign bit copies in the least significant
	     bit.  */
	  && ((INTVAL (XEXP (x, 1))
	       + num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))))
	      >= GET_MODE_PRECISION (xmode))
	  && pow2p_hwi (mask + 1)
	  /* Number of bits left after the shift must be more than the mask
	     needs.  */
	  && ((INTVAL (XEXP (x, 1)) + exact_log2 (mask + 1))
	      <= GET_MODE_PRECISION (xmode))
	  /* Must be more sign bit copies than the mask needs.  */
	  && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
	      >= exact_log2 (mask + 1)))
	{
	  int nbits = GET_MODE_PRECISION (xmode) - exact_log2 (mask + 1);
	  x = simplify_gen_binary (LSHIFTRT, xmode, XEXP (x, 0),
				   gen_int_shift_amount (xmode, nbits));
	}
      goto shiftrt;

    case ASHIFTRT:
      /* If we are just looking for the sign bit, we don't need this shift at
	 all, even if it has a variable count.  */
      if (val_signbit_p (xmode, mask))
	return force_to_mode (XEXP (x, 0), mode, mask, next_select);

      /* If this is a shift by a constant, get a mask that contains those bits
	 that are not copies of the sign bit.  We then have two cases:  If
	 MASK only includes those bits, this can be a logical shift, which may
	 allow simplifications.  If MASK is a single-bit field not within
	 those bits, we are requesting a copy of the sign bit and hence can
	 shift the sign bit to the appropriate location.  */

      if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0
	  && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
	{
	  unsigned HOST_WIDE_INT nonzero;
	  int i;

	  /* If the considered data is wider than HOST_WIDE_INT, we can't
	     represent a mask for all its bits in a single scalar.
	     But we only care about the lower bits, so calculate these.  */

	  if (GET_MODE_PRECISION (xmode) > HOST_BITS_PER_WIDE_INT)
	    {
	      nonzero = HOST_WIDE_INT_M1U;

	      /* GET_MODE_PRECISION (GET_MODE (x)) - INTVAL (XEXP (x, 1))
		 is the number of bits a full-width mask would have set.
		 We need only shift if these are fewer than nonzero can
		 hold.  If not, we must keep all bits set in nonzero.  */

	      if (GET_MODE_PRECISION (xmode) - INTVAL (XEXP (x, 1))
		  < HOST_BITS_PER_WIDE_INT)
		nonzero >>= INTVAL (XEXP (x, 1))
			    + HOST_BITS_PER_WIDE_INT
			    - GET_MODE_PRECISION (xmode);
	    }
	  else
	    {
	      nonzero = GET_MODE_MASK (xmode);
	      nonzero >>= INTVAL (XEXP (x, 1));
	    }

	  if ((mask & ~nonzero) == 0)
	    {
	      x = simplify_shift_const (NULL_RTX, LSHIFTRT, xmode,
					XEXP (x, 0), INTVAL (XEXP (x, 1)));
	      if (GET_CODE (x) != ASHIFTRT)
		return force_to_mode (x, mode, mask, next_select);
	    }

	  else if ((i = exact_log2 (mask)) >= 0)
	    {
	      x = simplify_shift_const
		  (NULL_RTX, LSHIFTRT, xmode, XEXP (x, 0),
		   GET_MODE_PRECISION (xmode) - 1 - i);

	      if (GET_CODE (x) != ASHIFTRT)
		return force_to_mode (x, mode, mask, next_select);
	    }
	}

      /* If MASK is 1, convert this to an LSHIFTRT.  This can be done
	 even if the shift count isn't a constant.  */
      if (mask == 1)
	x = simplify_gen_binary (LSHIFTRT, xmode, XEXP (x, 0), XEXP (x, 1));

    shiftrt:

      /* If this is a zero- or sign-extension operation that just affects bits
	 we don't care about, remove it.  Be sure the call above returned
	 something that is still a shift.  */

      if ((GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ASHIFTRT)
	  && CONST_INT_P (XEXP (x, 1))
	  && INTVAL (XEXP (x, 1)) >= 0
	  && (INTVAL (XEXP (x, 1))
	      <= GET_MODE_PRECISION (xmode) - (floor_log2 (mask) + 1))
	  && GET_CODE (XEXP (x, 0)) == ASHIFT
	  && XEXP (XEXP (x, 0), 1) == XEXP (x, 1))
	return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask,
			      next_select);

      break;

    case ROTATE:
    case ROTATERT:
      /* If the shift count is constant and we can do computations
	 in the mode of X, compute where the bits we care about are.
	 Otherwise, we can't do anything.  Don't change the mode of
	 the shift or propagate MODE into the shift, though.  */
      if (CONST_INT_P (XEXP (x, 1))
	  && INTVAL (XEXP (x, 1)) >= 0)
	{
	  temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE,
					    xmode, gen_int_mode (mask, xmode),
					    XEXP (x, 1));
	  if (temp && CONST_INT_P (temp))
	    x = simplify_gen_binary (code, xmode,
				     force_to_mode (XEXP (x, 0), xmode,
						    INTVAL (temp), next_select),
				     XEXP (x, 1));
	}
      break;

    case NEG:
      /* If we just want the low-order bit, the NEG isn't needed since it
	 won't change the low-order bit.  */
      if (mask == 1)
	return force_to_mode (XEXP (x, 0), mode, mask, just_select);

      /* We need any bits less significant than the most significant bit in
	 MASK since carries from those bits will affect the bits we are
	 interested in.  */
      mask = fuller_mask;
      goto unop;

    case NOT:
      /* (not FOO) is (xor FOO CONST), so if FOO is an LSHIFTRT, we can do the
	 same as the XOR case above.  Ensure that the constant we form is not
	 wider than the mode of X.  */

      if (GET_CODE (XEXP (x, 0)) == LSHIFTRT
	  && CONST_INT_P (XEXP (XEXP (x, 0), 1))
	  && INTVAL (XEXP (XEXP (x, 0), 1)) >= 0
	  && (INTVAL (XEXP (XEXP (x, 0), 1)) + floor_log2 (mask)
	      < GET_MODE_PRECISION (xmode))
	  && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT)
	{
	  temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)), xmode);
	  temp = simplify_gen_binary (XOR, xmode, XEXP (XEXP (x, 0), 0), temp);
	  x = simplify_gen_binary (LSHIFTRT, xmode,
				   temp, XEXP (XEXP (x, 0), 1));

	  return force_to_mode (x, mode, mask, next_select);
	}

      /* (and (not FOO) CONST) is (not (or FOO (not CONST))), so we must
	 use the full mask inside the NOT.  */
      mask = fuller_mask;

    unop:
      op0 = gen_lowpart_or_truncate (op_mode,
				     force_to_mode (XEXP (x, 0), mode, mask,
						    next_select));
      if (op_mode != xmode || op0 != XEXP (x, 0))
	{
	  x = simplify_gen_unary (code, op_mode, op0, op_mode);
	  xmode = op_mode;
	}
      break;

    case NE:
      /* (and (ne FOO 0) CONST) can be (and FOO CONST) if CONST is included
	 in STORE_FLAG_VALUE and FOO has a single bit that might be nonzero,
	 which is equal to STORE_FLAG_VALUE.  */
      if ((mask & ~STORE_FLAG_VALUE) == 0
	  && XEXP (x, 1) == const0_rtx
	  && GET_MODE (XEXP (x, 0)) == mode
	  && pow2p_hwi (nonzero_bits (XEXP (x, 0), mode))
	  && (nonzero_bits (XEXP (x, 0), mode)
	      == (unsigned HOST_WIDE_INT) STORE_FLAG_VALUE))
	return force_to_mode (XEXP (x, 0), mode, mask, next_select);

      break;

    case IF_THEN_ELSE:
      /* We have no way of knowing if the IF_THEN_ELSE can itself be
	 written in a narrower mode.  We play it safe and do not do so.  */

      op0 = gen_lowpart_or_truncate (xmode,
				     force_to_mode (XEXP (x, 1), mode,
						    mask, next_select));
      op1 = gen_lowpart_or_truncate (xmode,
				     force_to_mode (XEXP (x, 2), mode,
						    mask, next_select));
      if (op0 != XEXP (x, 1) || op1 != XEXP (x, 2))
	x = simplify_gen_ternary (IF_THEN_ELSE, xmode,
				  GET_MODE (XEXP (x, 0)), XEXP (x, 0),
				  op0, op1);
      break;

    default:
      break;
    }

  /* Ensure we return a value of the proper mode.  */
  return gen_lowpart_or_truncate (mode, x);
}

/* Return nonzero if X is an expression that has one of two values depending on
   whether some other value is zero or nonzero.  In that case, we return the
   value that is being tested, *PTRUE is set to the value if the rtx being
   returned has a nonzero value, and *PFALSE is set to the other alternative.

   If we return zero, we set *PTRUE and *PFALSE to X.  */

static rtx
if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
{
  machine_mode mode = GET_MODE (x);
  enum rtx_code code = GET_CODE (x);
  rtx cond0, cond1, true0, true1, false0, false1;
  unsigned HOST_WIDE_INT nz;
  scalar_int_mode int_mode;

  /* If we are comparing a value against zero, we are done.  */
  if ((code == NE || code == EQ)
      && XEXP (x, 1) == const0_rtx)
    {
      *ptrue = (code == NE) ? const_true_rtx : const0_rtx;
      *pfalse = (code == NE) ? const0_rtx : const_true_rtx;
      return XEXP (x, 0);
    }

  /* If this is a unary operation whose operand has one of two values, apply
     our opcode to compute those values.  */
  else if (UNARY_P (x)
	   && (cond0 = if_then_else_cond (XEXP (x, 0), &true0, &false0)) != 0)
    {
      *ptrue = simplify_gen_unary (code, mode, true0, GET_MODE (XEXP (x, 0)));
      *pfalse = simplify_gen_unary (code, mode, false0,
				    GET_MODE (XEXP (x, 0)));
      return cond0;
    }

  /* If this is a COMPARE, do nothing, since the IF_THEN_ELSE we would
     make can't possibly match and would suppress other optimizations.  */
  else if (code == COMPARE)
    ;

  /* If this is a binary operation, see if either side has only one of two
     values.  If either one does or if both do and they are conditional on
     the same value, compute the new true and false values.  */
  else if (BINARY_P (x))
    {
      rtx op0 = XEXP (x, 0);
      rtx op1 = XEXP (x, 1);
      cond0 = if_then_else_cond (op0, &true0, &false0);
      cond1 = if_then_else_cond (op1, &true1, &false1);

      if ((cond0 != 0 && cond1 != 0 && !rtx_equal_p (cond0, cond1))
	  && (REG_P (op0) || REG_P (op1)))
	{
	  /* Try to enable a simplification by undoing work done by
	     if_then_else_cond if it converted a REG into something more
	     complex.  */
	  if (REG_P (op0))
	    {
	      cond0 = 0;
	      true0 = false0 = op0;
	    }
	  else
	    {
	      cond1 = 0;
	      true1 = false1 = op1;
	    }
	}

      if ((cond0 != 0 || cond1 != 0)
	  && ! (cond0 != 0 && cond1 != 0 && !rtx_equal_p (cond0, cond1)))
	{
	  /* If if_then_else_cond returned zero, then true/false are the
	     same rtl.  We must copy one of them to prevent invalid rtl
	     sharing.  */
	  if (cond0 == 0)
	    true0 = copy_rtx (true0);
	  else if (cond1 == 0)
	    true1 = copy_rtx (true1);

	  if (COMPARISON_P (x))
	    {
	      *ptrue = simplify_gen_relational (code, mode, VOIDmode,
						true0, true1);
	      *pfalse = simplify_gen_relational (code, mode, VOIDmode,
						 false0, false1);
	     }
	  else
	    {
	      *ptrue = simplify_gen_binary (code, mode, true0, true1);
	      *pfalse = simplify_gen_binary (code, mode, false0, false1);
	    }

	  return cond0 ? cond0 : cond1;
	}

      /* See if we have PLUS, IOR, XOR, MINUS or UMAX, where one of the
	 operands is zero when the other is nonzero, and vice-versa,
	 and STORE_FLAG_VALUE is 1 or -1.  */

      if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
	  && (code == PLUS || code == IOR || code == XOR || code == MINUS
	      || code == UMAX)
	  && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
	{
	  rtx op0 = XEXP (XEXP (x, 0), 1);
	  rtx op1 = XEXP (XEXP (x, 1), 1);

	  cond0 = XEXP (XEXP (x, 0), 0);
	  cond1 = XEXP (XEXP (x, 1), 0);

	  if (COMPARISON_P (cond0)
	      && COMPARISON_P (cond1)
	      && SCALAR_INT_MODE_P (mode)
	      && ((GET_CODE (cond0) == reversed_comparison_code (cond1, NULL)
		   && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
		   && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
		  || ((swap_condition (GET_CODE (cond0))
		       == reversed_comparison_code (cond1, NULL))
		      && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
	      && ! side_effects_p (x))
	    {
	      *ptrue = simplify_gen_binary (MULT, mode, op0, const_true_rtx);
	      *pfalse = simplify_gen_binary (MULT, mode,
					     (code == MINUS
					      ? simplify_gen_unary (NEG, mode,
								    op1, mode)
					      : op1),
					      const_true_rtx);
	      return cond0;
	    }
	}

      /* Similarly for MULT, AND and UMIN, except that for these the result
	 is always zero.  */
      if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
	  && (code == MULT || code == AND || code == UMIN)
	  && GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == MULT)
	{
	  cond0 = XEXP (XEXP (x, 0), 0);
	  cond1 = XEXP (XEXP (x, 1), 0);

	  if (COMPARISON_P (cond0)
	      && COMPARISON_P (cond1)
	      && ((GET_CODE (cond0) == reversed_comparison_code (cond1, NULL)
		   && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 0))
		   && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 1)))
		  || ((swap_condition (GET_CODE (cond0))
		       == reversed_comparison_code (cond1, NULL))
		      && rtx_equal_p (XEXP (cond0, 0), XEXP (cond1, 1))
		      && rtx_equal_p (XEXP (cond0, 1), XEXP (cond1, 0))))
	      && ! side_effects_p (x))
	    {
	      *ptrue = *pfalse = const0_rtx;
	      return cond0;
	    }
	}
    }

  else if (code == IF_THEN_ELSE)
    {
      /* If we have IF_THEN_ELSE already, extract the condition and
	 canonicalize it if it is NE or EQ.  */
      cond0 = XEXP (x, 0);
      *ptrue = XEXP (x, 1), *pfalse = XEXP (x, 2);
      if (GET_CODE (cond0) == NE && XEXP (cond0, 1) == const0_rtx)
	return XEXP (cond0, 0);
      else if (GET_CODE (cond0) == EQ && XEXP (cond0, 1) == const0_rtx)
	{
	  *ptrue = XEXP (x, 2), *pfalse = XEXP (x, 1);
	  return XEXP (cond0, 0);
	}
      else
	return cond0;
    }

  /* If X is a SUBREG, we can narrow both the true and false values
     if the inner expression, if there is a condition.  */
  else if (code == SUBREG
	   && (cond0 = if_then_else_cond (SUBREG_REG (x), &true0,
					  &false0)) != 0)
    {
      true0 = simplify_gen_subreg (mode, true0,
				   GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
      false0 = simplify_gen_subreg (mode, false0,
				    GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
      if (true0 && false0)
	{
	  *ptrue = true0;
	  *pfalse = false0;
	  return cond0;
	}
    }

  /* If X is a constant, this isn't special and will cause confusions
     if we treat it as such.  Likewise if it is equivalent to a constant.  */
  else if (CONSTANT_P (x)
	   || ((cond0 = get_last_value (x)) != 0 && CONSTANT_P (cond0)))
    ;

  /* If we're in BImode, canonicalize on 0 and STORE_FLAG_VALUE, as that
     will be least confusing to the rest of the compiler.  */
  else if (mode == BImode)
    {
      *ptrue = GEN_INT (STORE_FLAG_VALUE), *pfalse = const0_rtx;
      return x;
    }

  /* If X is known to be either 0 or -1, those are the true and
     false values when testing X.  */
  else if (x == constm1_rtx || x == const0_rtx
	   || (is_a <scalar_int_mode> (mode, &int_mode)
	       && (num_sign_bit_copies (x, int_mode)
		   == GET_MODE_PRECISION (int_mode))))
    {
      *ptrue = constm1_rtx, *pfalse = const0_rtx;
      return x;
    }

  /* Likewise for 0 or a single bit.  */
  else if (HWI_COMPUTABLE_MODE_P (mode)
	   && pow2p_hwi (nz = nonzero_bits (x, mode)))
    {
      *ptrue = gen_int_mode (nz, mode), *pfalse = const0_rtx;
      return x;
    }

  /* Otherwise fail; show no condition with true and false values the same.  */
  *ptrue = *pfalse = x;
  return 0;
}

/* Return the value of expression X given the fact that condition COND
   is known to be true when applied to REG as its first operand and VAL
   as its second.  X is known to not be shared and so can be modified in
   place.

   We only handle the simplest cases, and specifically those cases that
   arise with IF_THEN_ELSE expressions.  */

static rtx
known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val)
{
  enum rtx_code code = GET_CODE (x);
  const char *fmt;
  int i, j;

  if (side_effects_p (x))
    return x;

  /* If either operand of the condition is a floating point value,
     then we have to avoid collapsing an EQ comparison.  */
  if (cond == EQ
      && rtx_equal_p (x, reg)
      && ! FLOAT_MODE_P (GET_MODE (x))
      && ! FLOAT_MODE_P (GET_MODE (val)))
    return val;

  if (cond == UNEQ && rtx_equal_p (x, reg))
    return val;

  /* If X is (abs REG) and we know something about REG's relationship
     with zero, we may be able to simplify this.  */

  if (code == ABS && rtx_equal_p (XEXP (x, 0), reg) && val == const0_rtx)
    switch (cond)
      {
      case GE:  case GT:  case EQ:
	return XEXP (x, 0);
      case LT:  case LE:
	return simplify_gen_unary (NEG, GET_MODE (XEXP (x, 0)),
				   XEXP (x, 0),
				   GET_MODE (XEXP (x, 0)));
      default:
	break;
      }

  /* The only other cases we handle are MIN, MAX, and comparisons if the
     operands are the same as REG and VAL.  */

  else if (COMPARISON_P (x) || COMMUTATIVE_ARITH_P (x))
    {
      if (rtx_equal_p (XEXP (x, 0), val))
        {
	  std::swap (val, reg);
	  cond = swap_condition (cond);
        }

      if (rtx_equal_p (XEXP (x, 0), reg) && rtx_equal_p (XEXP (x, 1), val))
	{
	  if (COMPARISON_P (x))
	    {
	      if (comparison_dominates_p (cond, code))
		return VECTOR_MODE_P (GET_MODE (x)) ? x : const_true_rtx;

	      code = reversed_comparison_code (x, NULL);
	      if (code != UNKNOWN
		  && comparison_dominates_p (cond, code))
		return CONST0_RTX (GET_MODE (x));
	      else
		return x;
	    }
	  else if (code == SMAX || code == SMIN
		   || code == UMIN || code == UMAX)
	    {
	      int unsignedp = (code == UMIN || code == UMAX);

	      /* Do not reverse the condition when it is NE or EQ.
		 This is because we cannot conclude anything about
		 the value of 'SMAX (x, y)' when x is not equal to y,
		 but we can when x equals y.  */
	      if ((code == SMAX || code == UMAX)
		  && ! (cond == EQ || cond == NE))
		cond = reverse_condition (cond);

	      switch (cond)
		{
		case GE:   case GT:
		  return unsignedp ? x : XEXP (x, 1);
		case LE:   case LT:
		  return unsignedp ? x : XEXP (x, 0);
		case GEU:  case GTU:
		  return unsignedp ? XEXP (x, 1) : x;
		case LEU:  case LTU:
		  return unsignedp ? XEXP (x, 0) : x;
		default:
		  break;
		}
	    }
	}
    }
  else if (code == SUBREG)
    {
      machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
      rtx new_rtx, r = known_cond (SUBREG_REG (x), cond, reg, val);

      if (SUBREG_REG (x) != r)
	{
	  /* We must simplify subreg here, before we lose track of the
	     original inner_mode.  */
	  new_rtx = simplify_subreg (GET_MODE (x), r,
				     inner_mode, SUBREG_BYTE (x));
	  if (new_rtx)
	    return new_rtx;
	  else
	    SUBST (SUBREG_REG (x), r);
	}

      return x;
    }
  /* We don't have to handle SIGN_EXTEND here, because even in the
     case of replacing something with a modeless CONST_INT, a
     CONST_INT is already (supposed to be) a valid sign extension for
     its narrower mode, which implies it's already properly
     sign-extended for the wider mode.  Now, for ZERO_EXTEND, the
     story is different.  */
  else if (code == ZERO_EXTEND)
    {
      machine_mode inner_mode = GET_MODE (XEXP (x, 0));
      rtx new_rtx, r = known_cond (XEXP (x, 0), cond, reg, val);

      if (XEXP (x, 0) != r)
	{
	  /* We must simplify the zero_extend here, before we lose
	     track of the original inner_mode.  */
	  new_rtx = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
					      r, inner_mode);
	  if (new_rtx)
	    return new_rtx;
	  else
	    SUBST (XEXP (x, 0), r);
	}

      return x;
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	SUBST (XEXP (x, i), known_cond (XEXP (x, i), cond, reg, val));
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  SUBST (XVECEXP (x, i, j), known_cond (XVECEXP (x, i, j),
						cond, reg, val));
    }

  return x;
}

/* See if X and Y are equal for the purposes of seeing if we can rewrite an
   assignment as a field assignment.  */

static int
rtx_equal_for_field_assignment_p (rtx x, rtx y, bool widen_x)
{
  if (widen_x && GET_MODE (x) != GET_MODE (y))
    {
      if (paradoxical_subreg_p (GET_MODE (x), GET_MODE (y)))
	return 0;
      if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
	return 0;
      x = adjust_address_nv (x, GET_MODE (y),
			     byte_lowpart_offset (GET_MODE (y),
						  GET_MODE (x)));
    }

  if (x == y || rtx_equal_p (x, y))
    return 1;

  if (x == 0 || y == 0 || GET_MODE (x) != GET_MODE (y))
    return 0;

  /* Check for a paradoxical SUBREG of a MEM compared with the MEM.
     Note that all SUBREGs of MEM are paradoxical; otherwise they
     would have been rewritten.  */
  if (MEM_P (x) && GET_CODE (y) == SUBREG
      && MEM_P (SUBREG_REG (y))
      && rtx_equal_p (SUBREG_REG (y),
		      gen_lowpart (GET_MODE (SUBREG_REG (y)), x)))
    return 1;

  if (MEM_P (y) && GET_CODE (x) == SUBREG
      && MEM_P (SUBREG_REG (x))
      && rtx_equal_p (SUBREG_REG (x),
		      gen_lowpart (GET_MODE (SUBREG_REG (x)), y)))
    return 1;

  /* We used to see if get_last_value of X and Y were the same but that's
     not correct.  In one direction, we'll cause the assignment to have
     the wrong destination and in the case, we'll import a register into this
     insn that might have already have been dead.   So fail if none of the
     above cases are true.  */
  return 0;
}

/* See if X, a SET operation, can be rewritten as a bit-field assignment.
   Return that assignment if so.

   We only handle the most common cases.  */

static rtx
make_field_assignment (rtx x)
{
  rtx dest = SET_DEST (x);
  rtx src = SET_SRC (x);
  rtx assign;
  rtx rhs, lhs;
  HOST_WIDE_INT c1;
  HOST_WIDE_INT pos;
  unsigned HOST_WIDE_INT len;
  rtx other;

  /* All the rules in this function are specific to scalar integers.  */
  scalar_int_mode mode;
  if (!is_a <scalar_int_mode> (GET_MODE (dest), &mode))
    return x;

  /* If SRC was (and (not (ashift (const_int 1) POS)) DEST), this is
     a clear of a one-bit field.  We will have changed it to
     (and (rotate (const_int -2) POS) DEST), so check for that.  Also check
     for a SUBREG.  */

  if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == ROTATE
      && CONST_INT_P (XEXP (XEXP (src, 0), 0))
      && INTVAL (XEXP (XEXP (src, 0), 0)) == -2
      && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
    {
      assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
				1, 1, 1, 0);
      if (assign != 0)
	return gen_rtx_SET (assign, const0_rtx);
      return x;
    }

  if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG
      && subreg_lowpart_p (XEXP (src, 0))
      && partial_subreg_p (XEXP (src, 0))
      && GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE
      && CONST_INT_P (XEXP (SUBREG_REG (XEXP (src, 0)), 0))
      && INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2
      && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
    {
      assign = make_extraction (VOIDmode, dest, 0,
				XEXP (SUBREG_REG (XEXP (src, 0)), 1),
				1, 1, 1, 0);
      if (assign != 0)
	return gen_rtx_SET (assign, const0_rtx);
      return x;
    }

  /* If SRC is (ior (ashift (const_int 1) POS) DEST), this is a set of a
     one-bit field.  */
  if (GET_CODE (src) == IOR && GET_CODE (XEXP (src, 0)) == ASHIFT
      && XEXP (XEXP (src, 0), 0) == const1_rtx
      && rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
    {
      assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
				1, 1, 1, 0);
      if (assign != 0)
	return gen_rtx_SET (assign, const1_rtx);
      return x;
    }

  /* If DEST is already a field assignment, i.e. ZERO_EXTRACT, and the
     SRC is an AND with all bits of that field set, then we can discard
     the AND.  */
  if (GET_CODE (dest) == ZERO_EXTRACT
      && CONST_INT_P (XEXP (dest, 1))
      && GET_CODE (src) == AND
      && CONST_INT_P (XEXP (src, 1)))
    {
      HOST_WIDE_INT width = INTVAL (XEXP (dest, 1));
      unsigned HOST_WIDE_INT and_mask = INTVAL (XEXP (src, 1));
      unsigned HOST_WIDE_INT ze_mask;

      if (width >= HOST_BITS_PER_WIDE_INT)
	ze_mask = -1;
      else
	ze_mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;

      /* Complete overlap.  We can remove the source AND.  */
      if ((and_mask & ze_mask) == ze_mask)
	return gen_rtx_SET (dest, XEXP (src, 0));

      /* Partial overlap.  We can reduce the source AND.  */
      if ((and_mask & ze_mask) != and_mask)
	{
	  src = gen_rtx_AND (mode, XEXP (src, 0),
			     gen_int_mode (and_mask & ze_mask, mode));
	  return gen_rtx_SET (dest, src);
	}
    }

  /* The other case we handle is assignments into a constant-position
     field.  They look like (ior/xor (and DEST C1) OTHER).  If C1 represents
     a mask that has all one bits except for a group of zero bits and
     OTHER is known to have zeros where C1 has ones, this is such an
     assignment.  Compute the position and length from C1.  Shift OTHER
     to the appropriate position, force it to the required mode, and
     make the extraction.  Check for the AND in both operands.  */

  /* One or more SUBREGs might obscure the constant-position field
     assignment.  The first one we are likely to encounter is an outer
     narrowing SUBREG, which we can just strip for the purposes of
     identifying the constant-field assignment.  */
  scalar_int_mode src_mode = mode;
  if (GET_CODE (src) == SUBREG
      && subreg_lowpart_p (src)
      && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (src)), &src_mode))
    src = SUBREG_REG (src);

  if (GET_CODE (src) != IOR && GET_CODE (src) != XOR)
    return x;

  rhs = expand_compound_operation (XEXP (src, 0));
  lhs = expand_compound_operation (XEXP (src, 1));

  if (GET_CODE (rhs) == AND
      && CONST_INT_P (XEXP (rhs, 1))
      && rtx_equal_for_field_assignment_p (XEXP (rhs, 0), dest))
    c1 = INTVAL (XEXP (rhs, 1)), other = lhs;
  /* The second SUBREG that might get in the way is a paradoxical
     SUBREG around the first operand of the AND.  We want to 
     pretend the operand is as wide as the destination here.   We
     do this by adjusting the MEM to wider mode for the sole
     purpose of the call to rtx_equal_for_field_assignment_p.   Also
     note this trick only works for MEMs.  */
  else if (GET_CODE (rhs) == AND
	   && paradoxical_subreg_p (XEXP (rhs, 0))
	   && MEM_P (SUBREG_REG (XEXP (rhs, 0)))
	   && CONST_INT_P (XEXP (rhs, 1))
	   && rtx_equal_for_field_assignment_p (SUBREG_REG (XEXP (rhs, 0)),
						dest, true))
    c1 = INTVAL (XEXP (rhs, 1)), other = lhs;
  else if (GET_CODE (lhs) == AND
	   && CONST_INT_P (XEXP (lhs, 1))
	   && rtx_equal_for_field_assignment_p (XEXP (lhs, 0), dest))
    c1 = INTVAL (XEXP (lhs, 1)), other = rhs;
  /* The second SUBREG that might get in the way is a paradoxical
     SUBREG around the first operand of the AND.  We want to 
     pretend the operand is as wide as the destination here.   We
     do this by adjusting the MEM to wider mode for the sole
     purpose of the call to rtx_equal_for_field_assignment_p.   Also
     note this trick only works for MEMs.  */
  else if (GET_CODE (lhs) == AND
	   && paradoxical_subreg_p (XEXP (lhs, 0))
	   && MEM_P (SUBREG_REG (XEXP (lhs, 0)))
	   && CONST_INT_P (XEXP (lhs, 1))
	   && rtx_equal_for_field_assignment_p (SUBREG_REG (XEXP (lhs, 0)),
						dest, true))
    c1 = INTVAL (XEXP (lhs, 1)), other = rhs;
  else
    return x;

  pos = get_pos_from_mask ((~c1) & GET_MODE_MASK (mode), &len);
  if (pos < 0
      || pos + len > GET_MODE_PRECISION (mode)
      || GET_MODE_PRECISION (mode) > HOST_BITS_PER_WIDE_INT
      || (c1 & nonzero_bits (other, mode)) != 0)
    return x;

  assign = make_extraction (VOIDmode, dest, pos, NULL_RTX, len, 1, 1, 0);
  if (assign == 0)
    return x;

  /* The mode to use for the source is the mode of the assignment, or of
     what is inside a possible STRICT_LOW_PART.  */
  machine_mode new_mode = (GET_CODE (assign) == STRICT_LOW_PART
			   ? GET_MODE (XEXP (assign, 0)) : GET_MODE (assign));

  /* Shift OTHER right POS places and make it the source, restricting it
     to the proper length and mode.  */

  src = canon_reg_for_combine (simplify_shift_const (NULL_RTX, LSHIFTRT,
						     src_mode, other, pos),
			       dest);
  src = force_to_mode (src, new_mode,
		       len >= HOST_BITS_PER_WIDE_INT
		       ? HOST_WIDE_INT_M1U
		       : (HOST_WIDE_INT_1U << len) - 1,
		       0);

  /* If SRC is masked by an AND that does not make a difference in
     the value being stored, strip it.  */
  if (GET_CODE (assign) == ZERO_EXTRACT
      && CONST_INT_P (XEXP (assign, 1))
      && INTVAL (XEXP (assign, 1)) < HOST_BITS_PER_WIDE_INT
      && GET_CODE (src) == AND
      && CONST_INT_P (XEXP (src, 1))
      && UINTVAL (XEXP (src, 1))
	 == (HOST_WIDE_INT_1U << INTVAL (XEXP (assign, 1))) - 1)
    src = XEXP (src, 0);

  return gen_rtx_SET (assign, src);
}

/* See if X is of the form (+ (* a c) (* b c)) and convert to (* (+ a b) c)
   if so.  */

static rtx
apply_distributive_law (rtx x)
{
  enum rtx_code code = GET_CODE (x);
  enum rtx_code inner_code;
  rtx lhs, rhs, other;
  rtx tem;

  /* Distributivity is not true for floating point as it can change the
     value.  So we don't do it unless -funsafe-math-optimizations.  */
  if (FLOAT_MODE_P (GET_MODE (x))
      && ! flag_unsafe_math_optimizations)
    return x;

  /* The outer operation can only be one of the following:  */
  if (code != IOR && code != AND && code != XOR
      && code != PLUS && code != MINUS)
    return x;

  lhs = XEXP (x, 0);
  rhs = XEXP (x, 1);

  /* If either operand is a primitive we can't do anything, so get out
     fast.  */
  if (OBJECT_P (lhs) || OBJECT_P (rhs))
    return x;

  lhs = expand_compound_operation (lhs);
  rhs = expand_compound_operation (rhs);
  inner_code = GET_CODE (lhs);
  if (inner_code != GET_CODE (rhs))
    return x;

  /* See if the inner and outer operations distribute.  */
  switch (inner_code)
    {
    case LSHIFTRT:
    case ASHIFTRT:
    case AND:
    case IOR:
      /* These all distribute except over PLUS.  */
      if (code == PLUS || code == MINUS)
	return x;
      break;

    case MULT:
      if (code != PLUS && code != MINUS)
	return x;
      break;

    case ASHIFT:
      /* This is also a multiply, so it distributes over everything.  */
      break;

    /* This used to handle SUBREG, but this turned out to be counter-
       productive, since (subreg (op ...)) usually is not handled by
       insn patterns, and this "optimization" therefore transformed
       recognizable patterns into unrecognizable ones.  Therefore the
       SUBREG case was removed from here.

       It is possible that distributing SUBREG over arithmetic operations
       leads to an intermediate result than can then be optimized further,
       e.g. by moving the outer SUBREG to the other side of a SET as done
       in simplify_set.  This seems to have been the original intent of
       handling SUBREGs here.

       However, with current GCC this does not appear to actually happen,
       at least on major platforms.  If some case is found where removing
       the SUBREG case here prevents follow-on optimizations, distributing
       SUBREGs ought to be re-added at that place, e.g. in simplify_set.  */

    default:
      return x;
    }

  /* Set LHS and RHS to the inner operands (A and B in the example
     above) and set OTHER to the common operand (C in the example).
     There is only one way to do this unless the inner operation is
     commutative.  */
  if (COMMUTATIVE_ARITH_P (lhs)
      && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 0)))
    other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 1);
  else if (COMMUTATIVE_ARITH_P (lhs)
	   && rtx_equal_p (XEXP (lhs, 0), XEXP (rhs, 1)))
    other = XEXP (lhs, 0), lhs = XEXP (lhs, 1), rhs = XEXP (rhs, 0);
  else if (COMMUTATIVE_ARITH_P (lhs)
	   && rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 0)))
    other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 1);
  else if (rtx_equal_p (XEXP (lhs, 1), XEXP (rhs, 1)))
    other = XEXP (lhs, 1), lhs = XEXP (lhs, 0), rhs = XEXP (rhs, 0);
  else
    return x;

  /* Form the new inner operation, seeing if it simplifies first.  */
  tem = simplify_gen_binary (code, GET_MODE (x), lhs, rhs);

  /* There is one exception to the general way of distributing:
     (a | c) ^ (b | c) -> (a ^ b) & ~c  */
  if (code == XOR && inner_code == IOR)
    {
      inner_code = AND;
      other = simplify_gen_unary (NOT, GET_MODE (x), other, GET_MODE (x));
    }

  /* We may be able to continuing distributing the result, so call
     ourselves recursively on the inner operation before forming the
     outer operation, which we return.  */
  return simplify_gen_binary (inner_code, GET_MODE (x),
			      apply_distributive_law (tem), other);
}

/* See if X is of the form (* (+ A B) C), and if so convert to
   (+ (* A C) (* B C)) and try to simplify.

   Most of the time, this results in no change.  However, if some of
   the operands are the same or inverses of each other, simplifications
   will result.

   For example, (and (ior A B) (not B)) can occur as the result of
   expanding a bit field assignment.  When we apply the distributive
   law to this, we get (ior (and (A (not B))) (and (B (not B)))),
   which then simplifies to (and (A (not B))).

   Note that no checks happen on the validity of applying the inverse
   distributive law.  This is pointless since we can do it in the
   few places where this routine is called.

   N is the index of the term that is decomposed (the arithmetic operation,
   i.e. (+ A B) in the first example above).  !N is the index of the term that
   is distributed, i.e. of C in the first example above.  */
static rtx
distribute_and_simplify_rtx (rtx x, int n)
{
  machine_mode mode;
  enum rtx_code outer_code, inner_code;
  rtx decomposed, distributed, inner_op0, inner_op1, new_op0, new_op1, tmp;

  /* Distributivity is not true for floating point as it can change the
     value.  So we don't do it unless -funsafe-math-optimizations.  */
  if (FLOAT_MODE_P (GET_MODE (x))
      && ! flag_unsafe_math_optimizations)
    return NULL_RTX;

  decomposed = XEXP (x, n);
  if (!ARITHMETIC_P (decomposed))
    return NULL_RTX;

  mode = GET_MODE (x);
  outer_code = GET_CODE (x);
  distributed = XEXP (x, !n);

  inner_code = GET_CODE (decomposed);
  inner_op0 = XEXP (decomposed, 0);
  inner_op1 = XEXP (decomposed, 1);

  /* Special case (and (xor B C) (not A)), which is equivalent to
     (xor (ior A B) (ior A C))  */
  if (outer_code == AND && inner_code == XOR && GET_CODE (distributed) == NOT)
    {
      distributed = XEXP (distributed, 0);
      outer_code = IOR;
    }

  if (n == 0)
    {
      /* Distribute the second term.  */
      new_op0 = simplify_gen_binary (outer_code, mode, inner_op0, distributed);
      new_op1 = simplify_gen_binary (outer_code, mode, inner_op1, distributed);
    }
  else
    {
      /* Distribute the first term.  */
      new_op0 = simplify_gen_binary (outer_code, mode, distributed, inner_op0);
      new_op1 = simplify_gen_binary (outer_code, mode, distributed, inner_op1);
    }

  tmp = apply_distributive_law (simplify_gen_binary (inner_code, mode,
						     new_op0, new_op1));
  if (GET_CODE (tmp) != outer_code
      && (set_src_cost (tmp, mode, optimize_this_for_speed_p)
	  < set_src_cost (x, mode, optimize_this_for_speed_p)))
    return tmp;

  return NULL_RTX;
}

/* Simplify a logical `and' of VAROP with the constant CONSTOP, to be done
   in MODE.  Return an equivalent form, if different from (and VAROP
   (const_int CONSTOP)).  Otherwise, return NULL_RTX.  */

static rtx
simplify_and_const_int_1 (scalar_int_mode mode, rtx varop,
			  unsigned HOST_WIDE_INT constop)
{
  unsigned HOST_WIDE_INT nonzero;
  unsigned HOST_WIDE_INT orig_constop;
  rtx orig_varop;
  int i;

  orig_varop = varop;
  orig_constop = constop;
  if (GET_CODE (varop) == CLOBBER)
    return NULL_RTX;

  /* Simplify VAROP knowing that we will be only looking at some of the
     bits in it.

     Note by passing in CONSTOP, we guarantee that the bits not set in
     CONSTOP are not significant and will never be examined.  We must
     ensure that is the case by explicitly masking out those bits
     before returning.  */
  varop = force_to_mode (varop, mode, constop, 0);

  /* If VAROP is a CLOBBER, we will fail so return it.  */
  if (GET_CODE (varop) == CLOBBER)
    return varop;

  /* If VAROP is a CONST_INT, then we need to apply the mask in CONSTOP
     to VAROP and return the new constant.  */
  if (CONST_INT_P (varop))
    return gen_int_mode (INTVAL (varop) & constop, mode);

  /* See what bits may be nonzero in VAROP.  Unlike the general case of
     a call to nonzero_bits, here we don't care about bits outside
     MODE.  */

  nonzero = nonzero_bits (varop, mode) & GET_MODE_MASK (mode);

  /* Turn off all bits in the constant that are known to already be zero.
     Thus, if the AND isn't needed at all, we will have CONSTOP == NONZERO_BITS
     which is tested below.  */

  constop &= nonzero;

  /* If we don't have any bits left, return zero.  */
  if (constop == 0 && !side_effects_p (varop))
    return const0_rtx;

  /* If VAROP is a NEG of something known to be zero or 1 and CONSTOP is
     a power of two, we can replace this with an ASHIFT.  */
  if (GET_CODE (varop) == NEG && nonzero_bits (XEXP (varop, 0), mode) == 1
      && (i = exact_log2 (constop)) >= 0)
    return simplify_shift_const (NULL_RTX, ASHIFT, mode, XEXP (varop, 0), i);

  /* If VAROP is an IOR or XOR, apply the AND to both branches of the IOR
     or XOR, then try to apply the distributive law.  This may eliminate
     operations if either branch can be simplified because of the AND.
     It may also make some cases more complex, but those cases probably
     won't match a pattern either with or without this.  */

  if (GET_CODE (varop) == IOR || GET_CODE (varop) == XOR)
    {
      scalar_int_mode varop_mode = as_a <scalar_int_mode> (GET_MODE (varop));
      return
	gen_lowpart
	  (mode,
	   apply_distributive_law
	   (simplify_gen_binary (GET_CODE (varop), varop_mode,
				 simplify_and_const_int (NULL_RTX, varop_mode,
							 XEXP (varop, 0),
							 constop),
				 simplify_and_const_int (NULL_RTX, varop_mode,
							 XEXP (varop, 1),
							 constop))));
    }

  /* If VAROP is PLUS, and the constant is a mask of low bits, distribute
     the AND and see if one of the operands simplifies to zero.  If so, we
     may eliminate it.  */

  if (GET_CODE (varop) == PLUS
      && pow2p_hwi (constop + 1))
    {
      rtx o0, o1;

      o0 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 0), constop);
      o1 = simplify_and_const_int (NULL_RTX, mode, XEXP (varop, 1), constop);
      if (o0 == const0_rtx)
	return o1;
      if (o1 == const0_rtx)
	return o0;
    }

  /* Make a SUBREG if necessary.  If we can't make it, fail.  */
  varop = gen_lowpart (mode, varop);
  if (varop == NULL_RTX || GET_CODE (varop) == CLOBBER)
    return NULL_RTX;

  /* If we are only masking insignificant bits, return VAROP.  */
  if (constop == nonzero)
    return varop;

  if (varop == orig_varop && constop == orig_constop)
    return NULL_RTX;

  /* Otherwise, return an AND.  */
  return simplify_gen_binary (AND, mode, varop, gen_int_mode (constop, mode));
}


/* We have X, a logical `and' of VAROP with the constant CONSTOP, to be done
   in MODE.

   Return an equivalent form, if different from X.  Otherwise, return X.  If
   X is zero, we are to always construct the equivalent form.  */

static rtx
simplify_and_const_int (rtx x, scalar_int_mode mode, rtx varop,
			unsigned HOST_WIDE_INT constop)
{
  rtx tem = simplify_and_const_int_1 (mode, varop, constop);
  if (tem)
    return tem;

  if (!x)
    x = simplify_gen_binary (AND, GET_MODE (varop), varop,
			     gen_int_mode (constop, mode));
  if (GET_MODE (x) != mode)
    x = gen_lowpart (mode, x);
  return x;
}

/* Given a REG X of mode XMODE, compute which bits in X can be nonzero.
   We don't care about bits outside of those defined in MODE.
   We DO care about all the bits in MODE, even if XMODE is smaller than MODE.

   For most X this is simply GET_MODE_MASK (GET_MODE (MODE)), but if X is
   a shift, AND, or zero_extract, we can do better.  */

static rtx
reg_nonzero_bits_for_combine (const_rtx x, scalar_int_mode xmode,
			      scalar_int_mode mode,
			      unsigned HOST_WIDE_INT *nonzero)
{
  rtx tem;
  reg_stat_type *rsp;

  /* If X is a register whose nonzero bits value is current, use it.
     Otherwise, if X is a register whose value we can find, use that
     value.  Otherwise, use the previously-computed global nonzero bits
     for this register.  */

  rsp = &reg_stat[REGNO (x)];
  if (rsp->last_set_value != 0
      && (rsp->last_set_mode == mode
	  || (REGNO (x) >= FIRST_PSEUDO_REGISTER
	      && GET_MODE_CLASS (rsp->last_set_mode) == MODE_INT
	      && GET_MODE_CLASS (mode) == MODE_INT))
      && ((rsp->last_set_label >= label_tick_ebb_start
	   && rsp->last_set_label < label_tick)
	  || (rsp->last_set_label == label_tick
              && DF_INSN_LUID (rsp->last_set) < subst_low_luid)
	  || (REGNO (x) >= FIRST_PSEUDO_REGISTER
	      && REGNO (x) < reg_n_sets_max
	      && REG_N_SETS (REGNO (x)) == 1
	      && !REGNO_REG_SET_P
		  (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb),
		   REGNO (x)))))
    {
      /* Note that, even if the precision of last_set_mode is lower than that
	 of mode, record_value_for_reg invoked nonzero_bits on the register
	 with nonzero_bits_mode (because last_set_mode is necessarily integral
	 and HWI_COMPUTABLE_MODE_P in this case) so bits in nonzero_bits_mode
	 are all valid, hence in mode too since nonzero_bits_mode is defined
	 to the largest HWI_COMPUTABLE_MODE_P mode.  */
      *nonzero &= rsp->last_set_nonzero_bits;
      return NULL;
    }

  tem = get_last_value (x);
  if (tem)
    {
      if (SHORT_IMMEDIATES_SIGN_EXTEND)
	tem = sign_extend_short_imm (tem, xmode, GET_MODE_PRECISION (mode));

      return tem;
    }

  if (nonzero_sign_valid && rsp->nonzero_bits)
    {
      unsigned HOST_WIDE_INT mask = rsp->nonzero_bits;

      if (GET_MODE_PRECISION (xmode) < GET_MODE_PRECISION (mode))
	/* We don't know anything about the upper bits.  */
	mask |= GET_MODE_MASK (mode) ^ GET_MODE_MASK (xmode);

      *nonzero &= mask;
    }

  return NULL;
}

/* Given a reg X of mode XMODE, return the number of bits at the high-order
   end of X that are known to be equal to the sign bit.  X will be used
   in mode MODE; the returned value will always be between 1 and the
   number of bits in MODE.  */

static rtx
reg_num_sign_bit_copies_for_combine (const_rtx x, scalar_int_mode xmode,
				     scalar_int_mode mode,
				     unsigned int *result)
{
  rtx tem;
  reg_stat_type *rsp;

  rsp = &reg_stat[REGNO (x)];
  if (rsp->last_set_value != 0
      && rsp->last_set_mode == mode
      && ((rsp->last_set_label >= label_tick_ebb_start
	   && rsp->last_set_label < label_tick)
	  || (rsp->last_set_label == label_tick
              && DF_INSN_LUID (rsp->last_set) < subst_low_luid)
	  || (REGNO (x) >= FIRST_PSEUDO_REGISTER
	      && REGNO (x) < reg_n_sets_max
	      && REG_N_SETS (REGNO (x)) == 1
	      && !REGNO_REG_SET_P
		  (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb),
		   REGNO (x)))))
    {
      *result = rsp->last_set_sign_bit_copies;
      return NULL;
    }

  tem = get_last_value (x);
  if (tem != 0)
    return tem;

  if (nonzero_sign_valid && rsp->sign_bit_copies != 0
      && GET_MODE_PRECISION (xmode) == GET_MODE_PRECISION (mode))
    *result = rsp->sign_bit_copies;

  return NULL;
}

/* Return the number of "extended" bits there are in X, when interpreted
   as a quantity in MODE whose signedness is indicated by UNSIGNEDP.  For
   unsigned quantities, this is the number of high-order zero bits.
   For signed quantities, this is the number of copies of the sign bit
   minus 1.  In both case, this function returns the number of "spare"
   bits.  For example, if two quantities for which this function returns
   at least 1 are added, the addition is known not to overflow.

   This function will always return 0 unless called during combine, which
   implies that it must be called from a define_split.  */

unsigned int
extended_count (const_rtx x, machine_mode mode, int unsignedp)
{
  if (nonzero_sign_valid == 0)
    return 0;

  scalar_int_mode int_mode;
  return (unsignedp
	  ? (is_a <scalar_int_mode> (mode, &int_mode)
	     && HWI_COMPUTABLE_MODE_P (int_mode)
	     ? (unsigned int) (GET_MODE_PRECISION (int_mode) - 1
			       - floor_log2 (nonzero_bits (x, int_mode)))
	     : 0)
	  : num_sign_bit_copies (x, mode) - 1);
}

/* This function is called from `simplify_shift_const' to merge two
   outer operations.  Specifically, we have already found that we need
   to perform operation *POP0 with constant *PCONST0 at the outermost
   position.  We would now like to also perform OP1 with constant CONST1
   (with *POP0 being done last).

   Return 1 if we can do the operation and update *POP0 and *PCONST0 with
   the resulting operation.  *PCOMP_P is set to 1 if we would need to
   complement the innermost operand, otherwise it is unchanged.

   MODE is the mode in which the operation will be done.  No bits outside
   the width of this mode matter.  It is assumed that the width of this mode
   is smaller than or equal to HOST_BITS_PER_WIDE_INT.

   If *POP0 or OP1 are UNKNOWN, it means no operation is required.  Only NEG, PLUS,
   IOR, XOR, and AND are supported.  We may set *POP0 to SET if the proper
   result is simply *PCONST0.

   If the resulting operation cannot be expressed as one operation, we
   return 0 and do not change *POP0, *PCONST0, and *PCOMP_P.  */

static int
merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, HOST_WIDE_INT const1, machine_mode mode, int *pcomp_p)
{
  enum rtx_code op0 = *pop0;
  HOST_WIDE_INT const0 = *pconst0;

  const0 &= GET_MODE_MASK (mode);
  const1 &= GET_MODE_MASK (mode);

  /* If OP0 is an AND, clear unimportant bits in CONST1.  */
  if (op0 == AND)
    const1 &= const0;

  /* If OP0 or OP1 is UNKNOWN, this is easy.  Similarly if they are the same or
     if OP0 is SET.  */

  if (op1 == UNKNOWN || op0 == SET)
    return 1;

  else if (op0 == UNKNOWN)
    op0 = op1, const0 = const1;

  else if (op0 == op1)
    {
      switch (op0)
	{
	case AND:
	  const0 &= const1;
	  break;
	case IOR:
	  const0 |= const1;
	  break;
	case XOR:
	  const0 ^= const1;
	  break;
	case PLUS:
	  const0 += const1;
	  break;
	case NEG:
	  op0 = UNKNOWN;
	  break;
	default:
	  break;
	}
    }

  /* Otherwise, if either is a PLUS or NEG, we can't do anything.  */
  else if (op0 == PLUS || op1 == PLUS || op0 == NEG || op1 == NEG)
    return 0;

  /* If the two constants aren't the same, we can't do anything.  The
     remaining six cases can all be done.  */
  else if (const0 != const1)
    return 0;

  else
    switch (op0)
      {
      case IOR:
	if (op1 == AND)
	  /* (a & b) | b == b */
	  op0 = SET;
	else /* op1 == XOR */
	  /* (a ^ b) | b == a | b */
	  {;}
	break;

      case XOR:
	if (op1 == AND)
	  /* (a & b) ^ b == (~a) & b */
	  op0 = AND, *pcomp_p = 1;
	else /* op1 == IOR */
	  /* (a | b) ^ b == a & ~b */
	  op0 = AND, const0 = ~const0;
	break;

      case AND:
	if (op1 == IOR)
	  /* (a | b) & b == b */
	op0 = SET;
	else /* op1 == XOR */
	  /* (a ^ b) & b) == (~a) & b */
	  *pcomp_p = 1;
	break;
      default:
	break;
      }

  /* Check for NO-OP cases.  */
  const0 &= GET_MODE_MASK (mode);
  if (const0 == 0
      && (op0 == IOR || op0 == XOR || op0 == PLUS))
    op0 = UNKNOWN;
  else if (const0 == 0 && op0 == AND)
    op0 = SET;
  else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode)
	   && op0 == AND)
    op0 = UNKNOWN;

  *pop0 = op0;

  /* ??? Slightly redundant with the above mask, but not entirely.
     Moving this above means we'd have to sign-extend the mode mask
     for the final test.  */
  if (op0 != UNKNOWN && op0 != NEG)
    *pconst0 = trunc_int_for_mode (const0, mode);

  return 1;
}

/* A helper to simplify_shift_const_1 to determine the mode we can perform
   the shift in.  The original shift operation CODE is performed on OP in
   ORIG_MODE.  Return the wider mode MODE if we can perform the operation
   in that mode.  Return ORIG_MODE otherwise.  We can also assume that the
   result of the shift is subject to operation OUTER_CODE with operand
   OUTER_CONST.  */

static scalar_int_mode
try_widen_shift_mode (enum rtx_code code, rtx op, int count,
		      scalar_int_mode orig_mode, scalar_int_mode mode,
		      enum rtx_code outer_code, HOST_WIDE_INT outer_const)
{
  gcc_assert (GET_MODE_PRECISION (mode) > GET_MODE_PRECISION (orig_mode));

  /* In general we can't perform in wider mode for right shift and rotate.  */
  switch (code)
    {
    case ASHIFTRT:
      /* We can still widen if the bits brought in from the left are identical
	 to the sign bit of ORIG_MODE.  */
      if (num_sign_bit_copies (op, mode)
	  > (unsigned) (GET_MODE_PRECISION (mode)
			- GET_MODE_PRECISION (orig_mode)))
	return mode;
      return orig_mode;

    case LSHIFTRT:
      /* Similarly here but with zero bits.  */
      if (HWI_COMPUTABLE_MODE_P (mode)
	  && (nonzero_bits (op, mode) & ~GET_MODE_MASK (orig_mode)) == 0)
	return mode;

      /* We can also widen if the bits brought in will be masked off.  This
	 operation is performed in ORIG_MODE.  */
      if (outer_code == AND)
	{
	  int care_bits = low_bitmask_len (orig_mode, outer_const);

	  if (care_bits >= 0
	      && GET_MODE_PRECISION (orig_mode) - care_bits >= count)
	    return mode;
	}
      /* fall through */

    case ROTATE:
      return orig_mode;

    case ROTATERT:
      gcc_unreachable ();

    default:
      return mode;
    }
}

/* Simplify a shift of VAROP by ORIG_COUNT bits.  CODE says what kind
   of shift.  The result of the shift is RESULT_MODE.  Return NULL_RTX
   if we cannot simplify it.  Otherwise, return a simplified value.

   The shift is normally computed in the widest mode we find in VAROP, as
   long as it isn't a different number of words than RESULT_MODE.  Exceptions
   are ASHIFTRT and ROTATE, which are always done in their original mode.  */

static rtx
simplify_shift_const_1 (enum rtx_code code, machine_mode result_mode,
			rtx varop, int orig_count)
{
  enum rtx_code orig_code = code;
  rtx orig_varop = varop;
  int count, log2;
  machine_mode mode = result_mode;
  machine_mode shift_mode;
  scalar_int_mode tmode, inner_mode, int_mode, int_varop_mode, int_result_mode;
  /* We form (outer_op (code varop count) (outer_const)).  */
  enum rtx_code outer_op = UNKNOWN;
  HOST_WIDE_INT outer_const = 0;
  int complement_p = 0;
  rtx new_rtx, x;

  /* Make sure and truncate the "natural" shift on the way in.  We don't
     want to do this inside the loop as it makes it more difficult to
     combine shifts.  */
  if (SHIFT_COUNT_TRUNCATED)
    orig_count &= GET_MODE_UNIT_BITSIZE (mode) - 1;

  /* If we were given an invalid count, don't do anything except exactly
     what was requested.  */

  if (orig_count < 0 || orig_count >= (int) GET_MODE_UNIT_PRECISION (mode))
    return NULL_RTX;

  count = orig_count;

  /* Unless one of the branches of the `if' in this loop does a `continue',
     we will `break' the loop after the `if'.  */

  while (count != 0)
    {
      /* If we have an operand of (clobber (const_int 0)), fail.  */
      if (GET_CODE (varop) == CLOBBER)
	return NULL_RTX;

      /* Convert ROTATERT to ROTATE.  */
      if (code == ROTATERT)
	{
	  unsigned int bitsize = GET_MODE_UNIT_PRECISION (result_mode);
	  code = ROTATE;
	  count = bitsize - count;
	}

      shift_mode = result_mode;
      if (shift_mode != mode)
	{
	  /* We only change the modes of scalar shifts.  */
	  int_mode = as_a <scalar_int_mode> (mode);
	  int_result_mode = as_a <scalar_int_mode> (result_mode);
	  shift_mode = try_widen_shift_mode (code, varop, count,
					     int_result_mode, int_mode,
					     outer_op, outer_const);
	}

      scalar_int_mode shift_unit_mode
	= as_a <scalar_int_mode> (GET_MODE_INNER (shift_mode));

      /* Handle cases where the count is greater than the size of the mode
	 minus 1.  For ASHIFT, use the size minus one as the count (this can
	 occur when simplifying (lshiftrt (ashiftrt ..))).  For rotates,
	 take the count modulo the size.  For other shifts, the result is
	 zero.

	 Since these shifts are being produced by the compiler by combining
	 multiple operations, each of which are defined, we know what the
	 result is supposed to be.  */

      if (count > (GET_MODE_PRECISION (shift_unit_mode) - 1))
	{
	  if (code == ASHIFTRT)
	    count = GET_MODE_PRECISION (shift_unit_mode) - 1;
	  else if (code == ROTATE || code == ROTATERT)
	    count %= GET_MODE_PRECISION (shift_unit_mode);
	  else
	    {
	      /* We can't simply return zero because there may be an
		 outer op.  */
	      varop = const0_rtx;
	      count = 0;
	      break;
	    }
	}

      /* If we discovered we had to complement VAROP, leave.  Making a NOT
	 here would cause an infinite loop.  */
      if (complement_p)
	break;

      if (shift_mode == shift_unit_mode)
	{
	  /* An arithmetic right shift of a quantity known to be -1 or 0
	     is a no-op.  */
	  if (code == ASHIFTRT
	      && (num_sign_bit_copies (varop, shift_unit_mode)
		  == GET_MODE_PRECISION (shift_unit_mode)))
	    {
	      count = 0;
	      break;
	    }

	  /* If we are doing an arithmetic right shift and discarding all but
	     the sign bit copies, this is equivalent to doing a shift by the
	     bitsize minus one.  Convert it into that shift because it will
	     often allow other simplifications.  */

	  if (code == ASHIFTRT
	      && (count + num_sign_bit_copies (varop, shift_unit_mode)
		  >= GET_MODE_PRECISION (shift_unit_mode)))
	    count = GET_MODE_PRECISION (shift_unit_mode) - 1;

	  /* We simplify the tests below and elsewhere by converting
	     ASHIFTRT to LSHIFTRT if we know the sign bit is clear.
	     `make_compound_operation' will convert it to an ASHIFTRT for
	     those machines (such as VAX) that don't have an LSHIFTRT.  */
	  if (code == ASHIFTRT
	      && HWI_COMPUTABLE_MODE_P (shift_unit_mode)
	      && val_signbit_known_clear_p (shift_unit_mode,
					    nonzero_bits (varop,
							  shift_unit_mode)))
	    code = LSHIFTRT;

	  if (((code == LSHIFTRT
		&& HWI_COMPUTABLE_MODE_P (shift_unit_mode)
		&& !(nonzero_bits (varop, shift_unit_mode) >> count))
	       || (code == ASHIFT
		   && HWI_COMPUTABLE_MODE_P (shift_unit_mode)
		   && !((nonzero_bits (varop, shift_unit_mode) << count)
			& GET_MODE_MASK (shift_unit_mode))))
	      && !side_effects_p (varop))
	    varop = const0_rtx;
	}

      switch (GET_CODE (varop))
	{
	case SIGN_EXTEND:
	case ZERO_EXTEND:
	case SIGN_EXTRACT:
	case ZERO_EXTRACT:
	  new_rtx = expand_compound_operation (varop);
	  if (new_rtx != varop)
	    {
	      varop = new_rtx;
	      continue;
	    }
	  break;

	case MEM:
	  /* The following rules apply only to scalars.  */
	  if (shift_mode != shift_unit_mode)
	    break;
	  int_mode = as_a <scalar_int_mode> (mode);

	  /* If we have (xshiftrt (mem ...) C) and C is MODE_WIDTH
	     minus the width of a smaller mode, we can do this with a
	     SIGN_EXTEND or ZERO_EXTEND from the narrower memory location.  */
	  if ((code == ASHIFTRT || code == LSHIFTRT)
	      && ! mode_dependent_address_p (XEXP (varop, 0),
					     MEM_ADDR_SPACE (varop))
	      && ! MEM_VOLATILE_P (varop)
	      && (int_mode_for_size (GET_MODE_BITSIZE (int_mode) - count, 1)
		  .exists (&tmode)))
	    {
	      new_rtx = adjust_address_nv (varop, tmode,
					   BYTES_BIG_ENDIAN ? 0
					   : count / BITS_PER_UNIT);

	      varop = gen_rtx_fmt_e (code == ASHIFTRT ? SIGN_EXTEND
				     : ZERO_EXTEND, int_mode, new_rtx);
	      count = 0;
	      continue;
	    }
	  break;

	case SUBREG:
	  /* The following rules apply only to scalars.  */
	  if (shift_mode != shift_unit_mode)
	    break;
	  int_mode = as_a <scalar_int_mode> (mode);
	  int_varop_mode = as_a <scalar_int_mode> (GET_MODE (varop));

	  /* If VAROP is a SUBREG, strip it as long as the inner operand has
	     the same number of words as what we've seen so far.  Then store
	     the widest mode in MODE.  */
	  if (subreg_lowpart_p (varop)
	      && is_int_mode (GET_MODE (SUBREG_REG (varop)), &inner_mode)
	      && GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (int_varop_mode)
	      && (CEIL (GET_MODE_SIZE (inner_mode), UNITS_PER_WORD)
		  == CEIL (GET_MODE_SIZE (int_mode), UNITS_PER_WORD))
	      && GET_MODE_CLASS (int_varop_mode) == MODE_INT)
	    {
	      varop = SUBREG_REG (varop);
	      if (GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (int_mode))
		mode = inner_mode;
	      continue;
	    }
	  break;

	case MULT:
	  /* Some machines use MULT instead of ASHIFT because MULT
	     is cheaper.  But it is still better on those machines to
	     merge two shifts into one.  */
	  if (CONST_INT_P (XEXP (varop, 1))
	      && (log2 = exact_log2 (UINTVAL (XEXP (varop, 1)))) >= 0)
	    {
	      rtx log2_rtx = gen_int_shift_amount (GET_MODE (varop), log2);
	      varop = simplify_gen_binary (ASHIFT, GET_MODE (varop),
					   XEXP (varop, 0), log2_rtx);
	      continue;
	    }
	  break;

	case UDIV:
	  /* Similar, for when divides are cheaper.  */
	  if (CONST_INT_P (XEXP (varop, 1))
	      && (log2 = exact_log2 (UINTVAL (XEXP (varop, 1)))) >= 0)
	    {
	      rtx log2_rtx = gen_int_shift_amount (GET_MODE (varop), log2);
	      varop = simplify_gen_binary (LSHIFTRT, GET_MODE (varop),
					   XEXP (varop, 0), log2_rtx);
	      continue;
	    }
	  break;

	case ASHIFTRT:
	  /* If we are extracting just the sign bit of an arithmetic
	     right shift, that shift is not needed.  However, the sign
	     bit of a wider mode may be different from what would be
	     interpreted as the sign bit in a narrower mode, so, if
	     the result is narrower, don't discard the shift.  */
	  if (code == LSHIFTRT
	      && count == (GET_MODE_UNIT_BITSIZE (result_mode) - 1)
	      && (GET_MODE_UNIT_BITSIZE (result_mode)
		  >= GET_MODE_UNIT_BITSIZE (GET_MODE (varop))))
	    {
	      varop = XEXP (varop, 0);
	      continue;
	    }

	  /* fall through */

	case LSHIFTRT:
	case ASHIFT:
	case ROTATE:
	  /* The following rules apply only to scalars.  */
	  if (shift_mode != shift_unit_mode)
	    break;
	  int_mode = as_a <scalar_int_mode> (mode);
	  int_varop_mode = as_a <scalar_int_mode> (GET_MODE (varop));
	  int_result_mode = as_a <scalar_int_mode> (result_mode);

	  /* Here we have two nested shifts.  The result is usually the
	     AND of a new shift with a mask.  We compute the result below.  */
	  if (CONST_INT_P (XEXP (varop, 1))
	      && INTVAL (XEXP (varop, 1)) >= 0
	      && INTVAL (XEXP (varop, 1)) < GET_MODE_PRECISION (int_varop_mode)
	      && HWI_COMPUTABLE_MODE_P (int_result_mode)
	      && HWI_COMPUTABLE_MODE_P (int_mode))
	    {
	      enum rtx_code first_code = GET_CODE (varop);
	      unsigned int first_count = INTVAL (XEXP (varop, 1));
	      unsigned HOST_WIDE_INT mask;
	      rtx mask_rtx;

	      /* We have one common special case.  We can't do any merging if
		 the inner code is an ASHIFTRT of a smaller mode.  However, if
		 we have (ashift:M1 (subreg:M1 (ashiftrt:M2 FOO C1) 0) C2)
		 with C2 == GET_MODE_BITSIZE (M1) - GET_MODE_BITSIZE (M2),
		 we can convert it to
		 (ashiftrt:M1 (ashift:M1 (and:M1 (subreg:M1 FOO 0) C3) C2) C1).
		 This simplifies certain SIGN_EXTEND operations.  */
	      if (code == ASHIFT && first_code == ASHIFTRT
		  && count == (GET_MODE_PRECISION (int_result_mode)
			       - GET_MODE_PRECISION (int_varop_mode)))
		{
		  /* C3 has the low-order C1 bits zero.  */

		  mask = GET_MODE_MASK (int_mode)
			 & ~((HOST_WIDE_INT_1U << first_count) - 1);

		  varop = simplify_and_const_int (NULL_RTX, int_result_mode,
						  XEXP (varop, 0), mask);
		  varop = simplify_shift_const (NULL_RTX, ASHIFT,
						int_result_mode, varop, count);
		  count = first_count;
		  code = ASHIFTRT;
		  continue;
		}

	      /* If this was (ashiftrt (ashift foo C1) C2) and FOO has more
		 than C1 high-order bits equal to the sign bit, we can convert
		 this to either an ASHIFT or an ASHIFTRT depending on the
		 two counts.

		 We cannot do this if VAROP's mode is not SHIFT_UNIT_MODE.  */

	      if (code == ASHIFTRT && first_code == ASHIFT
		  && int_varop_mode == shift_unit_mode
		  && (num_sign_bit_copies (XEXP (varop, 0), shift_unit_mode)
		      > first_count))
		{
		  varop = XEXP (varop, 0);
		  count -= first_count;
		  if (count < 0)
		    {
		      count = -count;
		      code = ASHIFT;
		    }

		  continue;
		}

	      /* There are some cases we can't do.  If CODE is ASHIFTRT,
		 we can only do this if FIRST_CODE is also ASHIFTRT.

		 We can't do the case when CODE is ROTATE and FIRST_CODE is
		 ASHIFTRT.

		 If the mode of this shift is not the mode of the outer shift,
		 we can't do this if either shift is a right shift or ROTATE.

		 Finally, we can't do any of these if the mode is too wide
		 unless the codes are the same.

		 Handle the case where the shift codes are the same
		 first.  */

	      if (code == first_code)
		{
		  if (int_varop_mode != int_result_mode
		      && (code == ASHIFTRT || code == LSHIFTRT
			  || code == ROTATE))
		    break;

		  count += first_count;
		  varop = XEXP (varop, 0);
		  continue;
		}

	      if (code == ASHIFTRT
		  || (code == ROTATE && first_code == ASHIFTRT)
		  || GET_MODE_PRECISION (int_mode) > HOST_BITS_PER_WIDE_INT
		  || (int_varop_mode != int_result_mode
		      && (first_code == ASHIFTRT || first_code == LSHIFTRT
			  || first_code == ROTATE
			  || code == ROTATE)))
		break;

	      /* To compute the mask to apply after the shift, shift the
		 nonzero bits of the inner shift the same way the
		 outer shift will.  */

	      mask_rtx = gen_int_mode (nonzero_bits (varop, int_varop_mode),
				       int_result_mode);
	      rtx count_rtx = gen_int_shift_amount (int_result_mode, count);
	      mask_rtx
		= simplify_const_binary_operation (code, int_result_mode,
						   mask_rtx, count_rtx);

	      /* Give up if we can't compute an outer operation to use.  */
	      if (mask_rtx == 0
		  || !CONST_INT_P (mask_rtx)
		  || ! merge_outer_ops (&outer_op, &outer_const, AND,
					INTVAL (mask_rtx),
					int_result_mode, &complement_p))
		break;

	      /* If the shifts are in the same direction, we add the
		 counts.  Otherwise, we subtract them.  */
	      if ((code == ASHIFTRT || code == LSHIFTRT)
		  == (first_code == ASHIFTRT || first_code == LSHIFTRT))
		count += first_count;
	      else
		count -= first_count;

	      /* If COUNT is positive, the new shift is usually CODE,
		 except for the two exceptions below, in which case it is
		 FIRST_CODE.  If the count is negative, FIRST_CODE should
		 always be used  */
	      if (count > 0
		  && ((first_code == ROTATE && code == ASHIFT)
		      || (first_code == ASHIFTRT && code == LSHIFTRT)))
		code = first_code;
	      else if (count < 0)
		code = first_code, count = -count;

	      varop = XEXP (varop, 0);
	      continue;
	    }

	  /* If we have (A << B << C) for any shift, we can convert this to
	     (A << C << B).  This wins if A is a constant.  Only try this if
	     B is not a constant.  */

	  else if (GET_CODE (varop) == code
		   && CONST_INT_P (XEXP (varop, 0))
		   && !CONST_INT_P (XEXP (varop, 1)))
	    {
	      /* For ((unsigned) (cstULL >> count)) >> cst2 we have to make
		 sure the result will be masked.  See PR70222.  */
	      if (code == LSHIFTRT
		  && int_mode != int_result_mode
		  && !merge_outer_ops (&outer_op, &outer_const, AND,
				       GET_MODE_MASK (int_result_mode)
				       >> orig_count, int_result_mode,
				       &complement_p))
		break;
	      /* For ((int) (cstLL >> count)) >> cst2 just give up.  Queuing
		 up outer sign extension (often left and right shift) is
		 hardly more efficient than the original.  See PR70429.
		 Similarly punt for rotates with different modes.
		 See PR97386.  */
	      if ((code == ASHIFTRT || code == ROTATE)
		  && int_mode != int_result_mode)
		break;

	      rtx count_rtx = gen_int_shift_amount (int_result_mode, count);
	      rtx new_rtx = simplify_const_binary_operation (code, int_mode,
							     XEXP (varop, 0),
							     count_rtx);
	      varop = gen_rtx_fmt_ee (code, int_mode, new_rtx, XEXP (varop, 1));
	      count = 0;
	      continue;
	    }
	  break;

	case NOT:
	  /* The following rules apply only to scalars.  */
	  if (shift_mode != shift_unit_mode)
	    break;

	  /* Make this fit the case below.  */
	  varop = gen_rtx_XOR (mode, XEXP (varop, 0), constm1_rtx);
	  continue;

	case IOR:
	case AND:
	case XOR:
	  /* The following rules apply only to scalars.  */
	  if (shift_mode != shift_unit_mode)
	    break;
	  int_varop_mode = as_a <scalar_int_mode> (GET_MODE (varop));
	  int_result_mode = as_a <scalar_int_mode> (result_mode);

	  /* If we have (xshiftrt (ior (plus X (const_int -1)) X) C)
	     with C the size of VAROP - 1 and the shift is logical if
	     STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1,
	     we have an (le X 0) operation.   If we have an arithmetic shift
	     and STORE_FLAG_VALUE is 1 or we have a logical shift with
	     STORE_FLAG_VALUE of -1, we have a (neg (le X 0)) operation.  */

	  if (GET_CODE (varop) == IOR && GET_CODE (XEXP (varop, 0)) == PLUS
	      && XEXP (XEXP (varop, 0), 1) == constm1_rtx
	      && (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
	      && (code == LSHIFTRT || code == ASHIFTRT)
	      && count == (GET_MODE_PRECISION (int_varop_mode) - 1)
	      && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
	    {
	      count = 0;
	      varop = gen_rtx_LE (int_varop_mode, XEXP (varop, 1),
				  const0_rtx);

	      if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
		varop = gen_rtx_NEG (int_varop_mode, varop);

	      continue;
	    }

	  /* If we have (shift (logical)), move the logical to the outside
	     to allow it to possibly combine with another logical and the
	     shift to combine with another shift.  This also canonicalizes to
	     what a ZERO_EXTRACT looks like.  Also, some machines have
	     (and (shift)) insns.  */

	  if (CONST_INT_P (XEXP (varop, 1))
	      /* We can't do this if we have (ashiftrt (xor))  and the
		 constant has its sign bit set in shift_unit_mode with
		 shift_unit_mode wider than result_mode.  */
	      && !(code == ASHIFTRT && GET_CODE (varop) == XOR
		   && int_result_mode != shift_unit_mode
		   && trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
					  shift_unit_mode) < 0)
	      && (new_rtx = simplify_const_binary_operation
		  (code, int_result_mode,
		   gen_int_mode (INTVAL (XEXP (varop, 1)), int_result_mode),
		   gen_int_shift_amount (int_result_mode, count))) != 0
	      && CONST_INT_P (new_rtx)
	      && merge_outer_ops (&outer_op, &outer_const, GET_CODE (varop),
				  INTVAL (new_rtx), int_result_mode,
				  &complement_p))
	    {
	      varop = XEXP (varop, 0);
	      continue;
	    }

	  /* If we can't do that, try to simplify the shift in each arm of the
	     logical expression, make a new logical expression, and apply
	     the inverse distributive law.  This also can't be done for
	     (ashiftrt (xor)) where we've widened the shift and the constant
	     changes the sign bit.  */
	  if (CONST_INT_P (XEXP (varop, 1))
	      && !(code == ASHIFTRT && GET_CODE (varop) == XOR
		   && int_result_mode != shift_unit_mode
		   && trunc_int_for_mode (INTVAL (XEXP (varop, 1)),
					  shift_unit_mode) < 0))
	    {
	      rtx lhs = simplify_shift_const (NULL_RTX, code, shift_unit_mode,
					      XEXP (varop, 0), count);
	      rtx rhs = simplify_shift_const (NULL_RTX, code, shift_unit_mode,
					      XEXP (varop, 1), count);

	      varop = simplify_gen_binary (GET_CODE (varop), shift_unit_mode,
					   lhs, rhs);
	      varop = apply_distributive_law (varop);

	      count = 0;
	      continue;
	    }
	  break;

	case EQ:
	  /* The following rules apply only to scalars.  */
	  if (shift_mode != shift_unit_mode)
	    break;
	  int_result_mode = as_a <scalar_int_mode> (result_mode);

	  /* Convert (lshiftrt (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE
	     says that the sign bit can be tested, FOO has mode MODE, C is
	     GET_MODE_PRECISION (MODE) - 1, and FOO has only its low-order bit
	     that may be nonzero.  */
	  if (code == LSHIFTRT
	      && XEXP (varop, 1) == const0_rtx
	      && GET_MODE (XEXP (varop, 0)) == int_result_mode
	      && count == (GET_MODE_PRECISION (int_result_mode) - 1)
	      && HWI_COMPUTABLE_MODE_P (int_result_mode)
	      && STORE_FLAG_VALUE == -1
	      && nonzero_bits (XEXP (varop, 0), int_result_mode) == 1
	      && merge_outer_ops (&outer_op, &outer_const, XOR, 1,
				  int_result_mode, &complement_p))
	    {
	      varop = XEXP (varop, 0);
	      count = 0;
	      continue;
	    }
	  break;

	case NEG:
	  /* The following rules apply only to scalars.  */
	  if (shift_mode != shift_unit_mode)
	    break;
	  int_result_mode = as_a <scalar_int_mode> (result_mode);

	  /* (lshiftrt (neg A) C) where A is either 0 or 1 and C is one less
	     than the number of bits in the mode is equivalent to A.  */
	  if (code == LSHIFTRT
	      && count == (GET_MODE_PRECISION (int_result_mode) - 1)
	      && nonzero_bits (XEXP (varop, 0), int_result_mode) == 1)
	    {
	      varop = XEXP (varop, 0);
	      count = 0;
	      continue;
	    }

	  /* NEG commutes with ASHIFT since it is multiplication.  Move the
	     NEG outside to allow shifts to combine.  */
	  if (code == ASHIFT
	      && merge_outer_ops (&outer_op, &outer_const, NEG, 0,
				  int_result_mode, &complement_p))
	    {
	      varop = XEXP (varop, 0);
	      continue;
	    }
	  break;

	case PLUS:
	  /* The following rules apply only to scalars.  */
	  if (shift_mode != shift_unit_mode)
	    break;
	  int_result_mode = as_a <scalar_int_mode> (result_mode);

	  /* (lshiftrt (plus A -1) C) where A is either 0 or 1 and C
	     is one less than the number of bits in the mode is
	     equivalent to (xor A 1).  */
	  if (code == LSHIFTRT
	      && count == (GET_MODE_PRECISION (int_result_mode) - 1)
	      && XEXP (varop, 1) == constm1_rtx
	      && nonzero_bits (XEXP (varop, 0), int_result_mode) == 1
	      && merge_outer_ops (&outer_op, &outer_const, XOR, 1,
				  int_result_mode, &complement_p))
	    {
	      count = 0;
	      varop = XEXP (varop, 0);
	      continue;
	    }

	  /* If we have (xshiftrt (plus FOO BAR) C), and the only bits
	     that might be nonzero in BAR are those being shifted out and those
	     bits are known zero in FOO, we can replace the PLUS with FOO.
	     Similarly in the other operand order.  This code occurs when
	     we are computing the size of a variable-size array.  */

	  if ((code == ASHIFTRT || code == LSHIFTRT)
	      && count < HOST_BITS_PER_WIDE_INT
	      && nonzero_bits (XEXP (varop, 1), int_result_mode) >> count == 0
	      && (nonzero_bits (XEXP (varop, 1), int_result_mode)
		  & nonzero_bits (XEXP (varop, 0), int_result_mode)) == 0)
	    {
	      varop = XEXP (varop, 0);
	      continue;
	    }
	  else if ((code == ASHIFTRT || code == LSHIFTRT)
		   && count < HOST_BITS_PER_WIDE_INT
		   && HWI_COMPUTABLE_MODE_P (int_result_mode)
		   && (nonzero_bits (XEXP (varop, 0), int_result_mode)
		       >> count) == 0
		   && (nonzero_bits (XEXP (varop, 0), int_result_mode)
		       & nonzero_bits (XEXP (varop, 1), int_result_mode)) == 0)
	    {
	      varop = XEXP (varop, 1);
	      continue;
	    }

	  /* (ashift (plus foo C) N) is (plus (ashift foo N) C').  */
	  if (code == ASHIFT
	      && CONST_INT_P (XEXP (varop, 1))
	      && (new_rtx = simplify_const_binary_operation
		  (ASHIFT, int_result_mode,
		   gen_int_mode (INTVAL (XEXP (varop, 1)), int_result_mode),
		   gen_int_shift_amount (int_result_mode, count))) != 0
	      && CONST_INT_P (new_rtx)
	      && merge_outer_ops (&outer_op, &outer_const, PLUS,
				  INTVAL (new_rtx), int_result_mode,
				  &complement_p))
	    {
	      varop = XEXP (varop, 0);
	      continue;
	    }

	  /* Check for 'PLUS signbit', which is the canonical form of 'XOR
	     signbit', and attempt to change the PLUS to an XOR and move it to
	     the outer operation as is done above in the AND/IOR/XOR case
	     leg for shift(logical). See details in logical handling above
	     for reasoning in doing so.  */
	  if (code == LSHIFTRT
	      && CONST_INT_P (XEXP (varop, 1))
	      && mode_signbit_p (int_result_mode, XEXP (varop, 1))
	      && (new_rtx = simplify_const_binary_operation
		  (code, int_result_mode,
		   gen_int_mode (INTVAL (XEXP (varop, 1)), int_result_mode),
		   gen_int_shift_amount (int_result_mode, count))) != 0
	      && CONST_INT_P (new_rtx)
	      && merge_outer_ops (&outer_op, &outer_const, XOR,
				  INTVAL (new_rtx), int_result_mode,
				  &complement_p))
	    {
	      varop = XEXP (varop, 0);
	      continue;
	    }

	  break;

	case MINUS:
	  /* The following rules apply only to scalars.  */
	  if (shift_mode != shift_unit_mode)
	    break;
	  int_varop_mode = as_a <scalar_int_mode> (GET_MODE (varop));

	  /* If we have (xshiftrt (minus (ashiftrt X C)) X) C)
	     with C the size of VAROP - 1 and the shift is logical if
	     STORE_FLAG_VALUE is 1 and arithmetic if STORE_FLAG_VALUE is -1,
	     we have a (gt X 0) operation.  If the shift is arithmetic with
	     STORE_FLAG_VALUE of 1 or logical with STORE_FLAG_VALUE == -1,
	     we have a (neg (gt X 0)) operation.  */

	  if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
	      && GET_CODE (XEXP (varop, 0)) == ASHIFTRT
	      && count == (GET_MODE_PRECISION (int_varop_mode) - 1)
	      && (code == LSHIFTRT || code == ASHIFTRT)
	      && CONST_INT_P (XEXP (XEXP (varop, 0), 1))
	      && INTVAL (XEXP (XEXP (varop, 0), 1)) == count
	      && rtx_equal_p (XEXP (XEXP (varop, 0), 0), XEXP (varop, 1)))
	    {
	      count = 0;
	      varop = gen_rtx_GT (int_varop_mode, XEXP (varop, 1),
				  const0_rtx);

	      if (STORE_FLAG_VALUE == 1 ? code == ASHIFTRT : code == LSHIFTRT)
		varop = gen_rtx_NEG (int_varop_mode, varop);

	      continue;
	    }
	  break;

	case TRUNCATE:
	  /* Change (lshiftrt (truncate (lshiftrt))) to (truncate (lshiftrt))
	     if the truncate does not affect the value.  */
	  if (code == LSHIFTRT
	      && GET_CODE (XEXP (varop, 0)) == LSHIFTRT
	      && CONST_INT_P (XEXP (XEXP (varop, 0), 1))
	      && (INTVAL (XEXP (XEXP (varop, 0), 1))
		  >= (GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (varop, 0)))
		      - GET_MODE_UNIT_PRECISION (GET_MODE (varop)))))
	    {
	      rtx varop_inner = XEXP (varop, 0);
	      int new_count = count + INTVAL (XEXP (varop_inner, 1));
	      rtx new_count_rtx = gen_int_shift_amount (GET_MODE (varop_inner),
							new_count);
	      varop_inner = gen_rtx_LSHIFTRT (GET_MODE (varop_inner),
					      XEXP (varop_inner, 0),
					      new_count_rtx);
	      varop = gen_rtx_TRUNCATE (GET_MODE (varop), varop_inner);
	      count = 0;
	      continue;
	    }
	  break;

	default:
	  break;
	}

      break;
    }

  shift_mode = result_mode;
  if (shift_mode != mode)
    {
      /* We only change the modes of scalar shifts.  */
      int_mode = as_a <scalar_int_mode> (mode);
      int_result_mode = as_a <scalar_int_mode> (result_mode);
      shift_mode = try_widen_shift_mode (code, varop, count, int_result_mode,
					 int_mode, outer_op, outer_const);
    }

  /* We have now finished analyzing the shift.  The result should be
     a shift of type CODE with SHIFT_MODE shifting VAROP COUNT places.  If
     OUTER_OP is non-UNKNOWN, it is an operation that needs to be applied
     to the result of the shift.  OUTER_CONST is the relevant constant,
     but we must turn off all bits turned off in the shift.  */

  if (outer_op == UNKNOWN
      && orig_code == code && orig_count == count
      && varop == orig_varop
      && shift_mode == GET_MODE (varop))
    return NULL_RTX;

  /* Make a SUBREG if necessary.  If we can't make it, fail.  */
  varop = gen_lowpart (shift_mode, varop);
  if (varop == NULL_RTX || GET_CODE (varop) == CLOBBER)
    return NULL_RTX;

  /* If we have an outer operation and we just made a shift, it is
     possible that we could have simplified the shift were it not
     for the outer operation.  So try to do the simplification
     recursively.  */

  if (outer_op != UNKNOWN)
    x = simplify_shift_const_1 (code, shift_mode, varop, count);
  else
    x = NULL_RTX;

  if (x == NULL_RTX)
    x = simplify_gen_binary (code, shift_mode, varop,
			     gen_int_shift_amount (shift_mode, count));

  /* If we were doing an LSHIFTRT in a wider mode than it was originally,
     turn off all the bits that the shift would have turned off.  */
  if (orig_code == LSHIFTRT && result_mode != shift_mode)
    /* We only change the modes of scalar shifts.  */
    x = simplify_and_const_int (NULL_RTX, as_a <scalar_int_mode> (shift_mode),
				x, GET_MODE_MASK (result_mode) >> orig_count);

  /* Do the remainder of the processing in RESULT_MODE.  */
  x = gen_lowpart_or_truncate (result_mode, x);

  /* If COMPLEMENT_P is set, we have to complement X before doing the outer
     operation.  */
  if (complement_p)
    x = simplify_gen_unary (NOT, result_mode, x, result_mode);

  if (outer_op != UNKNOWN)
    {
      int_result_mode = as_a <scalar_int_mode> (result_mode);

      if (GET_RTX_CLASS (outer_op) != RTX_UNARY
	  && GET_MODE_PRECISION (int_result_mode) < HOST_BITS_PER_WIDE_INT)
	outer_const = trunc_int_for_mode (outer_const, int_result_mode);

      if (outer_op == AND)
	x = simplify_and_const_int (NULL_RTX, int_result_mode, x, outer_const);
      else if (outer_op == SET)
	{
	  /* This means that we have determined that the result is
	     equivalent to a constant.  This should be rare.  */
	  if (!side_effects_p (x))
	    x = GEN_INT (outer_const);
	}
      else if (GET_RTX_CLASS (outer_op) == RTX_UNARY)
	x = simplify_gen_unary (outer_op, int_result_mode, x, int_result_mode);
      else
	x = simplify_gen_binary (outer_op, int_result_mode, x,
				 GEN_INT (outer_const));
    }

  return x;
}

/* Simplify a shift of VAROP by COUNT bits.  CODE says what kind of shift.
   The result of the shift is RESULT_MODE.  If we cannot simplify it,
   return X or, if it is NULL, synthesize the expression with
   simplify_gen_binary.  Otherwise, return a simplified value.

   The shift is normally computed in the widest mode we find in VAROP, as
   long as it isn't a different number of words than RESULT_MODE.  Exceptions
   are ASHIFTRT and ROTATE, which are always done in their original mode.  */

static rtx
simplify_shift_const (rtx x, enum rtx_code code, machine_mode result_mode,
		      rtx varop, int count)
{
  rtx tem = simplify_shift_const_1 (code, result_mode, varop, count);
  if (tem)
    return tem;

  if (!x)
    x = simplify_gen_binary (code, GET_MODE (varop), varop,
			     gen_int_shift_amount (GET_MODE (varop), count));
  if (GET_MODE (x) != result_mode)
    x = gen_lowpart (result_mode, x);
  return x;
}


/* A subroutine of recog_for_combine.  See there for arguments and
   return value.  */

static int
recog_for_combine_1 (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
{
  rtx pat = *pnewpat;
  rtx pat_without_clobbers;
  int insn_code_number;
  int num_clobbers_to_add = 0;
  int i;
  rtx notes = NULL_RTX;
  rtx old_notes, old_pat;
  int old_icode;

  /* If PAT is a PARALLEL, check to see if it contains the CLOBBER
     we use to indicate that something didn't match.  If we find such a
     thing, force rejection.  */
  if (GET_CODE (pat) == PARALLEL)
    for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
      if (GET_CODE (XVECEXP (pat, 0, i)) == CLOBBER
	  && XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
	return -1;

  old_pat = PATTERN (insn);
  old_notes = REG_NOTES (insn);
  PATTERN (insn) = pat;
  REG_NOTES (insn) = NULL_RTX;

  insn_code_number = recog (pat, insn, &num_clobbers_to_add);
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      if (insn_code_number < 0)
	fputs ("Failed to match this instruction:\n", dump_file);
      else
	fputs ("Successfully matched this instruction:\n", dump_file);
      print_rtl_single (dump_file, pat);
    }

  /* If it isn't, there is the possibility that we previously had an insn
     that clobbered some register as a side effect, but the combined
     insn doesn't need to do that.  So try once more without the clobbers
     unless this represents an ASM insn.  */

  if (insn_code_number < 0 && ! check_asm_operands (pat)
      && GET_CODE (pat) == PARALLEL)
    {
      int pos;

      for (pos = 0, i = 0; i < XVECLEN (pat, 0); i++)
	if (GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
	  {
	    if (i != pos)
	      SUBST (XVECEXP (pat, 0, pos), XVECEXP (pat, 0, i));
	    pos++;
	  }

      SUBST_INT (XVECLEN (pat, 0), pos);

      if (pos == 1)
	pat = XVECEXP (pat, 0, 0);

      PATTERN (insn) = pat;
      insn_code_number = recog (pat, insn, &num_clobbers_to_add);
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  if (insn_code_number < 0)
	    fputs ("Failed to match this instruction:\n", dump_file);
	  else
	    fputs ("Successfully matched this instruction:\n", dump_file);
	  print_rtl_single (dump_file, pat);
	}
    }

  pat_without_clobbers = pat;

  PATTERN (insn) = old_pat;
  REG_NOTES (insn) = old_notes;

  /* Recognize all noop sets, these will be killed by followup pass.  */
  if (insn_code_number < 0 && GET_CODE (pat) == SET && set_noop_p (pat))
    insn_code_number = NOOP_MOVE_INSN_CODE, num_clobbers_to_add = 0;

  /* If we had any clobbers to add, make a new pattern than contains
     them.  Then check to make sure that all of them are dead.  */
  if (num_clobbers_to_add)
    {
      rtx newpat = gen_rtx_PARALLEL (VOIDmode,
				     rtvec_alloc (GET_CODE (pat) == PARALLEL
						  ? (XVECLEN (pat, 0)
						     + num_clobbers_to_add)
						  : num_clobbers_to_add + 1));

      if (GET_CODE (pat) == PARALLEL)
	for (i = 0; i < XVECLEN (pat, 0); i++)
	  XVECEXP (newpat, 0, i) = XVECEXP (pat, 0, i);
      else
	XVECEXP (newpat, 0, 0) = pat;

      add_clobbers (newpat, insn_code_number);

      for (i = XVECLEN (newpat, 0) - num_clobbers_to_add;
	   i < XVECLEN (newpat, 0); i++)
	{
	  if (REG_P (XEXP (XVECEXP (newpat, 0, i), 0))
	      && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn))
	    return -1;
	  if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) != SCRATCH)
	    {
	      gcc_assert (REG_P (XEXP (XVECEXP (newpat, 0, i), 0)));
	      notes = alloc_reg_note (REG_UNUSED,
				      XEXP (XVECEXP (newpat, 0, i), 0), notes);
	    }
	}
      pat = newpat;
    }

  if (insn_code_number >= 0
      && insn_code_number != NOOP_MOVE_INSN_CODE)
    {
      old_pat = PATTERN (insn);
      old_notes = REG_NOTES (insn);
      old_icode = INSN_CODE (insn);
      PATTERN (insn) = pat;
      REG_NOTES (insn) = notes;
      INSN_CODE (insn) = insn_code_number;

      /* Allow targets to reject combined insn.  */
      if (!targetm.legitimate_combined_insn (insn))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    fputs ("Instruction not appropriate for target.",
		   dump_file);

	  /* Callers expect recog_for_combine to strip
	     clobbers from the pattern on failure.  */
	  pat = pat_without_clobbers;
	  notes = NULL_RTX;

	  insn_code_number = -1;
	}

      PATTERN (insn) = old_pat;
      REG_NOTES (insn) = old_notes;
      INSN_CODE (insn) = old_icode;
    }

  *pnewpat = pat;
  *pnotes = notes;

  return insn_code_number;
}

/* Change every ZERO_EXTRACT and ZERO_EXTEND of a SUBREG that can be
   expressed as an AND and maybe an LSHIFTRT, to that formulation.
   Return whether anything was so changed.  */

static bool
change_zero_ext (rtx pat)
{
  bool changed = false;
  rtx *src = &SET_SRC (pat);

  subrtx_ptr_iterator::array_type array;
  FOR_EACH_SUBRTX_PTR (iter, array, src, NONCONST)
    {
      rtx x = **iter;
      scalar_int_mode mode, inner_mode;
      if (!is_a <scalar_int_mode> (GET_MODE (x), &mode))
	continue;
      int size;

      if (GET_CODE (x) == ZERO_EXTRACT
	  && CONST_INT_P (XEXP (x, 1))
	  && CONST_INT_P (XEXP (x, 2))
	  && is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &inner_mode)
	  && GET_MODE_PRECISION (inner_mode) <= GET_MODE_PRECISION (mode))
	{
	  size = INTVAL (XEXP (x, 1));

	  int start = INTVAL (XEXP (x, 2));
	  if (BITS_BIG_ENDIAN)
	    start = GET_MODE_PRECISION (inner_mode) - size - start;

	  if (start != 0)
	    x = gen_rtx_LSHIFTRT (inner_mode, XEXP (x, 0),
				  gen_int_shift_amount (inner_mode, start));
	  else
	    x = XEXP (x, 0);

	  if (mode != inner_mode)
	    {
	      if (REG_P (x) && HARD_REGISTER_P (x)
		  && !can_change_dest_mode (x, 0, mode))
		continue;

	      x = gen_lowpart_SUBREG (mode, x);
	    }
	}
      else if (GET_CODE (x) == ZERO_EXTEND
	       && GET_CODE (XEXP (x, 0)) == SUBREG
	       && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (XEXP (x, 0))))
	       && !paradoxical_subreg_p (XEXP (x, 0))
	       && subreg_lowpart_p (XEXP (x, 0)))
	{
	  inner_mode = as_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)));
	  size = GET_MODE_PRECISION (inner_mode);
	  x = SUBREG_REG (XEXP (x, 0));
	  if (GET_MODE (x) != mode)
	    {
	      if (REG_P (x) && HARD_REGISTER_P (x)
		  && !can_change_dest_mode (x, 0, mode))
		continue;

	      x = gen_lowpart_SUBREG (mode, x);
	    }
	}
      else if (GET_CODE (x) == ZERO_EXTEND
	       && REG_P (XEXP (x, 0))
	       && HARD_REGISTER_P (XEXP (x, 0))
	       && can_change_dest_mode (XEXP (x, 0), 0, mode))
	{
	  inner_mode = as_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)));
	  size = GET_MODE_PRECISION (inner_mode);
	  x = gen_rtx_REG (mode, REGNO (XEXP (x, 0)));
	}
      else
	continue;

      if (!(GET_CODE (x) == LSHIFTRT
	    && CONST_INT_P (XEXP (x, 1))
	    && size + INTVAL (XEXP (x, 1)) == GET_MODE_PRECISION (mode)))
	{
	  wide_int mask = wi::mask (size, false, GET_MODE_PRECISION (mode));
	  x = gen_rtx_AND (mode, x, immed_wide_int_const (mask, mode));
	}

      SUBST (**iter, x);
      changed = true;
    }

  if (changed)
    FOR_EACH_SUBRTX_PTR (iter, array, src, NONCONST)
      maybe_swap_commutative_operands (**iter);

  rtx *dst = &SET_DEST (pat);
  scalar_int_mode mode;
  if (GET_CODE (*dst) == ZERO_EXTRACT
      && REG_P (XEXP (*dst, 0))
      && is_a <scalar_int_mode> (GET_MODE (XEXP (*dst, 0)), &mode)
      && CONST_INT_P (XEXP (*dst, 1))
      && CONST_INT_P (XEXP (*dst, 2)))
    {
      rtx reg = XEXP (*dst, 0);
      int width = INTVAL (XEXP (*dst, 1));
      int offset = INTVAL (XEXP (*dst, 2));
      int reg_width = GET_MODE_PRECISION (mode);
      if (BITS_BIG_ENDIAN)
	offset = reg_width - width - offset;

      rtx x, y, z, w;
      wide_int mask = wi::shifted_mask (offset, width, true, reg_width);
      wide_int mask2 = wi::shifted_mask (offset, width, false, reg_width);
      x = gen_rtx_AND (mode, reg, immed_wide_int_const (mask, mode));
      if (offset)
	y = gen_rtx_ASHIFT (mode, SET_SRC (pat), GEN_INT (offset));
      else
	y = SET_SRC (pat);
      z = gen_rtx_AND (mode, y, immed_wide_int_const (mask2, mode));
      w = gen_rtx_IOR (mode, x, z);
      SUBST (SET_DEST (pat), reg);
      SUBST (SET_SRC (pat), w);

      changed = true;
    }

  return changed;
}

/* Like recog, but we receive the address of a pointer to a new pattern.
   We try to match the rtx that the pointer points to.
   If that fails, we may try to modify or replace the pattern,
   storing the replacement into the same pointer object.

   Modifications include deletion or addition of CLOBBERs.  If the
   instruction will still not match, we change ZERO_EXTEND and ZERO_EXTRACT
   to the equivalent AND and perhaps LSHIFTRT patterns, and try with that
   (and undo if that fails).

   PNOTES is a pointer to a location where any REG_UNUSED notes added for
   the CLOBBERs are placed.

   The value is the final insn code from the pattern ultimately matched,
   or -1.  */

static int
recog_for_combine (rtx *pnewpat, rtx_insn *insn, rtx *pnotes)
{
  rtx pat = *pnewpat;
  int insn_code_number = recog_for_combine_1 (pnewpat, insn, pnotes);
  if (insn_code_number >= 0 || check_asm_operands (pat))
    return insn_code_number;

  void *marker = get_undo_marker ();
  bool changed = false;

  if (GET_CODE (pat) == SET)
    changed = change_zero_ext (pat);
  else if (GET_CODE (pat) == PARALLEL)
    {
      int i;
      for (i = 0; i < XVECLEN (pat, 0); i++)
	{
	  rtx set = XVECEXP (pat, 0, i);
	  if (GET_CODE (set) == SET)
	    changed |= change_zero_ext (set);
	}
    }

  if (changed)
    {
      insn_code_number = recog_for_combine_1 (pnewpat, insn, pnotes);

      if (insn_code_number < 0)
	undo_to_marker (marker);
    }

  return insn_code_number;
}

/* Like gen_lowpart_general but for use by combine.  In combine it
   is not possible to create any new pseudoregs.  However, it is
   safe to create invalid memory addresses, because combine will
   try to recognize them and all they will do is make the combine
   attempt fail.

   If for some reason this cannot do its job, an rtx
   (clobber (const_int 0)) is returned.
   An insn containing that will not be recognized.  */

static rtx
gen_lowpart_for_combine (machine_mode omode, rtx x)
{
  machine_mode imode = GET_MODE (x);
  rtx result;

  if (omode == imode)
    return x;

  /* We can only support MODE being wider than a word if X is a
     constant integer or has a mode the same size.  */
  if (maybe_gt (GET_MODE_SIZE (omode), UNITS_PER_WORD)
      && ! (CONST_SCALAR_INT_P (x)
	    || known_eq (GET_MODE_SIZE (imode), GET_MODE_SIZE (omode))))
    goto fail;

  /* X might be a paradoxical (subreg (mem)).  In that case, gen_lowpart
     won't know what to do.  So we will strip off the SUBREG here and
     process normally.  */
  if (GET_CODE (x) == SUBREG && MEM_P (SUBREG_REG (x)))
    {
      x = SUBREG_REG (x);

      /* For use in case we fall down into the address adjustments
	 further below, we need to adjust the known mode and size of
	 x; imode and isize, since we just adjusted x.  */
      imode = GET_MODE (x);

      if (imode == omode)
	return x;
    }

  result = gen_lowpart_common (omode, x);

  if (result)
    return result;

  if (MEM_P (x))
    {
      /* Refuse to work on a volatile memory ref or one with a mode-dependent
	 address.  */
      if (MEM_VOLATILE_P (x)
	  || mode_dependent_address_p (XEXP (x, 0), MEM_ADDR_SPACE (x)))
	goto fail;

      /* If we want to refer to something bigger than the original memref,
	 generate a paradoxical subreg instead.  That will force a reload
	 of the original memref X.  */
      if (paradoxical_subreg_p (omode, imode))
	return gen_rtx_SUBREG (omode, x, 0);

      poly_int64 offset = byte_lowpart_offset (omode, imode);
      return adjust_address_nv (x, omode, offset);
    }

  /* If X is a comparison operator, rewrite it in a new mode.  This
     probably won't match, but may allow further simplifications.  */
  else if (COMPARISON_P (x))
    return gen_rtx_fmt_ee (GET_CODE (x), omode, XEXP (x, 0), XEXP (x, 1));

  /* If we couldn't simplify X any other way, just enclose it in a
     SUBREG.  Normally, this SUBREG won't match, but some patterns may
     include an explicit SUBREG or we may simplify it further in combine.  */
  else
    {
      rtx res;

      if (imode == VOIDmode)
	{
	  imode = int_mode_for_mode (omode).require ();
	  x = gen_lowpart_common (imode, x);
	  if (x == NULL)
	    goto fail;
	}
      res = lowpart_subreg (omode, x, imode);
      if (res)
	return res;
    }

 fail:
  return gen_rtx_CLOBBER (omode, const0_rtx);
}

/* Try to simplify a comparison between OP0 and a constant OP1,
   where CODE is the comparison code that will be tested, into a
   (CODE OP0 const0_rtx) form.

   The result is a possibly different comparison code to use.
   *POP1 may be updated.  */

static enum rtx_code
simplify_compare_const (enum rtx_code code, machine_mode mode,
			rtx op0, rtx *pop1)
{
  scalar_int_mode int_mode;
  HOST_WIDE_INT const_op = INTVAL (*pop1);

  /* Get the constant we are comparing against and turn off all bits
     not on in our mode.  */
  if (mode != VOIDmode)
    const_op = trunc_int_for_mode (const_op, mode);

  /* If we are comparing against a constant power of two and the value
     being compared can only have that single bit nonzero (e.g., it was
     `and'ed with that bit), we can replace this with a comparison
     with zero.  */
  if (const_op
      && (code == EQ || code == NE || code == GE || code == GEU
	  || code == LT || code == LTU)
      && is_a <scalar_int_mode> (mode, &int_mode)
      && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
      && pow2p_hwi (const_op & GET_MODE_MASK (int_mode))
      && (nonzero_bits (op0, int_mode)
	  == (unsigned HOST_WIDE_INT) (const_op & GET_MODE_MASK (int_mode))))
    {
      code = (code == EQ || code == GE || code == GEU ? NE : EQ);
      const_op = 0;
    }

  /* Similarly, if we are comparing a value known to be either -1 or
     0 with -1, change it to the opposite comparison against zero.  */
  if (const_op == -1
      && (code == EQ || code == NE || code == GT || code == LE
	  || code == GEU || code == LTU)
      && is_a <scalar_int_mode> (mode, &int_mode)
      && num_sign_bit_copies (op0, int_mode) == GET_MODE_PRECISION (int_mode))
    {
      code = (code == EQ || code == LE || code == GEU ? NE : EQ);
      const_op = 0;
    }

  /* Do some canonicalizations based on the comparison code.  We prefer
     comparisons against zero and then prefer equality comparisons.
     If we can reduce the size of a constant, we will do that too.  */
  switch (code)
    {
    case LT:
      /* < C is equivalent to <= (C - 1) */
      if (const_op > 0)
	{
	  const_op -= 1;
	  code = LE;
	  /* ... fall through to LE case below.  */
	  gcc_fallthrough ();
	}
      else
	break;

    case LE:
      /* <= C is equivalent to < (C + 1); we do this for C < 0  */
      if (const_op < 0)
	{
	  const_op += 1;
	  code = LT;
	}

      /* If we are doing a <= 0 comparison on a value known to have
	 a zero sign bit, we can replace this with == 0.  */
      else if (const_op == 0
	       && is_a <scalar_int_mode> (mode, &int_mode)
	       && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
	       && (nonzero_bits (op0, int_mode)
		   & (HOST_WIDE_INT_1U << (GET_MODE_PRECISION (int_mode) - 1)))
	       == 0)
	code = EQ;
      break;

    case GE:
      /* >= C is equivalent to > (C - 1).  */
      if (const_op > 0)
	{
	  const_op -= 1;
	  code = GT;
	  /* ... fall through to GT below.  */
	  gcc_fallthrough ();
	}
      else
	break;

    case GT:
      /* > C is equivalent to >= (C + 1); we do this for C < 0.  */
      if (const_op < 0)
	{
	  const_op += 1;
	  code = GE;
	}

      /* If we are doing a > 0 comparison on a value known to have
	 a zero sign bit, we can replace this with != 0.  */
      else if (const_op == 0
	       && is_a <scalar_int_mode> (mode, &int_mode)
	       && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
	       && (nonzero_bits (op0, int_mode)
		   & (HOST_WIDE_INT_1U << (GET_MODE_PRECISION (int_mode) - 1)))
	       == 0)
	code = NE;
      break;

    case LTU:
      /* < C is equivalent to <= (C - 1).  */
      if (const_op > 0)
	{
	  const_op -= 1;
	  code = LEU;
	  /* ... fall through ...  */
	  gcc_fallthrough ();
	}
      /* (unsigned) < 0x80000000 is equivalent to >= 0.  */
      else if (is_a <scalar_int_mode> (mode, &int_mode)
	       && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
	       && ((unsigned HOST_WIDE_INT) const_op
		   == HOST_WIDE_INT_1U << (GET_MODE_PRECISION (int_mode) - 1)))
	{
	  const_op = 0;
	  code = GE;
	  break;
	}
      else
	break;

    case LEU:
      /* unsigned <= 0 is equivalent to == 0 */
      if (const_op == 0)
	code = EQ;
      /* (unsigned) <= 0x7fffffff is equivalent to >= 0.  */
      else if (is_a <scalar_int_mode> (mode, &int_mode)
	       && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
	       && ((unsigned HOST_WIDE_INT) const_op
		   == ((HOST_WIDE_INT_1U
			<< (GET_MODE_PRECISION (int_mode) - 1)) - 1)))
	{
	  const_op = 0;
	  code = GE;
	}
      break;

    case GEU:
      /* >= C is equivalent to > (C - 1).  */
      if (const_op > 1)
	{
	  const_op -= 1;
	  code = GTU;
	  /* ... fall through ...  */
	  gcc_fallthrough ();
	}

      /* (unsigned) >= 0x80000000 is equivalent to < 0.  */
      else if (is_a <scalar_int_mode> (mode, &int_mode)
	       && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
	       && ((unsigned HOST_WIDE_INT) const_op
		   == HOST_WIDE_INT_1U << (GET_MODE_PRECISION (int_mode) - 1)))
	{
	  const_op = 0;
	  code = LT;
	  break;
	}
      else
	break;

    case GTU:
      /* unsigned > 0 is equivalent to != 0 */
      if (const_op == 0)
	code = NE;
      /* (unsigned) > 0x7fffffff is equivalent to < 0.  */
      else if (is_a <scalar_int_mode> (mode, &int_mode)
	       && GET_MODE_PRECISION (int_mode) - 1 < HOST_BITS_PER_WIDE_INT
	       && ((unsigned HOST_WIDE_INT) const_op
		   == (HOST_WIDE_INT_1U
		       << (GET_MODE_PRECISION (int_mode) - 1)) - 1))
	{
	  const_op = 0;
	  code = LT;
	}
      break;

    default:
      break;
    }

  *pop1 = GEN_INT (const_op);
  return code;
}

/* Simplify a comparison between *POP0 and *POP1 where CODE is the
   comparison code that will be tested.

   The result is a possibly different comparison code to use.  *POP0 and
   *POP1 may be updated.

   It is possible that we might detect that a comparison is either always
   true or always false.  However, we do not perform general constant
   folding in combine, so this knowledge isn't useful.  Such tautologies
   should have been detected earlier.  Hence we ignore all such cases.  */

static enum rtx_code
simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
{
  rtx op0 = *pop0;
  rtx op1 = *pop1;
  rtx tem, tem1;
  int i;
  scalar_int_mode mode, inner_mode, tmode;
  opt_scalar_int_mode tmode_iter;

  /* Try a few ways of applying the same transformation to both operands.  */
  while (1)
    {
      /* The test below this one won't handle SIGN_EXTENDs on these machines,
	 so check specially.  */
      if (!WORD_REGISTER_OPERATIONS
	  && code != GTU && code != GEU && code != LTU && code != LEU
	  && GET_CODE (op0) == ASHIFTRT && GET_CODE (op1) == ASHIFTRT
	  && GET_CODE (XEXP (op0, 0)) == ASHIFT
	  && GET_CODE (XEXP (op1, 0)) == ASHIFT
	  && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SUBREG
	  && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SUBREG
	  && is_a <scalar_int_mode> (GET_MODE (op0), &mode)
	  && (is_a <scalar_int_mode>
	      (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0))), &inner_mode))
	  && inner_mode == GET_MODE (SUBREG_REG (XEXP (XEXP (op1, 0), 0)))
	  && CONST_INT_P (XEXP (op0, 1))
	  && XEXP (op0, 1) == XEXP (op1, 1)
	  && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
	  && XEXP (op0, 1) == XEXP (XEXP (op1, 0), 1)
	  && (INTVAL (XEXP (op0, 1))
	      == (GET_MODE_PRECISION (mode)
		  - GET_MODE_PRECISION (inner_mode))))
	{
	  op0 = SUBREG_REG (XEXP (XEXP (op0, 0), 0));
	  op1 = SUBREG_REG (XEXP (XEXP (op1, 0), 0));
	}

      /* If both operands are the same constant shift, see if we can ignore the
	 shift.  We can if the shift is a rotate or if the bits shifted out of
	 this shift are known to be zero for both inputs and if the type of
	 comparison is compatible with the shift.  */
      if (GET_CODE (op0) == GET_CODE (op1)
	  && HWI_COMPUTABLE_MODE_P (GET_MODE (op0))
	  && ((GET_CODE (op0) == ROTATE && (code == NE || code == EQ))
	      || ((GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFT)
		  && (code != GT && code != LT && code != GE && code != LE))
	      || (GET_CODE (op0) == ASHIFTRT
		  && (code != GTU && code != LTU
		      && code != GEU && code != LEU)))
	  && CONST_INT_P (XEXP (op0, 1))
	  && INTVAL (XEXP (op0, 1)) >= 0
	  && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
	  && XEXP (op0, 1) == XEXP (op1, 1))
	{
	  machine_mode mode = GET_MODE (op0);
	  unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
	  int shift_count = INTVAL (XEXP (op0, 1));

	  if (GET_CODE (op0) == LSHIFTRT || GET_CODE (op0) == ASHIFTRT)
	    mask &= (mask >> shift_count) << shift_count;
	  else if (GET_CODE (op0) == ASHIFT)
	    mask = (mask & (mask << shift_count)) >> shift_count;

	  if ((nonzero_bits (XEXP (op0, 0), mode) & ~mask) == 0
	      && (nonzero_bits (XEXP (op1, 0), mode) & ~mask) == 0)
	    op0 = XEXP (op0, 0), op1 = XEXP (op1, 0);
	  else
	    break;
	}

      /* If both operands are AND's of a paradoxical SUBREG by constant, the
	 SUBREGs are of the same mode, and, in both cases, the AND would
	 be redundant if the comparison was done in the narrower mode,
	 do the comparison in the narrower mode (e.g., we are AND'ing with 1
	 and the operand's possibly nonzero bits are 0xffffff01; in that case
	 if we only care about QImode, we don't need the AND).  This case
	 occurs if the output mode of an scc insn is not SImode and
	 STORE_FLAG_VALUE == 1 (e.g., the 386).

	 Similarly, check for a case where the AND's are ZERO_EXTEND
	 operations from some narrower mode even though a SUBREG is not
	 present.  */

      else if (GET_CODE (op0) == AND && GET_CODE (op1) == AND
	       && CONST_INT_P (XEXP (op0, 1))
	       && CONST_INT_P (XEXP (op1, 1)))
	{
	  rtx inner_op0 = XEXP (op0, 0);
	  rtx inner_op1 = XEXP (op1, 0);
	  HOST_WIDE_INT c0 = INTVAL (XEXP (op0, 1));
	  HOST_WIDE_INT c1 = INTVAL (XEXP (op1, 1));
	  int changed = 0;

	  if (paradoxical_subreg_p (inner_op0)
	      && GET_CODE (inner_op1) == SUBREG
	      && HWI_COMPUTABLE_MODE_P (GET_MODE (SUBREG_REG (inner_op0)))
	      && (GET_MODE (SUBREG_REG (inner_op0))
		  == GET_MODE (SUBREG_REG (inner_op1)))
	      && ((~c0) & nonzero_bits (SUBREG_REG (inner_op0),
					GET_MODE (SUBREG_REG (inner_op0)))) == 0
	      && ((~c1) & nonzero_bits (SUBREG_REG (inner_op1),
					GET_MODE (SUBREG_REG (inner_op1)))) == 0)
	    {
	      op0 = SUBREG_REG (inner_op0);
	      op1 = SUBREG_REG (inner_op1);

	      /* The resulting comparison is always unsigned since we masked
		 off the original sign bit.  */
	      code = unsigned_condition (code);

	      changed = 1;
	    }

	  else if (c0 == c1)
	    FOR_EACH_MODE_UNTIL (tmode,
				 as_a <scalar_int_mode> (GET_MODE (op0)))
	      if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
		{
		  op0 = gen_lowpart_or_truncate (tmode, inner_op0);
		  op1 = gen_lowpart_or_truncate (tmode, inner_op1);
		  code = unsigned_condition (code);
		  changed = 1;
		  break;
		}

	  if (! changed)
	    break;
	}

      /* If both operands are NOT, we can strip off the outer operation
	 and adjust the comparison code for swapped operands; similarly for
	 NEG, except that this must be an equality comparison.  */
      else if ((GET_CODE (op0) == NOT && GET_CODE (op1) == NOT)
	       || (GET_CODE (op0) == NEG && GET_CODE (op1) == NEG
		   && (code == EQ || code == NE)))
	op0 = XEXP (op0, 0), op1 = XEXP (op1, 0), code = swap_condition (code);

      else
	break;
    }

  /* If the first operand is a constant, swap the operands and adjust the
     comparison code appropriately, but don't do this if the second operand
     is already a constant integer.  */
  if (swap_commutative_operands_p (op0, op1))
    {
      std::swap (op0, op1);
      code = swap_condition (code);
    }

  /* We now enter a loop during which we will try to simplify the comparison.
     For the most part, we only are concerned with comparisons with zero,
     but some things may really be comparisons with zero but not start
     out looking that way.  */

  while (CONST_INT_P (op1))
    {
      machine_mode raw_mode = GET_MODE (op0);
      scalar_int_mode int_mode;
      int equality_comparison_p;
      int sign_bit_comparison_p;
      int unsigned_comparison_p;
      HOST_WIDE_INT const_op;

      /* We only want to handle integral modes.  This catches VOIDmode,
	 CCmode, and the floating-point modes.  An exception is that we
	 can handle VOIDmode if OP0 is a COMPARE or a comparison
	 operation.  */

      if (GET_MODE_CLASS (raw_mode) != MODE_INT
	  && ! (raw_mode == VOIDmode
		&& (GET_CODE (op0) == COMPARE || COMPARISON_P (op0))))
	break;

      /* Try to simplify the compare to constant, possibly changing the
	 comparison op, and/or changing op1 to zero.  */
      code = simplify_compare_const (code, raw_mode, op0, &op1);
      const_op = INTVAL (op1);

      /* Compute some predicates to simplify code below.  */

      equality_comparison_p = (code == EQ || code == NE);
      sign_bit_comparison_p = ((code == LT || code == GE) && const_op == 0);
      unsigned_comparison_p = (code == LTU || code == LEU || code == GTU
			       || code == GEU);

      /* If this is a sign bit comparison and we can do arithmetic in
	 MODE, say that we will only be needing the sign bit of OP0.  */
      if (sign_bit_comparison_p
	  && is_a <scalar_int_mode> (raw_mode, &int_mode)
	  && HWI_COMPUTABLE_MODE_P (int_mode))
	op0 = force_to_mode (op0, int_mode,
			     HOST_WIDE_INT_1U
			     << (GET_MODE_PRECISION (int_mode) - 1),
			     0);

      if (COMPARISON_P (op0))
	{
	  /* We can't do anything if OP0 is a condition code value, rather
	     than an actual data value.  */
	  if (const_op != 0
	      || CC0_P (XEXP (op0, 0))
	      || GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
	    break;

	  /* Get the two operands being compared.  */
	  if (GET_CODE (XEXP (op0, 0)) == COMPARE)
	    tem = XEXP (XEXP (op0, 0), 0), tem1 = XEXP (XEXP (op0, 0), 1);
	  else
	    tem = XEXP (op0, 0), tem1 = XEXP (op0, 1);

	  /* Check for the cases where we simply want the result of the
	     earlier test or the opposite of that result.  */
	  if (code == NE || code == EQ
	      || (val_signbit_known_set_p (raw_mode, STORE_FLAG_VALUE)
		  && (code == LT || code == GE)))
	    {
	      enum rtx_code new_code;
	      if (code == LT || code == NE)
		new_code = GET_CODE (op0);
	      else
		new_code = reversed_comparison_code (op0, NULL);

	      if (new_code != UNKNOWN)
		{
		  code = new_code;
		  op0 = tem;
		  op1 = tem1;
		  continue;
		}
	    }
	  break;
	}

      if (raw_mode == VOIDmode)
	break;
      scalar_int_mode mode = as_a <scalar_int_mode> (raw_mode);

      /* Now try cases based on the opcode of OP0.  If none of the cases
	 does a "continue", we exit this loop immediately after the
	 switch.  */

      unsigned int mode_width = GET_MODE_PRECISION (mode);
      unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
      switch (GET_CODE (op0))
	{
	case ZERO_EXTRACT:
	  /* If we are extracting a single bit from a variable position in
	     a constant that has only a single bit set and are comparing it
	     with zero, we can convert this into an equality comparison
	     between the position and the location of the single bit.  */
	  /* Except we can't if SHIFT_COUNT_TRUNCATED is set, since we might
	     have already reduced the shift count modulo the word size.  */
	  if (!SHIFT_COUNT_TRUNCATED
	      && CONST_INT_P (XEXP (op0, 0))
	      && XEXP (op0, 1) == const1_rtx
	      && equality_comparison_p && const_op == 0
	      && (i = exact_log2 (UINTVAL (XEXP (op0, 0)))) >= 0)
	    {
	      if (BITS_BIG_ENDIAN)
		i = BITS_PER_WORD - 1 - i;

	      op0 = XEXP (op0, 2);
	      op1 = GEN_INT (i);
	      const_op = i;

	      /* Result is nonzero iff shift count is equal to I.  */
	      code = reverse_condition (code);
	      continue;
	    }

	  /* fall through */

	case SIGN_EXTRACT:
	  tem = expand_compound_operation (op0);
	  if (tem != op0)
	    {
	      op0 = tem;
	      continue;
	    }
	  break;

	case NOT:
	  /* If testing for equality, we can take the NOT of the constant.  */
	  if (equality_comparison_p
	      && (tem = simplify_unary_operation (NOT, mode, op1, mode)) != 0)
	    {
	      op0 = XEXP (op0, 0);
	      op1 = tem;
	      continue;
	    }

	  /* If just looking at the sign bit, reverse the sense of the
	     comparison.  */
	  if (sign_bit_comparison_p)
	    {
	      op0 = XEXP (op0, 0);
	      code = (code == GE ? LT : GE);
	      continue;
	    }
	  break;

	case NEG:
	  /* If testing for equality, we can take the NEG of the constant.  */
	  if (equality_comparison_p
	      && (tem = simplify_unary_operation (NEG, mode, op1, mode)) != 0)
	    {
	      op0 = XEXP (op0, 0);
	      op1 = tem;
	      continue;
	    }

	  /* The remaining cases only apply to comparisons with zero.  */
	  if (const_op != 0)
	    break;

	  /* When X is ABS or is known positive,
	     (neg X) is < 0 if and only if X != 0.  */

	  if (sign_bit_comparison_p
	      && (GET_CODE (XEXP (op0, 0)) == ABS
		  || (mode_width <= HOST_BITS_PER_WIDE_INT
		      && (nonzero_bits (XEXP (op0, 0), mode)
			  & (HOST_WIDE_INT_1U << (mode_width - 1)))
			 == 0)))
	    {
	      op0 = XEXP (op0, 0);
	      code = (code == LT ? NE : EQ);
	      continue;
	    }

	  /* If we have NEG of something whose two high-order bits are the
	     same, we know that "(-a) < 0" is equivalent to "a > 0".  */
	  if (num_sign_bit_copies (op0, mode) >= 2)
	    {
	      op0 = XEXP (op0, 0);
	      code = swap_condition (code);
	      continue;
	    }
	  break;

	case ROTATE:
	  /* If we are testing equality and our count is a constant, we
	     can perform the inverse operation on our RHS.  */
	  if (equality_comparison_p && CONST_INT_P (XEXP (op0, 1))
	      && (tem = simplify_binary_operation (ROTATERT, mode,
						   op1, XEXP (op0, 1))) != 0)
	    {
	      op0 = XEXP (op0, 0);
	      op1 = tem;
	      continue;
	    }

	  /* If we are doing a < 0 or >= 0 comparison, it means we are testing
	     a particular bit.  Convert it to an AND of a constant of that
	     bit.  This will be converted into a ZERO_EXTRACT.  */
	  if (const_op == 0 && sign_bit_comparison_p
	      && CONST_INT_P (XEXP (op0, 1))
	      && mode_width <= HOST_BITS_PER_WIDE_INT
	      && UINTVAL (XEXP (op0, 1)) < mode_width)
	    {
	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
					    (HOST_WIDE_INT_1U
					     << (mode_width - 1
						 - INTVAL (XEXP (op0, 1)))));
	      code = (code == LT ? NE : EQ);
	      continue;
	    }

	  /* Fall through.  */

	case ABS:
	  /* ABS is ignorable inside an equality comparison with zero.  */
	  if (const_op == 0 && equality_comparison_p)
	    {
	      op0 = XEXP (op0, 0);
	      continue;
	    }
	  break;

	case SIGN_EXTEND:
	  /* Can simplify (compare (zero/sign_extend FOO) CONST) to
	     (compare FOO CONST) if CONST fits in FOO's mode and we
	     are either testing inequality or have an unsigned
	     comparison with ZERO_EXTEND or a signed comparison with
	     SIGN_EXTEND.  But don't do it if we don't have a compare
	     insn of the given mode, since we'd have to revert it
	     later on, and then we wouldn't know whether to sign- or
	     zero-extend.  */
	  if (is_int_mode (GET_MODE (XEXP (op0, 0)), &mode)
	      && ! unsigned_comparison_p
	      && HWI_COMPUTABLE_MODE_P (mode)
	      && trunc_int_for_mode (const_op, mode) == const_op
	      && have_insn_for (COMPARE, mode))
	    {
	      op0 = XEXP (op0, 0);
	      continue;
	    }
	  break;

	case SUBREG:
	  /* Check for the case where we are comparing A - C1 with C2, that is

	       (subreg:MODE (plus (A) (-C1))) op (C2)

	     with C1 a constant, and try to lift the SUBREG, i.e. to do the
	     comparison in the wider mode.  One of the following two conditions
	     must be true in order for this to be valid:

	       1. The mode extension results in the same bit pattern being added
		  on both sides and the comparison is equality or unsigned.  As
		  C2 has been truncated to fit in MODE, the pattern can only be
		  all 0s or all 1s.

	       2. The mode extension results in the sign bit being copied on
		  each side.

	     The difficulty here is that we have predicates for A but not for
	     (A - C1) so we need to check that C1 is within proper bounds so
	     as to perturbate A as little as possible.  */

	  if (mode_width <= HOST_BITS_PER_WIDE_INT
	      && subreg_lowpart_p (op0)
	      && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
					 &inner_mode)
	      && GET_MODE_PRECISION (inner_mode) > mode_width
	      && GET_CODE (SUBREG_REG (op0)) == PLUS
	      && CONST_INT_P (XEXP (SUBREG_REG (op0), 1)))
	    {
	      rtx a = XEXP (SUBREG_REG (op0), 0);
	      HOST_WIDE_INT c1 = -INTVAL (XEXP (SUBREG_REG (op0), 1));

	      if ((c1 > 0
		   && (unsigned HOST_WIDE_INT) c1
		       < HOST_WIDE_INT_1U << (mode_width - 1)
		   && (equality_comparison_p || unsigned_comparison_p)
		   /* (A - C1) zero-extends if it is positive and sign-extends
		      if it is negative, C2 both zero- and sign-extends.  */
		   && (((nonzero_bits (a, inner_mode)
			 & ~GET_MODE_MASK (mode)) == 0
			&& const_op >= 0)
		       /* (A - C1) sign-extends if it is positive and 1-extends
			  if it is negative, C2 both sign- and 1-extends.  */
		       || (num_sign_bit_copies (a, inner_mode)
			   > (unsigned int) (GET_MODE_PRECISION (inner_mode)
					     - mode_width)
			   && const_op < 0)))
		  || ((unsigned HOST_WIDE_INT) c1
		       < HOST_WIDE_INT_1U << (mode_width - 2)
		      /* (A - C1) always sign-extends, like C2.  */
		      && num_sign_bit_copies (a, inner_mode)
			 > (unsigned int) (GET_MODE_PRECISION (inner_mode)
					   - (mode_width - 1))))
		{
		  op0 = SUBREG_REG (op0);
		  continue;
		}
	    }

	  /* If the inner mode is narrower and we are extracting the low part,
	     we can treat the SUBREG as if it were a ZERO_EXTEND.  */
	  if (paradoxical_subreg_p (op0))
	    ;
	  else if (subreg_lowpart_p (op0)
		   && GET_MODE_CLASS (mode) == MODE_INT
		   && is_int_mode (GET_MODE (SUBREG_REG (op0)), &inner_mode)
		   && (code == NE || code == EQ)
		   && GET_MODE_PRECISION (inner_mode) <= HOST_BITS_PER_WIDE_INT
		   && !paradoxical_subreg_p (op0)
		   && (nonzero_bits (SUBREG_REG (op0), inner_mode)
		       & ~GET_MODE_MASK (mode)) == 0)
	    {
	      /* Remove outer subregs that don't do anything.  */
	      tem = gen_lowpart (inner_mode, op1);

	      if ((nonzero_bits (tem, inner_mode)
		   & ~GET_MODE_MASK (mode)) == 0)
		{
		  op0 = SUBREG_REG (op0);
		  op1 = tem;
		  continue;
		}
	      break;
	    }
	  else
	    break;

	  /* FALLTHROUGH */

	case ZERO_EXTEND:
	  if (is_int_mode (GET_MODE (XEXP (op0, 0)), &mode)
	      && (unsigned_comparison_p || equality_comparison_p)
	      && HWI_COMPUTABLE_MODE_P (mode)
	      && (unsigned HOST_WIDE_INT) const_op <= GET_MODE_MASK (mode)
	      && const_op >= 0
	      && have_insn_for (COMPARE, mode))
	    {
	      op0 = XEXP (op0, 0);
	      continue;
	    }
	  break;

	case PLUS:
	  /* (eq (plus X A) B) -> (eq X (minus B A)).  We can only do
	     this for equality comparisons due to pathological cases involving
	     overflows.  */
	  if (equality_comparison_p
	      && (tem = simplify_binary_operation (MINUS, mode,
						   op1, XEXP (op0, 1))) != 0)
	    {
	      op0 = XEXP (op0, 0);
	      op1 = tem;
	      continue;
	    }

	  /* (plus (abs X) (const_int -1)) is < 0 if and only if X == 0.  */
	  if (const_op == 0 && XEXP (op0, 1) == constm1_rtx
	      && GET_CODE (XEXP (op0, 0)) == ABS && sign_bit_comparison_p)
	    {
	      op0 = XEXP (XEXP (op0, 0), 0);
	      code = (code == LT ? EQ : NE);
	      continue;
	    }
	  break;

	case MINUS:
	  /* We used to optimize signed comparisons against zero, but that
	     was incorrect.  Unsigned comparisons against zero (GTU, LEU)
	     arrive here as equality comparisons, or (GEU, LTU) are
	     optimized away.  No need to special-case them.  */

	  /* (eq (minus A B) C) -> (eq A (plus B C)) or
	     (eq B (minus A C)), whichever simplifies.  We can only do
	     this for equality comparisons due to pathological cases involving
	     overflows.  */
	  if (equality_comparison_p
	      && (tem = simplify_binary_operation (PLUS, mode,
						   XEXP (op0, 1), op1)) != 0)
	    {
	      op0 = XEXP (op0, 0);
	      op1 = tem;
	      continue;
	    }

	  if (equality_comparison_p
	      && (tem = simplify_binary_operation (MINUS, mode,
						   XEXP (op0, 0), op1)) != 0)
	    {
	      op0 = XEXP (op0, 1);
	      op1 = tem;
	      continue;
	    }

	  /* The sign bit of (minus (ashiftrt X C) X), where C is the number
	     of bits in X minus 1, is one iff X > 0.  */
	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == ASHIFTRT
	      && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
	      && UINTVAL (XEXP (XEXP (op0, 0), 1)) == mode_width - 1
	      && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
	    {
	      op0 = XEXP (op0, 1);
	      code = (code == GE ? LE : GT);
	      continue;
	    }
	  break;

	case XOR:
	  /* (eq (xor A B) C) -> (eq A (xor B C)).  This is a simplification
	     if C is zero or B is a constant.  */
	  if (equality_comparison_p
	      && (tem = simplify_binary_operation (XOR, mode,
						   XEXP (op0, 1), op1)) != 0)
	    {
	      op0 = XEXP (op0, 0);
	      op1 = tem;
	      continue;
	    }
	  break;


	case IOR:
	  /* The sign bit of (ior (plus X (const_int -1)) X) is nonzero
	     iff X <= 0.  */
	  if (sign_bit_comparison_p && GET_CODE (XEXP (op0, 0)) == PLUS
	      && XEXP (XEXP (op0, 0), 1) == constm1_rtx
	      && rtx_equal_p (XEXP (XEXP (op0, 0), 0), XEXP (op0, 1)))
	    {
	      op0 = XEXP (op0, 1);
	      code = (code == GE ? GT : LE);
	      continue;
	    }
	  break;

	case AND:
	  /* Convert (and (xshift 1 X) Y) to (and (lshiftrt Y X) 1).  This
	     will be converted to a ZERO_EXTRACT later.  */
	  if (const_op == 0 && equality_comparison_p
	      && GET_CODE (XEXP (op0, 0)) == ASHIFT
	      && XEXP (XEXP (op0, 0), 0) == const1_rtx)
	    {
	      op0 = gen_rtx_LSHIFTRT (mode, XEXP (op0, 1),
				      XEXP (XEXP (op0, 0), 1));
	      op0 = simplify_and_const_int (NULL_RTX, mode, op0, 1);
	      continue;
	    }

	  /* If we are comparing (and (lshiftrt X C1) C2) for equality with
	     zero and X is a comparison and C1 and C2 describe only bits set
	     in STORE_FLAG_VALUE, we can compare with X.  */
	  if (const_op == 0 && equality_comparison_p
	      && mode_width <= HOST_BITS_PER_WIDE_INT
	      && CONST_INT_P (XEXP (op0, 1))
	      && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
	      && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
	      && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
	      && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT)
	    {
	      mask = ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
		      << INTVAL (XEXP (XEXP (op0, 0), 1)));
	      if ((~STORE_FLAG_VALUE & mask) == 0
		  && (COMPARISON_P (XEXP (XEXP (op0, 0), 0))
		      || ((tem = get_last_value (XEXP (XEXP (op0, 0), 0))) != 0
			  && COMPARISON_P (tem))))
		{
		  op0 = XEXP (XEXP (op0, 0), 0);
		  continue;
		}
	    }

	  /* If we are doing an equality comparison of an AND of a bit equal
	     to the sign bit, replace this with a LT or GE comparison of
	     the underlying value.  */
	  if (equality_comparison_p
	      && const_op == 0
	      && CONST_INT_P (XEXP (op0, 1))
	      && mode_width <= HOST_BITS_PER_WIDE_INT
	      && ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode))
		  == HOST_WIDE_INT_1U << (mode_width - 1)))
	    {
	      op0 = XEXP (op0, 0);
	      code = (code == EQ ? GE : LT);
	      continue;
	    }

	  /* If this AND operation is really a ZERO_EXTEND from a narrower
	     mode, the constant fits within that mode, and this is either an
	     equality or unsigned comparison, try to do this comparison in
	     the narrower mode.

	     Note that in:

	     (ne:DI (and:DI (reg:DI 4) (const_int 0xffffffff)) (const_int 0))
	     -> (ne:DI (reg:SI 4) (const_int 0))

	     unless TARGET_TRULY_NOOP_TRUNCATION allows it or the register is
	     known to hold a value of the required mode the
	     transformation is invalid.  */
	  if ((equality_comparison_p || unsigned_comparison_p)
	      && CONST_INT_P (XEXP (op0, 1))
	      && (i = exact_log2 ((UINTVAL (XEXP (op0, 1))
				   & GET_MODE_MASK (mode))
				  + 1)) >= 0
	      && const_op >> i == 0
	      && int_mode_for_size (i, 1).exists (&tmode))
	    {
	      op0 = gen_lowpart_or_truncate (tmode, XEXP (op0, 0));
	      continue;
	    }

	  /* If this is (and:M1 (subreg:M1 X:M2 0) (const_int C1)) where C1
	     fits in both M1 and M2 and the SUBREG is either paradoxical
	     or represents the low part, permute the SUBREG and the AND
	     and try again.  */
	  if (GET_CODE (XEXP (op0, 0)) == SUBREG
	      && CONST_INT_P (XEXP (op0, 1)))
	    {
	      unsigned HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
	      /* Require an integral mode, to avoid creating something like
		 (AND:SF ...).  */
	      if ((is_a <scalar_int_mode>
		   (GET_MODE (SUBREG_REG (XEXP (op0, 0))), &tmode))
		  /* It is unsafe to commute the AND into the SUBREG if the
		     SUBREG is paradoxical and WORD_REGISTER_OPERATIONS is
		     not defined.  As originally written the upper bits
		     have a defined value due to the AND operation.
		     However, if we commute the AND inside the SUBREG then
		     they no longer have defined values and the meaning of
		     the code has been changed.
		     Also C1 should not change value in the smaller mode,
		     see PR67028 (a positive C1 can become negative in the
		     smaller mode, so that the AND does no longer mask the
		     upper bits).  */
		  && ((WORD_REGISTER_OPERATIONS
		       && mode_width > GET_MODE_PRECISION (tmode)
		       && mode_width <= BITS_PER_WORD
		       && trunc_int_for_mode (c1, tmode) == (HOST_WIDE_INT) c1)
		      || (mode_width <= GET_MODE_PRECISION (tmode)
			  && subreg_lowpart_p (XEXP (op0, 0))))
		  && mode_width <= HOST_BITS_PER_WIDE_INT
		  && HWI_COMPUTABLE_MODE_P (tmode)
		  && (c1 & ~mask) == 0
		  && (c1 & ~GET_MODE_MASK (tmode)) == 0
		  && c1 != mask
		  && c1 != GET_MODE_MASK (tmode))
		{
		  op0 = simplify_gen_binary (AND, tmode,
					     SUBREG_REG (XEXP (op0, 0)),
					     gen_int_mode (c1, tmode));
		  op0 = gen_lowpart (mode, op0);
		  continue;
		}
	    }

	  /* Convert (ne (and (not X) 1) 0) to (eq (and X 1) 0).  */
	  if (const_op == 0 && equality_comparison_p
	      && XEXP (op0, 1) == const1_rtx
	      && GET_CODE (XEXP (op0, 0)) == NOT)
	    {
	      op0 = simplify_and_const_int (NULL_RTX, mode,
					    XEXP (XEXP (op0, 0), 0), 1);
	      code = (code == NE ? EQ : NE);
	      continue;
	    }

	  /* Convert (ne (and (lshiftrt (not X)) 1) 0) to
	     (eq (and (lshiftrt X) 1) 0).
	     Also handle the case where (not X) is expressed using xor.  */
	  if (const_op == 0 && equality_comparison_p
	      && XEXP (op0, 1) == const1_rtx
	      && GET_CODE (XEXP (op0, 0)) == LSHIFTRT)
	    {
	      rtx shift_op = XEXP (XEXP (op0, 0), 0);
	      rtx shift_count = XEXP (XEXP (op0, 0), 1);

	      if (GET_CODE (shift_op) == NOT
		  || (GET_CODE (shift_op) == XOR
		      && CONST_INT_P (XEXP (shift_op, 1))
		      && CONST_INT_P (shift_count)
		      && HWI_COMPUTABLE_MODE_P (mode)
		      && (UINTVAL (XEXP (shift_op, 1))
			  == HOST_WIDE_INT_1U
			       << INTVAL (shift_count))))
		{
		  op0
		    = gen_rtx_LSHIFTRT (mode, XEXP (shift_op, 0), shift_count);
		  op0 = simplify_and_const_int (NULL_RTX, mode, op0, 1);
		  code = (code == NE ? EQ : NE);
		  continue;
		}
	    }
	  break;

	case ASHIFT:
	  /* If we have (compare (ashift FOO N) (const_int C)) and
	     the high order N bits of FOO (N+1 if an inequality comparison)
	     are known to be zero, we can do this by comparing FOO with C
	     shifted right N bits so long as the low-order N bits of C are
	     zero.  */
	  if (CONST_INT_P (XEXP (op0, 1))
	      && INTVAL (XEXP (op0, 1)) >= 0
	      && ((INTVAL (XEXP (op0, 1)) + ! equality_comparison_p)
		  < HOST_BITS_PER_WIDE_INT)
	      && (((unsigned HOST_WIDE_INT) const_op
		   & ((HOST_WIDE_INT_1U << INTVAL (XEXP (op0, 1)))
		      - 1)) == 0)
	      && mode_width <= HOST_BITS_PER_WIDE_INT
	      && (nonzero_bits (XEXP (op0, 0), mode)
		  & ~(mask >> (INTVAL (XEXP (op0, 1))
			       + ! equality_comparison_p))) == 0)
	    {
	      /* We must perform a logical shift, not an arithmetic one,
		 as we want the top N bits of C to be zero.  */
	      unsigned HOST_WIDE_INT temp = const_op & GET_MODE_MASK (mode);

	      temp >>= INTVAL (XEXP (op0, 1));
	      op1 = gen_int_mode (temp, mode);
	      op0 = XEXP (op0, 0);
	      continue;
	    }

	  /* If we are doing a sign bit comparison, it means we are testing
	     a particular bit.  Convert it to the appropriate AND.  */
	  if (sign_bit_comparison_p && CONST_INT_P (XEXP (op0, 1))
	      && mode_width <= HOST_BITS_PER_WIDE_INT)
	    {
	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0),
					    (HOST_WIDE_INT_1U
					     << (mode_width - 1
						 - INTVAL (XEXP (op0, 1)))));
	      code = (code == LT ? NE : EQ);
	      continue;
	    }

	  /* If this an equality comparison with zero and we are shifting
	     the low bit to the sign bit, we can convert this to an AND of the
	     low-order bit.  */
	  if (const_op == 0 && equality_comparison_p
	      && CONST_INT_P (XEXP (op0, 1))
	      && UINTVAL (XEXP (op0, 1)) == mode_width - 1)
	    {
	      op0 = simplify_and_const_int (NULL_RTX, mode, XEXP (op0, 0), 1);
	      continue;
	    }
	  break;

	case ASHIFTRT:
	  /* If this is an equality comparison with zero, we can do this
	     as a logical shift, which might be much simpler.  */
	  if (equality_comparison_p && const_op == 0
	      && CONST_INT_P (XEXP (op0, 1)))
	    {
	      op0 = simplify_shift_const (NULL_RTX, LSHIFTRT, mode,
					  XEXP (op0, 0),
					  INTVAL (XEXP (op0, 1)));
	      continue;
	    }

	  /* If OP0 is a sign extension and CODE is not an unsigned comparison,
	     do the comparison in a narrower mode.  */
	  if (! unsigned_comparison_p
	      && CONST_INT_P (XEXP (op0, 1))
	      && GET_CODE (XEXP (op0, 0)) == ASHIFT
	      && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
	      && (int_mode_for_size (mode_width - INTVAL (XEXP (op0, 1)), 1)
		  .exists (&tmode))
	      && (((unsigned HOST_WIDE_INT) const_op
		   + (GET_MODE_MASK (tmode) >> 1) + 1)
		  <= GET_MODE_MASK (tmode)))
	    {
	      op0 = gen_lowpart (tmode, XEXP (XEXP (op0, 0), 0));
	      continue;
	    }

	  /* Likewise if OP0 is a PLUS of a sign extension with a
	     constant, which is usually represented with the PLUS
	     between the shifts.  */
	  if (! unsigned_comparison_p
	      && CONST_INT_P (XEXP (op0, 1))
	      && GET_CODE (XEXP (op0, 0)) == PLUS
	      && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
	      && GET_CODE (XEXP (XEXP (op0, 0), 0)) == ASHIFT
	      && XEXP (op0, 1) == XEXP (XEXP (XEXP (op0, 0), 0), 1)
	      && (int_mode_for_size (mode_width - INTVAL (XEXP (op0, 1)), 1)
		  .exists (&tmode))
	      && (((unsigned HOST_WIDE_INT) const_op
		   + (GET_MODE_MASK (tmode) >> 1) + 1)
		  <= GET_MODE_MASK (tmode)))
	    {
	      rtx inner = XEXP (XEXP (XEXP (op0, 0), 0), 0);
	      rtx add_const = XEXP (XEXP (op0, 0), 1);
	      rtx new_const = simplify_gen_binary (ASHIFTRT, mode,
						   add_const, XEXP (op0, 1));

	      op0 = simplify_gen_binary (PLUS, tmode,
					 gen_lowpart (tmode, inner),
					 new_const);
	      continue;
	    }

	  /* FALLTHROUGH */
	case LSHIFTRT:
	  /* If we have (compare (xshiftrt FOO N) (const_int C)) and
	     the low order N bits of FOO are known to be zero, we can do this
	     by comparing FOO with C shifted left N bits so long as no
	     overflow occurs.  Even if the low order N bits of FOO aren't known
	     to be zero, if the comparison is >= or < we can use the same
	     optimization and for > or <= by setting all the low
	     order N bits in the comparison constant.  */
	  if (CONST_INT_P (XEXP (op0, 1))
	      && INTVAL (XEXP (op0, 1)) > 0
	      && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT
	      && mode_width <= HOST_BITS_PER_WIDE_INT
	      && (((unsigned HOST_WIDE_INT) const_op
		   + (GET_CODE (op0) != LSHIFTRT
		      ? ((GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1)) >> 1)
			 + 1)
		      : 0))
		  <= GET_MODE_MASK (mode) >> INTVAL (XEXP (op0, 1))))
	    {
	      unsigned HOST_WIDE_INT low_bits
		= (nonzero_bits (XEXP (op0, 0), mode)
		   & ((HOST_WIDE_INT_1U
		       << INTVAL (XEXP (op0, 1))) - 1));
	      if (low_bits == 0 || !equality_comparison_p)
		{
		  /* If the shift was logical, then we must make the condition
		     unsigned.  */
		  if (GET_CODE (op0) == LSHIFTRT)
		    code = unsigned_condition (code);

		  const_op = (unsigned HOST_WIDE_INT) const_op
			      << INTVAL (XEXP (op0, 1));
		  if (low_bits != 0
		      && (code == GT || code == GTU
			  || code == LE || code == LEU))
		    const_op
		      |= ((HOST_WIDE_INT_1 << INTVAL (XEXP (op0, 1))) - 1);
		  op1 = GEN_INT (const_op);
		  op0 = XEXP (op0, 0);
		  continue;
		}
	    }

	  /* If we are using this shift to extract just the sign bit, we
	     can replace this with an LT or GE comparison.  */
	  if (const_op == 0
	      && (equality_comparison_p || sign_bit_comparison_p)
	      && CONST_INT_P (XEXP (op0, 1))
	      && UINTVAL (XEXP (op0, 1)) == mode_width - 1)
	    {
	      op0 = XEXP (op0, 0);
	      code = (code == NE || code == GT ? LT : GE);
	      continue;
	    }
	  break;

	default:
	  break;
	}

      break;
    }

  /* Now make any compound operations involved in this comparison.  Then,
     check for an outmost SUBREG on OP0 that is not doing anything or is
     paradoxical.  The latter transformation must only be performed when
     it is known that the "extra" bits will be the same in op0 and op1 or
     that they don't matter.  There are three cases to consider:

     1. SUBREG_REG (op0) is a register.  In this case the bits are don't
     care bits and we can assume they have any convenient value.  So
     making the transformation is safe.

     2. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is UNKNOWN.
     In this case the upper bits of op0 are undefined.  We should not make
     the simplification in that case as we do not know the contents of
     those bits.

     3. SUBREG_REG (op0) is a memory and LOAD_EXTEND_OP is not UNKNOWN.
     In that case we know those bits are zeros or ones.  We must also be
     sure that they are the same as the upper bits of op1.

     We can never remove a SUBREG for a non-equality comparison because
     the sign bit is in a different place in the underlying object.  */

  rtx_code op0_mco_code = SET;
  if (op1 == const0_rtx)
    op0_mco_code = code == NE || code == EQ ? EQ : COMPARE;

  op0 = make_compound_operation (op0, op0_mco_code);
  op1 = make_compound_operation (op1, SET);

  if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
      && is_int_mode (GET_MODE (op0), &mode)
      && is_int_mode (GET_MODE (SUBREG_REG (op0)), &inner_mode)
      && (code == NE || code == EQ))
    {
      if (paradoxical_subreg_p (op0))
	{
	  /* For paradoxical subregs, allow case 1 as above.  Case 3 isn't
	     implemented.  */
	  if (REG_P (SUBREG_REG (op0)))
	    {
	      op0 = SUBREG_REG (op0);
	      op1 = gen_lowpart (inner_mode, op1);
	    }
	}
      else if (GET_MODE_PRECISION (inner_mode) <= HOST_BITS_PER_WIDE_INT
	       && (nonzero_bits (SUBREG_REG (op0), inner_mode)
		   & ~GET_MODE_MASK (mode)) == 0)
	{
	  tem = gen_lowpart (inner_mode, op1);

	  if ((nonzero_bits (tem, inner_mode) & ~GET_MODE_MASK (mode)) == 0)
	    op0 = SUBREG_REG (op0), op1 = tem;
	}
    }

  /* We now do the opposite procedure: Some machines don't have compare
     insns in all modes.  If OP0's mode is an integer mode smaller than a
     word and we can't do a compare in that mode, see if there is a larger
     mode for which we can do the compare.  There are a number of cases in
     which we can use the wider mode.  */

  if (is_int_mode (GET_MODE (op0), &mode)
      && GET_MODE_SIZE (mode) < UNITS_PER_WORD
      && ! have_insn_for (COMPARE, mode))
    FOR_EACH_WIDER_MODE (tmode_iter, mode)
      {
	tmode = tmode_iter.require ();
	if (!HWI_COMPUTABLE_MODE_P (tmode))
	  break;
	if (have_insn_for (COMPARE, tmode))
	  {
	    int zero_extended;

	    /* If this is a test for negative, we can make an explicit
	       test of the sign bit.  Test this first so we can use
	       a paradoxical subreg to extend OP0.  */

	    if (op1 == const0_rtx && (code == LT || code == GE)
		&& HWI_COMPUTABLE_MODE_P (mode))
	      {
		unsigned HOST_WIDE_INT sign
		  = HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (mode) - 1);
		op0 = simplify_gen_binary (AND, tmode,
					   gen_lowpart (tmode, op0),
					   gen_int_mode (sign, tmode));
		code = (code == LT) ? NE : EQ;
		break;
	      }

	    /* If the only nonzero bits in OP0 and OP1 are those in the
	       narrower mode and this is an equality or unsigned comparison,
	       we can use the wider mode.  Similarly for sign-extended
	       values, in which case it is true for all comparisons.  */
	    zero_extended = ((code == EQ || code == NE
			      || code == GEU || code == GTU
			      || code == LEU || code == LTU)
			     && (nonzero_bits (op0, tmode)
				 & ~GET_MODE_MASK (mode)) == 0
			     && ((CONST_INT_P (op1)
				  || (nonzero_bits (op1, tmode)
				      & ~GET_MODE_MASK (mode)) == 0)));

	    if (zero_extended
		|| ((num_sign_bit_copies (op0, tmode)
		     > (unsigned int) (GET_MODE_PRECISION (tmode)
				       - GET_MODE_PRECISION (mode)))
		    && (num_sign_bit_copies (op1, tmode)
			> (unsigned int) (GET_MODE_PRECISION (tmode)
					  - GET_MODE_PRECISION (mode)))))
	      {
		/* If OP0 is an AND and we don't have an AND in MODE either,
		   make a new AND in the proper mode.  */
		if (GET_CODE (op0) == AND
		    && !have_insn_for (AND, mode))
		  op0 = simplify_gen_binary (AND, tmode,
					     gen_lowpart (tmode,
							  XEXP (op0, 0)),
					     gen_lowpart (tmode,
							  XEXP (op0, 1)));
		else
		  {
		    if (zero_extended)
		      {
			op0 = simplify_gen_unary (ZERO_EXTEND, tmode,
						  op0, mode);
			op1 = simplify_gen_unary (ZERO_EXTEND, tmode,
						  op1, mode);
		      }
		    else
		      {
			op0 = simplify_gen_unary (SIGN_EXTEND, tmode,
						  op0, mode);
			op1 = simplify_gen_unary (SIGN_EXTEND, tmode,
						  op1, mode);
		      }
		    break;
		  }
	      }
	  }
      }

  /* We may have changed the comparison operands.  Re-canonicalize.  */
  if (swap_commutative_operands_p (op0, op1))
    {
      std::swap (op0, op1);
      code = swap_condition (code);
    }

  /* If this machine only supports a subset of valid comparisons, see if we
     can convert an unsupported one into a supported one.  */
  target_canonicalize_comparison (&code, &op0, &op1, 0);

  *pop0 = op0;
  *pop1 = op1;

  return code;
}

/* Utility function for record_value_for_reg.  Count number of
   rtxs in X.  */
static int
count_rtxs (rtx x)
{
  enum rtx_code code = GET_CODE (x);
  const char *fmt;
  int i, j, ret = 1;

  if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
      || GET_RTX_CLASS (code) == RTX_COMM_ARITH)
    {
      rtx x0 = XEXP (x, 0);
      rtx x1 = XEXP (x, 1);

      if (x0 == x1)
	return 1 + 2 * count_rtxs (x0);

      if ((GET_RTX_CLASS (GET_CODE (x1)) == RTX_BIN_ARITH
	   || GET_RTX_CLASS (GET_CODE (x1)) == RTX_COMM_ARITH)
	  && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
	return 2 + 2 * count_rtxs (x0)
	       + count_rtxs (x == XEXP (x1, 0)
			     ? XEXP (x1, 1) : XEXP (x1, 0));

      if ((GET_RTX_CLASS (GET_CODE (x0)) == RTX_BIN_ARITH
	   || GET_RTX_CLASS (GET_CODE (x0)) == RTX_COMM_ARITH)
	  && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
	return 2 + 2 * count_rtxs (x1)
	       + count_rtxs (x == XEXP (x0, 0)
			     ? XEXP (x0, 1) : XEXP (x0, 0));
    }

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    if (fmt[i] == 'e')
      ret += count_rtxs (XEXP (x, i));
    else if (fmt[i] == 'E')
      for (j = 0; j < XVECLEN (x, i); j++)
	ret += count_rtxs (XVECEXP (x, i, j));

  return ret;
}

/* Utility function for following routine.  Called when X is part of a value
   being stored into last_set_value.  Sets last_set_table_tick
   for each register mentioned.  Similar to mention_regs in cse.c  */

static void
update_table_tick (rtx x)
{
  enum rtx_code code = GET_CODE (x);
  const char *fmt = GET_RTX_FORMAT (code);
  int i, j;

  if (code == REG)
    {
      unsigned int regno = REGNO (x);
      unsigned int endregno = END_REGNO (x);
      unsigned int r;

      for (r = regno; r < endregno; r++)
	{
	  reg_stat_type *rsp = &reg_stat[r];
	  rsp->last_set_table_tick = label_tick;
	}

      return;
    }

  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    if (fmt[i] == 'e')
      {
	/* Check for identical subexpressions.  If x contains
	   identical subexpression we only have to traverse one of
	   them.  */
	if (i == 0 && ARITHMETIC_P (x))
	  {
	    /* Note that at this point x1 has already been
	       processed.  */
	    rtx x0 = XEXP (x, 0);
	    rtx x1 = XEXP (x, 1);

	    /* If x0 and x1 are identical then there is no need to
	       process x0.  */
	    if (x0 == x1)
	      break;

	    /* If x0 is identical to a subexpression of x1 then while
	       processing x1, x0 has already been processed.  Thus we
	       are done with x.  */
	    if (ARITHMETIC_P (x1)
		&& (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
	      break;

	    /* If x1 is identical to a subexpression of x0 then we
	       still have to process the rest of x0.  */
	    if (ARITHMETIC_P (x0)
		&& (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
	      {
		update_table_tick (XEXP (x0, x1 == XEXP (x0, 0) ? 1 : 0));
		break;
	      }
	  }

	update_table_tick (XEXP (x, i));
      }
    else if (fmt[i] == 'E')
      for (j = 0; j < XVECLEN (x, i); j++)
	update_table_tick (XVECEXP (x, i, j));
}

/* Record that REG is set to VALUE in insn INSN.  If VALUE is zero, we
   are saying that the register is clobbered and we no longer know its
   value.  If INSN is zero, don't update reg_stat[].last_set; this is
   only permitted with VALUE also zero and is used to invalidate the
   register.  */

static void
record_value_for_reg (rtx reg, rtx_insn *insn, rtx value)
{
  unsigned int regno = REGNO (reg);
  unsigned int endregno = END_REGNO (reg);
  unsigned int i;
  reg_stat_type *rsp;

  /* If VALUE contains REG and we have a previous value for REG, substitute
     the previous value.  */
  if (value && insn && reg_overlap_mentioned_p (reg, value))
    {
      rtx tem;

      /* Set things up so get_last_value is allowed to see anything set up to
	 our insn.  */
      subst_low_luid = DF_INSN_LUID (insn);
      tem = get_last_value (reg);

      /* If TEM is simply a binary operation with two CLOBBERs as operands,
	 it isn't going to be useful and will take a lot of time to process,
	 so just use the CLOBBER.  */

      if (tem)
	{
	  if (ARITHMETIC_P (tem)
	      && GET_CODE (XEXP (tem, 0)) == CLOBBER
	      && GET_CODE (XEXP (tem, 1)) == CLOBBER)
	    tem = XEXP (tem, 0);
	  else if (count_occurrences (value, reg, 1) >= 2)
	    {
	      /* If there are two or more occurrences of REG in VALUE,
		 prevent the value from growing too much.  */
	      if (count_rtxs (tem) > MAX_LAST_VALUE_RTL)
		tem = gen_rtx_CLOBBER (GET_MODE (tem), const0_rtx);
	    }

	  value = replace_rtx (copy_rtx (value), reg, tem);
	}
    }

  /* For each register modified, show we don't know its value, that
     we don't know about its bitwise content, that its value has been
     updated, and that we don't know the location of the death of the
     register.  */
  for (i = regno; i < endregno; i++)
    {
      rsp = &reg_stat[i];

      if (insn)
	rsp->last_set = insn;

      rsp->last_set_value = 0;
      rsp->last_set_mode = VOIDmode;
      rsp->last_set_nonzero_bits = 0;
      rsp->last_set_sign_bit_copies = 0;
      rsp->last_death = 0;
      rsp->truncated_to_mode = VOIDmode;
    }

  /* Mark registers that are being referenced in this value.  */
  if (value)
    update_table_tick (value);

  /* Now update the status of each register being set.
     If someone is using this register in this block, set this register
     to invalid since we will get confused between the two lives in this
     basic block.  This makes using this register always invalid.  In cse, we
     scan the table to invalidate all entries using this register, but this
     is too much work for us.  */

  for (i = regno; i < endregno; i++)
    {
      rsp = &reg_stat[i];
      rsp->last_set_label = label_tick;
      if (!insn
	  || (value && rsp->last_set_table_tick >= label_tick_ebb_start))
	rsp->last_set_invalid = 1;
      else
	rsp->last_set_invalid = 0;
    }

  /* The value being assigned might refer to X (like in "x++;").  In that
     case, we must replace it with (clobber (const_int 0)) to prevent
     infinite loops.  */
  rsp = &reg_stat[regno];
  if (value && !get_last_value_validate (&value, insn, label_tick, 0))
    {
      value = copy_rtx (value);
      if (!get_last_value_validate (&value, insn, label_tick, 1))
	value = 0;
    }

  /* For the main register being modified, update the value, the mode, the
     nonzero bits, and the number of sign bit copies.  */

  rsp->last_set_value = value;

  if (value)
    {
      machine_mode mode = GET_MODE (reg);
      subst_low_luid = DF_INSN_LUID (insn);
      rsp->last_set_mode = mode;
      if (GET_MODE_CLASS (mode) == MODE_INT
	  && HWI_COMPUTABLE_MODE_P (mode))
	mode = nonzero_bits_mode;
      rsp->last_set_nonzero_bits = nonzero_bits (value, mode);
      rsp->last_set_sign_bit_copies
	= num_sign_bit_copies (value, GET_MODE (reg));
    }
}

/* Called via note_stores from record_dead_and_set_regs to handle one
   SET or CLOBBER in an insn.  DATA is the instruction in which the
   set is occurring.  */

static void
record_dead_and_set_regs_1 (rtx dest, const_rtx setter, void *data)
{
  rtx_insn *record_dead_insn = (rtx_insn *) data;

  if (GET_CODE (dest) == SUBREG)
    dest = SUBREG_REG (dest);

  if (!record_dead_insn)
    {
      if (REG_P (dest))
	record_value_for_reg (dest, NULL, NULL_RTX);
      return;
    }

  if (REG_P (dest))
    {
      /* If we are setting the whole register, we know its value.  Otherwise
	 show that we don't know the value.  We can handle a SUBREG if it's
	 the low part, but we must be careful with paradoxical SUBREGs on
	 RISC architectures because we cannot strip e.g. an extension around
	 a load and record the naked load since the RTL middle-end considers
	 that the upper bits are defined according to LOAD_EXTEND_OP.  */
      if (GET_CODE (setter) == SET && dest == SET_DEST (setter))
	record_value_for_reg (dest, record_dead_insn, SET_SRC (setter));
      else if (GET_CODE (setter) == SET
	       && GET_CODE (SET_DEST (setter)) == SUBREG
	       && SUBREG_REG (SET_DEST (setter)) == dest
	       && known_le (GET_MODE_PRECISION (GET_MODE (dest)),
			    BITS_PER_WORD)
	       && subreg_lowpart_p (SET_DEST (setter)))
	record_value_for_reg (dest, record_dead_insn,
			      WORD_REGISTER_OPERATIONS
			      && word_register_operation_p (SET_SRC (setter))
			      && paradoxical_subreg_p (SET_DEST (setter))
			      ? SET_SRC (setter)
			      : gen_lowpart (GET_MODE (dest),
					     SET_SRC (setter)));
      else if (GET_CODE (setter) == CLOBBER_HIGH)
	{
	  reg_stat_type *rsp = &reg_stat[REGNO (dest)];
	  if (rsp->last_set_value
	      && reg_is_clobbered_by_clobber_high
		   (REGNO (dest), GET_MODE (rsp->last_set_value),
		    XEXP (setter, 0)))
	    record_value_for_reg (dest, NULL, NULL_RTX);
	}
      else
	record_value_for_reg (dest, record_dead_insn, NULL_RTX);
    }
  else if (MEM_P (dest)
	   /* Ignore pushes, they clobber nothing.  */
	   && ! push_operand (dest, GET_MODE (dest)))
    mem_last_set = DF_INSN_LUID (record_dead_insn);
}

/* Update the records of when each REG was most recently set or killed
   for the things done by INSN.  This is the last thing done in processing
   INSN in the combiner loop.

   We update reg_stat[], in particular fields last_set, last_set_value,
   last_set_mode, last_set_nonzero_bits, last_set_sign_bit_copies,
   last_death, and also the similar information mem_last_set (which insn
   most recently modified memory) and last_call_luid (which insn was the
   most recent subroutine call).  */

static void
record_dead_and_set_regs (rtx_insn *insn)
{
  rtx link;
  unsigned int i;

  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
    {
      if (REG_NOTE_KIND (link) == REG_DEAD
	  && REG_P (XEXP (link, 0)))
	{
	  unsigned int regno = REGNO (XEXP (link, 0));
	  unsigned int endregno = END_REGNO (XEXP (link, 0));

	  for (i = regno; i < endregno; i++)
	    {
	      reg_stat_type *rsp;

	      rsp = &reg_stat[i];
	      rsp->last_death = insn;
	    }
	}
      else if (REG_NOTE_KIND (link) == REG_INC)
	record_value_for_reg (XEXP (link, 0), insn, NULL_RTX);
    }

  if (CALL_P (insn))
    {
      hard_reg_set_iterator hrsi;
      EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, i, hrsi)
	{
	  reg_stat_type *rsp;

	  rsp = &reg_stat[i];
	  rsp->last_set_invalid = 1;
	  rsp->last_set = insn;
	  rsp->last_set_value = 0;
	  rsp->last_set_mode = VOIDmode;
	  rsp->last_set_nonzero_bits = 0;
	  rsp->last_set_sign_bit_copies = 0;
	  rsp->last_death = 0;
	  rsp->truncated_to_mode = VOIDmode;
	}

      last_call_luid = mem_last_set = DF_INSN_LUID (insn);

      /* We can't combine into a call pattern.  Remember, though, that
	 the return value register is set at this LUID.  We could
	 still replace a register with the return value from the
	 wrong subroutine call!  */
      note_stores (PATTERN (insn), record_dead_and_set_regs_1, NULL_RTX);
    }
  else
    note_stores (PATTERN (insn), record_dead_and_set_regs_1, insn);
}

/* If a SUBREG has the promoted bit set, it is in fact a property of the
   register present in the SUBREG, so for each such SUBREG go back and
   adjust nonzero and sign bit information of the registers that are
   known to have some zero/sign bits set.

   This is needed because when combine blows the SUBREGs away, the
   information on zero/sign bits is lost and further combines can be
   missed because of that.  */

static void
record_promoted_value (rtx_insn *insn, rtx subreg)
{
  struct insn_link *links;
  rtx set;
  unsigned int regno = REGNO (SUBREG_REG (subreg));
  machine_mode mode = GET_MODE (subreg);

  if (!HWI_COMPUTABLE_MODE_P (mode))
    return;

  for (links = LOG_LINKS (insn); links;)
    {
      reg_stat_type *rsp;

      insn = links->insn;
      set = single_set (insn);

      if (! set || !REG_P (SET_DEST (set))
	  || REGNO (SET_DEST (set)) != regno
	  || GET_MODE (SET_DEST (set)) != GET_MODE (SUBREG_REG (subreg)))
	{
	  links = links->next;
	  continue;
	}

      rsp = &reg_stat[regno];
      if (rsp->last_set == insn)
	{
	  if (SUBREG_PROMOTED_UNSIGNED_P (subreg))
	    rsp->last_set_nonzero_bits &= GET_MODE_MASK (mode);
	}

      if (REG_P (SET_SRC (set)))
	{
	  regno = REGNO (SET_SRC (set));
	  links = LOG_LINKS (insn);
	}
      else
	break;
    }
}

/* Check if X, a register, is known to contain a value already
   truncated to MODE.  In this case we can use a subreg to refer to
   the truncated value even though in the generic case we would need
   an explicit truncation.  */

static bool
reg_truncated_to_mode (machine_mode mode, const_rtx x)
{
  reg_stat_type *rsp = &reg_stat[REGNO (x)];
  machine_mode truncated = rsp->truncated_to_mode;

  if (truncated == 0
      || rsp->truncation_label < label_tick_ebb_start)
    return false;
  if (!partial_subreg_p (mode, truncated))
    return true;
  if (TRULY_NOOP_TRUNCATION_MODES_P (mode, truncated))
    return true;
  return false;
}

/* If X is a hard reg or a subreg record the mode that the register is
   accessed in.  For non-TARGET_TRULY_NOOP_TRUNCATION targets we might be
   able to turn a truncate into a subreg using this information.  Return true
   if traversing X is complete.  */

static bool
record_truncated_value (rtx x)
{
  machine_mode truncated_mode;
  reg_stat_type *rsp;

  if (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x)))
    {
      machine_mode original_mode = GET_MODE (SUBREG_REG (x));
      truncated_mode = GET_MODE (x);

      if (!partial_subreg_p (truncated_mode, original_mode))
	return true;

      truncated_mode = GET_MODE (x);
      if (TRULY_NOOP_TRUNCATION_MODES_P (truncated_mode, original_mode))
	return true;

      x = SUBREG_REG (x);
    }
  /* ??? For hard-regs we now record everything.  We might be able to
     optimize this using last_set_mode.  */
  else if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
    truncated_mode = GET_MODE (x);
  else
    return false;

  rsp = &reg_stat[REGNO (x)];
  if (rsp->truncated_to_mode == 0
      || rsp->truncation_label < label_tick_ebb_start
      || partial_subreg_p (truncated_mode, rsp->truncated_to_mode))
    {
      rsp->truncated_to_mode = truncated_mode;
      rsp->truncation_label = label_tick;
    }

  return true;
}

/* Callback for note_uses.  Find hardregs and subregs of pseudos and
   the modes they are used in.  This can help truning TRUNCATEs into
   SUBREGs.  */

static void
record_truncated_values (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
  subrtx_var_iterator::array_type array;
  FOR_EACH_SUBRTX_VAR (iter, array, *loc, NONCONST)
    if (record_truncated_value (*iter))
      iter.skip_subrtxes ();
}

/* Scan X for promoted SUBREGs.  For each one found,
   note what it implies to the registers used in it.  */

static void
check_promoted_subreg (rtx_insn *insn, rtx x)
{
  if (GET_CODE (x) == SUBREG
      && SUBREG_PROMOTED_VAR_P (x)
      && REG_P (SUBREG_REG (x)))
    record_promoted_value (insn, x);
  else
    {
      const char *format = GET_RTX_FORMAT (GET_CODE (x));
      int i, j;

      for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
	switch (format[i])
	  {
	  case 'e':
	    check_promoted_subreg (insn, XEXP (x, i));
	    break;
	  case 'V':
	  case 'E':
	    if (XVEC (x, i) != 0)
	      for (j = 0; j < XVECLEN (x, i); j++)
		check_promoted_subreg (insn, XVECEXP (x, i, j));
	    break;
	  }
    }
}

/* Verify that all the registers and memory references mentioned in *LOC are
   still valid.  *LOC was part of a value set in INSN when label_tick was
   equal to TICK.  Return 0 if some are not.  If REPLACE is nonzero, replace
   the invalid references with (clobber (const_int 0)) and return 1.  This
   replacement is useful because we often can get useful information about
   the form of a value (e.g., if it was produced by a shift that always
   produces -1 or 0) even though we don't know exactly what registers it
   was produced from.  */

static int
get_last_value_validate (rtx *loc, rtx_insn *insn, int tick, int replace)
{
  rtx x = *loc;
  const char *fmt = GET_RTX_FORMAT (GET_CODE (x));
  int len = GET_RTX_LENGTH (GET_CODE (x));
  int i, j;

  if (REG_P (x))
    {
      unsigned int regno = REGNO (x);
      unsigned int endregno = END_REGNO (x);
      unsigned int j;

      for (j = regno; j < endregno; j++)
	{
	  reg_stat_type *rsp = &reg_stat[j];
	  if (rsp->last_set_invalid
	      /* If this is a pseudo-register that was only set once and not
		 live at the beginning of the function, it is always valid.  */
	      || (! (regno >= FIRST_PSEUDO_REGISTER
		     && regno < reg_n_sets_max
		     && REG_N_SETS (regno) == 1
		     && (!REGNO_REG_SET_P
			 (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb),
			  regno)))
		  && rsp->last_set_label > tick))
	  {
	    if (replace)
	      *loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
	    return replace;
	  }
	}

      return 1;
    }
  /* If this is a memory reference, make sure that there were no stores after
     it that might have clobbered the value.  We don't have alias info, so we
     assume any store invalidates it.  Moreover, we only have local UIDs, so
     we also assume that there were stores in the intervening basic blocks.  */
  else if (MEM_P (x) && !MEM_READONLY_P (x)
	   && (tick != label_tick || DF_INSN_LUID (insn) <= mem_last_set))
    {
      if (replace)
	*loc = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
      return replace;
    }

  for (i = 0; i < len; i++)
    {
      if (fmt[i] == 'e')
	{
	  /* Check for identical subexpressions.  If x contains
	     identical subexpression we only have to traverse one of
	     them.  */
	  if (i == 1 && ARITHMETIC_P (x))
	    {
	      /* Note that at this point x0 has already been checked
		 and found valid.  */
	      rtx x0 = XEXP (x, 0);
	      rtx x1 = XEXP (x, 1);

	      /* If x0 and x1 are identical then x is also valid.  */
	      if (x0 == x1)
		return 1;

	      /* If x1 is identical to a subexpression of x0 then
		 while checking x0, x1 has already been checked.  Thus
		 it is valid and so as x.  */
	      if (ARITHMETIC_P (x0)
		  && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
		return 1;

	      /* If x0 is identical to a subexpression of x1 then x is
		 valid iff the rest of x1 is valid.  */
	      if (ARITHMETIC_P (x1)
		  && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
		return
		  get_last_value_validate (&XEXP (x1,
						  x0 == XEXP (x1, 0) ? 1 : 0),
					   insn, tick, replace);
	    }

	  if (get_last_value_validate (&XEXP (x, i), insn, tick,
				       replace) == 0)
	    return 0;
	}
      else if (fmt[i] == 'E')
	for (j = 0; j < XVECLEN (x, i); j++)
	  if (get_last_value_validate (&XVECEXP (x, i, j),
				       insn, tick, replace) == 0)
	    return 0;
    }

  /* If we haven't found a reason for it to be invalid, it is valid.  */
  return 1;
}

/* Get the last value assigned to X, if known.  Some registers
   in the value may be replaced with (clobber (const_int 0)) if their value
   is known longer known reliably.  */

static rtx
get_last_value (const_rtx x)
{
  unsigned int regno;
  rtx value;
  reg_stat_type *rsp;

  /* If this is a non-paradoxical SUBREG, get the value of its operand and
     then convert it to the desired mode.  If this is a paradoxical SUBREG,
     we cannot predict what values the "extra" bits might have.  */
  if (GET_CODE (x) == SUBREG
      && subreg_lowpart_p (x)
      && !paradoxical_subreg_p (x)
      && (value = get_last_value (SUBREG_REG (x))) != 0)
    return gen_lowpart (GET_MODE (x), value);

  if (!REG_P (x))
    return 0;

  regno = REGNO (x);
  rsp = &reg_stat[regno];
  value = rsp->last_set_value;

  /* If we don't have a value, or if it isn't for this basic block and
     it's either a hard register, set more than once, or it's a live
     at the beginning of the function, return 0.

     Because if it's not live at the beginning of the function then the reg
     is always set before being used (is never used without being set).
     And, if it's set only once, and it's always set before use, then all
     uses must have the same last value, even if it's not from this basic
     block.  */

  if (value == 0
      || (rsp->last_set_label < label_tick_ebb_start
	  && (regno < FIRST_PSEUDO_REGISTER
	      || regno >= reg_n_sets_max
	      || REG_N_SETS (regno) != 1
	      || REGNO_REG_SET_P
		 (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb), regno))))
    return 0;

  /* If the value was set in a later insn than the ones we are processing,
     we can't use it even if the register was only set once.  */
  if (rsp->last_set_label == label_tick
      && DF_INSN_LUID (rsp->last_set) >= subst_low_luid)
    return 0;

  /* If fewer bits were set than what we are asked for now, we cannot use
     the value.  */
  if (maybe_lt (GET_MODE_PRECISION (rsp->last_set_mode),
		GET_MODE_PRECISION (GET_MODE (x))))
    return 0;

  /* If the value has all its registers valid, return it.  */
  if (get_last_value_validate (&value, rsp->last_set, rsp->last_set_label, 0))
    return value;

  /* Otherwise, make a copy and replace any invalid register with
     (clobber (const_int 0)).  If that fails for some reason, return 0.  */

  value = copy_rtx (value);
  if (get_last_value_validate (&value, rsp->last_set, rsp->last_set_label, 1))
    return value;

  return 0;
}

/* Define three variables used for communication between the following
   routines.  */

static unsigned int reg_dead_regno, reg_dead_endregno;
static int reg_dead_flag;
rtx reg_dead_reg;

/* Function called via note_stores from reg_dead_at_p.

   If DEST is within [reg_dead_regno, reg_dead_endregno), set
   reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET.  */

static void
reg_dead_at_p_1 (rtx dest, const_rtx x, void *data ATTRIBUTE_UNUSED)
{
  unsigned int regno, endregno;

  if (!REG_P (dest))
    return;

  if (GET_CODE (x) == CLOBBER_HIGH
      && !reg_is_clobbered_by_clobber_high (reg_dead_reg, XEXP (x, 0)))
    return;

  regno = REGNO (dest);
  endregno = END_REGNO (dest);
  if (reg_dead_endregno > regno && reg_dead_regno < endregno)
    reg_dead_flag = (GET_CODE (x) == CLOBBER) ? 1 : -1;
}

/* Return nonzero if REG is known to be dead at INSN.

   We scan backwards from INSN.  If we hit a REG_DEAD note or a CLOBBER
   referencing REG, it is dead.  If we hit a SET referencing REG, it is
   live.  Otherwise, see if it is live or dead at the start of the basic
   block we are in.  Hard regs marked as being live in NEWPAT_USED_REGS
   must be assumed to be always live.  */

static int
reg_dead_at_p (rtx reg, rtx_insn *insn)
{
  basic_block block;
  unsigned int i;

  /* Set variables for reg_dead_at_p_1.  */
  reg_dead_regno = REGNO (reg);
  reg_dead_endregno = END_REGNO (reg);
  reg_dead_reg = reg;

  reg_dead_flag = 0;

  /* Check that reg isn't mentioned in NEWPAT_USED_REGS.  For fixed registers
     we allow the machine description to decide whether use-and-clobber
     patterns are OK.  */
  if (reg_dead_regno < FIRST_PSEUDO_REGISTER)
    {
      for (i = reg_dead_regno; i < reg_dead_endregno; i++)
	if (!fixed_regs[i] && TEST_HARD_REG_BIT (newpat_used_regs, i))
	  return 0;
    }

  /* Scan backwards until we find a REG_DEAD note, SET, CLOBBER, or
     beginning of basic block.  */
  block = BLOCK_FOR_INSN (insn);
  for (;;)
    {
      if (INSN_P (insn))
        {
	  if (find_regno_note (insn, REG_UNUSED, reg_dead_regno))
	    return 1;

	  note_stores (PATTERN (insn), reg_dead_at_p_1, NULL);
	  if (reg_dead_flag)
	    return reg_dead_flag == 1 ? 1 : 0;

	  if (find_regno_note (insn, REG_DEAD, reg_dead_regno))
	    return 1;
        }

      if (insn == BB_HEAD (block))
	break;

      insn = PREV_INSN (insn);
    }

  /* Look at live-in sets for the basic block that we were in.  */
  for (i = reg_dead_regno; i < reg_dead_endregno; i++)
    if (REGNO_REG_SET_P (df_get_live_in (block), i))
      return 0;

  return 1;
}

/* Note hard registers in X that are used.  */

static void
mark_used_regs_combine (rtx x)
{
  RTX_CODE code = GET_CODE (x);
  unsigned int regno;
  int i;

  switch (code)
    {
    case LABEL_REF:
    case SYMBOL_REF:
    case CONST:
    CASE_CONST_ANY:
    case PC:
    case ADDR_VEC:
    case ADDR_DIFF_VEC:
    case ASM_INPUT:
    /* CC0 must die in the insn after it is set, so we don't need to take
       special note of it here.  */
    case CC0:
      return;

    case CLOBBER:
      /* If we are clobbering a MEM, mark any hard registers inside the
	 address as used.  */
      if (MEM_P (XEXP (x, 0)))
	mark_used_regs_combine (XEXP (XEXP (x, 0), 0));
      return;

    case REG:
      regno = REGNO (x);
      /* A hard reg in a wide mode may really be multiple registers.
	 If so, mark all of them just like the first.  */
      if (regno < FIRST_PSEUDO_REGISTER)
	{
	  /* None of this applies to the stack, frame or arg pointers.  */
	  if (regno == STACK_POINTER_REGNUM
	      || (!HARD_FRAME_POINTER_IS_FRAME_POINTER
		  && regno == HARD_FRAME_POINTER_REGNUM)
	      || (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
		  && regno == ARG_POINTER_REGNUM && fixed_regs[regno])
	      || regno == FRAME_POINTER_REGNUM)
	    return;

	  add_to_hard_reg_set (&newpat_used_regs, GET_MODE (x), regno);
	}
      return;

    case SET:
      {
	/* If setting a MEM, or a SUBREG of a MEM, then note any hard regs in
	   the address.  */
	rtx testreg = SET_DEST (x);

	while (GET_CODE (testreg) == SUBREG
	       || GET_CODE (testreg) == ZERO_EXTRACT
	       || GET_CODE (testreg) == STRICT_LOW_PART)
	  testreg = XEXP (testreg, 0);

	if (MEM_P (testreg))
	  mark_used_regs_combine (XEXP (testreg, 0));

	mark_used_regs_combine (SET_SRC (x));
      }
      return;

    default:
      break;
    }

  /* Recursively scan the operands of this expression.  */

  {
    const char *fmt = GET_RTX_FORMAT (code);

    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
	if (fmt[i] == 'e')
	  mark_used_regs_combine (XEXP (x, i));
	else if (fmt[i] == 'E')
	  {
	    int j;

	    for (j = 0; j < XVECLEN (x, i); j++)
	      mark_used_regs_combine (XVECEXP (x, i, j));
	  }
      }
  }
}

/* Remove register number REGNO from the dead registers list of INSN.

   Return the note used to record the death, if there was one.  */

rtx
remove_death (unsigned int regno, rtx_insn *insn)
{
  rtx note = find_regno_note (insn, REG_DEAD, regno);

  if (note)
    remove_note (insn, note);

  return note;
}

/* For each register (hardware or pseudo) used within expression X, if its
   death is in an instruction with luid between FROM_LUID (inclusive) and
   TO_INSN (exclusive), put a REG_DEAD note for that register in the
   list headed by PNOTES.

   That said, don't move registers killed by maybe_kill_insn.

   This is done when X is being merged by combination into TO_INSN.  These
   notes will then be distributed as needed.  */

static void
move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn,
	     rtx *pnotes)
{
  const char *fmt;
  int len, i;
  enum rtx_code code = GET_CODE (x);

  if (code == REG)
    {
      unsigned int regno = REGNO (x);
      rtx_insn *where_dead = reg_stat[regno].last_death;

      /* If we do not know where the register died, it may still die between
	 FROM_LUID and TO_INSN.  If so, find it.  This is PR83304.  */
      if (!where_dead || DF_INSN_LUID (where_dead) >= DF_INSN_LUID (to_insn))
	{
	  rtx_insn *insn = prev_real_nondebug_insn (to_insn);
	  while (insn
		 && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (to_insn)
		 && DF_INSN_LUID (insn) >= from_luid)
	    {
	      if (dead_or_set_regno_p (insn, regno))
		{
		  if (find_regno_note (insn, REG_DEAD, regno))
		    where_dead = insn;
		  break;
		}

	      insn = prev_real_nondebug_insn (insn);
	    }
	}

      /* Don't move the register if it gets killed in between from and to.  */
      if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
	  && ! reg_referenced_p (x, maybe_kill_insn))
	return;

      if (where_dead
	  && BLOCK_FOR_INSN (where_dead) == BLOCK_FOR_INSN (to_insn)
	  && DF_INSN_LUID (where_dead) >= from_luid
	  && DF_INSN_LUID (where_dead) < DF_INSN_LUID (to_insn))
	{
	  rtx note = remove_death (regno, where_dead);

	  /* It is possible for the call above to return 0.  This can occur
	     when last_death points to I2 or I1 that we combined with.
	     In that case make a new note.

	     We must also check for the case where X is a hard register
	     and NOTE is a death note for a range of hard registers
	     including X.  In that case, we must put REG_DEAD notes for
	     the remaining registers in place of NOTE.  */

	  if (note != 0 && regno < FIRST_PSEUDO_REGISTER
	      && partial_subreg_p (GET_MODE (x), GET_MODE (XEXP (note, 0))))
	    {
	      unsigned int deadregno = REGNO (XEXP (note, 0));
	      unsigned int deadend = END_REGNO (XEXP (note, 0));
	      unsigned int ourend = END_REGNO (x);
	      unsigned int i;

	      for (i = deadregno; i < deadend; i++)
		if (i < regno || i >= ourend)
		  add_reg_note (where_dead, REG_DEAD, regno_reg_rtx[i]);
	    }

	  /* If we didn't find any note, or if we found a REG_DEAD note that
	     covers only part of the given reg, and we have a multi-reg hard
	     register, then to be safe we must check for REG_DEAD notes
	     for each register other than the first.  They could have
	     their own REG_DEAD notes lying around.  */
	  else if ((note == 0
		    || (note != 0
			&& partial_subreg_p (GET_MODE (XEXP (note, 0)),
					     GET_MODE (x))))
		   && regno < FIRST_PSEUDO_REGISTER
		   && REG_NREGS (x) > 1)
	    {
	      unsigned int ourend = END_REGNO (x);
	      unsigned int i, offset;
	      rtx oldnotes = 0;

	      if (note)
		offset = hard_regno_nregs (regno, GET_MODE (XEXP (note, 0)));
	      else
		offset = 1;

	      for (i = regno + offset; i < ourend; i++)
		move_deaths (regno_reg_rtx[i],
			     maybe_kill_insn, from_luid, to_insn, &oldnotes);
	    }

	  if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x))
	    {
	      XEXP (note, 1) = *pnotes;
	      *pnotes = note;
	    }
	  else
	    *pnotes = alloc_reg_note (REG_DEAD, x, *pnotes);
	}

      return;
    }

  else if (GET_CODE (x) == SET)
    {
      rtx dest = SET_DEST (x);

      move_deaths (SET_SRC (x), maybe_kill_insn, from_luid, to_insn, pnotes);

      /* In the case of a ZERO_EXTRACT, a STRICT_LOW_PART, or a SUBREG
	 that accesses one word of a multi-word item, some
	 piece of everything register in the expression is used by
	 this insn, so remove any old death.  */
      /* ??? So why do we test for equality of the sizes?  */

      if (GET_CODE (dest) == ZERO_EXTRACT
	  || GET_CODE (dest) == STRICT_LOW_PART
	  || (GET_CODE (dest) == SUBREG
	      && !read_modify_subreg_p (dest)))
	{
	  move_deaths (dest, maybe_kill_insn, from_luid, to_insn, pnotes);
	  return;
	}

      /* If this is some other SUBREG, we know it replaces the entire
	 value, so use that as the destination.  */
      if (GET_CODE (dest) == SUBREG)
	dest = SUBREG_REG (dest);

      /* If this is a MEM, adjust deaths of anything used in the address.
	 For a REG (the only other possibility), the entire value is
	 being replaced so the old value is not used in this insn.  */

      if (MEM_P (dest))
	move_deaths (XEXP (dest, 0), maybe_kill_insn, from_luid,
		     to_insn, pnotes);
      return;
    }

  else if (GET_CODE (x) == CLOBBER)
    return;

  len = GET_RTX_LENGTH (code);
  fmt = GET_RTX_FORMAT (code);

  for (i = 0; i < len; i++)
    {
      if (fmt[i] == 'E')
	{
	  int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    move_deaths (XVECEXP (x, i, j), maybe_kill_insn, from_luid,
			 to_insn, pnotes);
	}
      else if (fmt[i] == 'e')
	move_deaths (XEXP (x, i), maybe_kill_insn, from_luid, to_insn, pnotes);
    }
}

/* Return 1 if X is the target of a bit-field assignment in BODY, the
   pattern of an insn.  X must be a REG.  */

static int
reg_bitfield_target_p (rtx x, rtx body)
{
  int i;

  if (GET_CODE (body) == SET)
    {
      rtx dest = SET_DEST (body);
      rtx target;
      unsigned int regno, tregno, endregno, endtregno;

      if (GET_CODE (dest) == ZERO_EXTRACT)
	target = XEXP (dest, 0);
      else if (GET_CODE (dest) == STRICT_LOW_PART)
	target = SUBREG_REG (XEXP (dest, 0));
      else
	return 0;

      if (GET_CODE (target) == SUBREG)
	target = SUBREG_REG (target);

      if (!REG_P (target))
	return 0;

      tregno = REGNO (target), regno = REGNO (x);
      if (tregno >= FIRST_PSEUDO_REGISTER || regno >= FIRST_PSEUDO_REGISTER)
	return target == x;

      endtregno = end_hard_regno (GET_MODE (target), tregno);
      endregno = end_hard_regno (GET_MODE (x), regno);

      return endregno > tregno && regno < endtregno;
    }

  else if (GET_CODE (body) == PARALLEL)
    for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
      if (reg_bitfield_target_p (x, XVECEXP (body, 0, i)))
	return 1;

  return 0;
}

/* Given a chain of REG_NOTES originally from FROM_INSN, try to place them
   as appropriate.  I3 and I2 are the insns resulting from the combination
   insns including FROM (I2 may be zero).

   ELIM_I2 and ELIM_I1 are either zero or registers that we know will
   not need REG_DEAD notes because they are being substituted for.  This
   saves searching in the most common cases.

   Each note in the list is either ignored or placed on some insns, depending
   on the type of note.  */

static void
distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
		  rtx elim_i2, rtx elim_i1, rtx elim_i0)
{
  rtx note, next_note;
  rtx tem_note;
  rtx_insn *tem_insn;

  for (note = notes; note; note = next_note)
    {
      rtx_insn *place = 0, *place2 = 0;

      next_note = XEXP (note, 1);
      switch (REG_NOTE_KIND (note))
	{
	case REG_BR_PROB:
	case REG_BR_PRED:
	  /* Doesn't matter much where we put this, as long as it's somewhere.
	     It is preferable to keep these notes on branches, which is most
	     likely to be i3.  */
	  place = i3;
	  break;

	case REG_NON_LOCAL_GOTO:
	  if (JUMP_P (i3))
	    place = i3;
	  else
	    {
	      gcc_assert (i2 && JUMP_P (i2));
	      place = i2;
	    }
	  break;

	case REG_EH_REGION:
	  /* These notes must remain with the call or trapping instruction.  */
	  if (CALL_P (i3))
	    place = i3;
	  else if (i2 && CALL_P (i2))
	    place = i2;
	  else
	    {
	      gcc_assert (cfun->can_throw_non_call_exceptions);
	      if (may_trap_p (i3))
		place = i3;
	      else if (i2 && may_trap_p (i2))
		place = i2;
	      /* ??? Otherwise assume we've combined things such that we
		 can now prove that the instructions can't trap.  Drop the
		 note in this case.  */
	    }
	  break;

	case REG_ARGS_SIZE:
	  /* ??? How to distribute between i3-i1.  Assume i3 contains the
	     entire adjustment.  Assert i3 contains at least some adjust.  */
	  if (!noop_move_p (i3))
	    {
	      poly_int64 old_size, args_size = get_args_size (note);
	      /* fixup_args_size_notes looks at REG_NORETURN note,
		 so ensure the note is placed there first.  */
	      if (CALL_P (i3))
		{
		  rtx *np;
		  for (np = &next_note; *np; np = &XEXP (*np, 1))
		    if (REG_NOTE_KIND (*np) == REG_NORETURN)
		      {
			rtx n = *np;
			*np = XEXP (n, 1);
			XEXP (n, 1) = REG_NOTES (i3);
			REG_NOTES (i3) = n;
			break;
		      }
		}
	      old_size = fixup_args_size_notes (PREV_INSN (i3), i3, args_size);
	      /* emit_call_1 adds for !ACCUMULATE_OUTGOING_ARGS
		 REG_ARGS_SIZE note to all noreturn calls, allow that here.  */
	      gcc_assert (maybe_ne (old_size, args_size)
			  || (CALL_P (i3)
			      && !ACCUMULATE_OUTGOING_ARGS
			      && find_reg_note (i3, REG_NORETURN, NULL_RTX)));
	    }
	  break;

	case REG_NORETURN:
	case REG_SETJMP:
	case REG_TM:
	case REG_CALL_DECL:
	case REG_CALL_NOCF_CHECK:
	  /* These notes must remain with the call.  It should not be
	     possible for both I2 and I3 to be a call.  */
	  if (CALL_P (i3))
	    place = i3;
	  else
	    {
	      gcc_assert (i2 && CALL_P (i2));
	      place = i2;
	    }
	  break;

	case REG_UNUSED:
	  /* Any clobbers for i3 may still exist, and so we must process
	     REG_UNUSED notes from that insn.

	     Any clobbers from i2 or i1 can only exist if they were added by
	     recog_for_combine.  In that case, recog_for_combine created the
	     necessary REG_UNUSED notes.  Trying to keep any original
	     REG_UNUSED notes from these insns can cause incorrect output
	     if it is for the same register as the original i3 dest.
	     In that case, we will notice that the register is set in i3,
	     and then add a REG_UNUSED note for the destination of i3, which
	     is wrong.  However, it is possible to have REG_UNUSED notes from
	     i2 or i1 for register which were both used and clobbered, so
	     we keep notes from i2 or i1 if they will turn into REG_DEAD
	     notes.  */

	  /* If this register is set or clobbered between FROM_INSN and I3,
	     we should not create a note for it.  */
	  if (reg_set_between_p (XEXP (note, 0), from_insn, i3))
	    break;

	  /* If this register is set or clobbered in I3, put the note there
	     unless there is one already.  */
	  if (reg_set_p (XEXP (note, 0), PATTERN (i3)))
	    {
	      if (from_insn != i3)
		break;

	      if (! (REG_P (XEXP (note, 0))
		     ? find_regno_note (i3, REG_UNUSED, REGNO (XEXP (note, 0)))
		     : find_reg_note (i3, REG_UNUSED, XEXP (note, 0))))
		place = i3;
	    }
	  /* Otherwise, if this register is used by I3, then this register
	     now dies here, so we must put a REG_DEAD note here unless there
	     is one already.  */
	  else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))
		   && ! (REG_P (XEXP (note, 0))
			 ? find_regno_note (i3, REG_DEAD,
					    REGNO (XEXP (note, 0)))
			 : find_reg_note (i3, REG_DEAD, XEXP (note, 0))))
	    {
	      PUT_REG_NOTE_KIND (note, REG_DEAD);
	      place = i3;
	    }

	  /* A SET or CLOBBER of the REG_UNUSED reg has been removed,
	     but we can't tell which at this point.  We must reset any
	     expectations we had about the value that was previously
	     stored in the reg.  ??? Ideally, we'd adjust REG_N_SETS
	     and, if appropriate, restore its previous value, but we
	     don't have enough information for that at this point.  */
	  else
	    {
	      record_value_for_reg (XEXP (note, 0), NULL, NULL_RTX);

	      /* Otherwise, if this register is now referenced in i2
		 then the register used to be modified in one of the
		 original insns.  If it was i3 (say, in an unused
		 parallel), it's now completely gone, so the note can
		 be discarded.  But if it was modified in i2, i1 or i0
		 and we still reference it in i2, then we're
		 referencing the previous value, and since the
		 register was modified and REG_UNUSED, we know that
		 the previous value is now dead.  So, if we only
		 reference the register in i2, we change the note to
		 REG_DEAD, to reflect the previous value.  However, if
		 we're also setting or clobbering the register as
		 scratch, we know (because the register was not
		 referenced in i3) that it's unused, just as it was
		 unused before, and we place the note in i2.  */
	      if (from_insn != i3 && i2 && INSN_P (i2)
		  && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
		{
		  if (!reg_set_p (XEXP (note, 0), PATTERN (i2)))
		    PUT_REG_NOTE_KIND (note, REG_DEAD);
		  if (! (REG_P (XEXP (note, 0))
			 ? find_regno_note (i2, REG_NOTE_KIND (note),
					    REGNO (XEXP (note, 0)))
			 : find_reg_note (i2, REG_NOTE_KIND (note),
					  XEXP (note, 0))))
		    place = i2;
		}
	    }

	  break;

	case REG_EQUAL:
	case REG_EQUIV:
	case REG_NOALIAS:
	  /* These notes say something about results of an insn.  We can
	     only support them if they used to be on I3 in which case they
	     remain on I3.  Otherwise they are ignored.

	     If the note refers to an expression that is not a constant, we
	     must also ignore the note since we cannot tell whether the
	     equivalence is still true.  It might be possible to do
	     slightly better than this (we only have a problem if I2DEST
	     or I1DEST is present in the expression), but it doesn't
	     seem worth the trouble.  */

	  if (from_insn == i3
	      && (XEXP (note, 0) == 0 || CONSTANT_P (XEXP (note, 0))))
	    place = i3;
	  break;

	case REG_INC:
	  /* These notes say something about how a register is used.  They must
	     be present on any use of the register in I2 or I3.  */
	  if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)))
	    place = i3;

	  if (i2 && reg_mentioned_p (XEXP (note, 0), PATTERN (i2)))
	    {
	      if (place)
		place2 = i2;
	      else
		place = i2;
	    }
	  break;

	case REG_LABEL_TARGET:
	case REG_LABEL_OPERAND:
	  /* This can show up in several ways -- either directly in the
	     pattern, or hidden off in the constant pool with (or without?)
	     a REG_EQUAL note.  */
	  /* ??? Ignore the without-reg_equal-note problem for now.  */
	  if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))
	      || ((tem_note = find_reg_note (i3, REG_EQUAL, NULL_RTX))
		  && GET_CODE (XEXP (tem_note, 0)) == LABEL_REF
		  && label_ref_label (XEXP (tem_note, 0)) == XEXP (note, 0)))
	    place = i3;

	  if (i2
	      && (reg_mentioned_p (XEXP (note, 0), PATTERN (i2))
		  || ((tem_note = find_reg_note (i2, REG_EQUAL, NULL_RTX))
		      && GET_CODE (XEXP (tem_note, 0)) == LABEL_REF
		      && label_ref_label (XEXP (tem_note, 0)) == XEXP (note, 0))))
	    {
	      if (place)
		place2 = i2;
	      else
		place = i2;
	    }

	  /* For REG_LABEL_TARGET on a JUMP_P, we prefer to put the note
	     as a JUMP_LABEL or decrement LABEL_NUSES if it's already
	     there.  */
	  if (place && JUMP_P (place)
	      && REG_NOTE_KIND (note) == REG_LABEL_TARGET
	      && (JUMP_LABEL (place) == NULL
		  || JUMP_LABEL (place) == XEXP (note, 0)))
	    {
	      rtx label = JUMP_LABEL (place);

	      if (!label)
		JUMP_LABEL (place) = XEXP (note, 0);
	      else if (LABEL_P (label))
		LABEL_NUSES (label)--;
	    }

	  if (place2 && JUMP_P (place2)
	      && REG_NOTE_KIND (note) == REG_LABEL_TARGET
	      && (JUMP_LABEL (place2) == NULL
		  || JUMP_LABEL (place2) == XEXP (note, 0)))
	    {
	      rtx label = JUMP_LABEL (place2);

	      if (!label)
		JUMP_LABEL (place2) = XEXP (note, 0);
	      else if (LABEL_P (label))
		LABEL_NUSES (label)--;
	      place2 = 0;
	    }
	  break;

	case REG_NONNEG:
	  /* This note says something about the value of a register prior
	     to the execution of an insn.  It is too much trouble to see
	     if the note is still correct in all situations.  It is better
	     to simply delete it.  */
	  break;

	case REG_DEAD:
	  /* If we replaced the right hand side of FROM_INSN with a
	     REG_EQUAL note, the original use of the dying register
	     will not have been combined into I3 and I2.  In such cases,
	     FROM_INSN is guaranteed to be the first of the combined
	     instructions, so we simply need to search back before
	     FROM_INSN for the previous use or set of this register,
	     then alter the notes there appropriately.

	     If the register is used as an input in I3, it dies there.
	     Similarly for I2, if it is nonzero and adjacent to I3.

	     If the register is not used as an input in either I3 or I2
	     and it is not one of the registers we were supposed to eliminate,
	     there are two possibilities.  We might have a non-adjacent I2
	     or we might have somehow eliminated an additional register
	     from a computation.  For example, we might have had A & B where
	     we discover that B will always be zero.  In this case we will
	     eliminate the reference to A.

	     In both cases, we must search to see if we can find a previous
	     use of A and put the death note there.  */

	  if (from_insn
	      && from_insn == i2mod
	      && !reg_overlap_mentioned_p (XEXP (note, 0), i2mod_new_rhs))
	    tem_insn = from_insn;
	  else
	    {
	      if (from_insn
		  && CALL_P (from_insn)
		  && find_reg_fusage (from_insn, USE, XEXP (note, 0)))
		place = from_insn;
	      else if (i2 && reg_set_p (XEXP (note, 0), PATTERN (i2)))
		{
		  /* If the new I2 sets the same register that is marked
		     dead in the note, we do not in general know where to
		     put the note.  One important case we _can_ handle is
		     when the note comes from I3.  */
		  if (from_insn == i3)
		    place = i3;
		  else
		    break;
		}
	      else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3)))
		place = i3;
	      else if (i2 != 0 && next_nonnote_nondebug_insn (i2) == i3
		       && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
		place = i2;
	      else if ((rtx_equal_p (XEXP (note, 0), elim_i2)
			&& !(i2mod
			     && reg_overlap_mentioned_p (XEXP (note, 0),
							 i2mod_old_rhs)))
		       || rtx_equal_p (XEXP (note, 0), elim_i1)
		       || rtx_equal_p (XEXP (note, 0), elim_i0))
		break;
	      tem_insn = i3;
	    }

	  if (place == 0)
	    {
	      basic_block bb = this_basic_block;

	      for (tem_insn = PREV_INSN (tem_insn); place == 0; tem_insn = PREV_INSN (tem_insn))
		{
		  if (!NONDEBUG_INSN_P (tem_insn))
		    {
		      if (tem_insn == BB_HEAD (bb))
			break;
		      continue;
		    }

		  /* If the register is being set at TEM_INSN, see if that is all
		     TEM_INSN is doing.  If so, delete TEM_INSN.  Otherwise, make this
		     into a REG_UNUSED note instead. Don't delete sets to
		     global register vars.  */
		  if ((REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER
		       || !global_regs[REGNO (XEXP (note, 0))])
		      && reg_set_p (XEXP (note, 0), PATTERN (tem_insn)))
		    {
		      rtx set = single_set (tem_insn);
		      rtx inner_dest = 0;
		      rtx_insn *cc0_setter = NULL;

		      if (set != 0)
			for (inner_dest = SET_DEST (set);
			     (GET_CODE (inner_dest) == STRICT_LOW_PART
			      || GET_CODE (inner_dest) == SUBREG
			      || GET_CODE (inner_dest) == ZERO_EXTRACT);
			     inner_dest = XEXP (inner_dest, 0))
			  ;

		      /* Verify that it was the set, and not a clobber that
			 modified the register.

			 CC0 targets must be careful to maintain setter/user
			 pairs.  If we cannot delete the setter due to side
			 effects, mark the user with an UNUSED note instead
			 of deleting it.  */

		      if (set != 0 && ! side_effects_p (SET_SRC (set))
			  && rtx_equal_p (XEXP (note, 0), inner_dest)
			  && (!HAVE_cc0
			      || (! reg_mentioned_p (cc0_rtx, SET_SRC (set))
				  || ((cc0_setter = prev_cc0_setter (tem_insn)) != NULL
				      && sets_cc0_p (PATTERN (cc0_setter)) > 0))))
			{
			  /* Move the notes and links of TEM_INSN elsewhere.
			     This might delete other dead insns recursively.
			     First set the pattern to something that won't use
			     any register.  */
			  rtx old_notes = REG_NOTES (tem_insn);

			  PATTERN (tem_insn) = pc_rtx;
			  REG_NOTES (tem_insn) = NULL;

			  distribute_notes (old_notes, tem_insn, tem_insn, NULL,
					    NULL_RTX, NULL_RTX, NULL_RTX);
			  distribute_links (LOG_LINKS (tem_insn));

			  unsigned int regno = REGNO (XEXP (note, 0));
			  reg_stat_type *rsp = &reg_stat[regno];
			  if (rsp->last_set == tem_insn)
			    record_value_for_reg (XEXP (note, 0), NULL, NULL_RTX);

			  SET_INSN_DELETED (tem_insn);
			  if (tem_insn == i2)
			    i2 = NULL;

			  /* Delete the setter too.  */
			  if (cc0_setter)
			    {
			      PATTERN (cc0_setter) = pc_rtx;
			      old_notes = REG_NOTES (cc0_setter);
			      REG_NOTES (cc0_setter) = NULL;

			      distribute_notes (old_notes, cc0_setter,
						cc0_setter, NULL,
						NULL_RTX, NULL_RTX, NULL_RTX);
			      distribute_links (LOG_LINKS (cc0_setter));

			      SET_INSN_DELETED (cc0_setter);
			      if (cc0_setter == i2)
				i2 = NULL;
			    }
			}
		      else
			{
			  PUT_REG_NOTE_KIND (note, REG_UNUSED);

			  /*  If there isn't already a REG_UNUSED note, put one
			      here.  Do not place a REG_DEAD note, even if
			      the register is also used here; that would not
			      match the algorithm used in lifetime analysis
			      and can cause the consistency check in the
			      scheduler to fail.  */
			  if (! find_regno_note (tem_insn, REG_UNUSED,
						 REGNO (XEXP (note, 0))))
			    place = tem_insn;
			  break;
			}
		    }
		  else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem_insn))
			   || (CALL_P (tem_insn)
			       && find_reg_fusage (tem_insn, USE, XEXP (note, 0))))
		    {
		      place = tem_insn;

		      /* If we are doing a 3->2 combination, and we have a
			 register which formerly died in i3 and was not used
			 by i2, which now no longer dies in i3 and is used in
			 i2 but does not die in i2, and place is between i2
			 and i3, then we may need to move a link from place to
			 i2.  */
		      if (i2 && DF_INSN_LUID (place) > DF_INSN_LUID (i2)
			  && from_insn
			  && DF_INSN_LUID (from_insn) > DF_INSN_LUID (i2)
			  && reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
			{
			  struct insn_link *links = LOG_LINKS (place);
			  LOG_LINKS (place) = NULL;
			  distribute_links (links);
			}
		      break;
		    }

		  if (tem_insn == BB_HEAD (bb))
		    break;
		}

	    }

	  /* If the register is set or already dead at PLACE, we needn't do
	     anything with this note if it is still a REG_DEAD note.
	     We check here if it is set at all, not if is it totally replaced,
	     which is what `dead_or_set_p' checks, so also check for it being
	     set partially.  */

	  if (place && REG_NOTE_KIND (note) == REG_DEAD)
	    {
	      unsigned int regno = REGNO (XEXP (note, 0));
	      reg_stat_type *rsp = &reg_stat[regno];

	      if (dead_or_set_p (place, XEXP (note, 0))
		  || reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
		{
		  /* Unless the register previously died in PLACE, clear
		     last_death.  [I no longer understand why this is
		     being done.] */
		  if (rsp->last_death != place)
		    rsp->last_death = 0;
		  place = 0;
		}
	      else
		rsp->last_death = place;

	      /* If this is a death note for a hard reg that is occupying
		 multiple registers, ensure that we are still using all
		 parts of the object.  If we find a piece of the object
		 that is unused, we must arrange for an appropriate REG_DEAD
		 note to be added for it.  However, we can't just emit a USE
		 and tag the note to it, since the register might actually
		 be dead; so we recourse, and the recursive call then finds
		 the previous insn that used this register.  */

	      if (place && REG_NREGS (XEXP (note, 0)) > 1)
		{
		  unsigned int endregno = END_REGNO (XEXP (note, 0));
		  bool all_used = true;
		  unsigned int i;

		  for (i = regno; i < endregno; i++)
		    if ((! refers_to_regno_p (i, PATTERN (place))
			 && ! find_regno_fusage (place, USE, i))
			|| dead_or_set_regno_p (place, i))
		      {
			all_used = false;
			break;
		      }

		  if (! all_used)
		    {
		      /* Put only REG_DEAD notes for pieces that are
			 not already dead or set.  */

		      for (i = regno; i < endregno;
			   i += hard_regno_nregs (i, reg_raw_mode[i]))
			{
			  rtx piece = regno_reg_rtx[i];
			  basic_block bb = this_basic_block;

			  if (! dead_or_set_p (place, piece)
			      && ! reg_bitfield_target_p (piece,
							  PATTERN (place)))
			    {
			      rtx new_note = alloc_reg_note (REG_DEAD, piece,
							     NULL_RTX);

			      distribute_notes (new_note, place, place,
						NULL, NULL_RTX, NULL_RTX,
						NULL_RTX);
			    }
			  else if (! refers_to_regno_p (i, PATTERN (place))
				   && ! find_regno_fusage (place, USE, i))
			    for (tem_insn = PREV_INSN (place); ;
				 tem_insn = PREV_INSN (tem_insn))
			      {
				if (!NONDEBUG_INSN_P (tem_insn))
				  {
				    if (tem_insn == BB_HEAD (bb))
			 	      break;
				    continue;
				  }
				if (dead_or_set_p (tem_insn, piece)
				    || reg_bitfield_target_p (piece,
							      PATTERN (tem_insn)))
				  {
				    add_reg_note (tem_insn, REG_UNUSED, piece);
				    break;
				  }
			      }
			}

		      place = 0;
		    }
		}
	    }
	  break;

	default:
	  /* Any other notes should not be present at this point in the
	     compilation.  */
	  gcc_unreachable ();
	}

      if (place)
	{
	  XEXP (note, 1) = REG_NOTES (place);
	  REG_NOTES (place) = note;

	  /* Set added_notes_insn to the earliest insn we added a note to.  */
	  if (added_notes_insn == 0
	      || DF_INSN_LUID (added_notes_insn) > DF_INSN_LUID (place))
	    added_notes_insn = place;
	}

      if (place2)
	{
	  add_shallow_copy_of_reg_note (place2, note);

	  /* Set added_notes_insn to the earliest insn we added a note to.  */
	  if (added_notes_insn == 0
	      || DF_INSN_LUID (added_notes_insn) > DF_INSN_LUID (place2))
	    added_notes_insn = place2;
	}
    }
}

/* Similarly to above, distribute the LOG_LINKS that used to be present on
   I3, I2, and I1 to new locations.  This is also called to add a link
   pointing at I3 when I3's destination is changed.  */

static void
distribute_links (struct insn_link *links)
{
  struct insn_link *link, *next_link;

  for (link = links; link; link = next_link)
    {
      rtx_insn *place = 0;
      rtx_insn *insn;
      rtx set, reg;

      next_link = link->next;

      /* If the insn that this link points to is a NOTE, ignore it.  */
      if (NOTE_P (link->insn))
	continue;

      set = 0;
      rtx pat = PATTERN (link->insn);
      if (GET_CODE (pat) == SET)
	set = pat;
      else if (GET_CODE (pat) == PARALLEL)
	{
	  int i;
	  for (i = 0; i < XVECLEN (pat, 0); i++)
	    {
	      set = XVECEXP (pat, 0, i);
	      if (GET_CODE (set) != SET)
		continue;

	      reg = SET_DEST (set);
	      while (GET_CODE (reg) == ZERO_EXTRACT
		     || GET_CODE (reg) == STRICT_LOW_PART
		     || GET_CODE (reg) == SUBREG)
		reg = XEXP (reg, 0);

	      if (!REG_P (reg))
		continue;

	      if (REGNO (reg) == link->regno)
		break;
	    }
	  if (i == XVECLEN (pat, 0))
	    continue;
	}
      else
	continue;

      reg = SET_DEST (set);

      while (GET_CODE (reg) == ZERO_EXTRACT
	     || GET_CODE (reg) == STRICT_LOW_PART
	     || GET_CODE (reg) == SUBREG)
	reg = XEXP (reg, 0);

      if (reg == pc_rtx)
	continue;

      /* A LOG_LINK is defined as being placed on the first insn that uses
	 a register and points to the insn that sets the register.  Start
	 searching at the next insn after the target of the link and stop
	 when we reach a set of the register or the end of the basic block.

	 Note that this correctly handles the link that used to point from
	 I3 to I2.  Also note that not much searching is typically done here
	 since most links don't point very far away.  */

      for (insn = NEXT_INSN (link->insn);
	   (insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
		     || BB_HEAD (this_basic_block->next_bb) != insn));
	   insn = NEXT_INSN (insn))
	if (DEBUG_INSN_P (insn))
	  continue;
	else if (INSN_P (insn) && reg_overlap_mentioned_p (reg, PATTERN (insn)))
	  {
	    if (reg_referenced_p (reg, PATTERN (insn)))
	      place = insn;
	    break;
	  }
	else if (CALL_P (insn)
		 && find_reg_fusage (insn, USE, reg))
	  {
	    place = insn;
	    break;
	  }
	else if (INSN_P (insn) && reg_set_p (reg, insn))
	  break;

      /* If we found a place to put the link, place it there unless there
	 is already a link to the same insn as LINK at that point.  */

      if (place)
	{
	  struct insn_link *link2;

	  FOR_EACH_LOG_LINK (link2, place)
	    if (link2->insn == link->insn && link2->regno == link->regno)
	      break;

	  if (link2 == NULL)
	    {
	      link->next = LOG_LINKS (place);
	      LOG_LINKS (place) = link;

	      /* Set added_links_insn to the earliest insn we added a
		 link to.  */
	      if (added_links_insn == 0
		  || DF_INSN_LUID (added_links_insn) > DF_INSN_LUID (place))
		added_links_insn = place;
	    }
	}
    }
}

/* Check for any register or memory mentioned in EQUIV that is not
   mentioned in EXPR.  This is used to restrict EQUIV to "specializations"
   of EXPR where some registers may have been replaced by constants.  */

static bool
unmentioned_reg_p (rtx equiv, rtx expr)
{
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, equiv, NONCONST)
    {
      const_rtx x = *iter;
      if ((REG_P (x) || MEM_P (x))
	  && !reg_mentioned_p (x, expr))
	return true;
    }
  return false;
}

DEBUG_FUNCTION void
dump_combine_stats (FILE *file)
{
  fprintf
    (file,
     ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n",
     combine_attempts, combine_merges, combine_extras, combine_successes);
}

void
dump_combine_total_stats (FILE *file)
{
  fprintf
    (file,
     "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
     total_attempts, total_merges, total_extras, total_successes);
}

/* Make pseudo-to-pseudo copies after every hard-reg-to-pseudo-copy, because
   the reg-to-reg copy can usefully combine with later instructions, but we
   do not want to combine the hard reg into later instructions, for that
   restricts register allocation.  */
static void
make_more_copies (void)
{
  basic_block bb;

  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;

      FOR_BB_INSNS (bb, insn)
        {
          if (!NONDEBUG_INSN_P (insn))
            continue;

	  rtx set = single_set (insn);
	  if (!set)
	    continue;

	  rtx dest = SET_DEST (set);
	  if (!(REG_P (dest) && !HARD_REGISTER_P (dest)))
	      continue;

	  rtx src = SET_SRC (set);
	  if (!(REG_P (src) && HARD_REGISTER_P (src)))
	    continue;
	  if (TEST_HARD_REG_BIT (fixed_reg_set, REGNO (src)))
	    continue;

	  rtx new_reg = gen_reg_rtx (GET_MODE (dest));
	  rtx_insn *new_insn = gen_move_insn (new_reg, src);
	  SET_SRC (set) = new_reg;
	  emit_insn_before (new_insn, insn);
	  df_insn_rescan (insn);
	}
    }
}

/* Try combining insns through substitution.  */
static unsigned int
rest_of_handle_combine (void)
{
  make_more_copies ();

  df_set_flags (DF_LR_RUN_DCE + DF_DEFER_INSN_RESCAN);
  df_note_add_problem ();
  df_analyze ();

  regstat_init_n_sets_and_refs ();
  reg_n_sets_max = max_reg_num ();

  int rebuild_jump_labels_after_combine
    = combine_instructions (get_insns (), max_reg_num ());

  /* Combining insns may have turned an indirect jump into a
     direct jump.  Rebuild the JUMP_LABEL fields of jumping
     instructions.  */
  if (rebuild_jump_labels_after_combine)
    {
      if (dom_info_available_p (CDI_DOMINATORS))
	free_dominance_info (CDI_DOMINATORS);
      timevar_push (TV_JUMP);
      rebuild_jump_labels (get_insns ());
      cleanup_cfg (0);
      timevar_pop (TV_JUMP);
    }

  regstat_free_n_sets_and_refs ();
  return 0;
}

namespace {

const pass_data pass_data_combine =
{
  RTL_PASS, /* type */
  "combine", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_COMBINE, /* tv_id */
  PROP_cfglayout, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_df_finish, /* todo_flags_finish */
};

class pass_combine : public rtl_opt_pass
{
public:
  pass_combine (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_combine, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *) { return (optimize > 0); }
  virtual unsigned int execute (function *)
    {
      return rest_of_handle_combine ();
    }

}; // class pass_combine

} // anon namespace

rtl_opt_pass *
make_pass_combine (gcc::context *ctxt)
{
  return new pass_combine (ctxt);
}
