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

   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.  */

#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 "tree-pass.h"
#include "valtrack.h"
#include "rtl-iter.h"
#include "print-rtl.h"
#include "function-abi.h"
#include "rtlanal.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, true);
  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 a REG.
   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:
      return 0;

    case SET:
      /* If the destination is anything other than 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)) != 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.

   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 (!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.  */

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;
  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;
  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, true);

  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 (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.  */
	    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_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 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_node (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.cc.  */
      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;
	}

      /* 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 or a SUBREG,
     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:
	      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 be a REG.  */
  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
    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 using LRA; if it were one
     and the incremented register were spilled, we would lose.
     Reload handles this correctly.  */

  if (AUTO_INC_DEC)
    for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
      if (REG_NOTE_KIND (link) == REG_INC
	  && ((JUMP_P (i3) && targetm.lra_p ())
	      || 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;

  /* 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 (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, true);

  /* 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
	 && !paradoxical_subreg_p (x)
	 && SUBREG_REG (x) == reg
	 && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT;
}

/* 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;
      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_insn *x)
{
  rtx set = single_set (x);
  if (!set)
    return false;

  return general_operand (SET_SRC (set), 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;
  bool has_non_call_exception = false;

  /* 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)
	      && 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 (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 (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;
    }

  /* With non-call exceptions we can end up trying to combine multiple
     insns with possible EH side effects.  Make sure we can combine
     that to a single insn which means there must be at most one insn
     in the combination with an EH side effect.  */
  if (cfun->can_throw_non_call_exceptions)
    {
      if (find_reg_note (i3, REG_EH_REGION, NULL_RTX)
	  || find_reg_note (i2, REG_EH_REGION, NULL_RTX)
	  || (i1 && find_reg_note (i1, REG_EH_REGION, NULL_RTX))
	  || (i0 && find_reg_note (i0, REG_EH_REGION, NULL_RTX)))
	{
	  has_non_call_exception = true;
	  if (insn_could_throw_p (i3)
	      + insn_could_throw_p (i2)
	      + (i1 ? insn_could_throw_p (i1) : 0)
	      + (i0 ? insn_could_throw_p (i0) : 0) > 1)
	    {
	      if (dump_file && (dump_flags & TDF_DETAILS))
		fprintf (dump_file, "Can't combine multiple insns with EH "
			 "side-effects\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 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 (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
	  /* 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)
	  /* We should not split a possibly trapping part when we
	     care about non-call EH and have REG_EH_REGION notes
	     to distribute.  */
	  && ! (cfun->can_throw_non_call_exceptions
		&& has_non_call_exception
		&& may_trap_p (*split)))
	{
	  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.  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
	 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)
	  /* 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)
	       /* 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);

	  /* Likewise, recog_for_combine might have added clobbers to NEWPAT.
	     Checking that the SET0's SET_DEST and SET1's SET_DEST aren't
	     mentioned/clobbered, ensures NEWI2PAT's SET_DEST is live.  */
	  if (insn_code_number >= 0 && GET_CODE (newpat) == PARALLEL)
	    {
	      for (i = XVECLEN (newpat, 0) - 1; i >= 0; i--)
		if (GET_CODE (XVECEXP (newpat, 0, i)) == CLOBBER)
		  {
		    rtx reg = XEXP (XVECEXP (newpat, 0, i), 0);
		    if (reg_overlap_mentioned_p (reg, SET_DEST (set0))
			|| reg_overlap_mentioned_p (reg, SET_DEST (set1)))
		      {
			undo_all ();
			return 0;
		      }
		  }
	    }

	  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;
	}
    }

  /* 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);

      if (REG_P (SET_DEST (x))
	  || (GET_CODE (SET_DEST (x)) == SUBREG
	      && REG_P (SUBREG_REG (SET_DEST (x)))))
	{
	  unsigned int regno = reg_or_subregno (SET_DEST (x));

	  bool done = false;
	  for (rtx_insn *insn = NEXT_INSN (i3);
	       !done
	       && insn
	       && INSN_P (insn)
	       && BLOCK_FOR_INSN (insn) == this_basic_block;
	       insn = NEXT_INSN (insn))
	    {
	      if (DEBUG_INSN_P (insn))
		continue;
	      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_pattern_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
    note_pattern_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:
      /* 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) != 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 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)) == 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 an exception 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.  */

		  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))))))
		    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) == SIGN_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);

	      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.cc, 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)
	  && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (XEXP (x, 0))))
	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)
	{
	  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;
    case VEC_SELECT:
      {
	rtx trueop0 = XEXP (x, 0);
	mode = GET_MODE (trueop0);
	rtx trueop1 = XEXP (x, 1);
	/* If we select a low-part subreg, return that.  */
	if (vec_series_lowpart_p (GET_MODE (x), mode, trueop1))
	  {
	    rtx new_rtx = lowpart_subreg (GET_MODE (x), trueop0, mode);
	    if (new_rtx != NULL_RTX)
	      return new_rtx;
	  }
      }

    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))))
    {
      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
	   && !HONOR_NANS (mode)
	   && !HONOR_SIGNED_ZEROS (mode)))
      && 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 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)
      && (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 (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 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) == MULT
	   && CONST_INT_P (XEXP (inner, 1))
	   && pos_rtx == 0 && pos == 0)
    {
      /* We're extracting the least significant bits of an rtx
	 (mult X (const_int 2^C)), where LEN > C.  Extract the
	 least significant (LEN - C) bits of X, giving an rtx
	 whose mode is MODE, then multiply it by 2^C.  */
      const HOST_WIDE_INT shift_amt = exact_log2 (INTVAL (XEXP (inner, 1)));
      if (IN_RANGE (shift_amt, 1, len - 1))
	{
	  new_rtx = make_extraction (mode, XEXP (inner, 0),
				     0, 0, len - shift_amt,
				     unsignedp, in_dest, in_compare);
	  if (new_rtx)
	    return gen_rtx_MULT (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.  */
  class 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)
    {
      /* For an unrecognized single set of a constant, try placing it in
	 the constant pool, if this function already uses one.  */
      rtx src = SET_SRC (pat);
      if (CONSTANT_P (src)
	  && !CONST_INT_P (src)
	  && crtl->uses_const_pool)
	{
	  machine_mode mode = GET_MODE (src);
	  if (mode == VOIDmode)
	    mode = GET_MODE (SET_DEST (pat));
	  src = force_const_mem (mode, src);
	  if (src)
	    {
	      SUBST (SET_SRC (pat), src);
	      changed = true;
	    }
	}
      else
	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)
	   && SCALAR_INT_MODE_P (imode)
	   && SCALAR_INT_MODE_P (omode))
    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
	      || 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.cc  */

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) > param_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
	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 callee_clobbers
	= insn_callee_abi (insn).full_and_partial_reg_clobbers ();
      hard_reg_set_iterator hrsi;
      EXECUTE_IF_SET_IN_HARD_REG_SET (callee_clobbers, 0, i, hrsi)
	{
	  reg_stat_type *rsp;

	  /* ??? We could try to preserve some information from the last
	     set of register I if the call doesn't actually clobber
	     (reg:last_set_mode I), which might be true for ABIs with
	     partial clobbers.  However, it would be difficult to
	     update last_set_nonzero_bits and last_sign_bit_copies
	     to account for the part of I that actually was clobbered.
	     It wouldn't help much anyway, since we rarely see this
	     situation before RA.  */
	  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 (insn, record_dead_and_set_regs_1, NULL_RTX);
    }
  else
    note_stores (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;

  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 (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:
      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:
	  {
	    /* The landing pad handling needs to be kept in sync with the
	       prerequisite checking in try_combine.  */
	    int lp_nr = INTVAL (XEXP (note, 0));
	    /* A REG_EH_REGION note transfering control can only ever come
	       from i3.  */
	    if (lp_nr > 0)
	      gcc_assert (from_insn == i3);
	    /* We are making sure there is a single effective REG_EH_REGION
	       note and it's valid to put it on i3.  */
	    if (!insn_could_throw_p (from_insn)
		&& !(lp_nr == INT_MIN && can_nonlocal_goto (from_insn)))
	      /* Throw away stray notes on insns that can never throw or
		 make a nonlocal goto.  */
	      ;
	    else
	      {
		if (CALL_P (i3))
		  place = i3;
		else
		  {
		    gcc_assert (cfun->can_throw_non_call_exceptions);
		    /* If i3 can still trap preserve the note, otherwise we've
		       combined things such that we can now prove that the
		       instructions can't trap.  Drop the note in this case.  */
		    if (may_trap_p (i3))
		      place = i3;
		  }
	      }
	    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_UNTYPED_CALL:
	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;

		      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.

			 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))
			{
			  /* 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;
			}
		      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: */
  bool gate (function *) final override { return (optimize > 0); }
  unsigned int execute (function *) final override
    {
      return rest_of_handle_combine ();
    }

}; // class pass_combine

} // anon namespace

rtl_opt_pass *
make_pass_combine (gcc::context *ctxt)
{
  return new pass_combine (ctxt);
}
