/* Fold a constant sub-tree into a single node for C-compiler
   Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
   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 2, 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 COPYING.  If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.  */

/*@@ This file should be rewritten to use an arbitrary precision
  @@ representation for "struct tree_int_cst" and "struct tree_real_cst".
  @@ Perhaps the routines could also be used for bc/dc, and made a lib.
  @@ The routines that translate from the ap rep should
  @@ warn if precision et. al. is lost.
  @@ This would also make life easier when this technology is used
  @@ for cross-compilers.  */

/* The entry points in this file are fold, size_int_wide, size_binop
   and force_fit_type.

   fold takes a tree as argument and returns a simplified tree.

   size_binop takes a tree code for an arithmetic operation
   and two operands that are trees, and produces a tree for the
   result, assuming the type comes from `sizetype'.

   size_int takes an integer value, and creates a tree constant
   with type from `sizetype'.

   force_fit_type takes a constant, an overflowable flag and prior
   overflow indicators.  It forces the value to fit the type and sets
   TREE_OVERFLOW and TREE_CONSTANT_OVERFLOW as appropriate.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "flags.h"
#include "tree.h"
#include "real.h"
#include "rtl.h"
#include "expr.h"
#include "tm_p.h"
#include "toplev.h"
#include "intl.h"
#include "ggc.h"
#include "hashtab.h"
#include "langhooks.h"
#include "md5.h"

/* Non-zero if we are folding constants inside an initializer; zero
   otherwise.  */
int folding_initializer = 0;

/* The following constants represent a bit based encoding of GCC's
   comparison operators.  This encoding simplifies transformations
   on relational comparison operators, such as AND and OR.  */
enum comparison_code {
  COMPCODE_FALSE = 0,
  COMPCODE_LT = 1,
  COMPCODE_EQ = 2,
  COMPCODE_LE = 3,
  COMPCODE_GT = 4,
  COMPCODE_LTGT = 5,
  COMPCODE_GE = 6,
  COMPCODE_ORD = 7,
  COMPCODE_UNORD = 8,
  COMPCODE_UNLT = 9,
  COMPCODE_UNEQ = 10,
  COMPCODE_UNLE = 11,
  COMPCODE_UNGT = 12,
  COMPCODE_NE = 13,
  COMPCODE_UNGE = 14,
  COMPCODE_TRUE = 15
};

static void encode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT, HOST_WIDE_INT);
static void decode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
static bool negate_mathfn_p (enum built_in_function);
static bool negate_expr_p (tree);
static tree negate_expr (tree);
static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
static tree associate_trees (tree, tree, enum tree_code, tree);
static tree const_binop (enum tree_code, tree, tree, int);
static enum comparison_code comparison_to_compcode (enum tree_code);
static enum tree_code compcode_to_comparison (enum comparison_code);
static tree combine_comparisons (enum tree_code, enum tree_code,
				 enum tree_code, tree, tree, tree);
static int truth_value_p (enum tree_code);
static int operand_equal_for_comparison_p (tree, tree, tree);
static int twoval_comparison_p (tree, tree *, tree *, int *);
static tree eval_subst (tree, tree, tree, tree, tree);
static tree pedantic_omit_one_operand (tree, tree, tree);
static tree distribute_bit_expr (enum tree_code, tree, tree, tree);
static tree make_bit_field_ref (tree, tree, int, int, int);
static tree optimize_bit_field_compare (enum tree_code, tree, tree, tree);
static tree decode_field_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
				    enum machine_mode *, int *, int *,
				    tree *, tree *);
static int all_ones_mask_p (tree, int);
static tree sign_bit_p (tree, tree);
static int simple_operand_p (tree);
static tree range_binop (enum tree_code, tree, tree, int, tree, int);
static tree range_predecessor (tree);
static tree range_successor (tree);
static tree make_range (tree, int *, tree *, tree *, bool *);
static tree build_range_check (tree, tree, int, tree, tree);
static int merge_ranges (int *, tree *, tree *, int, tree, tree, int, tree,
			 tree);
static tree fold_range_test (enum tree_code, tree, tree, tree);
static tree fold_cond_expr_with_comparison (tree, tree, tree, tree);
static tree unextend (tree, int, int, tree);
static tree fold_truthop (enum tree_code, tree, tree, tree);
static tree optimize_minmax_comparison (enum tree_code, tree, tree, tree);
static tree extract_muldiv (tree, tree, enum tree_code, tree, bool *);
static tree extract_muldiv_1 (tree, tree, enum tree_code, tree, bool *);
static int multiple_of_p (tree, tree, tree);
static tree fold_binary_op_with_conditional_arg (enum tree_code, tree,
						 tree, tree,
						 tree, tree, int);
static bool fold_real_zero_addition_p (tree, tree, int);
static tree fold_mathfn_compare (enum built_in_function, enum tree_code,
				 tree, tree, tree);
static tree fold_inf_compare (enum tree_code, tree, tree, tree);
static tree fold_div_compare (enum tree_code, tree, tree, tree);
static bool reorder_operands_p (tree, tree);
static tree fold_negate_const (tree, tree);
static tree fold_not_const (tree, tree);
static tree fold_relational_const (enum tree_code, tree, tree, tree);
static int native_encode_expr (tree, unsigned char *, int);
static tree native_interpret_expr (tree, unsigned char *, int);


/* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
   overflow.  Suppose A, B and SUM have the same respective signs as A1, B1,
   and SUM1.  Then this yields nonzero if overflow occurred during the
   addition.

   Overflow occurs if A and B have the same sign, but A and SUM differ in
   sign.  Use `^' to test whether signs differ, and `< 0' to isolate the
   sign.  */
#define OVERFLOW_SUM_SIGN(a, b, sum) ((~((a) ^ (b)) & ((a) ^ (sum))) < 0)

/* To do constant folding on INTEGER_CST nodes requires two-word arithmetic.
   We do that by representing the two-word integer in 4 words, with only
   HOST_BITS_PER_WIDE_INT / 2 bits stored in each word, as a positive
   number.  The value of the word is LOWPART + HIGHPART * BASE.  */

#define LOWPART(x) \
  ((x) & (((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)) - 1))
#define HIGHPART(x) \
  ((unsigned HOST_WIDE_INT) (x) >> HOST_BITS_PER_WIDE_INT / 2)
#define BASE ((unsigned HOST_WIDE_INT) 1 << HOST_BITS_PER_WIDE_INT / 2)

/* Unpack a two-word integer into 4 words.
   LOW and HI are the integer, as two `HOST_WIDE_INT' pieces.
   WORDS points to the array of HOST_WIDE_INTs.  */

static void
encode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
{
  words[0] = LOWPART (low);
  words[1] = HIGHPART (low);
  words[2] = LOWPART (hi);
  words[3] = HIGHPART (hi);
}

/* Pack an array of 4 words into a two-word integer.
   WORDS points to the array of words.
   The integer is stored into *LOW and *HI as two `HOST_WIDE_INT' pieces.  */

static void
decode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT *low,
	HOST_WIDE_INT *hi)
{
  *low = words[0] + words[1] * BASE;
  *hi = words[2] + words[3] * BASE;
}

/* T is an INT_CST node.  OVERFLOWABLE indicates if we are interested
   in overflow of the value, when >0 we are only interested in signed
   overflow, for <0 we are interested in any overflow.  OVERFLOWED
   indicates whether overflow has already occurred.  CONST_OVERFLOWED
   indicates whether constant overflow has already occurred.  We force
   T's value to be within range of T's type (by setting to 0 or 1 all
   the bits outside the type's range).  We set TREE_OVERFLOWED if,
  	OVERFLOWED is nonzero,
	or OVERFLOWABLE is >0 and signed overflow occurs
	or OVERFLOWABLE is <0 and any overflow occurs
   We set TREE_CONSTANT_OVERFLOWED if,
        CONST_OVERFLOWED is nonzero
	or we set TREE_OVERFLOWED.
  We return either the original T, or a copy.  */

tree
force_fit_type (tree t, int overflowable,
		bool overflowed, bool overflowed_const)
{
  unsigned HOST_WIDE_INT low;
  HOST_WIDE_INT high;
  unsigned int prec;
  int sign_extended_type;

  gcc_assert (TREE_CODE (t) == INTEGER_CST);

  low = TREE_INT_CST_LOW (t);
  high = TREE_INT_CST_HIGH (t);

  if (POINTER_TYPE_P (TREE_TYPE (t))
      || TREE_CODE (TREE_TYPE (t)) == OFFSET_TYPE)
    prec = POINTER_SIZE;
  else
    prec = TYPE_PRECISION (TREE_TYPE (t));
  /* Size types *are* sign extended.  */
  sign_extended_type = (!TYPE_UNSIGNED (TREE_TYPE (t))
			|| (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
			    && TYPE_IS_SIZETYPE (TREE_TYPE (t))));

  /* First clear all bits that are beyond the type's precision.  */

  if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
    ;
  else if (prec > HOST_BITS_PER_WIDE_INT)
    high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
  else
    {
      high = 0;
      if (prec < HOST_BITS_PER_WIDE_INT)
	low &= ~((HOST_WIDE_INT) (-1) << prec);
    }

  if (!sign_extended_type)
    /* No sign extension */;
  else if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
    /* Correct width already.  */;
  else if (prec > HOST_BITS_PER_WIDE_INT)
    {
      /* Sign extend top half? */
      if (high & ((unsigned HOST_WIDE_INT)1
		  << (prec - HOST_BITS_PER_WIDE_INT - 1)))
	high |= (HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT);
    }
  else if (prec == HOST_BITS_PER_WIDE_INT)
    {
      if ((HOST_WIDE_INT)low < 0)
	high = -1;
    }
  else
    {
      /* Sign extend bottom half? */
      if (low & ((unsigned HOST_WIDE_INT)1 << (prec - 1)))
	{
	  high = -1;
	  low |= (HOST_WIDE_INT)(-1) << prec;
	}
    }

  /* If the value changed, return a new node.  */
  if (overflowed || overflowed_const
      || low != TREE_INT_CST_LOW (t) || high != TREE_INT_CST_HIGH (t))
    {
      t = build_int_cst_wide (TREE_TYPE (t), low, high);

      if (overflowed
	  || overflowable < 0
	  || (overflowable > 0 && sign_extended_type))
	{
	  t = copy_node (t);
	  TREE_OVERFLOW (t) = 1;
	  TREE_CONSTANT_OVERFLOW (t) = 1;
	}
      else if (overflowed_const)
	{
	  t = copy_node (t);
	  TREE_CONSTANT_OVERFLOW (t) = 1;
	}
    }

  return t;
}

/* Add two doubleword integers with doubleword result.
   Return nonzero if the operation overflows according to UNSIGNED_P.
   Each argument is given as two `HOST_WIDE_INT' pieces.
   One argument is L1 and H1; the other, L2 and H2.
   The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV.  */

int
add_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
		      unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
		      unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
		      bool unsigned_p)
{
  unsigned HOST_WIDE_INT l;
  HOST_WIDE_INT h;

  l = l1 + l2;
  h = h1 + h2 + (l < l1);

  *lv = l;
  *hv = h;

  if (unsigned_p)
    return (unsigned HOST_WIDE_INT) h < (unsigned HOST_WIDE_INT) h1;
  else
    return OVERFLOW_SUM_SIGN (h1, h2, h);
}

/* Negate a doubleword integer with doubleword result.
   Return nonzero if the operation overflows, assuming it's signed.
   The argument is given as two `HOST_WIDE_INT' pieces in L1 and H1.
   The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV.  */

int
neg_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
	    unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
{
  if (l1 == 0)
    {
      *lv = 0;
      *hv = - h1;
      return (*hv & h1) < 0;
    }
  else
    {
      *lv = -l1;
      *hv = ~h1;
      return 0;
    }
}

/* Multiply two doubleword integers with doubleword result.
   Return nonzero if the operation overflows according to UNSIGNED_P.
   Each argument is given as two `HOST_WIDE_INT' pieces.
   One argument is L1 and H1; the other, L2 and H2.
   The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV.  */

int
mul_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
		      unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
		      unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
		      bool unsigned_p)
{
  HOST_WIDE_INT arg1[4];
  HOST_WIDE_INT arg2[4];
  HOST_WIDE_INT prod[4 * 2];
  unsigned HOST_WIDE_INT carry;
  int i, j, k;
  unsigned HOST_WIDE_INT toplow, neglow;
  HOST_WIDE_INT tophigh, neghigh;

  encode (arg1, l1, h1);
  encode (arg2, l2, h2);

  memset (prod, 0, sizeof prod);

  for (i = 0; i < 4; i++)
    {
      carry = 0;
      for (j = 0; j < 4; j++)
	{
	  k = i + j;
	  /* This product is <= 0xFFFE0001, the sum <= 0xFFFF0000.  */
	  carry += arg1[i] * arg2[j];
	  /* Since prod[p] < 0xFFFF, this sum <= 0xFFFFFFFF.  */
	  carry += prod[k];
	  prod[k] = LOWPART (carry);
	  carry = HIGHPART (carry);
	}
      prod[i + 4] = carry;
    }

  decode (prod, lv, hv);
  decode (prod + 4, &toplow, &tophigh);

  /* Unsigned overflow is immediate.  */
  if (unsigned_p)
    return (toplow | tophigh) != 0;

  /* Check for signed overflow by calculating the signed representation of the
     top half of the result; it should agree with the low half's sign bit.  */
  if (h1 < 0)
    {
      neg_double (l2, h2, &neglow, &neghigh);
      add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
    }
  if (h2 < 0)
    {
      neg_double (l1, h1, &neglow, &neghigh);
      add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
    }
  return (*hv < 0 ? ~(toplow & tophigh) : toplow | tophigh) != 0;
}

/* Shift the doubleword integer in L1, H1 left by COUNT places
   keeping only PREC bits of result.
   Shift right if COUNT is negative.
   ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
   Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV.  */

void
lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
	       HOST_WIDE_INT count, unsigned int prec,
	       unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, int arith)
{
  unsigned HOST_WIDE_INT signmask;

  if (count < 0)
    {
      rshift_double (l1, h1, -count, prec, lv, hv, arith);
      return;
    }

  if (SHIFT_COUNT_TRUNCATED)
    count %= prec;

  if (count >= 2 * HOST_BITS_PER_WIDE_INT)
    {
      /* Shifting by the host word size is undefined according to the
	 ANSI standard, so we must handle this as a special case.  */
      *hv = 0;
      *lv = 0;
    }
  else if (count >= HOST_BITS_PER_WIDE_INT)
    {
      *hv = l1 << (count - HOST_BITS_PER_WIDE_INT);
      *lv = 0;
    }
  else
    {
      *hv = (((unsigned HOST_WIDE_INT) h1 << count)
	     | (l1 >> (HOST_BITS_PER_WIDE_INT - count - 1) >> 1));
      *lv = l1 << count;
    }

  /* Sign extend all bits that are beyond the precision.  */

  signmask = -((prec > HOST_BITS_PER_WIDE_INT
		? ((unsigned HOST_WIDE_INT) *hv
		   >> (prec - HOST_BITS_PER_WIDE_INT - 1))
		: (*lv >> (prec - 1))) & 1);

  if (prec >= 2 * HOST_BITS_PER_WIDE_INT)
    ;
  else if (prec >= HOST_BITS_PER_WIDE_INT)
    {
      *hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
      *hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
    }
  else
    {
      *hv = signmask;
      *lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
      *lv |= signmask << prec;
    }
}

/* Shift the doubleword integer in L1, H1 right by COUNT places
   keeping only PREC bits of result.  COUNT must be positive.
   ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
   Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV.  */

void
rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
	       HOST_WIDE_INT count, unsigned int prec,
	       unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
	       int arith)
{
  unsigned HOST_WIDE_INT signmask;

  signmask = (arith
	      ? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
	      : 0);

  if (SHIFT_COUNT_TRUNCATED)
    count %= prec;

  if (count >= 2 * HOST_BITS_PER_WIDE_INT)
    {
      /* Shifting by the host word size is undefined according to the
	 ANSI standard, so we must handle this as a special case.  */
      *hv = 0;
      *lv = 0;
    }
  else if (count >= HOST_BITS_PER_WIDE_INT)
    {
      *hv = 0;
      *lv = (unsigned HOST_WIDE_INT) h1 >> (count - HOST_BITS_PER_WIDE_INT);
    }
  else
    {
      *hv = (unsigned HOST_WIDE_INT) h1 >> count;
      *lv = ((l1 >> count)
	     | ((unsigned HOST_WIDE_INT) h1 << (HOST_BITS_PER_WIDE_INT - count - 1) << 1));
    }

  /* Zero / sign extend all bits that are beyond the precision.  */

  if (count >= (HOST_WIDE_INT)prec)
    {
      *hv = signmask;
      *lv = signmask;
    }
  else if ((prec - count) >= 2 * HOST_BITS_PER_WIDE_INT)
    ;
  else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
    {
      *hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT));
      *hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
    }
  else
    {
      *hv = signmask;
      *lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count));
      *lv |= signmask << (prec - count);
    }
}

/* Rotate the doubleword integer in L1, H1 left by COUNT places
   keeping only PREC bits of result.
   Rotate right if COUNT is negative.
   Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV.  */

void
lrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
		HOST_WIDE_INT count, unsigned int prec,
		unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
{
  unsigned HOST_WIDE_INT s1l, s2l;
  HOST_WIDE_INT s1h, s2h;

  count %= prec;
  if (count < 0)
    count += prec;

  lshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
  rshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
  *lv = s1l | s2l;
  *hv = s1h | s2h;
}

/* Rotate the doubleword integer in L1, H1 left by COUNT places
   keeping only PREC bits of result.  COUNT must be positive.
   Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV.  */

void
rrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
		HOST_WIDE_INT count, unsigned int prec,
		unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
{
  unsigned HOST_WIDE_INT s1l, s2l;
  HOST_WIDE_INT s1h, s2h;

  count %= prec;
  if (count < 0)
    count += prec;

  rshift_double (l1, h1, count, prec, &s1l, &s1h, 0);
  lshift_double (l1, h1, prec - count, prec, &s2l, &s2h, 0);
  *lv = s1l | s2l;
  *hv = s1h | s2h;
}

/* Divide doubleword integer LNUM, HNUM by doubleword integer LDEN, HDEN
   for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM).
   CODE is a tree code for a kind of division, one of
   TRUNC_DIV_EXPR, FLOOR_DIV_EXPR, CEIL_DIV_EXPR, ROUND_DIV_EXPR
   or EXACT_DIV_EXPR
   It controls how the quotient is rounded to an integer.
   Return nonzero if the operation overflows.
   UNS nonzero says do unsigned division.  */

int
div_and_round_double (enum tree_code code, int uns,
		      unsigned HOST_WIDE_INT lnum_orig, /* num == numerator == dividend */
		      HOST_WIDE_INT hnum_orig,
		      unsigned HOST_WIDE_INT lden_orig, /* den == denominator == divisor */
		      HOST_WIDE_INT hden_orig,
		      unsigned HOST_WIDE_INT *lquo,
		      HOST_WIDE_INT *hquo, unsigned HOST_WIDE_INT *lrem,
		      HOST_WIDE_INT *hrem)
{
  int quo_neg = 0;
  HOST_WIDE_INT num[4 + 1];	/* extra element for scaling.  */
  HOST_WIDE_INT den[4], quo[4];
  int i, j;
  unsigned HOST_WIDE_INT work;
  unsigned HOST_WIDE_INT carry = 0;
  unsigned HOST_WIDE_INT lnum = lnum_orig;
  HOST_WIDE_INT hnum = hnum_orig;
  unsigned HOST_WIDE_INT lden = lden_orig;
  HOST_WIDE_INT hden = hden_orig;
  int overflow = 0;

  if (hden == 0 && lden == 0)
    overflow = 1, lden = 1;

  /* Calculate quotient sign and convert operands to unsigned.  */
  if (!uns)
    {
      if (hnum < 0)
	{
	  quo_neg = ~ quo_neg;
	  /* (minimum integer) / (-1) is the only overflow case.  */
	  if (neg_double (lnum, hnum, &lnum, &hnum)
	      && ((HOST_WIDE_INT) lden & hden) == -1)
	    overflow = 1;
	}
      if (hden < 0)
	{
	  quo_neg = ~ quo_neg;
	  neg_double (lden, hden, &lden, &hden);
	}
    }

  if (hnum == 0 && hden == 0)
    {				/* single precision */
      *hquo = *hrem = 0;
      /* This unsigned division rounds toward zero.  */
      *lquo = lnum / lden;
      goto finish_up;
    }

  if (hnum == 0)
    {				/* trivial case: dividend < divisor */
      /* hden != 0 already checked.  */
      *hquo = *lquo = 0;
      *hrem = hnum;
      *lrem = lnum;
      goto finish_up;
    }

  memset (quo, 0, sizeof quo);

  memset (num, 0, sizeof num);	/* to zero 9th element */
  memset (den, 0, sizeof den);

  encode (num, lnum, hnum);
  encode (den, lden, hden);

  /* Special code for when the divisor < BASE.  */
  if (hden == 0 && lden < (unsigned HOST_WIDE_INT) BASE)
    {
      /* hnum != 0 already checked.  */
      for (i = 4 - 1; i >= 0; i--)
	{
	  work = num[i] + carry * BASE;
	  quo[i] = work / lden;
	  carry = work % lden;
	}
    }
  else
    {
      /* Full double precision division,
	 with thanks to Don Knuth's "Seminumerical Algorithms".  */
      int num_hi_sig, den_hi_sig;
      unsigned HOST_WIDE_INT quo_est, scale;

      /* Find the highest nonzero divisor digit.  */
      for (i = 4 - 1;; i--)
	if (den[i] != 0)
	  {
	    den_hi_sig = i;
	    break;
	  }

      /* Insure that the first digit of the divisor is at least BASE/2.
	 This is required by the quotient digit estimation algorithm.  */

      scale = BASE / (den[den_hi_sig] + 1);
      if (scale > 1)
	{		/* scale divisor and dividend */
	  carry = 0;
	  for (i = 0; i <= 4 - 1; i++)
	    {
	      work = (num[i] * scale) + carry;
	      num[i] = LOWPART (work);
	      carry = HIGHPART (work);
	    }

	  num[4] = carry;
	  carry = 0;
	  for (i = 0; i <= 4 - 1; i++)
	    {
	      work = (den[i] * scale) + carry;
	      den[i] = LOWPART (work);
	      carry = HIGHPART (work);
	      if (den[i] != 0) den_hi_sig = i;
	    }
	}

      num_hi_sig = 4;

      /* Main loop */
      for (i = num_hi_sig - den_hi_sig - 1; i >= 0; i--)
	{
	  /* Guess the next quotient digit, quo_est, by dividing the first
	     two remaining dividend digits by the high order quotient digit.
	     quo_est is never low and is at most 2 high.  */
	  unsigned HOST_WIDE_INT tmp;

	  num_hi_sig = i + den_hi_sig + 1;
	  work = num[num_hi_sig] * BASE + num[num_hi_sig - 1];
	  if (num[num_hi_sig] != den[den_hi_sig])
	    quo_est = work / den[den_hi_sig];
	  else
	    quo_est = BASE - 1;

	  /* Refine quo_est so it's usually correct, and at most one high.  */
	  tmp = work - quo_est * den[den_hi_sig];
	  if (tmp < BASE
	      && (den[den_hi_sig - 1] * quo_est
		  > (tmp * BASE + num[num_hi_sig - 2])))
	    quo_est--;

	  /* Try QUO_EST as the quotient digit, by multiplying the
	     divisor by QUO_EST and subtracting from the remaining dividend.
	     Keep in mind that QUO_EST is the I - 1st digit.  */

	  carry = 0;
	  for (j = 0; j <= den_hi_sig; j++)
	    {
	      work = quo_est * den[j] + carry;
	      carry = HIGHPART (work);
	      work = num[i + j] - LOWPART (work);
	      num[i + j] = LOWPART (work);
	      carry += HIGHPART (work) != 0;
	    }

	  /* If quo_est was high by one, then num[i] went negative and
	     we need to correct things.  */
	  if (num[num_hi_sig] < (HOST_WIDE_INT) carry)
	    {
	      quo_est--;
	      carry = 0;		/* add divisor back in */
	      for (j = 0; j <= den_hi_sig; j++)
		{
		  work = num[i + j] + den[j] + carry;
		  carry = HIGHPART (work);
		  num[i + j] = LOWPART (work);
		}

	      num [num_hi_sig] += carry;
	    }

	  /* Store the quotient digit.  */
	  quo[i] = quo_est;
	}
    }

  decode (quo, lquo, hquo);

 finish_up:
  /* If result is negative, make it so.  */
  if (quo_neg)
    neg_double (*lquo, *hquo, lquo, hquo);

  /* Compute trial remainder:  rem = num - (quo * den)  */
  mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
  neg_double (*lrem, *hrem, lrem, hrem);
  add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);

  switch (code)
    {
    case TRUNC_DIV_EXPR:
    case TRUNC_MOD_EXPR:	/* round toward zero */
    case EXACT_DIV_EXPR:	/* for this one, it shouldn't matter */
      return overflow;

    case FLOOR_DIV_EXPR:
    case FLOOR_MOD_EXPR:	/* round toward negative infinity */
      if (quo_neg && (*lrem != 0 || *hrem != 0))   /* ratio < 0 && rem != 0 */
	{
	  /* quo = quo - 1;  */
	  add_double (*lquo, *hquo, (HOST_WIDE_INT) -1, (HOST_WIDE_INT)  -1,
		      lquo, hquo);
	}
      else
	return overflow;
      break;

    case CEIL_DIV_EXPR:
    case CEIL_MOD_EXPR:		/* round toward positive infinity */
      if (!quo_neg && (*lrem != 0 || *hrem != 0))  /* ratio > 0 && rem != 0 */
	{
	  add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
		      lquo, hquo);
	}
      else
	return overflow;
      break;

    case ROUND_DIV_EXPR:
    case ROUND_MOD_EXPR:	/* round to closest integer */
      {
	unsigned HOST_WIDE_INT labs_rem = *lrem;
	HOST_WIDE_INT habs_rem = *hrem;
	unsigned HOST_WIDE_INT labs_den = lden, ltwice;
	HOST_WIDE_INT habs_den = hden, htwice;

	/* Get absolute values.  */
	if (*hrem < 0)
	  neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
	if (hden < 0)
	  neg_double (lden, hden, &labs_den, &habs_den);

	/* If (2 * abs (lrem) >= abs (lden)) */
	mul_double ((HOST_WIDE_INT) 2, (HOST_WIDE_INT) 0,
		    labs_rem, habs_rem, &ltwice, &htwice);

	if (((unsigned HOST_WIDE_INT) habs_den
	     < (unsigned HOST_WIDE_INT) htwice)
	    || (((unsigned HOST_WIDE_INT) habs_den
		 == (unsigned HOST_WIDE_INT) htwice)
		&& (labs_den < ltwice)))
	  {
	    if (*hquo < 0)
	      /* quo = quo - 1;  */
	      add_double (*lquo, *hquo,
			  (HOST_WIDE_INT) -1, (HOST_WIDE_INT) -1, lquo, hquo);
	    else
	      /* quo = quo + 1; */
	      add_double (*lquo, *hquo, (HOST_WIDE_INT) 1, (HOST_WIDE_INT) 0,
			  lquo, hquo);
	  }
	else
	  return overflow;
      }
      break;

    default:
      gcc_unreachable ();
    }

  /* Compute true remainder:  rem = num - (quo * den)  */
  mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
  neg_double (*lrem, *hrem, lrem, hrem);
  add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
  return overflow;
}

/* If ARG2 divides ARG1 with zero remainder, carries out the division
   of type CODE and returns the quotient.
   Otherwise returns NULL_TREE.  */

static tree
div_if_zero_remainder (enum tree_code code, tree arg1, tree arg2)
{
  unsigned HOST_WIDE_INT int1l, int2l;
  HOST_WIDE_INT int1h, int2h;
  unsigned HOST_WIDE_INT quol, reml;
  HOST_WIDE_INT quoh, remh;
  tree type = TREE_TYPE (arg1);
  int uns = TYPE_UNSIGNED (type);

  int1l = TREE_INT_CST_LOW (arg1);
  int1h = TREE_INT_CST_HIGH (arg1);
  int2l = TREE_INT_CST_LOW (arg2);
  int2h = TREE_INT_CST_HIGH (arg2);

  div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
		  	&quol, &quoh, &reml, &remh);
  if (remh != 0 || reml != 0)
    return NULL_TREE;

  return build_int_cst_wide (type, quol, quoh);
}

/* This is non-zero if we should defer warnings about undefined
   overflow.  This facility exists because these warnings are a
   special case.  The code to estimate loop iterations does not want
   to issue any warnings, since it works with expressions which do not
   occur in user code.  Various bits of cleanup code call fold(), but
   only use the result if it has certain characteristics (e.g., is a
   constant); that code only wants to issue a warning if the result is
   used.  */

static int fold_deferring_overflow_warnings;

/* If a warning about undefined overflow is deferred, this is the
   warning.  Note that this may cause us to turn two warnings into
   one, but that is fine since it is sufficient to only give one
   warning per expression.  */

static const char* fold_deferred_overflow_warning;

/* If a warning about undefined overflow is deferred, this is the
   level at which the warning should be emitted.  */

static enum warn_strict_overflow_code fold_deferred_overflow_code;

/* Start deferring overflow warnings.  We could use a stack here to
   permit nested calls, but at present it is not necessary.  */

void
fold_defer_overflow_warnings (void)
{
  ++fold_deferring_overflow_warnings;
}

/* Stop deferring overflow warnings.  If there is a pending warning,
   and ISSUE is true, then issue the warning if appropriate.  STMT is
   the statement with which the warning should be associated (used for
   location information); STMT may be NULL.  CODE is the level of the
   warning--a warn_strict_overflow_code value.  This function will use
   the smaller of CODE and the deferred code when deciding whether to
   issue the warning.  CODE may be zero to mean to always use the
   deferred code.  */

void
fold_undefer_overflow_warnings (bool issue, tree stmt, int code)
{
  const char *warnmsg;
  location_t locus;

  gcc_assert (fold_deferring_overflow_warnings > 0);
  --fold_deferring_overflow_warnings;
  if (fold_deferring_overflow_warnings > 0)
    {
      if (fold_deferred_overflow_warning != NULL
	  && code != 0
	  && code < (int) fold_deferred_overflow_code)
	fold_deferred_overflow_code = code;
      return;
    }

  warnmsg = fold_deferred_overflow_warning;
  fold_deferred_overflow_warning = NULL;

  if (!issue || warnmsg == NULL)
    return;

  /* Use the smallest code level when deciding to issue the
     warning.  */
  if (code == 0 || code > (int) fold_deferred_overflow_code)
    code = fold_deferred_overflow_code;

  if (!issue_strict_overflow_warning (code))
    return;

  if (stmt == NULL_TREE || !EXPR_HAS_LOCATION (stmt))
    locus = input_location;
  else
    locus = EXPR_LOCATION (stmt);
  warning (OPT_Wstrict_overflow, "%H%s", &locus, warnmsg);
}

/* Stop deferring overflow warnings, ignoring any deferred
   warnings.  */

void
fold_undefer_and_ignore_overflow_warnings (void)
{
  fold_undefer_overflow_warnings (false, NULL_TREE, 0);
}

/* Whether we are deferring overflow warnings.  */

bool
fold_deferring_overflow_warnings_p (void)
{
  return fold_deferring_overflow_warnings > 0;
}

/* This is called when we fold something based on the fact that signed
   overflow is undefined.  */

static void
fold_overflow_warning (const char* gmsgid, enum warn_strict_overflow_code wc)
{
  gcc_assert (!flag_wrapv && !flag_trapv);
  if (fold_deferring_overflow_warnings > 0)
    {
      if (fold_deferred_overflow_warning == NULL
	  || wc < fold_deferred_overflow_code)
	{
	  fold_deferred_overflow_warning = gmsgid;
	  fold_deferred_overflow_code = wc;
	}
    }
  else if (issue_strict_overflow_warning (wc))
    warning (OPT_Wstrict_overflow, gmsgid);
}

/* Return true if the built-in mathematical function specified by CODE
   is odd, i.e. -f(x) == f(-x).  */

static bool
negate_mathfn_p (enum built_in_function code)
{
  switch (code)
    {
    CASE_FLT_FN (BUILT_IN_ASIN):
    CASE_FLT_FN (BUILT_IN_ASINH):
    CASE_FLT_FN (BUILT_IN_ATAN):
    CASE_FLT_FN (BUILT_IN_ATANH):
    CASE_FLT_FN (BUILT_IN_CBRT):
    CASE_FLT_FN (BUILT_IN_SIN):
    CASE_FLT_FN (BUILT_IN_SINH):
    CASE_FLT_FN (BUILT_IN_TAN):
    CASE_FLT_FN (BUILT_IN_TANH):
      return true;

    default:
      break;
    }
  return false;
}

/* Check whether we may negate an integer constant T without causing
   overflow.  */

bool
may_negate_without_overflow_p (tree t)
{
  unsigned HOST_WIDE_INT val;
  unsigned int prec;
  tree type;

  gcc_assert (TREE_CODE (t) == INTEGER_CST);

  type = TREE_TYPE (t);
  if (TYPE_UNSIGNED (type))
    return false;

  prec = TYPE_PRECISION (type);
  if (prec > HOST_BITS_PER_WIDE_INT)
    {
      if (TREE_INT_CST_LOW (t) != 0)
	return true;
      prec -= HOST_BITS_PER_WIDE_INT;
      val = TREE_INT_CST_HIGH (t);
    }
  else
    val = TREE_INT_CST_LOW (t);
  if (prec < HOST_BITS_PER_WIDE_INT)
    val &= ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
  return val != ((unsigned HOST_WIDE_INT) 1 << (prec - 1));
}

/* Determine whether an expression T can be cheaply negated using
   the function negate_expr without introducing undefined overflow.  */

static bool
negate_expr_p (tree t)
{
  tree type;

  if (t == 0)
    return false;

  type = TREE_TYPE (t);

  STRIP_SIGN_NOPS (t);
  switch (TREE_CODE (t))
    {
    case INTEGER_CST:
      if (TYPE_OVERFLOW_WRAPS (type))
	return true;

      /* Check that -CST will not overflow type.  */
      return may_negate_without_overflow_p (t);
    case BIT_NOT_EXPR:
      return (INTEGRAL_TYPE_P (type)
	      && TYPE_OVERFLOW_WRAPS (type));

    case REAL_CST:
    case NEGATE_EXPR:
      return true;

    case COMPLEX_CST:
      return negate_expr_p (TREE_REALPART (t))
	     && negate_expr_p (TREE_IMAGPART (t));

    case PLUS_EXPR:
      if (FLOAT_TYPE_P (type) && !flag_unsafe_math_optimizations)
	return false;
      /* -(A + B) -> (-B) - A.  */
      if (negate_expr_p (TREE_OPERAND (t, 1))
	  && reorder_operands_p (TREE_OPERAND (t, 0),
				 TREE_OPERAND (t, 1)))
	return true;
      /* -(A + B) -> (-A) - B.  */
      return negate_expr_p (TREE_OPERAND (t, 0));

    case MINUS_EXPR:
      /* We can't turn -(A-B) into B-A when we honor signed zeros.  */
      return (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
	     && reorder_operands_p (TREE_OPERAND (t, 0),
				    TREE_OPERAND (t, 1));

    case MULT_EXPR:
      if (TYPE_UNSIGNED (TREE_TYPE (t)))
        break;

      /* Fall through.  */

    case RDIV_EXPR:
      if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t))))
	return negate_expr_p (TREE_OPERAND (t, 1))
	       || negate_expr_p (TREE_OPERAND (t, 0));
      break;

    case TRUNC_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case EXACT_DIV_EXPR:
      /* In general we can't negate A / B, because if A is INT_MIN and
	 B is 1, we may turn this into INT_MIN / -1 which is undefined
	 and actually traps on some architectures.  But if overflow is
	 undefined, we can negate, because - (INT_MIN / 1) is an
	 overflow.  */
      if (INTEGRAL_TYPE_P (TREE_TYPE (t))
	  && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)))
        break;
      return negate_expr_p (TREE_OPERAND (t, 1))
             || negate_expr_p (TREE_OPERAND (t, 0));

    case NOP_EXPR:
      /* Negate -((double)float) as (double)(-float).  */
      if (TREE_CODE (type) == REAL_TYPE)
	{
	  tree tem = strip_float_extensions (t);
	  if (tem != t)
	    return negate_expr_p (tem);
	}
      break;

    case CALL_EXPR:
      /* Negate -f(x) as f(-x).  */
      if (negate_mathfn_p (builtin_mathfn_code (t)))
	return negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1)));
      break;

    case RSHIFT_EXPR:
      /* Optimize -((int)x >> 31) into (unsigned)x >> 31.  */
      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
	{
	  tree op1 = TREE_OPERAND (t, 1);
	  if (TREE_INT_CST_HIGH (op1) == 0
	      && (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1)
		 == TREE_INT_CST_LOW (op1))
	    return true;
	}
      break;

    default:
      break;
    }
  return false;
}

/* Given T, an expression, return a folded tree for -T or NULL_TREE, if no
   simplification is possible.
   If negate_expr_p would return true for T, NULL_TREE will never be
   returned.  */

static tree
fold_negate_expr (tree t)
{
  tree type = TREE_TYPE (t);
  tree tem;

  switch (TREE_CODE (t))
    {
    /* Convert - (~A) to A + 1.  */
    case BIT_NOT_EXPR:
      if (INTEGRAL_TYPE_P (type))
        return fold_build2 (PLUS_EXPR, type, TREE_OPERAND (t, 0),
                            build_int_cst (type, 1));
      break;
      
    case INTEGER_CST:
      tem = fold_negate_const (t, type);
      if (!TREE_OVERFLOW (tem)
	  || !TYPE_OVERFLOW_TRAPS (type))
	return tem;
      break;

    case REAL_CST:
      tem = fold_negate_const (t, type);
      /* Two's complement FP formats, such as c4x, may overflow.  */
      if (! TREE_OVERFLOW (tem) || ! flag_trapping_math)
	return tem;
      break;

    case COMPLEX_CST:
      {
	tree rpart = negate_expr (TREE_REALPART (t));
	tree ipart = negate_expr (TREE_IMAGPART (t));

	if ((TREE_CODE (rpart) == REAL_CST
	     && TREE_CODE (ipart) == REAL_CST)
	    || (TREE_CODE (rpart) == INTEGER_CST
		&& TREE_CODE (ipart) == INTEGER_CST))
	  return build_complex (type, rpart, ipart);
      }
      break;

    case NEGATE_EXPR:
      return TREE_OPERAND (t, 0);

    case PLUS_EXPR:
      if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
	{
	  /* -(A + B) -> (-B) - A.  */
	  if (negate_expr_p (TREE_OPERAND (t, 1))
	      && reorder_operands_p (TREE_OPERAND (t, 0),
				     TREE_OPERAND (t, 1)))
	    {
	      tem = negate_expr (TREE_OPERAND (t, 1));
	      return fold_build2 (MINUS_EXPR, type,
				  tem, TREE_OPERAND (t, 0));
	    }

	  /* -(A + B) -> (-A) - B.  */
	  if (negate_expr_p (TREE_OPERAND (t, 0)))
	    {
	      tem = negate_expr (TREE_OPERAND (t, 0));
	      return fold_build2 (MINUS_EXPR, type,
				  tem, TREE_OPERAND (t, 1));
	    }
	}
      break;

    case MINUS_EXPR:
      /* - (A - B) -> B - A  */
      if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
	  && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)))
	return fold_build2 (MINUS_EXPR, type,
			    TREE_OPERAND (t, 1), TREE_OPERAND (t, 0));
      break;

    case MULT_EXPR:
      if (TYPE_UNSIGNED (type))
        break;

      /* Fall through.  */

    case RDIV_EXPR:
      if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type)))
	{
	  tem = TREE_OPERAND (t, 1);
	  if (negate_expr_p (tem))
	    return fold_build2 (TREE_CODE (t), type,
				TREE_OPERAND (t, 0), negate_expr (tem));
	  tem = TREE_OPERAND (t, 0);
	  if (negate_expr_p (tem))
	    return fold_build2 (TREE_CODE (t), type,
				negate_expr (tem), TREE_OPERAND (t, 1));
	}
      break;

    case TRUNC_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case EXACT_DIV_EXPR:
      /* In general we can't negate A / B, because if A is INT_MIN and
	 B is 1, we may turn this into INT_MIN / -1 which is undefined
	 and actually traps on some architectures.  But if overflow is
	 undefined, we can negate, because - (INT_MIN / 1) is an
	 overflow.  */
      if (!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
        {
	  const char * const warnmsg = G_("assuming signed overflow does not "
					  "occur when negating a division");
          tem = TREE_OPERAND (t, 1);
          if (negate_expr_p (tem))
	    {
	      if (INTEGRAL_TYPE_P (type)
		  && (TREE_CODE (tem) != INTEGER_CST
		      || integer_onep (tem)))
		fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_MISC);
	      return fold_build2 (TREE_CODE (t), type,
				  TREE_OPERAND (t, 0), negate_expr (tem));
	    }
          tem = TREE_OPERAND (t, 0);
          if (negate_expr_p (tem))
	    {
	      if (INTEGRAL_TYPE_P (type)
		  && (TREE_CODE (tem) != INTEGER_CST
		      || tree_int_cst_equal (tem, TYPE_MIN_VALUE (type))))
		fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_MISC);
	      return fold_build2 (TREE_CODE (t), type,
				  negate_expr (tem), TREE_OPERAND (t, 1));
	    }
        }
      break;

    case NOP_EXPR:
      /* Convert -((double)float) into (double)(-float).  */
      if (TREE_CODE (type) == REAL_TYPE)
	{
	  tem = strip_float_extensions (t);
	  if (tem != t && negate_expr_p (tem))
	    return negate_expr (tem);
	}
      break;

    case CALL_EXPR:
      /* Negate -f(x) as f(-x).  */
      if (negate_mathfn_p (builtin_mathfn_code (t))
	  && negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1))))
	{
	  tree fndecl, arg, arglist;

	  fndecl = get_callee_fndecl (t);
	  arg = negate_expr (TREE_VALUE (TREE_OPERAND (t, 1)));
	  arglist = build_tree_list (NULL_TREE, arg);
	  return build_function_call_expr (fndecl, arglist);
	}
      break;

    case RSHIFT_EXPR:
      /* Optimize -((int)x >> 31) into (unsigned)x >> 31.  */
      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
	{
	  tree op1 = TREE_OPERAND (t, 1);
	  if (TREE_INT_CST_HIGH (op1) == 0
	      && (unsigned HOST_WIDE_INT) (TYPE_PRECISION (type) - 1)
		 == TREE_INT_CST_LOW (op1))
	    {
	      tree ntype = TYPE_UNSIGNED (type)
			   ? lang_hooks.types.signed_type (type)
			   : lang_hooks.types.unsigned_type (type);
	      tree temp = fold_convert (ntype, TREE_OPERAND (t, 0));
	      temp = fold_build2 (RSHIFT_EXPR, ntype, temp, op1);
	      return fold_convert (type, temp);
	    }
	}
      break;

    default:
      break;
    }

  return NULL_TREE;
}

/* Like fold_negate_expr, but return a NEGATE_EXPR tree, if T can not be
   negated in a simpler way.  Also allow for T to be NULL_TREE, in which case
   return NULL_TREE. */

static tree
negate_expr (tree t)
{
  tree type, tem;

  if (t == NULL_TREE)
    return NULL_TREE;

  type = TREE_TYPE (t);
  STRIP_SIGN_NOPS (t);

  tem = fold_negate_expr (t);
  if (!tem)
    tem = build1 (NEGATE_EXPR, TREE_TYPE (t), t);
  return fold_convert (type, tem);
}

/* Split a tree IN into a constant, literal and variable parts that could be
   combined with CODE to make IN.  "constant" means an expression with
   TREE_CONSTANT but that isn't an actual constant.  CODE must be a
   commutative arithmetic operation.  Store the constant part into *CONP,
   the literal in *LITP and return the variable part.  If a part isn't
   present, set it to null.  If the tree does not decompose in this way,
   return the entire tree as the variable part and the other parts as null.

   If CODE is PLUS_EXPR we also split trees that use MINUS_EXPR.  In that
   case, we negate an operand that was subtracted.  Except if it is a
   literal for which we use *MINUS_LITP instead.

   If NEGATE_P is true, we are negating all of IN, again except a literal
   for which we use *MINUS_LITP instead.

   If IN is itself a literal or constant, return it as appropriate.

   Note that we do not guarantee that any of the three values will be the
   same type as IN, but they will have the same signedness and mode.  */

static tree
split_tree (tree in, enum tree_code code, tree *conp, tree *litp,
	    tree *minus_litp, int negate_p)
{
  tree var = 0;

  *conp = 0;
  *litp = 0;
  *minus_litp = 0;

  /* Strip any conversions that don't change the machine mode or signedness.  */
  STRIP_SIGN_NOPS (in);

  if (TREE_CODE (in) == INTEGER_CST || TREE_CODE (in) == REAL_CST)
    *litp = in;
  else if (TREE_CODE (in) == code
	   || (! FLOAT_TYPE_P (TREE_TYPE (in))
	       /* We can associate addition and subtraction together (even
		  though the C standard doesn't say so) for integers because
		  the value is not affected.  For reals, the value might be
		  affected, so we can't.  */
	       && ((code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR)
		   || (code == MINUS_EXPR && TREE_CODE (in) == PLUS_EXPR))))
    {
      tree op0 = TREE_OPERAND (in, 0);
      tree op1 = TREE_OPERAND (in, 1);
      int neg1_p = TREE_CODE (in) == MINUS_EXPR;
      int neg_litp_p = 0, neg_conp_p = 0, neg_var_p = 0;

      /* First see if either of the operands is a literal, then a constant.  */
      if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
	*litp = op0, op0 = 0;
      else if (TREE_CODE (op1) == INTEGER_CST || TREE_CODE (op1) == REAL_CST)
	*litp = op1, neg_litp_p = neg1_p, op1 = 0;

      if (op0 != 0 && TREE_CONSTANT (op0))
	*conp = op0, op0 = 0;
      else if (op1 != 0 && TREE_CONSTANT (op1))
	*conp = op1, neg_conp_p = neg1_p, op1 = 0;

      /* If we haven't dealt with either operand, this is not a case we can
	 decompose.  Otherwise, VAR is either of the ones remaining, if any.  */
      if (op0 != 0 && op1 != 0)
	var = in;
      else if (op0 != 0)
	var = op0;
      else
	var = op1, neg_var_p = neg1_p;

      /* Now do any needed negations.  */
      if (neg_litp_p)
	*minus_litp = *litp, *litp = 0;
      if (neg_conp_p)
	*conp = negate_expr (*conp);
      if (neg_var_p)
	var = negate_expr (var);
    }
  else if (TREE_CONSTANT (in))
    *conp = in;
  else
    var = in;

  if (negate_p)
    {
      if (*litp)
	*minus_litp = *litp, *litp = 0;
      else if (*minus_litp)
	*litp = *minus_litp, *minus_litp = 0;
      *conp = negate_expr (*conp);
      var = negate_expr (var);
    }

  return var;
}

/* Re-associate trees split by the above function.  T1 and T2 are either
   expressions to associate or null.  Return the new expression, if any.  If
   we build an operation, do it in TYPE and with CODE.  */

static tree
associate_trees (tree t1, tree t2, enum tree_code code, tree type)
{
  if (t1 == 0)
    return t2;
  else if (t2 == 0)
    return t1;

  /* If either input is CODE, a PLUS_EXPR, or a MINUS_EXPR, don't
     try to fold this since we will have infinite recursion.  But do
     deal with any NEGATE_EXPRs.  */
  if (TREE_CODE (t1) == code || TREE_CODE (t2) == code
      || TREE_CODE (t1) == MINUS_EXPR || TREE_CODE (t2) == MINUS_EXPR)
    {
      if (code == PLUS_EXPR)
	{
	  if (TREE_CODE (t1) == NEGATE_EXPR)
	    return build2 (MINUS_EXPR, type, fold_convert (type, t2),
			   fold_convert (type, TREE_OPERAND (t1, 0)));
	  else if (TREE_CODE (t2) == NEGATE_EXPR)
	    return build2 (MINUS_EXPR, type, fold_convert (type, t1),
			   fold_convert (type, TREE_OPERAND (t2, 0)));
	  else if (integer_zerop (t2))
	    return fold_convert (type, t1);
	}
      else if (code == MINUS_EXPR)
	{
	  if (integer_zerop (t2))
	    return fold_convert (type, t1);
	}

      return build2 (code, type, fold_convert (type, t1),
		     fold_convert (type, t2));
    }

  return fold_build2 (code, type, fold_convert (type, t1),
		      fold_convert (type, t2));
}

/* Combine two integer constants ARG1 and ARG2 under operation CODE
   to produce a new constant.  Return NULL_TREE if we don't know how
   to evaluate CODE at compile-time.

   If NOTRUNC is nonzero, do not truncate the result to fit the data type.  */

tree
int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
{
  unsigned HOST_WIDE_INT int1l, int2l;
  HOST_WIDE_INT int1h, int2h;
  unsigned HOST_WIDE_INT low;
  HOST_WIDE_INT hi;
  unsigned HOST_WIDE_INT garbagel;
  HOST_WIDE_INT garbageh;
  tree t;
  tree type = TREE_TYPE (arg1);
  int uns = TYPE_UNSIGNED (type);
  int is_sizetype
    = (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type));
  int overflow = 0;

  int1l = TREE_INT_CST_LOW (arg1);
  int1h = TREE_INT_CST_HIGH (arg1);
  int2l = TREE_INT_CST_LOW (arg2);
  int2h = TREE_INT_CST_HIGH (arg2);

  switch (code)
    {
    case BIT_IOR_EXPR:
      low = int1l | int2l, hi = int1h | int2h;
      break;

    case BIT_XOR_EXPR:
      low = int1l ^ int2l, hi = int1h ^ int2h;
      break;

    case BIT_AND_EXPR:
      low = int1l & int2l, hi = int1h & int2h;
      break;

    case RSHIFT_EXPR:
      int2l = -int2l;
    case LSHIFT_EXPR:
      /* It's unclear from the C standard whether shifts can overflow.
	 The following code ignores overflow; perhaps a C standard
	 interpretation ruling is needed.  */
      lshift_double (int1l, int1h, int2l, TYPE_PRECISION (type),
		     &low, &hi, !uns);
      break;

    case RROTATE_EXPR:
      int2l = - int2l;
    case LROTATE_EXPR:
      lrotate_double (int1l, int1h, int2l, TYPE_PRECISION (type),
		      &low, &hi);
      break;

    case PLUS_EXPR:
      overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi);
      break;

    case MINUS_EXPR:
      neg_double (int2l, int2h, &low, &hi);
      add_double (int1l, int1h, low, hi, &low, &hi);
      overflow = OVERFLOW_SUM_SIGN (hi, int2h, int1h);
      break;

    case MULT_EXPR:
      overflow = mul_double (int1l, int1h, int2l, int2h, &low, &hi);
      break;

    case TRUNC_DIV_EXPR:
    case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
    case EXACT_DIV_EXPR:
      /* This is a shortcut for a common special case.  */
      if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
	  && ! TREE_CONSTANT_OVERFLOW (arg1)
	  && ! TREE_CONSTANT_OVERFLOW (arg2)
	  && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
	{
	  if (code == CEIL_DIV_EXPR)
	    int1l += int2l - 1;

	  low = int1l / int2l, hi = 0;
	  break;
	}

      /* ... fall through ...  */

    case ROUND_DIV_EXPR:
      if (int2h == 0 && int2l == 0)
	return NULL_TREE;
      if (int2h == 0 && int2l == 1)
	{
	  low = int1l, hi = int1h;
	  break;
	}
      if (int1l == int2l && int1h == int2h
	  && ! (int1l == 0 && int1h == 0))
	{
	  low = 1, hi = 0;
	  break;
	}
      overflow = div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
				       &low, &hi, &garbagel, &garbageh);
      break;

    case TRUNC_MOD_EXPR:
    case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
      /* This is a shortcut for a common special case.  */
      if (int2h == 0 && (HOST_WIDE_INT) int2l > 0
	  && ! TREE_CONSTANT_OVERFLOW (arg1)
	  && ! TREE_CONSTANT_OVERFLOW (arg2)
	  && int1h == 0 && (HOST_WIDE_INT) int1l >= 0)
	{
	  if (code == CEIL_MOD_EXPR)
	    int1l += int2l - 1;
	  low = int1l % int2l, hi = 0;
	  break;
	}

      /* ... fall through ...  */

    case ROUND_MOD_EXPR:
      if (int2h == 0 && int2l == 0)
	return NULL_TREE;
      overflow = div_and_round_double (code, uns,
				       int1l, int1h, int2l, int2h,
				       &garbagel, &garbageh, &low, &hi);
      break;

    case MIN_EXPR:
    case MAX_EXPR:
      if (uns)
	low = (((unsigned HOST_WIDE_INT) int1h
		< (unsigned HOST_WIDE_INT) int2h)
	       || (((unsigned HOST_WIDE_INT) int1h
		    == (unsigned HOST_WIDE_INT) int2h)
		   && int1l < int2l));
      else
	low = (int1h < int2h
	       || (int1h == int2h && int1l < int2l));

      if (low == (code == MIN_EXPR))
	low = int1l, hi = int1h;
      else
	low = int2l, hi = int2h;
      break;

    default:
      return NULL_TREE;
    }

  t = build_int_cst_wide (TREE_TYPE (arg1), low, hi);

  if (notrunc)
    {
      /* Propagate overflow flags ourselves.  */
      if (((!uns || is_sizetype) && overflow)
	  | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))
	{
	  t = copy_node (t);
	  TREE_OVERFLOW (t) = 1;
	  TREE_CONSTANT_OVERFLOW (t) = 1;
	}
      else if (TREE_CONSTANT_OVERFLOW (arg1) | TREE_CONSTANT_OVERFLOW (arg2))
	{
	  t = copy_node (t);
	  TREE_CONSTANT_OVERFLOW (t) = 1;
	}
    }
  else
    t = force_fit_type (t, 1,
			((!uns || is_sizetype) && overflow)
			| TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2),
			TREE_CONSTANT_OVERFLOW (arg1)
			| TREE_CONSTANT_OVERFLOW (arg2));

  return t;
}

/* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
   constant.  We assume ARG1 and ARG2 have the same data type, or at least
   are the same kind of constant and the same machine mode.  Return zero if
   combining the constants is not allowed in the current operating mode.

   If NOTRUNC is nonzero, do not truncate the result to fit the data type.  */

static tree
const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
{
  /* Sanity check for the recursive cases.  */
  if (!arg1 || !arg2)
    return NULL_TREE;

  STRIP_NOPS (arg1);
  STRIP_NOPS (arg2);

  if (TREE_CODE (arg1) == INTEGER_CST)
    return int_const_binop (code, arg1, arg2, notrunc);

  if (TREE_CODE (arg1) == REAL_CST)
    {
      enum machine_mode mode;
      REAL_VALUE_TYPE d1;
      REAL_VALUE_TYPE d2;
      REAL_VALUE_TYPE value;
      REAL_VALUE_TYPE result;
      bool inexact;
      tree t, type;

      /* The following codes are handled by real_arithmetic.  */
      switch (code)
	{
	case PLUS_EXPR:
	case MINUS_EXPR:
	case MULT_EXPR:
	case RDIV_EXPR:
	case MIN_EXPR:
	case MAX_EXPR:
	  break;

	default:
	  return NULL_TREE;
	}

      d1 = TREE_REAL_CST (arg1);
      d2 = TREE_REAL_CST (arg2);

      type = TREE_TYPE (arg1);
      mode = TYPE_MODE (type);

      /* Don't perform operation if we honor signaling NaNs and
	 either operand is a NaN.  */
      if (HONOR_SNANS (mode)
	  && (REAL_VALUE_ISNAN (d1) || REAL_VALUE_ISNAN (d2)))
	return NULL_TREE;

      /* Don't perform operation if it would raise a division
	 by zero exception.  */
      if (code == RDIV_EXPR
	  && REAL_VALUES_EQUAL (d2, dconst0)
	  && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
	return NULL_TREE;

      /* If either operand is a NaN, just return it.  Otherwise, set up
	 for floating-point trap; we return an overflow.  */
      if (REAL_VALUE_ISNAN (d1))
	return arg1;
      else if (REAL_VALUE_ISNAN (d2))
	return arg2;

      inexact = real_arithmetic (&value, code, &d1, &d2);
      real_convert (&result, mode, &value);

      /* Don't constant fold this floating point operation if
	 the result has overflowed and flag_trapping_math.  */
      if (flag_trapping_math
	  && MODE_HAS_INFINITIES (mode)
	  && REAL_VALUE_ISINF (result)
	  && !REAL_VALUE_ISINF (d1)
	  && !REAL_VALUE_ISINF (d2))
	return NULL_TREE;

      /* Don't constant fold this floating point operation if the
	 result may dependent upon the run-time rounding mode and
	 flag_rounding_math is set, or if GCC's software emulation
	 is unable to accurately represent the result.  */
      if ((flag_rounding_math
	   || (REAL_MODE_FORMAT_COMPOSITE_P (mode)
	       && !flag_unsafe_math_optimizations))
	  && (inexact || !real_identical (&result, &value)))
	return NULL_TREE;

      t = build_real (type, result);

      TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2);
      TREE_CONSTANT_OVERFLOW (t)
	= TREE_OVERFLOW (t)
	  | TREE_CONSTANT_OVERFLOW (arg1)
	  | TREE_CONSTANT_OVERFLOW (arg2);
      return t;
    }

  if (TREE_CODE (arg1) == COMPLEX_CST)
    {
      tree type = TREE_TYPE (arg1);
      tree r1 = TREE_REALPART (arg1);
      tree i1 = TREE_IMAGPART (arg1);
      tree r2 = TREE_REALPART (arg2);
      tree i2 = TREE_IMAGPART (arg2);
      tree real, imag;

      switch (code)
	{
	case PLUS_EXPR:
	case MINUS_EXPR:
	  real = const_binop (code, r1, r2, notrunc);
	  imag = const_binop (code, i1, i2, notrunc);
	  break;

	case MULT_EXPR:
	  real = const_binop (MINUS_EXPR,
			      const_binop (MULT_EXPR, r1, r2, notrunc),
			      const_binop (MULT_EXPR, i1, i2, notrunc),
			      notrunc);
	  imag = const_binop (PLUS_EXPR,
			      const_binop (MULT_EXPR, r1, i2, notrunc),
			      const_binop (MULT_EXPR, i1, r2, notrunc),
			      notrunc);
	  break;

	case RDIV_EXPR:
	  {
	    tree magsquared
	      = const_binop (PLUS_EXPR,
			     const_binop (MULT_EXPR, r2, r2, notrunc),
			     const_binop (MULT_EXPR, i2, i2, notrunc),
			     notrunc);
	    tree t1
	      = const_binop (PLUS_EXPR,
			     const_binop (MULT_EXPR, r1, r2, notrunc),
			     const_binop (MULT_EXPR, i1, i2, notrunc),
			     notrunc);
	    tree t2
	      = const_binop (MINUS_EXPR,
			     const_binop (MULT_EXPR, i1, r2, notrunc),
			     const_binop (MULT_EXPR, r1, i2, notrunc),
			     notrunc);

	    if (INTEGRAL_TYPE_P (TREE_TYPE (r1)))
	      code = TRUNC_DIV_EXPR;

	    real = const_binop (code, t1, magsquared, notrunc);
	    imag = const_binop (code, t2, magsquared, notrunc);
	  }
	  break;

	default:
	  return NULL_TREE;
	}

      if (real && imag)
	return build_complex (type, real, imag);
    }

  return NULL_TREE;
}

/* Create a size type INT_CST node with NUMBER sign extended.  KIND
   indicates which particular sizetype to create.  */

tree
size_int_kind (HOST_WIDE_INT number, enum size_type_kind kind)
{
  return build_int_cst (sizetype_tab[(int) kind], number);
}

/* Combine operands OP1 and OP2 with arithmetic operation CODE.  CODE
   is a tree code.  The type of the result is taken from the operands.
   Both must be the same type integer type and it must be a size type.
   If the operands are constant, so is the result.  */

tree
size_binop (enum tree_code code, tree arg0, tree arg1)
{
  tree type = TREE_TYPE (arg0);

  if (arg0 == error_mark_node || arg1 == error_mark_node)
    return error_mark_node;

  gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
	      && type == TREE_TYPE (arg1));

  /* Handle the special case of two integer constants faster.  */
  if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
    {
      /* And some specific cases even faster than that.  */
      /* LLVM local begin gcc 121252 */
      if (code == PLUS_EXPR)
	{
	  if (integer_zerop (arg0) && !TREE_OVERFLOW (arg0))
	    return arg1;
	  if (integer_zerop (arg1) && !TREE_OVERFLOW (arg1))
	    return arg0;
	}
      else if (code == MINUS_EXPR)
	{
	  if (integer_zerop (arg1) && !TREE_OVERFLOW (arg1))
	    return arg0;
	}
      else if (code == MULT_EXPR)
	{
	  if (integer_onep (arg0) && !TREE_OVERFLOW (arg0))
	    return arg1;
	}
      /* LLVM local end gcc 121252 */

      /* Handle general case of two integer constants.  */
      return int_const_binop (code, arg0, arg1, 0);
    }

  return fold_build2 (code, type, arg0, arg1);
}

/* Given two values, either both of sizetype or both of bitsizetype,
   compute the difference between the two values.  Return the value
   in signed type corresponding to the type of the operands.  */

tree
size_diffop (tree arg0, tree arg1)
{
  tree type = TREE_TYPE (arg0);
  tree ctype;

  gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
	      && type == TREE_TYPE (arg1));

  /* If the type is already signed, just do the simple thing.  */
  if (!TYPE_UNSIGNED (type))
    return size_binop (MINUS_EXPR, arg0, arg1);

  ctype = type == bitsizetype ? sbitsizetype : ssizetype;

  /* If either operand is not a constant, do the conversions to the signed
     type and subtract.  The hardware will do the right thing with any
     overflow in the subtraction.  */
  if (TREE_CODE (arg0) != INTEGER_CST || TREE_CODE (arg1) != INTEGER_CST)
    return size_binop (MINUS_EXPR, fold_convert (ctype, arg0),
		       fold_convert (ctype, arg1));

  /* If ARG0 is larger than ARG1, subtract and return the result in CTYPE.
     Otherwise, subtract the other way, convert to CTYPE (we know that can't
     overflow) and negate (which can't either).  Special-case a result
     of zero while we're here.  */
  if (tree_int_cst_equal (arg0, arg1))
    return build_int_cst (ctype, 0);
  else if (tree_int_cst_lt (arg1, arg0))
    return fold_convert (ctype, size_binop (MINUS_EXPR, arg0, arg1));
  else
    return size_binop (MINUS_EXPR, build_int_cst (ctype, 0),
		       fold_convert (ctype, size_binop (MINUS_EXPR,
							arg1, arg0)));
}

/* A subroutine of fold_convert_const handling conversions of an
   INTEGER_CST to another integer type.  */

static tree
fold_convert_const_int_from_int (tree type, tree arg1)
{
  tree t;

  /* Given an integer constant, make new constant with new type,
     appropriately sign-extended or truncated.  */
  t = build_int_cst_wide (type, TREE_INT_CST_LOW (arg1),
			  TREE_INT_CST_HIGH (arg1));

  t = force_fit_type (t,
		      /* Don't set the overflow when
		      	 converting a pointer  */
		      !POINTER_TYPE_P (TREE_TYPE (arg1)),
		      (TREE_INT_CST_HIGH (arg1) < 0
		       && (TYPE_UNSIGNED (type)
			   < TYPE_UNSIGNED (TREE_TYPE (arg1))))
		      | TREE_OVERFLOW (arg1),
		      TREE_CONSTANT_OVERFLOW (arg1));

  return t;
}

/* A subroutine of fold_convert_const handling conversions a REAL_CST
   to an integer type.  */

static tree
fold_convert_const_int_from_real (enum tree_code code, tree type, tree arg1)
{
  int overflow = 0;
  tree t;

  /* The following code implements the floating point to integer
     conversion rules required by the Java Language Specification,
     that IEEE NaNs are mapped to zero and values that overflow
     the target precision saturate, i.e. values greater than
     INT_MAX are mapped to INT_MAX, and values less than INT_MIN
     are mapped to INT_MIN.  These semantics are allowed by the
     C and C++ standards that simply state that the behavior of
     FP-to-integer conversion is unspecified upon overflow.  */

  HOST_WIDE_INT high, low;
  REAL_VALUE_TYPE r;
  REAL_VALUE_TYPE x = TREE_REAL_CST (arg1);

  switch (code)
    {
    case FIX_TRUNC_EXPR:
      real_trunc (&r, VOIDmode, &x);
      break;

    case FIX_CEIL_EXPR:
      real_ceil (&r, VOIDmode, &x);
      break;

    case FIX_FLOOR_EXPR:
      real_floor (&r, VOIDmode, &x);
      break;

    case FIX_ROUND_EXPR:
      real_round (&r, VOIDmode, &x);
      break;

    default:
      gcc_unreachable ();
    }

  /* If R is NaN, return zero and show we have an overflow.  */
  if (REAL_VALUE_ISNAN (r))
    {
      overflow = 1;
      high = 0;
      low = 0;
    }

  /* See if R is less than the lower bound or greater than the
     upper bound.  */

  if (! overflow)
    {
      tree lt = TYPE_MIN_VALUE (type);
      REAL_VALUE_TYPE l = real_value_from_int_cst (NULL_TREE, lt);
      if (REAL_VALUES_LESS (r, l))
	{
	  overflow = 1;
	  high = TREE_INT_CST_HIGH (lt);
	  low = TREE_INT_CST_LOW (lt);
	}
    }

  if (! overflow)
    {
      tree ut = TYPE_MAX_VALUE (type);
      if (ut)
	{
	  REAL_VALUE_TYPE u = real_value_from_int_cst (NULL_TREE, ut);
	  if (REAL_VALUES_LESS (u, r))
	    {
	      overflow = 1;
	      high = TREE_INT_CST_HIGH (ut);
	      low = TREE_INT_CST_LOW (ut);
	    }
	}
    }

  if (! overflow)
    REAL_VALUE_TO_INT (&low, &high, r);

  t = build_int_cst_wide (type, low, high);

  t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg1),
		      TREE_CONSTANT_OVERFLOW (arg1));
  return t;
}

/* A subroutine of fold_convert_const handling conversions a REAL_CST
   to another floating point type.  */

static tree
fold_convert_const_real_from_real (tree type, tree arg1)
{
  REAL_VALUE_TYPE value;
  tree t;

  real_convert (&value, TYPE_MODE (type), &TREE_REAL_CST (arg1));
  t = build_real (type, value);

  TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
  TREE_CONSTANT_OVERFLOW (t)
    = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
  return t;
}

/* Attempt to fold type conversion operation CODE of expression ARG1 to
   type TYPE.  If no simplification can be done return NULL_TREE.  */

static tree
fold_convert_const (enum tree_code code, tree type, tree arg1)
{
  if (TREE_TYPE (arg1) == type)
    return arg1;

  if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
    {
      if (TREE_CODE (arg1) == INTEGER_CST)
	return fold_convert_const_int_from_int (type, arg1);
      else if (TREE_CODE (arg1) == REAL_CST)
	return fold_convert_const_int_from_real (code, type, arg1);
    }
  else if (TREE_CODE (type) == REAL_TYPE)
    {
      if (TREE_CODE (arg1) == INTEGER_CST)
	return build_real_from_int_cst (type, arg1);
      if (TREE_CODE (arg1) == REAL_CST)
	return fold_convert_const_real_from_real (type, arg1);
    }
  return NULL_TREE;
}

/* Construct a vector of zero elements of vector type TYPE.  */

static tree
build_zero_vector (tree type)
{
  tree elem, list;
  int i, units;

  elem = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node);
  units = TYPE_VECTOR_SUBPARTS (type);
  
  list = NULL_TREE;
  for (i = 0; i < units; i++)
    list = tree_cons (NULL_TREE, elem, list);
  return build_vector (type, list);
}

/* Convert expression ARG to type TYPE.  Used by the middle-end for
   simple conversions in preference to calling the front-end's convert.  */

tree
fold_convert (tree type, tree arg)
{
  tree orig = TREE_TYPE (arg);
  tree tem;

  if (type == orig)
    return arg;

  if (TREE_CODE (arg) == ERROR_MARK
      || TREE_CODE (type) == ERROR_MARK
      || TREE_CODE (orig) == ERROR_MARK)
    return error_mark_node;

  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig)
      || lang_hooks.types_compatible_p (TYPE_MAIN_VARIANT (type),
					TYPE_MAIN_VARIANT (orig)))
    return fold_build1 (NOP_EXPR, type, arg);

  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
    case POINTER_TYPE: case REFERENCE_TYPE:
    case OFFSET_TYPE:
      if (TREE_CODE (arg) == INTEGER_CST)
	{
	  tem = fold_convert_const (NOP_EXPR, type, arg);
	  if (tem != NULL_TREE)
	    return tem;
	}
      if (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)
	  || TREE_CODE (orig) == OFFSET_TYPE)
        return fold_build1 (NOP_EXPR, type, arg);
      if (TREE_CODE (orig) == COMPLEX_TYPE)
	{
	  tem = fold_build1 (REALPART_EXPR, TREE_TYPE (orig), arg);
	  return fold_convert (type, tem);
	}
      gcc_assert (TREE_CODE (orig) == VECTOR_TYPE
		  && tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
      return fold_build1 (NOP_EXPR, type, arg);

    case REAL_TYPE:
      if (TREE_CODE (arg) == INTEGER_CST)
	{
	  tem = fold_convert_const (FLOAT_EXPR, type, arg);
	  if (tem != NULL_TREE)
	    return tem;
	}
      else if (TREE_CODE (arg) == REAL_CST)
	{
	  tem = fold_convert_const (NOP_EXPR, type, arg);
	  if (tem != NULL_TREE)
	    return tem;
	}

      switch (TREE_CODE (orig))
	{
	case INTEGER_TYPE:
	case BOOLEAN_TYPE: case ENUMERAL_TYPE:
	case POINTER_TYPE: case REFERENCE_TYPE:
	  return fold_build1 (FLOAT_EXPR, type, arg);

	case REAL_TYPE:
	  return fold_build1 (NOP_EXPR, type, arg);

	case COMPLEX_TYPE:
	  tem = fold_build1 (REALPART_EXPR, TREE_TYPE (orig), arg);
	  return fold_convert (type, tem);

	default:
	  gcc_unreachable ();
	}

    case COMPLEX_TYPE:
      switch (TREE_CODE (orig))
	{
	case INTEGER_TYPE:
	case BOOLEAN_TYPE: case ENUMERAL_TYPE:
	case POINTER_TYPE: case REFERENCE_TYPE:
	case REAL_TYPE:
	  return build2 (COMPLEX_EXPR, type,
			 fold_convert (TREE_TYPE (type), arg),
			 fold_convert (TREE_TYPE (type), integer_zero_node));
	case COMPLEX_TYPE:
	  {
	    tree rpart, ipart;

	    if (TREE_CODE (arg) == COMPLEX_EXPR)
	      {
		rpart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 0));
		ipart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 1));
		return fold_build2 (COMPLEX_EXPR, type, rpart, ipart);
	      }

	    arg = save_expr (arg);
	    rpart = fold_build1 (REALPART_EXPR, TREE_TYPE (orig), arg);
	    ipart = fold_build1 (IMAGPART_EXPR, TREE_TYPE (orig), arg);
	    rpart = fold_convert (TREE_TYPE (type), rpart);
	    ipart = fold_convert (TREE_TYPE (type), ipart);
	    return fold_build2 (COMPLEX_EXPR, type, rpart, ipart);
	  }

	default:
	  gcc_unreachable ();
	}

    case VECTOR_TYPE:
      if (integer_zerop (arg))
	return build_zero_vector (type);
      gcc_assert (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
      gcc_assert (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig)
		  || TREE_CODE (orig) == VECTOR_TYPE);
      return fold_build1 (VIEW_CONVERT_EXPR, type, arg);

    case VOID_TYPE:
      return fold_build1 (NOP_EXPR, type, fold_ignored_result (arg));

    default:
      gcc_unreachable ();
    }
}

/* Return false if expr can be assumed not to be an lvalue, true
   otherwise.  */

static bool
maybe_lvalue_p (tree x)
{
  /* We only need to wrap lvalue tree codes.  */
  switch (TREE_CODE (x))
  {
  case VAR_DECL:
  case PARM_DECL:
  case RESULT_DECL:
  case LABEL_DECL:
  case FUNCTION_DECL:
  case SSA_NAME:

  case COMPONENT_REF:
  case INDIRECT_REF:
  case ALIGN_INDIRECT_REF:
  case MISALIGNED_INDIRECT_REF:
  case ARRAY_REF:
  case ARRAY_RANGE_REF:
  case BIT_FIELD_REF:
  case OBJ_TYPE_REF:

  case REALPART_EXPR:
  case IMAGPART_EXPR:
  case PREINCREMENT_EXPR:
  case PREDECREMENT_EXPR:
  case SAVE_EXPR:
  case TRY_CATCH_EXPR:
  case WITH_CLEANUP_EXPR:
  case COMPOUND_EXPR:
  case MODIFY_EXPR:
  case TARGET_EXPR:
  case COND_EXPR:
  case BIND_EXPR:
  case MIN_EXPR:
  case MAX_EXPR:
    break;

  default:
    /* Assume the worst for front-end tree codes.  */
    if ((int)TREE_CODE (x) >= NUM_TREE_CODES)
      break;
    return false;
  }

  return true;
}

/* Return an expr equal to X but certainly not valid as an lvalue.  */

tree
non_lvalue (tree x)
{
  /* While we are in GIMPLE, NON_LVALUE_EXPR doesn't mean anything to
     us.  */
  if (in_gimple_form)
    return x;

  if (! maybe_lvalue_p (x))
    return x;
  return build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x);
}

/* Nonzero means lvalues are limited to those valid in pedantic ANSI C.
   Zero means allow extended lvalues.  */

int pedantic_lvalues;

/* When pedantic, return an expr equal to X but certainly not valid as a
   pedantic lvalue.  Otherwise, return X.  */

static tree
pedantic_non_lvalue (tree x)
{
  if (pedantic_lvalues)
    return non_lvalue (x);
  else
    return x;
}

/* Given a tree comparison code, return the code that is the logical inverse
   of the given code.  It is not safe to do this for floating-point
   comparisons, except for NE_EXPR and EQ_EXPR, so we receive a machine mode
   as well: if reversing the comparison is unsafe, return ERROR_MARK.  */

enum tree_code
invert_tree_comparison (enum tree_code code, bool honor_nans)
{
  if (honor_nans && flag_trapping_math)
    return ERROR_MARK;

  switch (code)
    {
    case EQ_EXPR:
      return NE_EXPR;
    case NE_EXPR:
      return EQ_EXPR;
    case GT_EXPR:
      return honor_nans ? UNLE_EXPR : LE_EXPR;
    case GE_EXPR:
      return honor_nans ? UNLT_EXPR : LT_EXPR;
    case LT_EXPR:
      return honor_nans ? UNGE_EXPR : GE_EXPR;
    case LE_EXPR:
      return honor_nans ? UNGT_EXPR : GT_EXPR;
    case LTGT_EXPR:
      return UNEQ_EXPR;
    case UNEQ_EXPR:
      return LTGT_EXPR;
    case UNGT_EXPR:
      return LE_EXPR;
    case UNGE_EXPR:
      return LT_EXPR;
    case UNLT_EXPR:
      return GE_EXPR;
    case UNLE_EXPR:
      return GT_EXPR;
    case ORDERED_EXPR:
      return UNORDERED_EXPR;
    case UNORDERED_EXPR:
      return ORDERED_EXPR;
    default:
      gcc_unreachable ();
    }
}

/* Similar, but return the comparison that results if the operands are
   swapped.  This is safe for floating-point.  */

enum tree_code
swap_tree_comparison (enum tree_code code)
{
  switch (code)
    {
    case EQ_EXPR:
    case NE_EXPR:
    case ORDERED_EXPR:
    case UNORDERED_EXPR:
    case LTGT_EXPR:
    case UNEQ_EXPR:
      return code;
    case GT_EXPR:
      return LT_EXPR;
    case GE_EXPR:
      return LE_EXPR;
    case LT_EXPR:
      return GT_EXPR;
    case LE_EXPR:
      return GE_EXPR;
    case UNGT_EXPR:
      return UNLT_EXPR;
    case UNGE_EXPR:
      return UNLE_EXPR;
    case UNLT_EXPR:
      return UNGT_EXPR;
    case UNLE_EXPR:
      return UNGE_EXPR;
    default:
      gcc_unreachable ();
    }
}


/* Convert a comparison tree code from an enum tree_code representation
   into a compcode bit-based encoding.  This function is the inverse of
   compcode_to_comparison.  */

static enum comparison_code
comparison_to_compcode (enum tree_code code)
{
  switch (code)
    {
    case LT_EXPR:
      return COMPCODE_LT;
    case EQ_EXPR:
      return COMPCODE_EQ;
    case LE_EXPR:
      return COMPCODE_LE;
    case GT_EXPR:
      return COMPCODE_GT;
    case NE_EXPR:
      return COMPCODE_NE;
    case GE_EXPR:
      return COMPCODE_GE;
    case ORDERED_EXPR:
      return COMPCODE_ORD;
    case UNORDERED_EXPR:
      return COMPCODE_UNORD;
    case UNLT_EXPR:
      return COMPCODE_UNLT;
    case UNEQ_EXPR:
      return COMPCODE_UNEQ;
    case UNLE_EXPR:
      return COMPCODE_UNLE;
    case UNGT_EXPR:
      return COMPCODE_UNGT;
    case LTGT_EXPR:
      return COMPCODE_LTGT;
    case UNGE_EXPR:
      return COMPCODE_UNGE;
    default:
      gcc_unreachable ();
    }
}

/* Convert a compcode bit-based encoding of a comparison operator back
   to GCC's enum tree_code representation.  This function is the
   inverse of comparison_to_compcode.  */

static enum tree_code
compcode_to_comparison (enum comparison_code code)
{
  switch (code)
    {
    case COMPCODE_LT:
      return LT_EXPR;
    case COMPCODE_EQ:
      return EQ_EXPR;
    case COMPCODE_LE:
      return LE_EXPR;
    case COMPCODE_GT:
      return GT_EXPR;
    case COMPCODE_NE:
      return NE_EXPR;
    case COMPCODE_GE:
      return GE_EXPR;
    case COMPCODE_ORD:
      return ORDERED_EXPR;
    case COMPCODE_UNORD:
      return UNORDERED_EXPR;
    case COMPCODE_UNLT:
      return UNLT_EXPR;
    case COMPCODE_UNEQ:
      return UNEQ_EXPR;
    case COMPCODE_UNLE:
      return UNLE_EXPR;
    case COMPCODE_UNGT:
      return UNGT_EXPR;
    case COMPCODE_LTGT:
      return LTGT_EXPR;
    case COMPCODE_UNGE:
      return UNGE_EXPR;
    default:
      gcc_unreachable ();
    }
}

/* Return a tree for the comparison which is the combination of
   doing the AND or OR (depending on CODE) of the two operations LCODE
   and RCODE on the identical operands LL_ARG and LR_ARG.  Take into account
   the possibility of trapping if the mode has NaNs, and return NULL_TREE
   if this makes the transformation invalid.  */

tree
combine_comparisons (enum tree_code code, enum tree_code lcode,
		     enum tree_code rcode, tree truth_type,
		     tree ll_arg, tree lr_arg)
{
  bool honor_nans = HONOR_NANS (TYPE_MODE (TREE_TYPE (ll_arg)));
  enum comparison_code lcompcode = comparison_to_compcode (lcode);
  enum comparison_code rcompcode = comparison_to_compcode (rcode);
  enum comparison_code compcode;

  switch (code)
    {
    case TRUTH_AND_EXPR: case TRUTH_ANDIF_EXPR:
      compcode = lcompcode & rcompcode;
      break;

    case TRUTH_OR_EXPR: case TRUTH_ORIF_EXPR:
      compcode = lcompcode | rcompcode;
      break;

    default:
      return NULL_TREE;
    }

  if (!honor_nans)
    {
      /* Eliminate unordered comparisons, as well as LTGT and ORD
	 which are not used unless the mode has NaNs.  */
      compcode &= ~COMPCODE_UNORD;
      if (compcode == COMPCODE_LTGT)
	compcode = COMPCODE_NE;
      else if (compcode == COMPCODE_ORD)
	compcode = COMPCODE_TRUE;
    }
   else if (flag_trapping_math)
     {
	/* Check that the original operation and the optimized ones will trap
	   under the same condition.  */
	bool ltrap = (lcompcode & COMPCODE_UNORD) == 0
		     && (lcompcode != COMPCODE_EQ)
		     && (lcompcode != COMPCODE_ORD);
	bool rtrap = (rcompcode & COMPCODE_UNORD) == 0
		     && (rcompcode != COMPCODE_EQ)
		     && (rcompcode != COMPCODE_ORD);
	bool trap = (compcode & COMPCODE_UNORD) == 0
		    && (compcode != COMPCODE_EQ)
		    && (compcode != COMPCODE_ORD);

        /* In a short-circuited boolean expression the LHS might be
	   such that the RHS, if evaluated, will never trap.  For
	   example, in ORD (x, y) && (x < y), we evaluate the RHS only
	   if neither x nor y is NaN.  (This is a mixed blessing: for
	   example, the expression above will never trap, hence
	   optimizing it to x < y would be invalid).  */
        if ((code == TRUTH_ORIF_EXPR && (lcompcode & COMPCODE_UNORD))
            || (code == TRUTH_ANDIF_EXPR && !(lcompcode & COMPCODE_UNORD)))
          rtrap = false;

        /* If the comparison was short-circuited, and only the RHS
	   trapped, we may now generate a spurious trap.  */
	if (rtrap && !ltrap
	    && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR))
	  return NULL_TREE;

	/* If we changed the conditions that cause a trap, we lose.  */
	if ((ltrap || rtrap) != trap)
	  return NULL_TREE;
      }

  if (compcode == COMPCODE_TRUE)
    return constant_boolean_node (true, truth_type);
  else if (compcode == COMPCODE_FALSE)
    return constant_boolean_node (false, truth_type);
  else
    return fold_build2 (compcode_to_comparison (compcode),
			truth_type, ll_arg, lr_arg);
}

/* Return nonzero if CODE is a tree code that represents a truth value.  */

static int
truth_value_p (enum tree_code code)
{
  return (TREE_CODE_CLASS (code) == tcc_comparison
	  || code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
	  || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
	  || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
}

/* Return nonzero if two operands (typically of the same tree node)
   are necessarily equal.  If either argument has side-effects this
   function returns zero.  FLAGS modifies behavior as follows:

   If OEP_ONLY_CONST is set, only return nonzero for constants.
   This function tests whether the operands are indistinguishable;
   it does not test whether they are equal using C's == operation.
   The distinction is important for IEEE floating point, because
   (1) -0.0 and 0.0 are distinguishable, but -0.0==0.0, and
   (2) two NaNs may be indistinguishable, but NaN!=NaN.

   If OEP_ONLY_CONST is unset, a VAR_DECL is considered equal to itself
   even though it may hold multiple values during a function.
   This is because a GCC tree node guarantees that nothing else is
   executed between the evaluation of its "operands" (which may often
   be evaluated in arbitrary order).  Hence if the operands themselves
   don't side-effect, the VAR_DECLs, PARM_DECLs etc... must hold the
   same value in each operand/subexpression.  Hence leaving OEP_ONLY_CONST
   unset means assuming isochronic (or instantaneous) tree equivalence.
   Unless comparing arbitrary expression trees, such as from different
   statements, this flag can usually be left unset.

   If OEP_PURE_SAME is set, then pure functions with identical arguments
   are considered the same.  It is used when the caller has other ways
   to ensure that global memory is unchanged in between.  */

int
operand_equal_p (tree arg0, tree arg1, unsigned int flags)
{
  /* If either is ERROR_MARK, they aren't equal.  */
  if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK)
    return 0;

  /* If both types don't have the same signedness, then we can't consider
     them equal.  We must check this before the STRIP_NOPS calls
     because they may change the signedness of the arguments.  */
  if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1)))
    return 0;

  /* If both types don't have the same precision, then it is not safe
     to strip NOPs.  */
  if (TYPE_PRECISION (TREE_TYPE (arg0)) != TYPE_PRECISION (TREE_TYPE (arg1)))
    return 0;

  STRIP_NOPS (arg0);
  STRIP_NOPS (arg1);

  /* In case both args are comparisons but with different comparison
     code, try to swap the comparison operands of one arg to produce
     a match and compare that variant.  */
  if (TREE_CODE (arg0) != TREE_CODE (arg1)
      && COMPARISON_CLASS_P (arg0)
      && COMPARISON_CLASS_P (arg1))
    {
      enum tree_code swap_code = swap_tree_comparison (TREE_CODE (arg1));

      if (TREE_CODE (arg0) == swap_code)
	return operand_equal_p (TREE_OPERAND (arg0, 0),
			        TREE_OPERAND (arg1, 1), flags)
	       && operand_equal_p (TREE_OPERAND (arg0, 1),
				   TREE_OPERAND (arg1, 0), flags);
    }

  if (TREE_CODE (arg0) != TREE_CODE (arg1)
      /* This is needed for conversions and for COMPONENT_REF.
	 Might as well play it safe and always test this.  */
      || TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK
      || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK
      || TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)))
    return 0;

  /* If ARG0 and ARG1 are the same SAVE_EXPR, they are necessarily equal.
     We don't care about side effects in that case because the SAVE_EXPR
     takes care of that for us. In all other cases, two expressions are
     equal if they have no side effects.  If we have two identical
     expressions with side effects that should be treated the same due
     to the only side effects being identical SAVE_EXPR's, that will
     be detected in the recursive calls below.  */
  if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST)
      && (TREE_CODE (arg0) == SAVE_EXPR
	  || (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
    return 1;

  /* Next handle constant cases, those for which we can return 1 even
     if ONLY_CONST is set.  */
  if (TREE_CONSTANT (arg0) && TREE_CONSTANT (arg1))
    switch (TREE_CODE (arg0))
      {
      case INTEGER_CST:
	return (! TREE_CONSTANT_OVERFLOW (arg0)
		&& ! TREE_CONSTANT_OVERFLOW (arg1)
		&& tree_int_cst_equal (arg0, arg1));

      case REAL_CST:
	return (! TREE_CONSTANT_OVERFLOW (arg0)
		&& ! TREE_CONSTANT_OVERFLOW (arg1)
		&& REAL_VALUES_IDENTICAL (TREE_REAL_CST (arg0),
					  TREE_REAL_CST (arg1)));

      case VECTOR_CST:
	{
	  tree v1, v2;

	  if (TREE_CONSTANT_OVERFLOW (arg0)
	      || TREE_CONSTANT_OVERFLOW (arg1))
	    return 0;

	  v1 = TREE_VECTOR_CST_ELTS (arg0);
	  v2 = TREE_VECTOR_CST_ELTS (arg1);
	  while (v1 && v2)
	    {
	      if (!operand_equal_p (TREE_VALUE (v1), TREE_VALUE (v2),
				    flags))
		return 0;
	      v1 = TREE_CHAIN (v1);
	      v2 = TREE_CHAIN (v2);
	    }

	  return v1 == v2;
	}

      case COMPLEX_CST:
	return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
				 flags)
		&& operand_equal_p (TREE_IMAGPART (arg0), TREE_IMAGPART (arg1),
				    flags));

      case STRING_CST:
	return (TREE_STRING_LENGTH (arg0) == TREE_STRING_LENGTH (arg1)
		&& ! memcmp (TREE_STRING_POINTER (arg0),
			      TREE_STRING_POINTER (arg1),
			      TREE_STRING_LENGTH (arg0)));

      case ADDR_EXPR:
	return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
				0);
      default:
	break;
      }

  if (flags & OEP_ONLY_CONST)
    return 0;

/* Define macros to test an operand from arg0 and arg1 for equality and a
   variant that allows null and views null as being different from any
   non-null value.  In the latter case, if either is null, the both
   must be; otherwise, do the normal comparison.  */
#define OP_SAME(N) operand_equal_p (TREE_OPERAND (arg0, N),	\
				    TREE_OPERAND (arg1, N), flags)

#define OP_SAME_WITH_NULL(N)				\
  ((!TREE_OPERAND (arg0, N) || !TREE_OPERAND (arg1, N))	\
   ? TREE_OPERAND (arg0, N) == TREE_OPERAND (arg1, N) : OP_SAME (N))

  switch (TREE_CODE_CLASS (TREE_CODE (arg0)))
    {
    case tcc_unary:
      /* Two conversions are equal only if signedness and modes match.  */
      switch (TREE_CODE (arg0))
        {
        case NOP_EXPR:
        case CONVERT_EXPR:
        case FIX_CEIL_EXPR:
        case FIX_TRUNC_EXPR:
        case FIX_FLOOR_EXPR:
        case FIX_ROUND_EXPR:
	  if (TYPE_UNSIGNED (TREE_TYPE (arg0))
	      != TYPE_UNSIGNED (TREE_TYPE (arg1)))
	    return 0;
	  break;
	default:
	  break;
	}

      return OP_SAME (0);


    case tcc_comparison:
    case tcc_binary:
      if (OP_SAME (0) && OP_SAME (1))
	return 1;

      /* For commutative ops, allow the other order.  */
      return (commutative_tree_code (TREE_CODE (arg0))
	      && operand_equal_p (TREE_OPERAND (arg0, 0),
				  TREE_OPERAND (arg1, 1), flags)
	      && operand_equal_p (TREE_OPERAND (arg0, 1),
				  TREE_OPERAND (arg1, 0), flags));

    case tcc_reference:
      /* If either of the pointer (or reference) expressions we are
	 dereferencing contain a side effect, these cannot be equal.  */
      if (TREE_SIDE_EFFECTS (arg0)
	  || TREE_SIDE_EFFECTS (arg1))
	return 0;

      switch (TREE_CODE (arg0))
	{
	case INDIRECT_REF:
	case ALIGN_INDIRECT_REF:
	case MISALIGNED_INDIRECT_REF:
	case REALPART_EXPR:
	case IMAGPART_EXPR:
	  return OP_SAME (0);

	case ARRAY_REF:
	case ARRAY_RANGE_REF:
	  /* Operands 2 and 3 may be null.  */
	  return (OP_SAME (0)
		  && OP_SAME (1)
		  && OP_SAME_WITH_NULL (2)
		  && OP_SAME_WITH_NULL (3));

	case COMPONENT_REF:
	  /* Handle operand 2 the same as for ARRAY_REF.  Operand 0
	     may be NULL when we're called to compare MEM_EXPRs.  */
	  return OP_SAME_WITH_NULL (0)
		 && OP_SAME (1)
		 && OP_SAME_WITH_NULL (2);

	case BIT_FIELD_REF:
	  return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);

	default:
	  return 0;
	}

    case tcc_expression:
      switch (TREE_CODE (arg0))
	{
	case ADDR_EXPR:
	case TRUTH_NOT_EXPR:
	  return OP_SAME (0);

	case TRUTH_ANDIF_EXPR:
	case TRUTH_ORIF_EXPR:
	  return OP_SAME (0) && OP_SAME (1);

	case TRUTH_AND_EXPR:
	case TRUTH_OR_EXPR:
	case TRUTH_XOR_EXPR:
	  if (OP_SAME (0) && OP_SAME (1))
	    return 1;

	  /* Otherwise take into account this is a commutative operation.  */
	  return (operand_equal_p (TREE_OPERAND (arg0, 0),
				   TREE_OPERAND (arg1, 1), flags)
		  && operand_equal_p (TREE_OPERAND (arg0, 1),
				      TREE_OPERAND (arg1, 0), flags));

	case CALL_EXPR:
	  /* If the CALL_EXPRs call different functions, then they
	     clearly can not be equal.  */
	  if (!OP_SAME (0))
	    return 0;

	  {
	    unsigned int cef = call_expr_flags (arg0);
	    if (flags & OEP_PURE_SAME)
	      cef &= ECF_CONST | ECF_PURE;
	    else
	      cef &= ECF_CONST;
	    if (!cef)
	      return 0;
	  }

	  /* Now see if all the arguments are the same.  operand_equal_p
	     does not handle TREE_LIST, so we walk the operands here
	     feeding them to operand_equal_p.  */
	  arg0 = TREE_OPERAND (arg0, 1);
	  arg1 = TREE_OPERAND (arg1, 1);
	  while (arg0 && arg1)
	    {
	      if (! operand_equal_p (TREE_VALUE (arg0), TREE_VALUE (arg1),
				     flags))
		return 0;

	      arg0 = TREE_CHAIN (arg0);
	      arg1 = TREE_CHAIN (arg1);
	    }

	  /* If we get here and both argument lists are exhausted
	     then the CALL_EXPRs are equal.  */
	  return ! (arg0 || arg1);

	default:
	  return 0;
	}

    case tcc_declaration:
      /* Consider __builtin_sqrt equal to sqrt.  */
      return (TREE_CODE (arg0) == FUNCTION_DECL
	      && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
	      && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
	      && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1));

    default:
      return 0;
    }

#undef OP_SAME
#undef OP_SAME_WITH_NULL
}

/* Similar to operand_equal_p, but see if ARG0 might have been made by
   shorten_compare from ARG1 when ARG1 was being compared with OTHER.

   When in doubt, return 0.  */

static int
operand_equal_for_comparison_p (tree arg0, tree arg1, tree other)
{
  int unsignedp1, unsignedpo;
  tree primarg0, primarg1, primother;
  unsigned int correct_width;

  if (operand_equal_p (arg0, arg1, 0))
    return 1;

  if (! INTEGRAL_TYPE_P (TREE_TYPE (arg0))
      || ! INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
    return 0;

  /* Discard any conversions that don't change the modes of ARG0 and ARG1
     and see if the inner values are the same.  This removes any
     signedness comparison, which doesn't matter here.  */
  primarg0 = arg0, primarg1 = arg1;
  STRIP_NOPS (primarg0);
  STRIP_NOPS (primarg1);
  if (operand_equal_p (primarg0, primarg1, 0))
    return 1;

  /* Duplicate what shorten_compare does to ARG1 and see if that gives the
     actual comparison operand, ARG0.

     First throw away any conversions to wider types
     already present in the operands.  */

  primarg1 = get_narrower (arg1, &unsignedp1);
  primother = get_narrower (other, &unsignedpo);

  correct_width = TYPE_PRECISION (TREE_TYPE (arg1));
  if (unsignedp1 == unsignedpo
      && TYPE_PRECISION (TREE_TYPE (primarg1)) < correct_width
      && TYPE_PRECISION (TREE_TYPE (primother)) < correct_width)
    {
      tree type = TREE_TYPE (arg0);

      /* Make sure shorter operand is extended the right way
	 to match the longer operand.  */
      primarg1 = fold_convert (lang_hooks.types.signed_or_unsigned_type
			       (unsignedp1, TREE_TYPE (primarg1)), primarg1);

      if (operand_equal_p (arg0, fold_convert (type, primarg1), 0))
	return 1;
    }

  return 0;
}

/* See if ARG is an expression that is either a comparison or is performing
   arithmetic on comparisons.  The comparisons must only be comparing
   two different values, which will be stored in *CVAL1 and *CVAL2; if
   they are nonzero it means that some operands have already been found.
   No variables may be used anywhere else in the expression except in the
   comparisons.  If SAVE_P is true it means we removed a SAVE_EXPR around
   the expression and save_expr needs to be called with CVAL1 and CVAL2.

   If this is true, return 1.  Otherwise, return zero.  */

static int
twoval_comparison_p (tree arg, tree *cval1, tree *cval2, int *save_p)
{
  enum tree_code code = TREE_CODE (arg);
  enum tree_code_class class = TREE_CODE_CLASS (code);

  /* We can handle some of the tcc_expression cases here.  */
  if (class == tcc_expression && code == TRUTH_NOT_EXPR)
    class = tcc_unary;
  else if (class == tcc_expression
	   && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR
	       || code == COMPOUND_EXPR))
    class = tcc_binary;

  else if (class == tcc_expression && code == SAVE_EXPR
	   && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
    {
      /* If we've already found a CVAL1 or CVAL2, this expression is
	 two complex to handle.  */
      if (*cval1 || *cval2)
	return 0;

      class = tcc_unary;
      *save_p = 1;
    }

  switch (class)
    {
    case tcc_unary:
      return twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p);

    case tcc_binary:
      return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2, save_p)
	      && twoval_comparison_p (TREE_OPERAND (arg, 1),
				      cval1, cval2, save_p));

    case tcc_constant:
      return 1;

    case tcc_expression:
      if (code == COND_EXPR)
	return (twoval_comparison_p (TREE_OPERAND (arg, 0),
				     cval1, cval2, save_p)
		&& twoval_comparison_p (TREE_OPERAND (arg, 1),
					cval1, cval2, save_p)
		&& twoval_comparison_p (TREE_OPERAND (arg, 2),
					cval1, cval2, save_p));
      return 0;

    case tcc_comparison:
      /* First see if we can handle the first operand, then the second.  For
	 the second operand, we know *CVAL1 can't be zero.  It must be that
	 one side of the comparison is each of the values; test for the
	 case where this isn't true by failing if the two operands
	 are the same.  */

      if (operand_equal_p (TREE_OPERAND (arg, 0),
			   TREE_OPERAND (arg, 1), 0))
	return 0;

      if (*cval1 == 0)
	*cval1 = TREE_OPERAND (arg, 0);
      else if (operand_equal_p (*cval1, TREE_OPERAND (arg, 0), 0))
	;
      else if (*cval2 == 0)
	*cval2 = TREE_OPERAND (arg, 0);
      else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 0), 0))
	;
      else
	return 0;

      if (operand_equal_p (*cval1, TREE_OPERAND (arg, 1), 0))
	;
      else if (*cval2 == 0)
	*cval2 = TREE_OPERAND (arg, 1);
      else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 1), 0))
	;
      else
	return 0;

      return 1;

    default:
      return 0;
    }
}

/* ARG is a tree that is known to contain just arithmetic operations and
   comparisons.  Evaluate the operations in the tree substituting NEW0 for
   any occurrence of OLD0 as an operand of a comparison and likewise for
   NEW1 and OLD1.  */

static tree
eval_subst (tree arg, tree old0, tree new0, tree old1, tree new1)
{
  tree type = TREE_TYPE (arg);
  enum tree_code code = TREE_CODE (arg);
  enum tree_code_class class = TREE_CODE_CLASS (code);

  /* We can handle some of the tcc_expression cases here.  */
  if (class == tcc_expression && code == TRUTH_NOT_EXPR)
    class = tcc_unary;
  else if (class == tcc_expression
	   && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR))
    class = tcc_binary;

  switch (class)
    {
    case tcc_unary:
      return fold_build1 (code, type,
			  eval_subst (TREE_OPERAND (arg, 0),
				      old0, new0, old1, new1));

    case tcc_binary:
      return fold_build2 (code, type,
			  eval_subst (TREE_OPERAND (arg, 0),
				      old0, new0, old1, new1),
			  eval_subst (TREE_OPERAND (arg, 1),
				      old0, new0, old1, new1));

    case tcc_expression:
      switch (code)
	{
	case SAVE_EXPR:
	  return eval_subst (TREE_OPERAND (arg, 0), old0, new0, old1, new1);

	case COMPOUND_EXPR:
	  return eval_subst (TREE_OPERAND (arg, 1), old0, new0, old1, new1);

	case COND_EXPR:
	  return fold_build3 (code, type,
			      eval_subst (TREE_OPERAND (arg, 0),
					  old0, new0, old1, new1),
			      eval_subst (TREE_OPERAND (arg, 1),
					  old0, new0, old1, new1),
			      eval_subst (TREE_OPERAND (arg, 2),
					  old0, new0, old1, new1));
	default:
	  break;
	}
      /* Fall through - ???  */

    case tcc_comparison:
      {
	tree arg0 = TREE_OPERAND (arg, 0);
	tree arg1 = TREE_OPERAND (arg, 1);

	/* We need to check both for exact equality and tree equality.  The
	   former will be true if the operand has a side-effect.  In that
	   case, we know the operand occurred exactly once.  */

	if (arg0 == old0 || operand_equal_p (arg0, old0, 0))
	  arg0 = new0;
	else if (arg0 == old1 || operand_equal_p (arg0, old1, 0))
	  arg0 = new1;

	if (arg1 == old0 || operand_equal_p (arg1, old0, 0))
	  arg1 = new0;
	else if (arg1 == old1 || operand_equal_p (arg1, old1, 0))
	  arg1 = new1;

	return fold_build2 (code, type, arg0, arg1);
      }

    default:
      return arg;
    }
}

/* Return a tree for the case when the result of an expression is RESULT
   converted to TYPE and OMITTED was previously an operand of the expression
   but is now not needed (e.g., we folded OMITTED * 0).

   If OMITTED has side effects, we must evaluate it.  Otherwise, just do
   the conversion of RESULT to TYPE.  */

tree
omit_one_operand (tree type, tree result, tree omitted)
{
  tree t = fold_convert (type, result);

  if (TREE_SIDE_EFFECTS (omitted))
    return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);

  return non_lvalue (t);
}

/* Similar, but call pedantic_non_lvalue instead of non_lvalue.  */

static tree
pedantic_omit_one_operand (tree type, tree result, tree omitted)
{
  tree t = fold_convert (type, result);

  if (TREE_SIDE_EFFECTS (omitted))
    return build2 (COMPOUND_EXPR, type, fold_ignored_result (omitted), t);

  return pedantic_non_lvalue (t);
}

/* Return a tree for the case when the result of an expression is RESULT
   converted to TYPE and OMITTED1 and OMITTED2 were previously operands
   of the expression but are now not needed.

   If OMITTED1 or OMITTED2 has side effects, they must be evaluated.
   If both OMITTED1 and OMITTED2 have side effects, OMITTED1 is
   evaluated before OMITTED2.  Otherwise, if neither has side effects,
   just do the conversion of RESULT to TYPE.  */

tree
omit_two_operands (tree type, tree result, tree omitted1, tree omitted2)
{
  tree t = fold_convert (type, result);

  if (TREE_SIDE_EFFECTS (omitted2))
    t = build2 (COMPOUND_EXPR, type, omitted2, t);
  if (TREE_SIDE_EFFECTS (omitted1))
    t = build2 (COMPOUND_EXPR, type, omitted1, t);

  return TREE_CODE (t) != COMPOUND_EXPR ? non_lvalue (t) : t;
}


/* Return a simplified tree node for the truth-negation of ARG.  This
   never alters ARG itself.  We assume that ARG is an operation that
   returns a truth value (0 or 1).

   FIXME: one would think we would fold the result, but it causes
   problems with the dominator optimizer.  */

tree
fold_truth_not_expr (tree arg)
{
  tree type = TREE_TYPE (arg);
  enum tree_code code = TREE_CODE (arg);

  /* If this is a comparison, we can simply invert it, except for
     floating-point non-equality comparisons, in which case we just
     enclose a TRUTH_NOT_EXPR around what we have.  */

  if (TREE_CODE_CLASS (code) == tcc_comparison)
    {
      tree op_type = TREE_TYPE (TREE_OPERAND (arg, 0));
      if (FLOAT_TYPE_P (op_type)
	  && flag_trapping_math
	  && code != ORDERED_EXPR && code != UNORDERED_EXPR
	  && code != NE_EXPR && code != EQ_EXPR)
	return NULL_TREE;
      else
	{
	  code = invert_tree_comparison (code,
					 HONOR_NANS (TYPE_MODE (op_type)));
	  if (code == ERROR_MARK)
	    return NULL_TREE;
	  else
	    return build2 (code, type,
			   TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
	}
    }

  switch (code)
    {
    case INTEGER_CST:
      return constant_boolean_node (integer_zerop (arg), type);

    case TRUTH_AND_EXPR:
      return build2 (TRUTH_OR_EXPR, type,
		     invert_truthvalue (TREE_OPERAND (arg, 0)),
		     invert_truthvalue (TREE_OPERAND (arg, 1)));

    case TRUTH_OR_EXPR:
      return build2 (TRUTH_AND_EXPR, type,
		     invert_truthvalue (TREE_OPERAND (arg, 0)),
		     invert_truthvalue (TREE_OPERAND (arg, 1)));

    case TRUTH_XOR_EXPR:
      /* Here we can invert either operand.  We invert the first operand
	 unless the second operand is a TRUTH_NOT_EXPR in which case our
	 result is the XOR of the first operand with the inside of the
	 negation of the second operand.  */

      if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
	return build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
		       TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
      else
	return build2 (TRUTH_XOR_EXPR, type,
		       invert_truthvalue (TREE_OPERAND (arg, 0)),
		       TREE_OPERAND (arg, 1));

    case TRUTH_ANDIF_EXPR:
      return build2 (TRUTH_ORIF_EXPR, type,
		     invert_truthvalue (TREE_OPERAND (arg, 0)),
		     invert_truthvalue (TREE_OPERAND (arg, 1)));

    case TRUTH_ORIF_EXPR:
      return build2 (TRUTH_ANDIF_EXPR, type,
		     invert_truthvalue (TREE_OPERAND (arg, 0)),
		     invert_truthvalue (TREE_OPERAND (arg, 1)));

    case TRUTH_NOT_EXPR:
      return TREE_OPERAND (arg, 0);

    case COND_EXPR:
      {
	tree arg1 = TREE_OPERAND (arg, 1);
	tree arg2 = TREE_OPERAND (arg, 2);
	/* A COND_EXPR may have a throw as one operand, which
	   then has void type.  Just leave void operands
	   as they are.  */
	return build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
		       VOID_TYPE_P (TREE_TYPE (arg1))
		       ? arg1 : invert_truthvalue (arg1),
		       VOID_TYPE_P (TREE_TYPE (arg2))
		       ? arg2 : invert_truthvalue (arg2));
      }

    case COMPOUND_EXPR:
      return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
		     invert_truthvalue (TREE_OPERAND (arg, 1)));

    case NON_LVALUE_EXPR:
      return invert_truthvalue (TREE_OPERAND (arg, 0));

    case NOP_EXPR:
      if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
	return build1 (TRUTH_NOT_EXPR, type, arg);

    case CONVERT_EXPR:
    case FLOAT_EXPR:
      return build1 (TREE_CODE (arg), type,
		     invert_truthvalue (TREE_OPERAND (arg, 0)));

    case BIT_AND_EXPR:
      if (!integer_onep (TREE_OPERAND (arg, 1)))
	break;
      return build2 (EQ_EXPR, type, arg,
		     build_int_cst (type, 0));

    case SAVE_EXPR:
      return build1 (TRUTH_NOT_EXPR, type, arg);

    case CLEANUP_POINT_EXPR:
      return build1 (CLEANUP_POINT_EXPR, type,
		     invert_truthvalue (TREE_OPERAND (arg, 0)));

    default:
      break;
    }

  return NULL_TREE;
}

/* Return a simplified tree node for the truth-negation of ARG.  This
   never alters ARG itself.  We assume that ARG is an operation that
   returns a truth value (0 or 1).

   FIXME: one would think we would fold the result, but it causes
   problems with the dominator optimizer.  */

tree
invert_truthvalue (tree arg)
{
  tree tem;

  if (TREE_CODE (arg) == ERROR_MARK)
    return arg;

  tem = fold_truth_not_expr (arg);
  if (!tem)
    tem = build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg), arg);

  return tem;
}

/* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both
   operands are another bit-wise operation with a common input.  If so,
   distribute the bit operations to save an operation and possibly two if
   constants are involved.  For example, convert
	(A | B) & (A | C) into A | (B & C)
   Further simplification will occur if B and C are constants.

   If this optimization cannot be done, 0 will be returned.  */

static tree
distribute_bit_expr (enum tree_code code, tree type, tree arg0, tree arg1)
{
  tree common;
  tree left, right;

  if (TREE_CODE (arg0) != TREE_CODE (arg1)
      || TREE_CODE (arg0) == code
      || (TREE_CODE (arg0) != BIT_AND_EXPR
	  && TREE_CODE (arg0) != BIT_IOR_EXPR))
    return 0;

  if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0))
    {
      common = TREE_OPERAND (arg0, 0);
      left = TREE_OPERAND (arg0, 1);
      right = TREE_OPERAND (arg1, 1);
    }
  else if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 1), 0))
    {
      common = TREE_OPERAND (arg0, 0);
      left = TREE_OPERAND (arg0, 1);
      right = TREE_OPERAND (arg1, 0);
    }
  else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 0), 0))
    {
      common = TREE_OPERAND (arg0, 1);
      left = TREE_OPERAND (arg0, 0);
      right = TREE_OPERAND (arg1, 1);
    }
  else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1), 0))
    {
      common = TREE_OPERAND (arg0, 1);
      left = TREE_OPERAND (arg0, 0);
      right = TREE_OPERAND (arg1, 0);
    }
  else
    return 0;

  return fold_build2 (TREE_CODE (arg0), type, common,
		      fold_build2 (code, type, left, right));
}

/* Knowing that ARG0 and ARG1 are both RDIV_EXPRs, simplify a binary operation
   with code CODE.  This optimization is unsafe.  */
static tree
distribute_real_division (enum tree_code code, tree type, tree arg0, tree arg1)
{
  bool mul0 = TREE_CODE (arg0) == MULT_EXPR;
  bool mul1 = TREE_CODE (arg1) == MULT_EXPR;

  /* (A / C) +- (B / C) -> (A +- B) / C.  */
  if (mul0 == mul1
      && operand_equal_p (TREE_OPERAND (arg0, 1),
		       TREE_OPERAND (arg1, 1), 0))
    return fold_build2 (mul0 ? MULT_EXPR : RDIV_EXPR, type,
			fold_build2 (code, type,
				     TREE_OPERAND (arg0, 0),
				     TREE_OPERAND (arg1, 0)),
			TREE_OPERAND (arg0, 1));

  /* (A / C1) +- (A / C2) -> A * (1 / C1 +- 1 / C2).  */
  if (operand_equal_p (TREE_OPERAND (arg0, 0),
		       TREE_OPERAND (arg1, 0), 0)
      && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
      && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
    {
      REAL_VALUE_TYPE r0, r1;
      r0 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
      r1 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
      if (!mul0)
	real_arithmetic (&r0, RDIV_EXPR, &dconst1, &r0);
      if (!mul1)
        real_arithmetic (&r1, RDIV_EXPR, &dconst1, &r1);
      real_arithmetic (&r0, code, &r0, &r1);
      return fold_build2 (MULT_EXPR, type,
			  TREE_OPERAND (arg0, 0),
			  build_real (type, r0));
    }

  return NULL_TREE;
}

/* Return a BIT_FIELD_REF of type TYPE to refer to BITSIZE bits of INNER
   starting at BITPOS.  The field is unsigned if UNSIGNEDP is nonzero.  */

static tree
make_bit_field_ref (tree inner, tree type, int bitsize, int bitpos,
		    int unsignedp)
{
  tree result;

  if (bitpos == 0)
    {
      tree size = TYPE_SIZE (TREE_TYPE (inner));
      if ((INTEGRAL_TYPE_P (TREE_TYPE (inner))
	   || POINTER_TYPE_P (TREE_TYPE (inner)))
	  && host_integerp (size, 0) 
	  && tree_low_cst (size, 0) == bitsize)
	return fold_convert (type, inner);
    }

  result = build3 (BIT_FIELD_REF, type, inner,
		   size_int (bitsize), bitsize_int (bitpos));

  BIT_FIELD_REF_UNSIGNED (result) = unsignedp;

  return result;
}

/* Optimize a bit-field compare.

   There are two cases:  First is a compare against a constant and the
   second is a comparison of two items where the fields are at the same
   bit position relative to the start of a chunk (byte, halfword, word)
   large enough to contain it.  In these cases we can avoid the shift
   implicit in bitfield extractions.

   For constants, we emit a compare of the shifted constant with the
   BIT_AND_EXPR of a mask and a byte, halfword, or word of the operand being
   compared.  For two fields at the same position, we do the ANDs with the
   similar mask and compare the result of the ANDs.

   CODE is the comparison code, known to be either NE_EXPR or EQ_EXPR.
   COMPARE_TYPE is the type of the comparison, and LHS and RHS
   are the left and right operands of the comparison, respectively.

   If the optimization described above can be done, we return the resulting
   tree.  Otherwise we return zero.  */

static tree
optimize_bit_field_compare (enum tree_code code, tree compare_type,
			    tree lhs, tree rhs)
{
  HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
  tree type = TREE_TYPE (lhs);
  tree signed_type, unsigned_type;
  int const_p = TREE_CODE (rhs) == INTEGER_CST;
  enum machine_mode lmode, rmode, nmode;
  int lunsignedp, runsignedp;
  int lvolatilep = 0, rvolatilep = 0;
  tree linner, rinner = NULL_TREE;
  tree mask;
  tree offset;

  /* Get all the information about the extractions being done.  If the bit size
     if the same as the size of the underlying object, we aren't doing an
     extraction at all and so can do nothing.  We also don't want to
     do anything if the inner expression is a PLACEHOLDER_EXPR since we
     then will no longer be able to replace it.  */
  linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode,
				&lunsignedp, &lvolatilep, false);
  if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0
      || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR)
    return 0;

 if (!const_p)
   {
     /* If this is not a constant, we can only do something if bit positions,
	sizes, and signedness are the same.  */
     rinner = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
				   &runsignedp, &rvolatilep, false);

     if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize
	 || lunsignedp != runsignedp || offset != 0
	 || TREE_CODE (rinner) == PLACEHOLDER_EXPR)
       return 0;
   }

  /* See if we can find a mode to refer to this field.  We should be able to,
     but fail if we can't.  */
  nmode = get_best_mode (lbitsize, lbitpos,
			 const_p ? TYPE_ALIGN (TREE_TYPE (linner))
			 : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
				TYPE_ALIGN (TREE_TYPE (rinner))),
			 word_mode, lvolatilep || rvolatilep);
  if (nmode == VOIDmode)
    return 0;

  /* Set signed and unsigned types of the precision of this mode for the
     shifts below.  */
  signed_type = lang_hooks.types.type_for_mode (nmode, 0);
  unsigned_type = lang_hooks.types.type_for_mode (nmode, 1);

  /* Compute the bit position and size for the new reference and our offset
     within it. If the new reference is the same size as the original, we
     won't optimize anything, so return zero.  */
  nbitsize = GET_MODE_BITSIZE (nmode);
  nbitpos = lbitpos & ~ (nbitsize - 1);
  lbitpos -= nbitpos;
  if (nbitsize == lbitsize)
    return 0;

  if (BYTES_BIG_ENDIAN)
    lbitpos = nbitsize - lbitsize - lbitpos;

  /* Make the mask to be used against the extracted field.  */
  mask = build_int_cst (unsigned_type, -1);
  mask = force_fit_type (mask, 0, false, false);
  mask = fold_convert (unsigned_type, mask);
  mask = const_binop (LSHIFT_EXPR, mask, size_int (nbitsize - lbitsize), 0);
  mask = const_binop (RSHIFT_EXPR, mask,
		      size_int (nbitsize - lbitsize - lbitpos), 0);

  if (! const_p)
    /* If not comparing with constant, just rework the comparison
       and return.  */
    return build2 (code, compare_type,
		   build2 (BIT_AND_EXPR, unsigned_type,
			   make_bit_field_ref (linner, unsigned_type,
					       nbitsize, nbitpos, 1),
			   mask),
		   build2 (BIT_AND_EXPR, unsigned_type,
			   make_bit_field_ref (rinner, unsigned_type,
					       nbitsize, nbitpos, 1),
			   mask));

  /* Otherwise, we are handling the constant case. See if the constant is too
     big for the field.  Warn and return a tree of for 0 (false) if so.  We do
     this not only for its own sake, but to avoid having to test for this
     error case below.  If we didn't, we might generate wrong code.

     For unsigned fields, the constant shifted right by the field length should
     be all zero.  For signed fields, the high-order bits should agree with
     the sign bit.  */

  if (lunsignedp)
    {
      if (! integer_zerop (const_binop (RSHIFT_EXPR,
					fold_convert (unsigned_type, rhs),
					size_int (lbitsize), 0)))
	{
	  warning (0, "comparison is always %d due to width of bit-field",
		   code == NE_EXPR);
	  return constant_boolean_node (code == NE_EXPR, compare_type);
	}
    }
  else
    {
      tree tem = const_binop (RSHIFT_EXPR, fold_convert (signed_type, rhs),
			      size_int (lbitsize - 1), 0);
      if (! integer_zerop (tem) && ! integer_all_onesp (tem))
	{
	  warning (0, "comparison is always %d due to width of bit-field",
		   code == NE_EXPR);
	  return constant_boolean_node (code == NE_EXPR, compare_type);
	}
    }

  /* Single-bit compares should always be against zero.  */
  if (lbitsize == 1 && ! integer_zerop (rhs))
    {
      code = code == EQ_EXPR ? NE_EXPR : EQ_EXPR;
      rhs = build_int_cst (type, 0);
    }

  /* Make a new bitfield reference, shift the constant over the
     appropriate number of bits and mask it with the computed mask
     (in case this was a signed field).  If we changed it, make a new one.  */
  lhs = make_bit_field_ref (linner, unsigned_type, nbitsize, nbitpos, 1);
  if (lvolatilep)
    {
      TREE_SIDE_EFFECTS (lhs) = 1;
      TREE_THIS_VOLATILE (lhs) = 1;
    }

  rhs = const_binop (BIT_AND_EXPR,
		     const_binop (LSHIFT_EXPR,
				  fold_convert (unsigned_type, rhs),
				  size_int (lbitpos), 0),
		     mask, 0);

  return build2 (code, compare_type,
		 build2 (BIT_AND_EXPR, unsigned_type, lhs, mask),
		 rhs);
}

/* Subroutine for fold_truthop: decode a field reference.

   If EXP is a comparison reference, we return the innermost reference.

   *PBITSIZE is set to the number of bits in the reference, *PBITPOS is
   set to the starting bit number.

   If the innermost field can be completely contained in a mode-sized
   unit, *PMODE is set to that mode.  Otherwise, it is set to VOIDmode.

   *PVOLATILEP is set to 1 if the any expression encountered is volatile;
   otherwise it is not changed.

   *PUNSIGNEDP is set to the signedness of the field.

   *PMASK is set to the mask used.  This is either contained in a
   BIT_AND_EXPR or derived from the width of the field.

   *PAND_MASK is set to the mask found in a BIT_AND_EXPR, if any.

   Return 0 if this is not a component reference or is one that we can't
   do anything with.  */

static tree
decode_field_reference (tree exp, HOST_WIDE_INT *pbitsize,
			HOST_WIDE_INT *pbitpos, enum machine_mode *pmode,
			int *punsignedp, int *pvolatilep,
			tree *pmask, tree *pand_mask)
{
  tree outer_type = 0;
  tree and_mask = 0;
  tree mask, inner, offset;
  tree unsigned_type;
  unsigned int precision;

  /* All the optimizations using this function assume integer fields.
     There are problems with FP fields since the type_for_size call
     below can fail for, e.g., XFmode.  */
  if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
    return 0;

  /* We are interested in the bare arrangement of bits, so strip everything
     that doesn't affect the machine mode.  However, record the type of the
     outermost expression if it may matter below.  */
  if (TREE_CODE (exp) == NOP_EXPR
      || TREE_CODE (exp) == CONVERT_EXPR
      || TREE_CODE (exp) == NON_LVALUE_EXPR)
    outer_type = TREE_TYPE (exp);
  STRIP_NOPS (exp);

  if (TREE_CODE (exp) == BIT_AND_EXPR)
    {
      and_mask = TREE_OPERAND (exp, 1);
      exp = TREE_OPERAND (exp, 0);
      STRIP_NOPS (exp); STRIP_NOPS (and_mask);
      if (TREE_CODE (and_mask) != INTEGER_CST)
	return 0;
    }

  inner = get_inner_reference (exp, pbitsize, pbitpos, &offset, pmode,
			       punsignedp, pvolatilep, false);
  if ((inner == exp && and_mask == 0)
      || *pbitsize < 0 || offset != 0
      || TREE_CODE (inner) == PLACEHOLDER_EXPR)
    return 0;

  /* If the number of bits in the reference is the same as the bitsize of
     the outer type, then the outer type gives the signedness. Otherwise
     (in case of a small bitfield) the signedness is unchanged.  */
  if (outer_type && *pbitsize == TYPE_PRECISION (outer_type))
    *punsignedp = TYPE_UNSIGNED (outer_type);

  /* Compute the mask to access the bitfield.  */
  unsigned_type = lang_hooks.types.type_for_size (*pbitsize, 1);
  precision = TYPE_PRECISION (unsigned_type);

  mask = build_int_cst (unsigned_type, -1);
  mask = force_fit_type (mask, 0, false, false);

  mask = const_binop (LSHIFT_EXPR, mask, size_int (precision - *pbitsize), 0);
  mask = const_binop (RSHIFT_EXPR, mask, size_int (precision - *pbitsize), 0);

  /* Merge it with the mask we found in the BIT_AND_EXPR, if any.  */
  if (and_mask != 0)
    mask = fold_build2 (BIT_AND_EXPR, unsigned_type,
			fold_convert (unsigned_type, and_mask), mask);

  *pmask = mask;
  *pand_mask = and_mask;
  return inner;
}

/* Return nonzero if MASK represents a mask of SIZE ones in the low-order
   bit positions.  */

static int
all_ones_mask_p (tree mask, int size)
{
  tree type = TREE_TYPE (mask);
  unsigned int precision = TYPE_PRECISION (type);
  tree tmask;

  tmask = build_int_cst (lang_hooks.types.signed_type (type), -1);
  tmask = force_fit_type (tmask, 0, false, false);

  return
    tree_int_cst_equal (mask,
			const_binop (RSHIFT_EXPR,
				     const_binop (LSHIFT_EXPR, tmask,
						  size_int (precision - size),
						  0),
				     size_int (precision - size), 0));
}

/* Subroutine for fold: determine if VAL is the INTEGER_CONST that
   represents the sign bit of EXP's type.  If EXP represents a sign
   or zero extension, also test VAL against the unextended type.
   The return value is the (sub)expression whose sign bit is VAL,
   or NULL_TREE otherwise.  */

static tree
sign_bit_p (tree exp, tree val)
{
  unsigned HOST_WIDE_INT mask_lo, lo;
  HOST_WIDE_INT mask_hi, hi;
  int width;
  tree t;

  /* Tree EXP must have an integral type.  */
  t = TREE_TYPE (exp);
  if (! INTEGRAL_TYPE_P (t))
    return NULL_TREE;

  /* Tree VAL must be an integer constant.  */
  if (TREE_CODE (val) != INTEGER_CST
      || TREE_CONSTANT_OVERFLOW (val))
    return NULL_TREE;

  width = TYPE_PRECISION (t);
  if (width > HOST_BITS_PER_WIDE_INT)
    {
      hi = (unsigned HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT - 1);
      lo = 0;

      mask_hi = ((unsigned HOST_WIDE_INT) -1
		 >> (2 * HOST_BITS_PER_WIDE_INT - width));
      mask_lo = -1;
    }
  else
    {
      hi = 0;
      lo = (unsigned HOST_WIDE_INT) 1 << (width - 1);

      mask_hi = 0;
      mask_lo = ((unsigned HOST_WIDE_INT) -1
		 >> (HOST_BITS_PER_WIDE_INT - width));
    }

  /* We mask off those bits beyond TREE_TYPE (exp) so that we can
     treat VAL as if it were unsigned.  */
  if ((TREE_INT_CST_HIGH (val) & mask_hi) == hi
      && (TREE_INT_CST_LOW (val) & mask_lo) == lo)
    return exp;

  /* Handle extension from a narrower type.  */
  if (TREE_CODE (exp) == NOP_EXPR
      && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))) < width)
    return sign_bit_p (TREE_OPERAND (exp, 0), val);

  return NULL_TREE;
}

/* Subroutine for fold_truthop: determine if an operand is simple enough
   to be evaluated unconditionally.  */

static int
simple_operand_p (tree exp)
{
  /* Strip any conversions that don't change the machine mode.  */
  STRIP_NOPS (exp);

  return (CONSTANT_CLASS_P (exp)
	  || TREE_CODE (exp) == SSA_NAME
	  || (DECL_P (exp)
	      && ! TREE_ADDRESSABLE (exp)
	      && ! TREE_THIS_VOLATILE (exp)
	      && ! DECL_NONLOCAL (exp)
	      /* Don't regard global variables as simple.  They may be
		 allocated in ways unknown to the compiler (shared memory,
		 #pragma weak, etc).  */
	      && ! TREE_PUBLIC (exp)
	      && ! DECL_EXTERNAL (exp)
	      /* Loading a static variable is unduly expensive, but global
		 registers aren't expensive.  */
	      && (! TREE_STATIC (exp) || DECL_REGISTER (exp))));
}

/* The following functions are subroutines to fold_range_test and allow it to
   try to change a logical combination of comparisons into a range test.

   For example, both
	X == 2 || X == 3 || X == 4 || X == 5
   and
	X >= 2 && X <= 5
   are converted to
	(unsigned) (X - 2) <= 3

   We describe each set of comparisons as being either inside or outside
   a range, using a variable named like IN_P, and then describe the
   range with a lower and upper bound.  If one of the bounds is omitted,
   it represents either the highest or lowest value of the type.

   In the comments below, we represent a range by two numbers in brackets
   preceded by a "+" to designate being inside that range, or a "-" to
   designate being outside that range, so the condition can be inverted by
   flipping the prefix.  An omitted bound is represented by a "-".  For
   example, "- [-, 10]" means being outside the range starting at the lowest
   possible value and ending at 10, in other words, being greater than 10.
   The range "+ [-, -]" is always true and hence the range "- [-, -]" is
   always false.

   We set up things so that the missing bounds are handled in a consistent
   manner so neither a missing bound nor "true" and "false" need to be
   handled using a special case.  */

/* Return the result of applying CODE to ARG0 and ARG1, but handle the case
   of ARG0 and/or ARG1 being omitted, meaning an unlimited range. UPPER0_P
   and UPPER1_P are nonzero if the respective argument is an upper bound
   and zero for a lower.  TYPE, if nonzero, is the type of the result; it
   must be specified for a comparison.  ARG1 will be converted to ARG0's
   type if both are specified.  */

static tree
range_binop (enum tree_code code, tree type, tree arg0, int upper0_p,
	     tree arg1, int upper1_p)
{
  tree tem;
  int result;
  int sgn0, sgn1;

  /* If neither arg represents infinity, do the normal operation.
     Else, if not a comparison, return infinity.  Else handle the special
     comparison rules. Note that most of the cases below won't occur, but
     are handled for consistency.  */

  if (arg0 != 0 && arg1 != 0)
    {
      tem = fold_build2 (code, type != 0 ? type : TREE_TYPE (arg0),
			 arg0, fold_convert (TREE_TYPE (arg0), arg1));
      STRIP_NOPS (tem);
      return TREE_CODE (tem) == INTEGER_CST ? tem : 0;
    }

  if (TREE_CODE_CLASS (code) != tcc_comparison)
    return 0;

  /* Set SGN[01] to -1 if ARG[01] is a lower bound, 1 for upper, and 0
     for neither.  In real maths, we cannot assume open ended ranges are
     the same. But, this is computer arithmetic, where numbers are finite.
     We can therefore make the transformation of any unbounded range with
     the value Z, Z being greater than any representable number. This permits
     us to treat unbounded ranges as equal.  */
  sgn0 = arg0 != 0 ? 0 : (upper0_p ? 1 : -1);
  sgn1 = arg1 != 0 ? 0 : (upper1_p ? 1 : -1);
  switch (code)
    {
    case EQ_EXPR:
      result = sgn0 == sgn1;
      break;
    case NE_EXPR:
      result = sgn0 != sgn1;
      break;
    case LT_EXPR:
      result = sgn0 < sgn1;
      break;
    case LE_EXPR:
      result = sgn0 <= sgn1;
      break;
    case GT_EXPR:
      result = sgn0 > sgn1;
      break;
    case GE_EXPR:
      result = sgn0 >= sgn1;
      break;
    default:
      gcc_unreachable ();
    }

  return constant_boolean_node (result, type);
}

/* Given EXP, a logical expression, set the range it is testing into
   variables denoted by PIN_P, PLOW, and PHIGH.  Return the expression
   actually being tested.  *PLOW and *PHIGH will be made of the same
   type as the returned expression.  If EXP is not a comparison, we
   will most likely not be returning a useful value and range.  Set
   *STRICT_OVERFLOW_P to true if the return value is only valid
   because signed overflow is undefined; otherwise, do not change
   *STRICT_OVERFLOW_P.  */

static tree
make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
	    bool *strict_overflow_p)
{
  enum tree_code code;
  tree arg0 = NULL_TREE, arg1 = NULL_TREE;
  tree exp_type = NULL_TREE, arg0_type = NULL_TREE;
  int in_p, n_in_p;
  tree low, high, n_low, n_high;

  /* Start with simply saying "EXP != 0" and then look at the code of EXP
     and see if we can refine the range.  Some of the cases below may not
     happen, but it doesn't seem worth worrying about this.  We "continue"
     the outer loop when we've changed something; otherwise we "break"
     the switch, which will "break" the while.  */

  in_p = 0;
  low = high = build_int_cst (TREE_TYPE (exp), 0);

  while (1)
    {
      code = TREE_CODE (exp);
      exp_type = TREE_TYPE (exp);

      if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
	{
	  if (TREE_CODE_LENGTH (code) > 0)
	    arg0 = TREE_OPERAND (exp, 0);
	  if (TREE_CODE_CLASS (code) == tcc_comparison
	      || TREE_CODE_CLASS (code) == tcc_unary
	      || TREE_CODE_CLASS (code) == tcc_binary)
	    arg0_type = TREE_TYPE (arg0);
	  if (TREE_CODE_CLASS (code) == tcc_binary
	      || TREE_CODE_CLASS (code) == tcc_comparison
	      || (TREE_CODE_CLASS (code) == tcc_expression
		  && TREE_CODE_LENGTH (code) > 1))
	    arg1 = TREE_OPERAND (exp, 1);
	}

      switch (code)
	{
	case TRUTH_NOT_EXPR:
	  in_p = ! in_p, exp = arg0;
	  continue;

	case EQ_EXPR: case NE_EXPR:
	case LT_EXPR: case LE_EXPR: case GE_EXPR: case GT_EXPR:
	  /* We can only do something if the range is testing for zero
	     and if the second operand is an integer constant.  Note that
	     saying something is "in" the range we make is done by
	     complementing IN_P since it will set in the initial case of
	     being not equal to zero; "out" is leaving it alone.  */
	  if (low == 0 || high == 0
	      || ! integer_zerop (low) || ! integer_zerop (high)
	      || TREE_CODE (arg1) != INTEGER_CST)
	    break;

	  switch (code)
	    {
	    case NE_EXPR:  /* - [c, c]  */
	      low = high = arg1;
	      break;
	    case EQ_EXPR:  /* + [c, c]  */
	      in_p = ! in_p, low = high = arg1;
	      break;
	    case GT_EXPR:  /* - [-, c] */
	      low = 0, high = arg1;
	      break;
	    case GE_EXPR:  /* + [c, -] */
	      in_p = ! in_p, low = arg1, high = 0;
	      break;
	    case LT_EXPR:  /* - [c, -] */
	      low = arg1, high = 0;
	      break;
	    case LE_EXPR:  /* + [-, c] */
	      in_p = ! in_p, low = 0, high = arg1;
	      break;
	    default:
	      gcc_unreachable ();
	    }

	  /* If this is an unsigned comparison, we also know that EXP is
	     greater than or equal to zero.  We base the range tests we make
	     on that fact, so we record it here so we can parse existing
	     range tests.  We test arg0_type since often the return type
	     of, e.g. EQ_EXPR, is boolean.  */
	  if (TYPE_UNSIGNED (arg0_type) && (low == 0 || high == 0))
	    {
	      if (! merge_ranges (&n_in_p, &n_low, &n_high,
				  in_p, low, high, 1,
				  build_int_cst (arg0_type, 0),
				  NULL_TREE))
		break;

	      in_p = n_in_p, low = n_low, high = n_high;

	      /* If the high bound is missing, but we have a nonzero low
		 bound, reverse the range so it goes from zero to the low bound
		 minus 1.  */
	      if (high == 0 && low && ! integer_zerop (low))
		{
		  in_p = ! in_p;
		  high = range_binop (MINUS_EXPR, NULL_TREE, low, 0,
				      integer_one_node, 0);
		  low = build_int_cst (arg0_type, 0);
		}
	    }

	  exp = arg0;
	  continue;

	case NEGATE_EXPR:
	  /* (-x) IN [a,b] -> x in [-b, -a]  */
	  n_low = range_binop (MINUS_EXPR, exp_type,
			       build_int_cst (exp_type, 0),
			       0, high, 1);
	  n_high = range_binop (MINUS_EXPR, exp_type,
				build_int_cst (exp_type, 0),
				0, low, 0);
	  low = n_low, high = n_high;
	  exp = arg0;
	  continue;

	case BIT_NOT_EXPR:
	  /* ~ X -> -X - 1  */
	  exp = build2 (MINUS_EXPR, exp_type, negate_expr (arg0),
			build_int_cst (exp_type, 1));
	  continue;

	case PLUS_EXPR:  case MINUS_EXPR:
	  if (TREE_CODE (arg1) != INTEGER_CST)
	    break;

	  /* If flag_wrapv and ARG0_TYPE is signed, then we cannot
	     move a constant to the other side.  */
	  if (!TYPE_UNSIGNED (arg0_type)
	      && !TYPE_OVERFLOW_UNDEFINED (arg0_type))
	    break;

	  /* If EXP is signed, any overflow in the computation is undefined,
	     so we don't worry about it so long as our computations on
	     the bounds don't overflow.  For unsigned, overflow is defined
	     and this is exactly the right thing.  */
	  n_low = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
			       arg0_type, low, 0, arg1, 0);
	  n_high = range_binop (code == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR,
				arg0_type, high, 1, arg1, 0);
	  if ((n_low != 0 && TREE_OVERFLOW (n_low))
	      || (n_high != 0 && TREE_OVERFLOW (n_high)))
	    break;

	  if (TYPE_OVERFLOW_UNDEFINED (arg0_type))
	    *strict_overflow_p = true;

	  /* Check for an unsigned range which has wrapped around the maximum
	     value thus making n_high < n_low, and normalize it.  */
	  if (n_low && n_high && tree_int_cst_lt (n_high, n_low))
	    {
	      low = range_binop (PLUS_EXPR, arg0_type, n_high, 0,
				 integer_one_node, 0);
	      high = range_binop (MINUS_EXPR, arg0_type, n_low, 0,
				  integer_one_node, 0);

	      /* If the range is of the form +/- [ x+1, x ], we won't
		 be able to normalize it.  But then, it represents the
		 whole range or the empty set, so make it
		 +/- [ -, - ].  */
	      if (tree_int_cst_equal (n_low, low)
		  && tree_int_cst_equal (n_high, high))
		low = high = 0;
	      else
		in_p = ! in_p;
	    }
	  else
	    low = n_low, high = n_high;

	  exp = arg0;
	  continue;

	case NOP_EXPR:  case NON_LVALUE_EXPR:  case CONVERT_EXPR:
	  if (TYPE_PRECISION (arg0_type) > TYPE_PRECISION (exp_type))
	    break;

	  if (! INTEGRAL_TYPE_P (arg0_type)
	      || (low != 0 && ! int_fits_type_p (low, arg0_type))
	      || (high != 0 && ! int_fits_type_p (high, arg0_type)))
	    break;

	  n_low = low, n_high = high;

	  if (n_low != 0)
	    n_low = fold_convert (arg0_type, n_low);

	  if (n_high != 0)
	    n_high = fold_convert (arg0_type, n_high);


	  /* If we're converting arg0 from an unsigned type, to exp,
	     a signed type,  we will be doing the comparison as unsigned.
	     The tests above have already verified that LOW and HIGH
	     are both positive.

	     So we have to ensure that we will handle large unsigned
	     values the same way that the current signed bounds treat
	     negative values.  */

	  if (!TYPE_UNSIGNED (exp_type) && TYPE_UNSIGNED (arg0_type))
	    {
	      tree high_positive;
	      tree equiv_type = lang_hooks.types.type_for_mode
		(TYPE_MODE (arg0_type), 1);

	      /* A range without an upper bound is, naturally, unbounded.
		 Since convert would have cropped a very large value, use
		 the max value for the destination type.  */
	      high_positive
		= TYPE_MAX_VALUE (equiv_type) ? TYPE_MAX_VALUE (equiv_type)
		: TYPE_MAX_VALUE (arg0_type);

	      if (TYPE_PRECISION (exp_type) == TYPE_PRECISION (arg0_type))
		high_positive = fold_build2 (RSHIFT_EXPR, arg0_type,
					     fold_convert (arg0_type,
							   high_positive),
					     fold_convert (arg0_type,
							   integer_one_node));

	      /* If the low bound is specified, "and" the range with the
		 range for which the original unsigned value will be
		 positive.  */
	      if (low != 0)
		{
		  if (! merge_ranges (&n_in_p, &n_low, &n_high,
				      1, n_low, n_high, 1,
				      fold_convert (arg0_type,
						    integer_zero_node),
				      high_positive))
		    break;

		  in_p = (n_in_p == in_p);
		}
	      else
		{
		  /* Otherwise, "or" the range with the range of the input
		     that will be interpreted as negative.  */
		  if (! merge_ranges (&n_in_p, &n_low, &n_high,
				      0, n_low, n_high, 1,
				      fold_convert (arg0_type,
						    integer_zero_node),
				      high_positive))
		    break;

		  in_p = (in_p != n_in_p);
		}
	    }

	  exp = arg0;
	  low = n_low, high = n_high;
	  continue;

	default:
	  break;
	}

      break;
    }

  /* If EXP is a constant, we can evaluate whether this is true or false.  */
  if (TREE_CODE (exp) == INTEGER_CST)
    {
      in_p = in_p == (integer_onep (range_binop (GE_EXPR, integer_type_node,
						 exp, 0, low, 0))
		      && integer_onep (range_binop (LE_EXPR, integer_type_node,
						    exp, 1, high, 1)));
      low = high = 0;
      exp = 0;
    }

  *pin_p = in_p, *plow = low, *phigh = high;
  return exp;
}

/* Given a range, LOW, HIGH, and IN_P, an expression, EXP, and a result
   type, TYPE, return an expression to test if EXP is in (or out of, depending
   on IN_P) the range.  Return 0 if the test couldn't be created.  */

static tree
build_range_check (tree type, tree exp, int in_p, tree low, tree high)
{
  tree etype = TREE_TYPE (exp);
  tree value;

#ifdef HAVE_canonicalize_funcptr_for_compare
  /* Disable this optimization for function pointer expressions
     on targets that require function pointer canonicalization.  */
  if (HAVE_canonicalize_funcptr_for_compare
      && TREE_CODE (etype) == POINTER_TYPE
      && TREE_CODE (TREE_TYPE (etype)) == FUNCTION_TYPE)
    return NULL_TREE;
#endif

  if (! in_p)
    {
      value = build_range_check (type, exp, 1, low, high);
      if (value != 0)
        return invert_truthvalue (value);

      return 0;
    }

  if (low == 0 && high == 0)
    return build_int_cst (type, 1);

  if (low == 0)
    return fold_build2 (LE_EXPR, type, exp,
			fold_convert (etype, high));

  if (high == 0)
    return fold_build2 (GE_EXPR, type, exp,
			fold_convert (etype, low));

  if (operand_equal_p (low, high, 0))
    return fold_build2 (EQ_EXPR, type, exp,
			fold_convert (etype, low));

  if (integer_zerop (low))
    {
      if (! TYPE_UNSIGNED (etype))
	{
	  etype = lang_hooks.types.unsigned_type (etype);
	  high = fold_convert (etype, high);
	  exp = fold_convert (etype, exp);
	}
      return build_range_check (type, exp, 1, 0, high);
    }

  /* Optimize (c>=1) && (c<=127) into (signed char)c > 0.  */
  if (integer_onep (low) && TREE_CODE (high) == INTEGER_CST)
    {
      unsigned HOST_WIDE_INT lo;
      HOST_WIDE_INT hi;
      int prec;

      prec = TYPE_PRECISION (etype);
      if (prec <= HOST_BITS_PER_WIDE_INT)
	{
	  hi = 0;
	  lo = ((unsigned HOST_WIDE_INT) 1 << (prec - 1)) - 1;
	}
      else
	{
	  hi = ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1)) - 1;
	  lo = (unsigned HOST_WIDE_INT) -1;
	}

      if (TREE_INT_CST_HIGH (high) == hi && TREE_INT_CST_LOW (high) == lo)
	{
	  if (TYPE_UNSIGNED (etype))
	    {
	      etype = lang_hooks.types.signed_type (etype);
	      exp = fold_convert (etype, exp);
	    }
	  return fold_build2 (GT_EXPR, type, exp,
			      build_int_cst (etype, 0));
	}
    }

  /* Optimize (c>=low) && (c<=high) into (c-low>=0) && (c-low<=high-low).
     This requires wrap-around arithmetics for the type of the expression.  */
  switch (TREE_CODE (etype))
    {
    case INTEGER_TYPE:
      /* There is no requirement that LOW be within the range of ETYPE
	 if the latter is a subtype.  It must, however, be within the base
	 type of ETYPE.  So be sure we do the subtraction in that type.  */
      if (TREE_TYPE (etype))
	etype = TREE_TYPE (etype);
      break;

    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
      etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
					      TYPE_UNSIGNED (etype));
      break;

    default:
      break;
    }

  /* If we don't have wrap-around arithmetics upfront, try to force it.  */
  if (TREE_CODE (etype) == INTEGER_TYPE
      && !TYPE_OVERFLOW_WRAPS (etype))
    {
      tree utype, minv, maxv;

      /* Check if (unsigned) INT_MAX + 1 == (unsigned) INT_MIN
	 for the type in question, as we rely on this here.  */
      utype = lang_hooks.types.unsigned_type (etype);
      maxv = fold_convert (utype, TYPE_MAX_VALUE (etype));
      maxv = range_binop (PLUS_EXPR, NULL_TREE, maxv, 1,
			  integer_one_node, 1);
      minv = fold_convert (utype, TYPE_MIN_VALUE (etype));

      if (integer_zerop (range_binop (NE_EXPR, integer_type_node,
				      minv, 1, maxv, 1)))
	etype = utype;
      else
	return 0;
    }

  high = fold_convert (etype, high);
  low = fold_convert (etype, low);
  exp = fold_convert (etype, exp);

  value = const_binop (MINUS_EXPR, high, low, 0);

  if (value != 0 && !TREE_OVERFLOW (value))
    return build_range_check (type,
			      fold_build2 (MINUS_EXPR, etype, exp, low),
			      1, build_int_cst (etype, 0), value);

  return 0;
}

/* Return the predecessor of VAL in its type, handling the infinite case.  */

static tree
range_predecessor (tree val)
{
  tree type = TREE_TYPE (val);

  if (INTEGRAL_TYPE_P (type)
      && operand_equal_p (val, TYPE_MIN_VALUE (type), 0))
    return 0;
  else
    return range_binop (MINUS_EXPR, NULL_TREE, val, 0, integer_one_node, 0);
}

/* Return the successor of VAL in its type, handling the infinite case.  */

static tree
range_successor (tree val)
{
  tree type = TREE_TYPE (val);

  if (INTEGRAL_TYPE_P (type)
      && operand_equal_p (val, TYPE_MAX_VALUE (type), 0))
    return 0;
  else
    return range_binop (PLUS_EXPR, NULL_TREE, val, 0, integer_one_node, 0);
}

/* Given two ranges, see if we can merge them into one.  Return 1 if we
   can, 0 if we can't.  Set the output range into the specified parameters.  */

static int
merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
	      tree high0, int in1_p, tree low1, tree high1)
{
  int no_overlap;
  int subset;
  int temp;
  tree tem;
  int in_p;
  tree low, high;
  int lowequal = ((low0 == 0 && low1 == 0)
		  || integer_onep (range_binop (EQ_EXPR, integer_type_node,
						low0, 0, low1, 0)));
  int highequal = ((high0 == 0 && high1 == 0)
		   || integer_onep (range_binop (EQ_EXPR, integer_type_node,
						 high0, 1, high1, 1)));

  /* Make range 0 be the range that starts first, or ends last if they
     start at the same value.  Swap them if it isn't.  */
  if (integer_onep (range_binop (GT_EXPR, integer_type_node,
				 low0, 0, low1, 0))
      || (lowequal
	  && integer_onep (range_binop (GT_EXPR, integer_type_node,
					high1, 1, high0, 1))))
    {
      temp = in0_p, in0_p = in1_p, in1_p = temp;
      tem = low0, low0 = low1, low1 = tem;
      tem = high0, high0 = high1, high1 = tem;
    }

  /* Now flag two cases, whether the ranges are disjoint or whether the
     second range is totally subsumed in the first.  Note that the tests
     below are simplified by the ones above.  */
  no_overlap = integer_onep (range_binop (LT_EXPR, integer_type_node,
					  high0, 1, low1, 0));
  subset = integer_onep (range_binop (LE_EXPR, integer_type_node,
				      high1, 1, high0, 1));

  /* We now have four cases, depending on whether we are including or
     excluding the two ranges.  */
  if (in0_p && in1_p)
    {
      /* If they don't overlap, the result is false.  If the second range
	 is a subset it is the result.  Otherwise, the range is from the start
	 of the second to the end of the first.  */
      if (no_overlap)
	in_p = 0, low = high = 0;
      else if (subset)
	in_p = 1, low = low1, high = high1;
      else
	in_p = 1, low = low1, high = high0;
    }

  else if (in0_p && ! in1_p)
    {
      /* If they don't overlap, the result is the first range.  If they are
	 equal, the result is false.  If the second range is a subset of the
	 first, and the ranges begin at the same place, we go from just after
	 the end of the second range to the end of the first.  If the second
	 range is not a subset of the first, or if it is a subset and both
	 ranges end at the same place, the range starts at the start of the
	 first range and ends just before the second range.
	 Otherwise, we can't describe this as a single range.  */
      if (no_overlap)
	in_p = 1, low = low0, high = high0;
      else if (lowequal && highequal)
	in_p = 0, low = high = 0;
      else if (subset && lowequal)
	{
	  low = range_successor (high1);
	  high = high0;
	  in_p = 1;
	  if (low == 0)
	    {
	      /* We are in the weird situation where high0 > high1 but
		 high1 has no successor.  Punt.  */
	      return 0;
	    }
	}
      else if (! subset || highequal)
	{
	  low = low0;
	  high = range_predecessor (low1);
	  in_p = 1;
	  if (high == 0)
	    {
	      /* low0 < low1 but low1 has no predecessor.  Punt.  */
	      return 0;
	    }
	}
      else
	return 0;
    }

  else if (! in0_p && in1_p)
    {
      /* If they don't overlap, the result is the second range.  If the second
	 is a subset of the first, the result is false.  Otherwise,
	 the range starts just after the first range and ends at the
	 end of the second.  */
      if (no_overlap)
	in_p = 1, low = low1, high = high1;
      else if (subset || highequal)
	in_p = 0, low = high = 0;
      else
	{
	  low = range_successor (high0);
	  high = high1;
	  in_p = 1;
	  if (low == 0)
	    {
	      /* high1 > high0 but high0 has no successor.  Punt.  */
	      return 0;
	    }
	}
    }

  else
    {
      /* The case where we are excluding both ranges.  Here the complex case
	 is if they don't overlap.  In that case, the only time we have a
	 range is if they are adjacent.  If the second is a subset of the
	 first, the result is the first.  Otherwise, the range to exclude
	 starts at the beginning of the first range and ends at the end of the
	 second.  */
      if (no_overlap)
	{
	  if (integer_onep (range_binop (EQ_EXPR, integer_type_node,
					 range_successor (high0),
					 1, low1, 0)))
	    in_p = 0, low = low0, high = high1;
	  else
	    {
	      /* Canonicalize - [min, x] into - [-, x].  */
	      if (low0 && TREE_CODE (low0) == INTEGER_CST)
		switch (TREE_CODE (TREE_TYPE (low0)))
		  {
		  case ENUMERAL_TYPE:
		    if (TYPE_PRECISION (TREE_TYPE (low0))
			!= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (low0))))
		      break;
		    /* FALLTHROUGH */
		  case INTEGER_TYPE:
		    if (tree_int_cst_equal (low0,
					    TYPE_MIN_VALUE (TREE_TYPE (low0))))
		      low0 = 0;
		    break;
		  case POINTER_TYPE:
		    if (TYPE_UNSIGNED (TREE_TYPE (low0))
			&& integer_zerop (low0))
		      low0 = 0;
		    break;
		  default:
		    break;
		  }

	      /* Canonicalize - [x, max] into - [x, -].  */
	      if (high1 && TREE_CODE (high1) == INTEGER_CST)
		switch (TREE_CODE (TREE_TYPE (high1)))
		  {
		  case ENUMERAL_TYPE:
		    if (TYPE_PRECISION (TREE_TYPE (high1))
			!= GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (high1))))
		      break;
		    /* FALLTHROUGH */
		  case INTEGER_TYPE:
		    if (tree_int_cst_equal (high1,
					    TYPE_MAX_VALUE (TREE_TYPE (high1))))
		      high1 = 0;
		    break;
		  case POINTER_TYPE:
		    if (TYPE_UNSIGNED (TREE_TYPE (high1))
			&& integer_zerop (range_binop (PLUS_EXPR, NULL_TREE,
						       high1, 1,
						       integer_one_node, 1)))
		      high1 = 0;
		    break;
		  default:
		    break;
		  }

	      /* The ranges might be also adjacent between the maximum and
	         minimum values of the given type.  For
	         - [{min,-}, x] and - [y, {max,-}] ranges where x + 1 < y
	         return + [x + 1, y - 1].  */
	      if (low0 == 0 && high1 == 0)
	        {
		  low = range_successor (high0);
		  high = range_predecessor (low1);
		  if (low == 0 || high == 0)
		    return 0;

		  in_p = 1;
		}
	      else
		return 0;
	    }
	}
      else if (subset)
	in_p = 0, low = low0, high = high0;
      else
	in_p = 0, low = low0, high = high1;
    }

  *pin_p = in_p, *plow = low, *phigh = high;
  return 1;
}


/* Subroutine of fold, looking inside expressions of the form
   A op B ? A : C, where ARG0, ARG1 and ARG2 are the three operands
   of the COND_EXPR.  This function is being used also to optimize
   A op B ? C : A, by reversing the comparison first.

   Return a folded expression whose code is not a COND_EXPR
   anymore, or NULL_TREE if no folding opportunity is found.  */

static tree
fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
{
  enum tree_code comp_code = TREE_CODE (arg0);
  tree arg00 = TREE_OPERAND (arg0, 0);
  tree arg01 = TREE_OPERAND (arg0, 1);
  tree arg1_type = TREE_TYPE (arg1);
  tree tem;

  STRIP_NOPS (arg1);
  STRIP_NOPS (arg2);

  /* If we have A op 0 ? A : -A, consider applying the following
     transformations:

     A == 0? A : -A    same as -A
     A != 0? A : -A    same as A
     A >= 0? A : -A    same as abs (A)
     A > 0?  A : -A    same as abs (A)
     A <= 0? A : -A    same as -abs (A)
     A < 0?  A : -A    same as -abs (A)

     None of these transformations work for modes with signed
     zeros.  If A is +/-0, the first two transformations will
     change the sign of the result (from +0 to -0, or vice
     versa).  The last four will fix the sign of the result,
     even though the original expressions could be positive or
     negative, depending on the sign of A.

     Note that all these transformations are correct if A is
     NaN, since the two alternatives (A and -A) are also NaNs.  */
  if ((FLOAT_TYPE_P (TREE_TYPE (arg01))
       ? real_zerop (arg01)
       : integer_zerop (arg01))
      && ((TREE_CODE (arg2) == NEGATE_EXPR
	   && operand_equal_p (TREE_OPERAND (arg2, 0), arg1, 0))
	     /* In the case that A is of the form X-Y, '-A' (arg2) may
	        have already been folded to Y-X, check for that. */
	  || (TREE_CODE (arg1) == MINUS_EXPR
	      && TREE_CODE (arg2) == MINUS_EXPR
	      && operand_equal_p (TREE_OPERAND (arg1, 0),
				  TREE_OPERAND (arg2, 1), 0)
	      && operand_equal_p (TREE_OPERAND (arg1, 1),
				  TREE_OPERAND (arg2, 0), 0))))
    switch (comp_code)
      {
      case EQ_EXPR:
      case UNEQ_EXPR:
	tem = fold_convert (arg1_type, arg1);
	return pedantic_non_lvalue (fold_convert (type, negate_expr (tem)));
      case NE_EXPR:
      case LTGT_EXPR:
	return pedantic_non_lvalue (fold_convert (type, arg1));
      case UNGE_EXPR:
      case UNGT_EXPR:
	if (flag_trapping_math)
	  break;
	/* Fall through.  */
      case GE_EXPR:
      case GT_EXPR:
	if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
	  arg1 = fold_convert (lang_hooks.types.signed_type
			       (TREE_TYPE (arg1)), arg1);
	tem = fold_build1 (ABS_EXPR, TREE_TYPE (arg1), arg1);
	return pedantic_non_lvalue (fold_convert (type, tem));
      case UNLE_EXPR:
      case UNLT_EXPR:
	if (flag_trapping_math)
	  break;
      case LE_EXPR:
      case LT_EXPR:
	if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
	  arg1 = fold_convert (lang_hooks.types.signed_type
			       (TREE_TYPE (arg1)), arg1);
	tem = fold_build1 (ABS_EXPR, TREE_TYPE (arg1), arg1);
	return negate_expr (fold_convert (type, tem));
      default:
	gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison);
	break;
      }

  /* A != 0 ? A : 0 is simply A, unless A is -0.  Likewise
     A == 0 ? A : 0 is always 0 unless A is -0.  Note that
     both transformations are correct when A is NaN: A != 0
     is then true, and A == 0 is false.  */

  if (integer_zerop (arg01) && integer_zerop (arg2))
    {
      if (comp_code == NE_EXPR)
	return pedantic_non_lvalue (fold_convert (type, arg1));
      else if (comp_code == EQ_EXPR)
	return build_int_cst (type, 0);
    }

  /* Try some transformations of A op B ? A : B.

     A == B? A : B    same as B
     A != B? A : B    same as A
     A >= B? A : B    same as max (A, B)
     A > B?  A : B    same as max (B, A)
     A <= B? A : B    same as min (A, B)
     A < B?  A : B    same as min (B, A)

     As above, these transformations don't work in the presence
     of signed zeros.  For example, if A and B are zeros of
     opposite sign, the first two transformations will change
     the sign of the result.  In the last four, the original
     expressions give different results for (A=+0, B=-0) and
     (A=-0, B=+0), but the transformed expressions do not.

     The first two transformations are correct if either A or B
     is a NaN.  In the first transformation, the condition will
     be false, and B will indeed be chosen.  In the case of the
     second transformation, the condition A != B will be true,
     and A will be chosen.

     The conversions to max() and min() are not correct if B is
     a number and A is not.  The conditions in the original
     expressions will be false, so all four give B.  The min()
     and max() versions would give a NaN instead.  */
  if (operand_equal_for_comparison_p (arg01, arg2, arg00)
      /* Avoid these transformations if the COND_EXPR may be used
	 as an lvalue in the C++ front-end.  PR c++/19199.  */
      && (in_gimple_form
	  || (strcmp (lang_hooks.name, "GNU C++") != 0
	      && strcmp (lang_hooks.name, "GNU Objective-C++") != 0)
	  || ! maybe_lvalue_p (arg1)
	  || ! maybe_lvalue_p (arg2)))
    {
      tree comp_op0 = arg00;
      tree comp_op1 = arg01;
      tree comp_type = TREE_TYPE (comp_op0);

      /* Avoid adding NOP_EXPRs in case this is an lvalue.  */
      if (TYPE_MAIN_VARIANT (comp_type) == TYPE_MAIN_VARIANT (type))
	{
	  comp_type = type;
	  comp_op0 = arg1;
	  comp_op1 = arg2;
	}

      switch (comp_code)
	{
	case EQ_EXPR:
	  return pedantic_non_lvalue (fold_convert (type, arg2));
	case NE_EXPR:
	  return pedantic_non_lvalue (fold_convert (type, arg1));
	case LE_EXPR:
	case LT_EXPR:
	case UNLE_EXPR:
	case UNLT_EXPR:
	  /* In C++ a ?: expression can be an lvalue, so put the
	     operand which will be used if they are equal first
	     so that we can convert this back to the
	     corresponding COND_EXPR.  */
	  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
	    {
	      comp_op0 = fold_convert (comp_type, comp_op0);
	      comp_op1 = fold_convert (comp_type, comp_op1);
	      tem = (comp_code == LE_EXPR || comp_code == UNLE_EXPR)
		    ? fold_build2 (MIN_EXPR, comp_type, comp_op0, comp_op1)
		    : fold_build2 (MIN_EXPR, comp_type, comp_op1, comp_op0);
	      return pedantic_non_lvalue (fold_convert (type, tem));
	    }
	  break;
	case GE_EXPR:
	case GT_EXPR:
	case UNGE_EXPR:
	case UNGT_EXPR:
	  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
	    {
	      comp_op0 = fold_convert (comp_type, comp_op0);
	      comp_op1 = fold_convert (comp_type, comp_op1);
	      tem = (comp_code == GE_EXPR || comp_code == UNGE_EXPR)
		    ? fold_build2 (MAX_EXPR, comp_type, comp_op0, comp_op1)
		    : fold_build2 (MAX_EXPR, comp_type, comp_op1, comp_op0);
	      return pedantic_non_lvalue (fold_convert (type, tem));
	    }
	  break;
	case UNEQ_EXPR:
	  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
	    return pedantic_non_lvalue (fold_convert (type, arg2));
	  break;
	case LTGT_EXPR:
	  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
	    return pedantic_non_lvalue (fold_convert (type, arg1));
	  break;
	default:
	  gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison);
	  break;
	}
    }

  /* If this is A op C1 ? A : C2 with C1 and C2 constant integers,
     we might still be able to simplify this.  For example,
     if C1 is one less or one more than C2, this might have started
     out as a MIN or MAX and been transformed by this function.
     Only good for INTEGER_TYPEs, because we need TYPE_MAX_VALUE.  */

  if (INTEGRAL_TYPE_P (type)
      && TREE_CODE (arg01) == INTEGER_CST
      && TREE_CODE (arg2) == INTEGER_CST)
    switch (comp_code)
      {
      case EQ_EXPR:
	/* We can replace A with C1 in this case.  */
	arg1 = fold_convert (type, arg01);
	return fold_build3 (COND_EXPR, type, arg0, arg1, arg2);

      case LT_EXPR:
	/* If C1 is C2 + 1, this is min(A, C2).  */
	if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
			       OEP_ONLY_CONST)
	    && operand_equal_p (arg01,
				const_binop (PLUS_EXPR, arg2,
					     integer_one_node, 0),
				OEP_ONLY_CONST))
	  return pedantic_non_lvalue (fold_build2 (MIN_EXPR,
						   type, arg1, arg2));
	break;

      case LE_EXPR:
	/* If C1 is C2 - 1, this is min(A, C2).  */
	if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
			       OEP_ONLY_CONST)
	    && operand_equal_p (arg01,
				const_binop (MINUS_EXPR, arg2,
					     integer_one_node, 0),
				OEP_ONLY_CONST))
	  return pedantic_non_lvalue (fold_build2 (MIN_EXPR,
						   type, arg1, arg2));
	break;

      case GT_EXPR:
	/* If C1 is C2 - 1, this is max(A, C2).  */
	if (! operand_equal_p (arg2, TYPE_MIN_VALUE (type),
			       OEP_ONLY_CONST)
	    && operand_equal_p (arg01,
				const_binop (MINUS_EXPR, arg2,
					     integer_one_node, 0),
				OEP_ONLY_CONST))
	  return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
						   type, arg1, arg2));
	break;

      case GE_EXPR:
	/* If C1 is C2 + 1, this is max(A, C2).  */
	if (! operand_equal_p (arg2, TYPE_MAX_VALUE (type),
			       OEP_ONLY_CONST)
	    && operand_equal_p (arg01,
				const_binop (PLUS_EXPR, arg2,
					     integer_one_node, 0),
				OEP_ONLY_CONST))
	  return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
						   type, arg1, arg2));
	break;
      case NE_EXPR:
	break;
      default:
	gcc_unreachable ();
      }

  return NULL_TREE;
}



#ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
#define LOGICAL_OP_NON_SHORT_CIRCUIT (BRANCH_COST >= 2)
#endif

/* EXP is some logical combination of boolean tests.  See if we can
   merge it into some range test.  Return the new tree if so.  */

static tree
fold_range_test (enum tree_code code, tree type, tree op0, tree op1)
{
  int or_op = (code == TRUTH_ORIF_EXPR
	       || code == TRUTH_OR_EXPR);
  int in0_p, in1_p, in_p;
  tree low0, low1, low, high0, high1, high;
  bool strict_overflow_p = false;
  tree lhs = make_range (op0, &in0_p, &low0, &high0, &strict_overflow_p);
  tree rhs = make_range (op1, &in1_p, &low1, &high1, &strict_overflow_p);
  tree tem;
  const char * const warnmsg = G_("assuming signed overflow does not occur "
				  "when simplifying range test");

  /* If this is an OR operation, invert both sides; we will invert
     again at the end.  */
  if (or_op)
    in0_p = ! in0_p, in1_p = ! in1_p;

  /* If both expressions are the same, if we can merge the ranges, and we
     can build the range test, return it or it inverted.  If one of the
     ranges is always true or always false, consider it to be the same
     expression as the other.  */
  if ((lhs == 0 || rhs == 0 || operand_equal_p (lhs, rhs, 0))
      && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
		       in1_p, low1, high1)
      && 0 != (tem = (build_range_check (type,
					 lhs != 0 ? lhs
					 : rhs != 0 ? rhs : integer_zero_node,
					 in_p, low, high))))
    {
      if (strict_overflow_p)
	fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_COMPARISON);
      return or_op ? invert_truthvalue (tem) : tem;
    }

  /* On machines where the branch cost is expensive, if this is a
     short-circuited branch and the underlying object on both sides
     is the same, make a non-short-circuit operation.  */
  else if (LOGICAL_OP_NON_SHORT_CIRCUIT
	   && lhs != 0 && rhs != 0
	   && (code == TRUTH_ANDIF_EXPR
	       || code == TRUTH_ORIF_EXPR)
	   && operand_equal_p (lhs, rhs, 0))
    {
      /* If simple enough, just rewrite.  Otherwise, make a SAVE_EXPR
	 unless we are at top level or LHS contains a PLACEHOLDER_EXPR, in
	 which cases we can't do this.  */
      if (simple_operand_p (lhs))
	return build2 (code == TRUTH_ANDIF_EXPR
		       ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
		       type, op0, op1);

      else if (lang_hooks.decls.global_bindings_p () == 0
	       && ! CONTAINS_PLACEHOLDER_P (lhs))
	{
	  tree common = save_expr (lhs);

	  if (0 != (lhs = build_range_check (type, common,
					     or_op ? ! in0_p : in0_p,
					     low0, high0))
	      && (0 != (rhs = build_range_check (type, common,
						 or_op ? ! in1_p : in1_p,
						 low1, high1))))
	    {
	      if (strict_overflow_p)
		fold_overflow_warning (warnmsg,
				       WARN_STRICT_OVERFLOW_COMPARISON);
	      return build2 (code == TRUTH_ANDIF_EXPR
			     ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
			     type, lhs, rhs);
	    }
	}
    }

  return 0;
}

/* Subroutine for fold_truthop: C is an INTEGER_CST interpreted as a P
   bit value.  Arrange things so the extra bits will be set to zero if and
   only if C is signed-extended to its full width.  If MASK is nonzero,
   it is an INTEGER_CST that should be AND'ed with the extra bits.  */

static tree
unextend (tree c, int p, int unsignedp, tree mask)
{
  tree type = TREE_TYPE (c);
  int modesize = GET_MODE_BITSIZE (TYPE_MODE (type));
  tree temp;

  if (p == modesize || unsignedp)
    return c;

  /* We work by getting just the sign bit into the low-order bit, then
     into the high-order bit, then sign-extend.  We then XOR that value
     with C.  */
  temp = const_binop (RSHIFT_EXPR, c, size_int (p - 1), 0);
  temp = const_binop (BIT_AND_EXPR, temp, size_int (1), 0);

  /* We must use a signed type in order to get an arithmetic right shift.
     However, we must also avoid introducing accidental overflows, so that
     a subsequent call to integer_zerop will work.  Hence we must
     do the type conversion here.  At this point, the constant is either
     zero or one, and the conversion to a signed type can never overflow.
     We could get an overflow if this conversion is done anywhere else.  */
  if (TYPE_UNSIGNED (type))
    temp = fold_convert (lang_hooks.types.signed_type (type), temp);

  temp = const_binop (LSHIFT_EXPR, temp, size_int (modesize - 1), 0);
  temp = const_binop (RSHIFT_EXPR, temp, size_int (modesize - p - 1), 0);
  if (mask != 0)
    temp = const_binop (BIT_AND_EXPR, temp,
			fold_convert (TREE_TYPE (c), mask), 0);
  /* If necessary, convert the type back to match the type of C.  */
  if (TYPE_UNSIGNED (type))
    temp = fold_convert (type, temp);

  return fold_convert (type, const_binop (BIT_XOR_EXPR, c, temp, 0));
}

/* Find ways of folding logical expressions of LHS and RHS:
   Try to merge two comparisons to the same innermost item.
   Look for range tests like "ch >= '0' && ch <= '9'".
   Look for combinations of simple terms on machines with expensive branches
   and evaluate the RHS unconditionally.

   For example, if we have p->a == 2 && p->b == 4 and we can make an
   object large enough to span both A and B, we can do this with a comparison
   against the object ANDed with the a mask.

   If we have p->a == q->a && p->b == q->b, we may be able to use bit masking
   operations to do this with one comparison.

   We check for both normal comparisons and the BIT_AND_EXPRs made this by
   function and the one above.

   CODE is the logical operation being done.  It can be TRUTH_ANDIF_EXPR,
   TRUTH_AND_EXPR, TRUTH_ORIF_EXPR, or TRUTH_OR_EXPR.

   TRUTH_TYPE is the type of the logical operand and LHS and RHS are its
   two operands.

   We return the simplified tree or 0 if no optimization is possible.  */

static tree
fold_truthop (enum tree_code code, tree truth_type, tree lhs, tree rhs)
{
  /* If this is the "or" of two comparisons, we can do something if
     the comparisons are NE_EXPR.  If this is the "and", we can do something
     if the comparisons are EQ_EXPR.  I.e.,
	(a->b == 2 && a->c == 4) can become (a->new == NEW).

     WANTED_CODE is this operation code.  For single bit fields, we can
     convert EQ_EXPR to NE_EXPR so we need not reject the "wrong"
     comparison for one-bit fields.  */

  enum tree_code wanted_code;
  enum tree_code lcode, rcode;
  tree ll_arg, lr_arg, rl_arg, rr_arg;
  tree ll_inner, lr_inner, rl_inner, rr_inner;
  HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
  HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
  HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
  HOST_WIDE_INT lnbitsize, lnbitpos, rnbitsize, rnbitpos;
  int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
  enum machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
  enum machine_mode lnmode, rnmode;
  tree ll_mask, lr_mask, rl_mask, rr_mask;
  tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
  tree l_const, r_const;
  tree lntype, rntype, result;
  int first_bit, end_bit;
  int volatilep;
  tree orig_lhs = lhs, orig_rhs = rhs;
  enum tree_code orig_code = code;

  /* Start by getting the comparison codes.  Fail if anything is volatile.
     If one operand is a BIT_AND_EXPR with the constant one, treat it as if
     it were surrounded with a NE_EXPR.  */

  if (TREE_SIDE_EFFECTS (lhs) || TREE_SIDE_EFFECTS (rhs))
    return 0;

  lcode = TREE_CODE (lhs);
  rcode = TREE_CODE (rhs);

  if (lcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (lhs, 1)))
    {
      lhs = build2 (NE_EXPR, truth_type, lhs,
		    build_int_cst (TREE_TYPE (lhs), 0));
      lcode = NE_EXPR;
    }

  if (rcode == BIT_AND_EXPR && integer_onep (TREE_OPERAND (rhs, 1)))
    {
      rhs = build2 (NE_EXPR, truth_type, rhs,
		    build_int_cst (TREE_TYPE (rhs), 0));
      rcode = NE_EXPR;
    }

  if (TREE_CODE_CLASS (lcode) != tcc_comparison
      || TREE_CODE_CLASS (rcode) != tcc_comparison)
    return 0;

  ll_arg = TREE_OPERAND (lhs, 0);
  lr_arg = TREE_OPERAND (lhs, 1);
  rl_arg = TREE_OPERAND (rhs, 0);
  rr_arg = TREE_OPERAND (rhs, 1);

  /* Simplify (x<y) && (x==y) into (x<=y) and related optimizations.  */
  if (simple_operand_p (ll_arg)
      && simple_operand_p (lr_arg))
    {
      tree result;
      if (operand_equal_p (ll_arg, rl_arg, 0)
          && operand_equal_p (lr_arg, rr_arg, 0))
	{
          result = combine_comparisons (code, lcode, rcode,
					truth_type, ll_arg, lr_arg);
	  if (result)
	    return result;
	}
      else if (operand_equal_p (ll_arg, rr_arg, 0)
               && operand_equal_p (lr_arg, rl_arg, 0))
	{
          result = combine_comparisons (code, lcode,
					swap_tree_comparison (rcode),
					truth_type, ll_arg, lr_arg);
	  if (result)
	    return result;
	}
    }

  code = ((code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR)
	  ? TRUTH_AND_EXPR : TRUTH_OR_EXPR);

  /* If the RHS can be evaluated unconditionally and its operands are
     simple, it wins to evaluate the RHS unconditionally on machines
     with expensive branches.  In this case, this isn't a comparison
     that can be merged.  Avoid doing this if the RHS is a floating-point
     comparison since those can trap.  */

  if (BRANCH_COST >= 2
      && ! FLOAT_TYPE_P (TREE_TYPE (rl_arg))
      && simple_operand_p (rl_arg)
      && simple_operand_p (rr_arg))
    {
      /* Convert (a != 0) || (b != 0) into (a | b) != 0.  */
      if (code == TRUTH_OR_EXPR
	  && lcode == NE_EXPR && integer_zerop (lr_arg)
	  && rcode == NE_EXPR && integer_zerop (rr_arg)
	  && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
	return build2 (NE_EXPR, truth_type,
		       build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
			       ll_arg, rl_arg),
		       build_int_cst (TREE_TYPE (ll_arg), 0));

      /* Convert (a == 0) && (b == 0) into (a | b) == 0.  */
      if (code == TRUTH_AND_EXPR
	  && lcode == EQ_EXPR && integer_zerop (lr_arg)
	  && rcode == EQ_EXPR && integer_zerop (rr_arg)
	  && TREE_TYPE (ll_arg) == TREE_TYPE (rl_arg))
	return build2 (EQ_EXPR, truth_type,
		       build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
			       ll_arg, rl_arg),
		       build_int_cst (TREE_TYPE (ll_arg), 0));

      if (LOGICAL_OP_NON_SHORT_CIRCUIT)
	{
	  if (code != orig_code || lhs != orig_lhs || rhs != orig_rhs)
	    return build2 (code, truth_type, lhs, rhs);
	  return NULL_TREE;
	}
    }

  /* See if the comparisons can be merged.  Then get all the parameters for
     each side.  */

  if ((lcode != EQ_EXPR && lcode != NE_EXPR)
      || (rcode != EQ_EXPR && rcode != NE_EXPR))
    return 0;

  volatilep = 0;
  ll_inner = decode_field_reference (ll_arg,
				     &ll_bitsize, &ll_bitpos, &ll_mode,
				     &ll_unsignedp, &volatilep, &ll_mask,
				     &ll_and_mask);
  lr_inner = decode_field_reference (lr_arg,
				     &lr_bitsize, &lr_bitpos, &lr_mode,
				     &lr_unsignedp, &volatilep, &lr_mask,
				     &lr_and_mask);
  rl_inner = decode_field_reference (rl_arg,
				     &rl_bitsize, &rl_bitpos, &rl_mode,
				     &rl_unsignedp, &volatilep, &rl_mask,
				     &rl_and_mask);
  rr_inner = decode_field_reference (rr_arg,
				     &rr_bitsize, &rr_bitpos, &rr_mode,
				     &rr_unsignedp, &volatilep, &rr_mask,
				     &rr_and_mask);

  /* It must be true that the inner operation on the lhs of each
     comparison must be the same if we are to be able to do anything.
     Then see if we have constants.  If not, the same must be true for
     the rhs's.  */
  if (volatilep || ll_inner == 0 || rl_inner == 0
      || ! operand_equal_p (ll_inner, rl_inner, 0))
    return 0;

  if (TREE_CODE (lr_arg) == INTEGER_CST
      && TREE_CODE (rr_arg) == INTEGER_CST)
    l_const = lr_arg, r_const = rr_arg;
  else if (lr_inner == 0 || rr_inner == 0
	   || ! operand_equal_p (lr_inner, rr_inner, 0))
    return 0;
  else
    l_const = r_const = 0;

  /* If either comparison code is not correct for our logical operation,
     fail.  However, we can convert a one-bit comparison against zero into
     the opposite comparison against that bit being set in the field.  */

  wanted_code = (code == TRUTH_AND_EXPR ? EQ_EXPR : NE_EXPR);
  if (lcode != wanted_code)
    {
      if (l_const && integer_zerop (l_const) && integer_pow2p (ll_mask))
	{
	  /* Make the left operand unsigned, since we are only interested
	     in the value of one bit.  Otherwise we are doing the wrong
	     thing below.  */
	  ll_unsignedp = 1;
	  l_const = ll_mask;
	}
      else
	return 0;
    }

  /* This is analogous to the code for l_const above.  */
  if (rcode != wanted_code)
    {
      if (r_const && integer_zerop (r_const) && integer_pow2p (rl_mask))
	{
	  rl_unsignedp = 1;
	  r_const = rl_mask;
	}
      else
	return 0;
    }

  /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
  return 0; /* disable creation of BIT_FIELD_REF, which pessimizes code. */
#endif
  /* LLVM LOCAL end */
  
  /* After this point all optimizations will generate bit-field
     references, which we might not want.  */
  if (! lang_hooks.can_use_bit_fields_p ())
    return 0;

  /* See if we can find a mode that contains both fields being compared on
     the left.  If we can't, fail.  Otherwise, update all constants and masks
     to be relative to a field of that size.  */
  first_bit = MIN (ll_bitpos, rl_bitpos);
  end_bit = MAX (ll_bitpos + ll_bitsize, rl_bitpos + rl_bitsize);
  lnmode = get_best_mode (end_bit - first_bit, first_bit,
			  TYPE_ALIGN (TREE_TYPE (ll_inner)), word_mode,
			  volatilep);
  if (lnmode == VOIDmode)
    return 0;

  lnbitsize = GET_MODE_BITSIZE (lnmode);
  lnbitpos = first_bit & ~ (lnbitsize - 1);
  lntype = lang_hooks.types.type_for_size (lnbitsize, 1);
  xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;

  if (BYTES_BIG_ENDIAN)
    {
      xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
      xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
    }

  ll_mask = const_binop (LSHIFT_EXPR, fold_convert (lntype, ll_mask),
			 size_int (xll_bitpos), 0);
  rl_mask = const_binop (LSHIFT_EXPR, fold_convert (lntype, rl_mask),
			 size_int (xrl_bitpos), 0);

  if (l_const)
    {
      l_const = fold_convert (lntype, l_const);
      l_const = unextend (l_const, ll_bitsize, ll_unsignedp, ll_and_mask);
      l_const = const_binop (LSHIFT_EXPR, l_const, size_int (xll_bitpos), 0);
      if (! integer_zerop (const_binop (BIT_AND_EXPR, l_const,
					fold_build1 (BIT_NOT_EXPR,
						     lntype, ll_mask),
					0)))
	{
	  warning (0, "comparison is always %d", wanted_code == NE_EXPR);

	  return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
	}
    }
  if (r_const)
    {
      r_const = fold_convert (lntype, r_const);
      r_const = unextend (r_const, rl_bitsize, rl_unsignedp, rl_and_mask);
      r_const = const_binop (LSHIFT_EXPR, r_const, size_int (xrl_bitpos), 0);
      if (! integer_zerop (const_binop (BIT_AND_EXPR, r_const,
					fold_build1 (BIT_NOT_EXPR,
						     lntype, rl_mask),
					0)))
	{
	  warning (0, "comparison is always %d", wanted_code == NE_EXPR);

	  return constant_boolean_node (wanted_code == NE_EXPR, truth_type);
	}
    }

  /* If the right sides are not constant, do the same for it.  Also,
     disallow this optimization if a size or signedness mismatch occurs
     between the left and right sides.  */
  if (l_const == 0)
    {
      if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize
	  || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp
	  /* Make sure the two fields on the right
	     correspond to the left without being swapped.  */
	  || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos)
	return 0;

      first_bit = MIN (lr_bitpos, rr_bitpos);
      end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
      rnmode = get_best_mode (end_bit - first_bit, first_bit,
			      TYPE_ALIGN (TREE_TYPE (lr_inner)), word_mode,
			      volatilep);
      if (rnmode == VOIDmode)
	return 0;

      rnbitsize = GET_MODE_BITSIZE (rnmode);
      rnbitpos = first_bit & ~ (rnbitsize - 1);
      rntype = lang_hooks.types.type_for_size (rnbitsize, 1);
      xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;

      if (BYTES_BIG_ENDIAN)
	{
	  xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
	  xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
	}

      lr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, lr_mask),
			     size_int (xlr_bitpos), 0);
      rr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, rr_mask),
			     size_int (xrr_bitpos), 0);

      /* Make a mask that corresponds to both fields being compared.
	 Do this for both items being compared.  If the operands are the
	 same size and the bits being compared are in the same position
	 then we can do this by masking both and comparing the masked
	 results.  */
      ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
      lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask, 0);
      if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
	{
	  lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
				    ll_unsignedp || rl_unsignedp);
	  if (! all_ones_mask_p (ll_mask, lnbitsize))
	    lhs = build2 (BIT_AND_EXPR, lntype, lhs, ll_mask);

	  rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos,
				    lr_unsignedp || rr_unsignedp);
	  if (! all_ones_mask_p (lr_mask, rnbitsize))
	    rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);

	  return build2 (wanted_code, truth_type, lhs, rhs);
	}

      /* There is still another way we can do something:  If both pairs of
	 fields being compared are adjacent, we may be able to make a wider
	 field containing them both.

	 Note that we still must mask the lhs/rhs expressions.  Furthermore,
	 the mask must be shifted to account for the shift done by
	 make_bit_field_ref.  */
      if ((ll_bitsize + ll_bitpos == rl_bitpos
	   && lr_bitsize + lr_bitpos == rr_bitpos)
	  || (ll_bitpos == rl_bitpos + rl_bitsize
	      && lr_bitpos == rr_bitpos + rr_bitsize))
	{
	  tree type;

	  lhs = make_bit_field_ref (ll_inner, lntype, ll_bitsize + rl_bitsize,
				    MIN (ll_bitpos, rl_bitpos), ll_unsignedp);
	  rhs = make_bit_field_ref (lr_inner, rntype, lr_bitsize + rr_bitsize,
				    MIN (lr_bitpos, rr_bitpos), lr_unsignedp);

	  ll_mask = const_binop (RSHIFT_EXPR, ll_mask,
				 size_int (MIN (xll_bitpos, xrl_bitpos)), 0);
	  lr_mask = const_binop (RSHIFT_EXPR, lr_mask,
				 size_int (MIN (xlr_bitpos, xrr_bitpos)), 0);

	  /* Convert to the smaller type before masking out unwanted bits.  */
	  type = lntype;
	  if (lntype != rntype)
	    {
	      if (lnbitsize > rnbitsize)
		{
		  lhs = fold_convert (rntype, lhs);
		  ll_mask = fold_convert (rntype, ll_mask);
		  type = rntype;
		}
	      else if (lnbitsize < rnbitsize)
		{
		  rhs = fold_convert (lntype, rhs);
		  lr_mask = fold_convert (lntype, lr_mask);
		  type = lntype;
		}
	    }

	  if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
	    lhs = build2 (BIT_AND_EXPR, type, lhs, ll_mask);

	  if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
	    rhs = build2 (BIT_AND_EXPR, type, rhs, lr_mask);

	  return build2 (wanted_code, truth_type, lhs, rhs);
	}

      return 0;
    }

  /* Handle the case of comparisons with constants.  If there is something in
     common between the masks, those bits of the constants must be the same.
     If not, the condition is always false.  Test for this to avoid generating
     incorrect code below.  */
  result = const_binop (BIT_AND_EXPR, ll_mask, rl_mask, 0);
  if (! integer_zerop (result)
      && simple_cst_equal (const_binop (BIT_AND_EXPR, result, l_const, 0),
			   const_binop (BIT_AND_EXPR, result, r_const, 0)) != 1)
    {
      if (wanted_code == NE_EXPR)
	{
	  warning (0, "%<or%> of unmatched not-equal tests is always 1");
	  return constant_boolean_node (true, truth_type);
	}
      else
	{
	  warning (0, "%<and%> of mutually exclusive equal-tests is always 0");
	  return constant_boolean_node (false, truth_type);
	}
    }

  /* Construct the expression we will return.  First get the component
     reference we will make.  Unless the mask is all ones the width of
     that field, perform the mask operation.  Then compare with the
     merged constant.  */
  result = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
			       ll_unsignedp || rl_unsignedp);

  ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
  if (! all_ones_mask_p (ll_mask, lnbitsize))
    result = build2 (BIT_AND_EXPR, lntype, result, ll_mask);

  return build2 (wanted_code, truth_type, result,
		 const_binop (BIT_IOR_EXPR, l_const, r_const, 0));
}

/* Optimize T, which is a comparison of a MIN_EXPR or MAX_EXPR with a
   constant.  */

static tree
optimize_minmax_comparison (enum tree_code code, tree type, tree op0, tree op1)
{
  tree arg0 = op0;
  enum tree_code op_code;
  tree comp_const = op1;
  tree minmax_const;
  int consts_equal, consts_lt;
  tree inner;

  STRIP_SIGN_NOPS (arg0);

  op_code = TREE_CODE (arg0);
  minmax_const = TREE_OPERAND (arg0, 1);
  consts_equal = tree_int_cst_equal (minmax_const, comp_const);
  consts_lt = tree_int_cst_lt (minmax_const, comp_const);
  inner = TREE_OPERAND (arg0, 0);

  /* If something does not permit us to optimize, return the original tree.  */
  if ((op_code != MIN_EXPR && op_code != MAX_EXPR)
      || TREE_CODE (comp_const) != INTEGER_CST
      || TREE_CONSTANT_OVERFLOW (comp_const)
      || TREE_CODE (minmax_const) != INTEGER_CST
      || TREE_CONSTANT_OVERFLOW (minmax_const))
    return NULL_TREE;

  /* Now handle all the various comparison codes.  We only handle EQ_EXPR
     and GT_EXPR, doing the rest with recursive calls using logical
     simplifications.  */
  switch (code)
    {
    case NE_EXPR:  case LT_EXPR:  case LE_EXPR:
      {
	tree tem = optimize_minmax_comparison (invert_tree_comparison (code, false),
					  type, op0, op1);
	if (tem)
	  return invert_truthvalue (tem);
	return NULL_TREE;
      }

    case GE_EXPR:
      return
	fold_build2 (TRUTH_ORIF_EXPR, type,
		     optimize_minmax_comparison
		     (EQ_EXPR, type, arg0, comp_const),
		     optimize_minmax_comparison
		     (GT_EXPR, type, arg0, comp_const));

    case EQ_EXPR:
      if (op_code == MAX_EXPR && consts_equal)
	/* MAX (X, 0) == 0  ->  X <= 0  */
	return fold_build2 (LE_EXPR, type, inner, comp_const);

      else if (op_code == MAX_EXPR && consts_lt)
	/* MAX (X, 0) == 5  ->  X == 5   */
	return fold_build2 (EQ_EXPR, type, inner, comp_const);

      else if (op_code == MAX_EXPR)
	/* MAX (X, 0) == -1  ->  false  */
	return omit_one_operand (type, integer_zero_node, inner);

      else if (consts_equal)
	/* MIN (X, 0) == 0  ->  X >= 0  */
	return fold_build2 (GE_EXPR, type, inner, comp_const);

      else if (consts_lt)
	/* MIN (X, 0) == 5  ->  false  */
	return omit_one_operand (type, integer_zero_node, inner);

      else
	/* MIN (X, 0) == -1  ->  X == -1  */
	return fold_build2 (EQ_EXPR, type, inner, comp_const);

    case GT_EXPR:
      if (op_code == MAX_EXPR && (consts_equal || consts_lt))
	/* MAX (X, 0) > 0  ->  X > 0
	   MAX (X, 0) > 5  ->  X > 5  */
	return fold_build2 (GT_EXPR, type, inner, comp_const);

      else if (op_code == MAX_EXPR)
	/* MAX (X, 0) > -1  ->  true  */
	return omit_one_operand (type, integer_one_node, inner);

      else if (op_code == MIN_EXPR && (consts_equal || consts_lt))
	/* MIN (X, 0) > 0  ->  false
	   MIN (X, 0) > 5  ->  false  */
	return omit_one_operand (type, integer_zero_node, inner);

      else
	/* MIN (X, 0) > -1  ->  X > -1  */
	return fold_build2 (GT_EXPR, type, inner, comp_const);

    default:
      return NULL_TREE;
    }
}

/* T is an integer expression that is being multiplied, divided, or taken a
   modulus (CODE says which and what kind of divide or modulus) by a
   constant C.  See if we can eliminate that operation by folding it with
   other operations already in T.  WIDE_TYPE, if non-null, is a type that
   should be used for the computation if wider than our type.

   For example, if we are dividing (X * 8) + (Y * 16) by 4, we can return
   (X * 2) + (Y * 4).  We must, however, be assured that either the original
   expression would not overflow or that overflow is undefined for the type
   in the language in question.

   We also canonicalize (X + 7) * 4 into X * 4 + 28 in the hope that either
   the machine has a multiply-accumulate insn or that this is part of an
   addressing calculation.

   If we return a non-null expression, it is an equivalent form of the
   original computation, but need not be in the original type.

   We set *STRICT_OVERFLOW_P to true if the return values depends on
   signed overflow being undefined.  Otherwise we do not change
   *STRICT_OVERFLOW_P.  */

static tree
extract_muldiv (tree t, tree c, enum tree_code code, tree wide_type,
		bool *strict_overflow_p)
{
  /* To avoid exponential search depth, refuse to allow recursion past
     three levels.  Beyond that (1) it's highly unlikely that we'll find
     something interesting and (2) we've probably processed it before
     when we built the inner expression.  */

  static int depth;
  tree ret;

  if (depth > 3)
    return NULL;

  depth++;
  ret = extract_muldiv_1 (t, c, code, wide_type, strict_overflow_p);
  depth--;

  return ret;
}

static tree
extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
		  bool *strict_overflow_p)
{
  tree type = TREE_TYPE (t);
  enum tree_code tcode = TREE_CODE (t);
  tree ctype = (wide_type != 0 && (GET_MODE_SIZE (TYPE_MODE (wide_type))
				   > GET_MODE_SIZE (TYPE_MODE (type)))
		? wide_type : type);
  tree t1, t2;
  int same_p = tcode == code;
  tree op0 = NULL_TREE, op1 = NULL_TREE;
  bool sub_strict_overflow_p;

  /* Don't deal with constants of zero here; they confuse the code below.  */
  if (integer_zerop (c))
    return NULL_TREE;

  if (TREE_CODE_CLASS (tcode) == tcc_unary)
    op0 = TREE_OPERAND (t, 0);

  if (TREE_CODE_CLASS (tcode) == tcc_binary)
    op0 = TREE_OPERAND (t, 0), op1 = TREE_OPERAND (t, 1);

  /* Note that we need not handle conditional operations here since fold
     already handles those cases.  So just do arithmetic here.  */
  switch (tcode)
    {
    case INTEGER_CST:
      /* For a constant, we can always simplify if we are a multiply
	 or (for divide and modulus) if it is a multiple of our constant.  */
      if (code == MULT_EXPR
	  || integer_zerop (const_binop (TRUNC_MOD_EXPR, t, c, 0)))
	return const_binop (code, fold_convert (ctype, t),
			    fold_convert (ctype, c), 0);
      break;

    case CONVERT_EXPR:  case NON_LVALUE_EXPR:  case NOP_EXPR:
      /* If op0 is an expression ...  */
      if ((COMPARISON_CLASS_P (op0)
	   || UNARY_CLASS_P (op0)
	   || BINARY_CLASS_P (op0)
	   || EXPRESSION_CLASS_P (op0))
	  /* ... and is unsigned, and its type is smaller than ctype,
	     then we cannot pass through as widening.  */
	  && ((TYPE_UNSIGNED (TREE_TYPE (op0))
	       && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
		     && TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
	       && (GET_MODE_SIZE (TYPE_MODE (ctype))
	           > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
	      /* ... or this is a truncation (t is narrower than op0),
		 then we cannot pass through this narrowing.  */
	      || (GET_MODE_SIZE (TYPE_MODE (type))
		  < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
	      /* ... or signedness changes for division or modulus,
		 then we cannot pass through this conversion.  */
	      || (code != MULT_EXPR
		  && (TYPE_UNSIGNED (ctype)
		      != TYPE_UNSIGNED (TREE_TYPE (op0))))))
	break;

      /* Pass the constant down and see if we can make a simplification.  If
	 we can, replace this expression with the inner simplification for
	 possible later conversion to our or some other type.  */
      if ((t2 = fold_convert (TREE_TYPE (op0), c)) != 0
	  && TREE_CODE (t2) == INTEGER_CST
	  && ! TREE_CONSTANT_OVERFLOW (t2)
	  && (0 != (t1 = extract_muldiv (op0, t2, code,
					 code == MULT_EXPR
					 ? ctype : NULL_TREE,
					 strict_overflow_p))))
	return t1;
      break;

    case ABS_EXPR:
      /* If widening the type changes it from signed to unsigned, then we
         must avoid building ABS_EXPR itself as unsigned.  */
      if (TYPE_UNSIGNED (ctype) && !TYPE_UNSIGNED (type))
        {
          tree cstype = (*lang_hooks.types.signed_type) (ctype);
          if ((t1 = extract_muldiv (op0, c, code, cstype, strict_overflow_p))
	      != 0)
            {
              t1 = fold_build1 (tcode, cstype, fold_convert (cstype, t1));
              return fold_convert (ctype, t1);
            }
          break;
        }
      /* APPLE LOCAL begin radar 5612779, mainline candidate */
      /* Do not move a negative constant from an ABS_EXPR. */
      else if (!TYPE_UNSIGNED (ctype)
               && !TYPE_UNSIGNED (type)
               && TREE_CODE (c) == INTEGER_CST
               && TREE_INT_CST_HIGH (c) < 0)
        break;
      /* APPLE LOCAL end radar 5612779, mainline candidate */
      /* FALLTHROUGH */
    case NEGATE_EXPR:
      if ((t1 = extract_muldiv (op0, c, code, wide_type, strict_overflow_p))
	  != 0)
	return fold_build1 (tcode, ctype, fold_convert (ctype, t1));
      break;

    case MIN_EXPR:  case MAX_EXPR:
      /* If widening the type changes the signedness, then we can't perform
	 this optimization as that changes the result.  */
      if (TYPE_UNSIGNED (ctype) != TYPE_UNSIGNED (type))
	break;

      /* MIN (a, b) / 5 -> MIN (a / 5, b / 5)  */
      sub_strict_overflow_p = false;
      if ((t1 = extract_muldiv (op0, c, code, wide_type,
				&sub_strict_overflow_p)) != 0
	  && (t2 = extract_muldiv (op1, c, code, wide_type,
				   &sub_strict_overflow_p)) != 0)
	{
	  if (tree_int_cst_sgn (c) < 0)
	    tcode = (tcode == MIN_EXPR ? MAX_EXPR : MIN_EXPR);
	  if (sub_strict_overflow_p)
	    *strict_overflow_p = true;
	  return fold_build2 (tcode, ctype, fold_convert (ctype, t1),
			      fold_convert (ctype, t2));
	}
      break;

    case LSHIFT_EXPR:  case RSHIFT_EXPR:
      /* If the second operand is constant, this is a multiplication
	 or floor division, by a power of two, so we can treat it that
	 way unless the multiplier or divisor overflows.  Signed
	 left-shift overflow is implementation-defined rather than
	 undefined in C90, so do not convert signed left shift into
	 multiplication.  */
      if (TREE_CODE (op1) == INTEGER_CST
	  && (tcode == RSHIFT_EXPR || TYPE_UNSIGNED (TREE_TYPE (op0)))
	  /* const_binop may not detect overflow correctly,
	     so check for it explicitly here.  */
	  && TYPE_PRECISION (TREE_TYPE (size_one_node)) > TREE_INT_CST_LOW (op1)
	  && TREE_INT_CST_HIGH (op1) == 0
	  && 0 != (t1 = fold_convert (ctype,
				      const_binop (LSHIFT_EXPR,
						   size_one_node,
						   op1, 0)))
	  && ! TREE_OVERFLOW (t1))
	return extract_muldiv (build2 (tcode == LSHIFT_EXPR
				       ? MULT_EXPR : FLOOR_DIV_EXPR,
				       ctype, fold_convert (ctype, op0), t1),
			       c, code, wide_type, strict_overflow_p);
      break;

    case PLUS_EXPR:  case MINUS_EXPR:
      /* See if we can eliminate the operation on both sides.  If we can, we
	 can return a new PLUS or MINUS.  If we can't, the only remaining
	 cases where we can do anything are if the second operand is a
	 constant.  */
      sub_strict_overflow_p = false;
      t1 = extract_muldiv (op0, c, code, wide_type, &sub_strict_overflow_p);
      t2 = extract_muldiv (op1, c, code, wide_type, &sub_strict_overflow_p);
      if (t1 != 0 && t2 != 0
	  && (code == MULT_EXPR
	      /* If not multiplication, we can only do this if both operands
		 are divisible by c.  */
	      || (multiple_of_p (ctype, op0, c)
	          && multiple_of_p (ctype, op1, c))))
	{
	  if (sub_strict_overflow_p)
	    *strict_overflow_p = true;
	  return fold_build2 (tcode, ctype, fold_convert (ctype, t1),
			      fold_convert (ctype, t2));
	}

      /* If this was a subtraction, negate OP1 and set it to be an addition.
	 This simplifies the logic below.  */
      if (tcode == MINUS_EXPR)
	tcode = PLUS_EXPR, op1 = negate_expr (op1);

      if (TREE_CODE (op1) != INTEGER_CST)
	break;

      /* If either OP1 or C are negative, this optimization is not safe for
	 some of the division and remainder types while for others we need
	 to change the code.  */
      if (tree_int_cst_sgn (op1) < 0 || tree_int_cst_sgn (c) < 0)
	{
	  if (code == CEIL_DIV_EXPR)
	    code = FLOOR_DIV_EXPR;
	  else if (code == FLOOR_DIV_EXPR)
	    code = CEIL_DIV_EXPR;
	  else if (code != MULT_EXPR
		   && code != CEIL_MOD_EXPR && code != FLOOR_MOD_EXPR)
	    break;
	}

      /* If it's a multiply or a division/modulus operation of a multiple
         of our constant, do the operation and verify it doesn't overflow.  */
      if (code == MULT_EXPR
	  || integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
	{
	  op1 = const_binop (code, fold_convert (ctype, op1),
			     fold_convert (ctype, c), 0);
	  /* We allow the constant to overflow with wrapping semantics.  */
	  if (op1 == 0
	      || (TREE_OVERFLOW (op1) && !TYPE_OVERFLOW_WRAPS (ctype)))
	    break;
	}
      else
	break;

      /* If we have an unsigned type is not a sizetype, we cannot widen
	 the operation since it will change the result if the original
	 computation overflowed.  */
      if (TYPE_UNSIGNED (ctype)
	  && ! (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype))
	  && ctype != type)
	break;

      /* If we were able to eliminate our operation from the first side,
	 apply our operation to the second side and reform the PLUS.  */
      if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR))
	return fold_build2 (tcode, ctype, fold_convert (ctype, t1), op1);

      /* The last case is if we are a multiply.  In that case, we can
	 apply the distributive law to commute the multiply and addition
	 if the multiplication of the constants doesn't overflow.  */
      if (code == MULT_EXPR)
	return fold_build2 (tcode, ctype,
			    fold_build2 (code, ctype,
					 fold_convert (ctype, op0),
					 fold_convert (ctype, c)),
			    op1);

      break;

    case MULT_EXPR:
      /* We have a special case here if we are doing something like
	 (C * 8) % 4 since we know that's zero.  */
      if ((code == TRUNC_MOD_EXPR || code == CEIL_MOD_EXPR
	   || code == FLOOR_MOD_EXPR || code == ROUND_MOD_EXPR)
	  && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
	  && integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
	return omit_one_operand (type, integer_zero_node, op0);

      /* ... fall through ...  */

    case TRUNC_DIV_EXPR:  case CEIL_DIV_EXPR:  case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:  case EXACT_DIV_EXPR:
      /* If we can extract our operation from the LHS, do so and return a
	 new operation.  Likewise for the RHS from a MULT_EXPR.  Otherwise,
	 do something only if the second operand is a constant.  */
      if (same_p
	  && (t1 = extract_muldiv (op0, c, code, wide_type,
				   strict_overflow_p)) != 0)
	return fold_build2 (tcode, ctype, fold_convert (ctype, t1),
			    fold_convert (ctype, op1));
      else if (tcode == MULT_EXPR && code == MULT_EXPR
	       && (t1 = extract_muldiv (op1, c, code, wide_type,
					strict_overflow_p)) != 0)
	return fold_build2 (tcode, ctype, fold_convert (ctype, op0),
			    fold_convert (ctype, t1));
      else if (TREE_CODE (op1) != INTEGER_CST)
	return 0;

      /* If these are the same operation types, we can associate them
	 assuming no overflow.  */
      if (tcode == code
	  && 0 != (t1 = const_binop (MULT_EXPR, fold_convert (ctype, op1),
				     fold_convert (ctype, c), 0))
	  && ! TREE_OVERFLOW (t1))
	return fold_build2 (tcode, ctype, fold_convert (ctype, op0), t1);

      /* If these operations "cancel" each other, we have the main
	 optimizations of this pass, which occur when either constant is a
	 multiple of the other, in which case we replace this with either an
	 operation or CODE or TCODE.

	 If we have an unsigned type that is not a sizetype, we cannot do
	 this since it will change the result if the original computation
	 overflowed.  */
      if ((TYPE_OVERFLOW_UNDEFINED (ctype)
	   || (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype)))
	  && ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
	      || (tcode == MULT_EXPR
		  && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
		  && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)))
	{
	  if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
	    {
	      if (TYPE_OVERFLOW_UNDEFINED (ctype))
		*strict_overflow_p = true;
	      return fold_build2 (tcode, ctype, fold_convert (ctype, op0),
				  fold_convert (ctype,
						const_binop (TRUNC_DIV_EXPR,
							     op1, c, 0)));
	    }
	  else if (integer_zerop (const_binop (TRUNC_MOD_EXPR, c, op1, 0)))
	    {
	      if (TYPE_OVERFLOW_UNDEFINED (ctype))
		*strict_overflow_p = true;
	      return fold_build2 (code, ctype, fold_convert (ctype, op0),
				  fold_convert (ctype,
						const_binop (TRUNC_DIV_EXPR,
							     c, op1, 0)));
	    }
	}
      break;

    default:
      break;
    }

  return 0;
}

/* Return a node which has the indicated constant VALUE (either 0 or
   1), and is of the indicated TYPE.  */

tree
constant_boolean_node (int value, tree type)
{
  if (type == integer_type_node)
    return value ? integer_one_node : integer_zero_node;
  else if (type == boolean_type_node)
    return value ? boolean_true_node : boolean_false_node;
  else
    return build_int_cst (type, value);
}


/* Return true if expr looks like an ARRAY_REF and set base and
   offset to the appropriate trees.  If there is no offset,
   offset is set to NULL_TREE.  Base will be canonicalized to
   something you can get the element type from using
   TREE_TYPE (TREE_TYPE (base)).  Offset will be the offset
   in bytes to the base.  */

static bool
extract_array_ref (tree expr, tree *base, tree *offset)
{
  /* One canonical form is a PLUS_EXPR with the first
     argument being an ADDR_EXPR with a possible NOP_EXPR
     attached.  */
  if (TREE_CODE (expr) == PLUS_EXPR)
    {
      tree op0 = TREE_OPERAND (expr, 0);
      tree inner_base, dummy1;
      /* Strip NOP_EXPRs here because the C frontends and/or
	 folders present us (int *)&x.a + 4B possibly.  */
      STRIP_NOPS (op0);
      if (extract_array_ref (op0, &inner_base, &dummy1))
	{
	  *base = inner_base;
	  if (dummy1 == NULL_TREE)
	    *offset = TREE_OPERAND (expr, 1);
	  else
	    *offset = fold_build2 (PLUS_EXPR, TREE_TYPE (expr),
				   dummy1, TREE_OPERAND (expr, 1));
	  return true;
	}
    }
  /* Other canonical form is an ADDR_EXPR of an ARRAY_REF,
     which we transform into an ADDR_EXPR with appropriate
     offset.  For other arguments to the ADDR_EXPR we assume
     zero offset and as such do not care about the ADDR_EXPR
     type and strip possible nops from it.  */
  else if (TREE_CODE (expr) == ADDR_EXPR)
    {
      tree op0 = TREE_OPERAND (expr, 0);
      if (TREE_CODE (op0) == ARRAY_REF)
	{
	  tree idx = TREE_OPERAND (op0, 1);
	  *base = TREE_OPERAND (op0, 0);
	  *offset = fold_build2 (MULT_EXPR, TREE_TYPE (idx), idx,
				 array_ref_element_size (op0)); 
	}
      else
	{
	  /* Handle array-to-pointer decay as &a.  */
	  if (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE)
	    *base = TREE_OPERAND (expr, 0);
	  else
	    *base = expr;
	  *offset = NULL_TREE;
	}
      return true;
    }
  /* The next canonical form is a VAR_DECL with POINTER_TYPE.  */
  else if (SSA_VAR_P (expr)
	   && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
    {
      *base = expr;
      *offset = NULL_TREE;
      return true;
    }

  return false;
}


/* Transform `a + (b ? x : y)' into `b ? (a + x) : (a + y)'.
   Transform, `a + (x < y)' into `(x < y) ? (a + 1) : (a + 0)'.  Here
   CODE corresponds to the `+', COND to the `(b ? x : y)' or `(x < y)'
   expression, and ARG to `a'.  If COND_FIRST_P is nonzero, then the
   COND is the first argument to CODE; otherwise (as in the example
   given here), it is the second argument.  TYPE is the type of the
   original expression.  Return NULL_TREE if no simplification is
   possible.  */

static tree
fold_binary_op_with_conditional_arg (enum tree_code code,
				     tree type, tree op0, tree op1,
				     tree cond, tree arg, int cond_first_p)
{
  tree cond_type = cond_first_p ? TREE_TYPE (op0) : TREE_TYPE (op1);
  tree arg_type = cond_first_p ? TREE_TYPE (op1) : TREE_TYPE (op0);
  tree test, true_value, false_value;
  tree lhs = NULL_TREE;
  tree rhs = NULL_TREE;

  /* This transformation is only worthwhile if we don't have to wrap
     arg in a SAVE_EXPR, and the operation can be simplified on at least
     one of the branches once its pushed inside the COND_EXPR.  */
  if (!TREE_CONSTANT (arg))
    return NULL_TREE;

  if (TREE_CODE (cond) == COND_EXPR)
    {
      test = TREE_OPERAND (cond, 0);
      true_value = TREE_OPERAND (cond, 1);
      false_value = TREE_OPERAND (cond, 2);
      /* If this operand throws an expression, then it does not make
	 sense to try to perform a logical or arithmetic operation
	 involving it.  */
      if (VOID_TYPE_P (TREE_TYPE (true_value)))
	lhs = true_value;
      if (VOID_TYPE_P (TREE_TYPE (false_value)))
	rhs = false_value;
    }
  else
    {
      tree testtype = TREE_TYPE (cond);
      test = cond;
      true_value = constant_boolean_node (true, testtype);
      false_value = constant_boolean_node (false, testtype);
    }

  arg = fold_convert (arg_type, arg);
  if (lhs == 0)
    {
      true_value = fold_convert (cond_type, true_value);
      if (cond_first_p)
	lhs = fold_build2 (code, type, true_value, arg);
      else
	lhs = fold_build2 (code, type, arg, true_value);
    }
  if (rhs == 0)
    {
      false_value = fold_convert (cond_type, false_value);
      if (cond_first_p)
	rhs = fold_build2 (code, type, false_value, arg);
      else
	rhs = fold_build2 (code, type, arg, false_value);
    }

  test = fold_build3 (COND_EXPR, type, test, lhs, rhs);
  return fold_convert (type, test);
}


/* Subroutine of fold() that checks for the addition of +/- 0.0.

   If !NEGATE, return true if ADDEND is +/-0.0 and, for all X of type
   TYPE, X + ADDEND is the same as X.  If NEGATE, return true if X -
   ADDEND is the same as X.

   X + 0 and X - 0 both give X when X is NaN, infinite, or nonzero
   and finite.  The problematic cases are when X is zero, and its mode
   has signed zeros.  In the case of rounding towards -infinity,
   X - 0 is not the same as X because 0 - 0 is -0.  In other rounding
   modes, X + 0 is not the same as X because -0 + 0 is 0.  */

static bool
fold_real_zero_addition_p (tree type, tree addend, int negate)
{
  if (!real_zerop (addend))
    return false;

  /* Don't allow the fold with -fsignaling-nans.  */
  if (HONOR_SNANS (TYPE_MODE (type)))
    return false;

  /* Allow the fold if zeros aren't signed, or their sign isn't important.  */
  if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
    return true;

  /* Treat x + -0 as x - 0 and x - -0 as x + 0.  */
  if (TREE_CODE (addend) == REAL_CST
      && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (addend)))
    negate = !negate;

  /* The mode has signed zeros, and we have to honor their sign.
     In this situation, there is only one case we can return true for.
     X - 0 is the same as X unless rounding towards -infinity is
     supported.  */
  return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type));
}

/* Subroutine of fold() that checks comparisons of built-in math
   functions against real constants.

   FCODE is the DECL_FUNCTION_CODE of the built-in, CODE is the comparison
   operator: EQ_EXPR, NE_EXPR, GT_EXPR, LT_EXPR, GE_EXPR or LE_EXPR.  TYPE
   is the type of the result and ARG0 and ARG1 are the operands of the
   comparison.  ARG1 must be a TREE_REAL_CST.

   The function returns the constant folded tree if a simplification
   can be made, and NULL_TREE otherwise.  */

static tree
fold_mathfn_compare (enum built_in_function fcode, enum tree_code code,
		     tree type, tree arg0, tree arg1)
{
  REAL_VALUE_TYPE c;

  if (BUILTIN_SQRT_P (fcode))
    {
      tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
      enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));

      c = TREE_REAL_CST (arg1);
      if (REAL_VALUE_NEGATIVE (c))
	{
	  /* sqrt(x) < y is always false, if y is negative.  */
	  if (code == EQ_EXPR || code == LT_EXPR || code == LE_EXPR)
	    return omit_one_operand (type, integer_zero_node, arg);

	  /* sqrt(x) > y is always true, if y is negative and we
	     don't care about NaNs, i.e. negative values of x.  */
	  if (code == NE_EXPR || !HONOR_NANS (mode))
	    return omit_one_operand (type, integer_one_node, arg);

	  /* sqrt(x) > y is the same as x >= 0, if y is negative.  */
	  return fold_build2 (GE_EXPR, type, arg,
			      build_real (TREE_TYPE (arg), dconst0));
	}
      else if (code == GT_EXPR || code == GE_EXPR)
	{
	  REAL_VALUE_TYPE c2;

	  REAL_ARITHMETIC (c2, MULT_EXPR, c, c);
	  real_convert (&c2, mode, &c2);

	  if (REAL_VALUE_ISINF (c2))
	    {
	      /* sqrt(x) > y is x == +Inf, when y is very large.  */
	      if (HONOR_INFINITIES (mode))
		return fold_build2 (EQ_EXPR, type, arg,
				    build_real (TREE_TYPE (arg), c2));

	      /* sqrt(x) > y is always false, when y is very large
		 and we don't care about infinities.  */
	      return omit_one_operand (type, integer_zero_node, arg);
	    }

	  /* sqrt(x) > c is the same as x > c*c.  */
	  return fold_build2 (code, type, arg,
			      build_real (TREE_TYPE (arg), c2));
	}
      else if (code == LT_EXPR || code == LE_EXPR)
	{
	  REAL_VALUE_TYPE c2;

	  REAL_ARITHMETIC (c2, MULT_EXPR, c, c);
	  real_convert (&c2, mode, &c2);

	  if (REAL_VALUE_ISINF (c2))
	    {
	      /* sqrt(x) < y is always true, when y is a very large
		 value and we don't care about NaNs or Infinities.  */
	      if (! HONOR_NANS (mode) && ! HONOR_INFINITIES (mode))
		return omit_one_operand (type, integer_one_node, arg);

	      /* sqrt(x) < y is x != +Inf when y is very large and we
		 don't care about NaNs.  */
	      if (! HONOR_NANS (mode))
		return fold_build2 (NE_EXPR, type, arg,
				    build_real (TREE_TYPE (arg), c2));

	      /* sqrt(x) < y is x >= 0 when y is very large and we
		 don't care about Infinities.  */
	      if (! HONOR_INFINITIES (mode))
		return fold_build2 (GE_EXPR, type, arg,
				    build_real (TREE_TYPE (arg), dconst0));

	      /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large.  */
	      if (lang_hooks.decls.global_bindings_p () != 0
		  || CONTAINS_PLACEHOLDER_P (arg))
		return NULL_TREE;

	      arg = save_expr (arg);
	      return fold_build2 (TRUTH_ANDIF_EXPR, type,
				  fold_build2 (GE_EXPR, type, arg,
					       build_real (TREE_TYPE (arg),
							   dconst0)),
				  fold_build2 (NE_EXPR, type, arg,
					       build_real (TREE_TYPE (arg),
							   c2)));
	    }

	  /* sqrt(x) < c is the same as x < c*c, if we ignore NaNs.  */
	  if (! HONOR_NANS (mode))
	    return fold_build2 (code, type, arg,
				build_real (TREE_TYPE (arg), c2));

	  /* sqrt(x) < c is the same as x >= 0 && x < c*c.  */
	  if (lang_hooks.decls.global_bindings_p () == 0
	      && ! CONTAINS_PLACEHOLDER_P (arg))
	    {
	      arg = save_expr (arg);
	      return fold_build2 (TRUTH_ANDIF_EXPR, type,
				  fold_build2 (GE_EXPR, type, arg,
					       build_real (TREE_TYPE (arg),
							   dconst0)),
				  fold_build2 (code, type, arg,
					       build_real (TREE_TYPE (arg),
							   c2)));
	    }
	}
    }

  return NULL_TREE;
}

/* Subroutine of fold() that optimizes comparisons against Infinities,
   either +Inf or -Inf.

   CODE is the comparison operator: EQ_EXPR, NE_EXPR, GT_EXPR, LT_EXPR,
   GE_EXPR or LE_EXPR.  TYPE is the type of the result and ARG0 and ARG1
   are the operands of the comparison.  ARG1 must be a TREE_REAL_CST.

   The function returns the constant folded tree if a simplification
   can be made, and NULL_TREE otherwise.  */

static tree
fold_inf_compare (enum tree_code code, tree type, tree arg0, tree arg1)
{
  enum machine_mode mode;
  REAL_VALUE_TYPE max;
  /* APPLE LOCAL 5752613 equality comparison to inf sets inv flag */
  /* Removed temp */
  bool neg;

  mode = TYPE_MODE (TREE_TYPE (arg0));

  /* For negative infinity swap the sense of the comparison.  */
  neg = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1));
  if (neg)
    code = swap_tree_comparison (code);

  switch (code)
    {
    case GT_EXPR:
      /* x > +Inf is always false, if with ignore sNANs.  */
      if (HONOR_SNANS (mode))
        return NULL_TREE;
      return omit_one_operand (type, integer_zero_node, arg0);

    case LE_EXPR:
      /* x <= +Inf is always true, if we don't case about NaNs.  */
      if (! HONOR_NANS (mode))
	return omit_one_operand (type, integer_one_node, arg0);

      /* x <= +Inf is the same as x == x, i.e. isfinite(x).  */
      if (lang_hooks.decls.global_bindings_p () == 0
	  && ! CONTAINS_PLACEHOLDER_P (arg0))
	{
	  arg0 = save_expr (arg0);
	  return fold_build2 (EQ_EXPR, type, arg0, arg0);
	}
      break;

    /* APPLE LOCAL 5752613 equality comparison to inf sets inv flag */
    /* removed lines */

    case LT_EXPR:
      /* x < +Inf is always equal to x <= DBL_MAX.  */
      real_maxval (&max, neg, mode);
      return fold_build2 (neg ? GE_EXPR : LE_EXPR, type,
			  arg0, build_real (TREE_TYPE (arg0), max));

    /* APPLE LOCAL 5752613 equality comparison to inf sets inv flag */
    /* removed lines */

    default:
      break;
    }

  return NULL_TREE;
}

/* Subroutine of fold() that optimizes comparisons of a division by
   a nonzero integer constant against an integer constant, i.e.
   X/C1 op C2.

   CODE is the comparison operator: EQ_EXPR, NE_EXPR, GT_EXPR, LT_EXPR,
   GE_EXPR or LE_EXPR.  TYPE is the type of the result and ARG0 and ARG1
   are the operands of the comparison.  ARG1 must be a TREE_REAL_CST.

   The function returns the constant folded tree if a simplification
   can be made, and NULL_TREE otherwise.  */

static tree
fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
{
  tree prod, tmp, hi, lo;
  tree arg00 = TREE_OPERAND (arg0, 0);
  tree arg01 = TREE_OPERAND (arg0, 1);
  unsigned HOST_WIDE_INT lpart;
  HOST_WIDE_INT hpart;
  bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (arg0));
  bool neg_overflow;
  int overflow;

  /* We have to do this the hard way to detect unsigned overflow.
     prod = int_const_binop (MULT_EXPR, arg01, arg1, 0);  */
  overflow = mul_double_with_sign (TREE_INT_CST_LOW (arg01),
				   TREE_INT_CST_HIGH (arg01),
				   TREE_INT_CST_LOW (arg1),
				   TREE_INT_CST_HIGH (arg1),
				   &lpart, &hpart, unsigned_p);
  prod = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart);
  prod = force_fit_type (prod, -1, overflow, false);
  neg_overflow = false;

  if (unsigned_p)
    {
      tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
      lo = prod;

      /* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp, 0).  */
      overflow = add_double_with_sign (TREE_INT_CST_LOW (prod),
				       TREE_INT_CST_HIGH (prod),
				       TREE_INT_CST_LOW (tmp),
				       TREE_INT_CST_HIGH (tmp),
				       &lpart, &hpart, unsigned_p);
      hi = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart);
      hi = force_fit_type (hi, -1, overflow | TREE_OVERFLOW (prod),
			   TREE_CONSTANT_OVERFLOW (prod));
    }
  else if (tree_int_cst_sgn (arg01) >= 0)
    {
      tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
      switch (tree_int_cst_sgn (arg1))
	{
	case -1:
	  neg_overflow = true;
	  lo = int_const_binop (MINUS_EXPR, prod, tmp, 0);
	  hi = prod;
	  break;

	case  0:
	  lo = fold_negate_const (tmp, TREE_TYPE (arg0));
	  hi = tmp;
	  break;

	case  1:
          hi = int_const_binop (PLUS_EXPR, prod, tmp, 0);
	  lo = prod;
	  break;

	default:
	  gcc_unreachable ();
	}
    }
  else
    {
      /* A negative divisor reverses the relational operators.  */
      code = swap_tree_comparison (code);

      tmp = int_const_binop (PLUS_EXPR, arg01, integer_one_node, 0);
      switch (tree_int_cst_sgn (arg1))
	{
	case -1:
	  hi = int_const_binop (MINUS_EXPR, prod, tmp, 0);
	  lo = prod;
	  break;

	case  0:
	  hi = fold_negate_const (tmp, TREE_TYPE (arg0));
	  lo = tmp;
	  break;

	case  1:
	  neg_overflow = true;
	  lo = int_const_binop (PLUS_EXPR, prod, tmp, 0);
	  hi = prod;
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  switch (code)
    {
    case EQ_EXPR:
      if (TREE_OVERFLOW (lo) && TREE_OVERFLOW (hi))
	return omit_one_operand (type, integer_zero_node, arg00);
      if (TREE_OVERFLOW (hi))
	return fold_build2 (GE_EXPR, type, arg00, lo);
      if (TREE_OVERFLOW (lo))
	return fold_build2 (LE_EXPR, type, arg00, hi);
      return build_range_check (type, arg00, 1, lo, hi);

    case NE_EXPR:
      if (TREE_OVERFLOW (lo) && TREE_OVERFLOW (hi))
	return omit_one_operand (type, integer_one_node, arg00);
      if (TREE_OVERFLOW (hi))
	return fold_build2 (LT_EXPR, type, arg00, lo);
      if (TREE_OVERFLOW (lo))
	return fold_build2 (GT_EXPR, type, arg00, hi);
      return build_range_check (type, arg00, 0, lo, hi);

    case LT_EXPR:
      if (TREE_OVERFLOW (lo))
	{
	  tmp = neg_overflow ? integer_zero_node : integer_one_node;
	  return omit_one_operand (type, tmp, arg00);
	}
      return fold_build2 (LT_EXPR, type, arg00, lo);

    case LE_EXPR:
      if (TREE_OVERFLOW (hi))
	{
	  tmp = neg_overflow ? integer_zero_node : integer_one_node;
	  return omit_one_operand (type, tmp, arg00);
	}
      return fold_build2 (LE_EXPR, type, arg00, hi);

    case GT_EXPR:
      if (TREE_OVERFLOW (hi))
	{
	  tmp = neg_overflow ? integer_one_node : integer_zero_node;
	  return omit_one_operand (type, tmp, arg00);
	}
      return fold_build2 (GT_EXPR, type, arg00, hi);

    case GE_EXPR:
      if (TREE_OVERFLOW (lo))
	{
	  tmp = neg_overflow ? integer_one_node : integer_zero_node;
	  return omit_one_operand (type, tmp, arg00);
	}
      return fold_build2 (GE_EXPR, type, arg00, lo);

    default:
      break;
    }

  return NULL_TREE;
}


/* If CODE with arguments ARG0 and ARG1 represents a single bit
   equality/inequality test, then return a simplified form of the test
   using a sign testing.  Otherwise return NULL.  TYPE is the desired
   result type.  */

static tree
fold_single_bit_test_into_sign_test (enum tree_code code, tree arg0, tree arg1,
				     tree result_type)
{
  /* If this is testing a single bit, we can optimize the test.  */
  if ((code == NE_EXPR || code == EQ_EXPR)
      && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
      && integer_pow2p (TREE_OPERAND (arg0, 1)))
    {
      /* If we have (A & C) != 0 where C is the sign bit of A, convert
	 this into A < 0.  Similarly for (A & C) == 0 into A >= 0.  */
      tree arg00 = sign_bit_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1));

      if (arg00 != NULL_TREE
	  /* This is only a win if casting to a signed type is cheap,
	     i.e. when arg00's type is not a partial mode.  */
	  && TYPE_PRECISION (TREE_TYPE (arg00))
	     == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg00))))
	{
	  tree stype = lang_hooks.types.signed_type (TREE_TYPE (arg00));
	  return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR,
			      result_type, fold_convert (stype, arg00),
			      build_int_cst (stype, 0));
	}
    }

  return NULL_TREE;
}

/* If CODE with arguments ARG0 and ARG1 represents a single bit
   equality/inequality test, then return a simplified form of
   the test using shifts and logical operations.  Otherwise return
   NULL.  TYPE is the desired result type.  */

tree
fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
		      tree result_type)
{
  /* If this is testing a single bit, we can optimize the test.  */
  if ((code == NE_EXPR || code == EQ_EXPR)
      && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
      && integer_pow2p (TREE_OPERAND (arg0, 1)))
    {
      tree inner = TREE_OPERAND (arg0, 0);
      tree type = TREE_TYPE (arg0);
      int bitnum = tree_log2 (TREE_OPERAND (arg0, 1));
      enum machine_mode operand_mode = TYPE_MODE (type);
      int ops_unsigned;
      tree signed_type, unsigned_type, intermediate_type;
      tree tem;

      /* First, see if we can fold the single bit test into a sign-bit
	 test.  */
      tem = fold_single_bit_test_into_sign_test (code, arg0, arg1,
						 result_type);
      if (tem)
	return tem;

      /* Otherwise we have (A & C) != 0 where C is a single bit,
	 convert that into ((A >> C2) & 1).  Where C2 = log2(C).
	 Similarly for (A & C) == 0.  */

      /* If INNER is a right shift of a constant and it plus BITNUM does
	 not overflow, adjust BITNUM and INNER.  */
      if (TREE_CODE (inner) == RSHIFT_EXPR
	  && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST
	  && TREE_INT_CST_HIGH (TREE_OPERAND (inner, 1)) == 0
	  && bitnum < TYPE_PRECISION (type)
	  && 0 > compare_tree_int (TREE_OPERAND (inner, 1),
				   bitnum - TYPE_PRECISION (type)))
	{
	  bitnum += TREE_INT_CST_LOW (TREE_OPERAND (inner, 1));
	  inner = TREE_OPERAND (inner, 0);
	}

      /* If we are going to be able to omit the AND below, we must do our
	 operations as unsigned.  If we must use the AND, we have a choice.
	 Normally unsigned is faster, but for some machines signed is.  */
#ifdef LOAD_EXTEND_OP
      ops_unsigned = (LOAD_EXTEND_OP (operand_mode) == SIGN_EXTEND 
		      && !flag_syntax_only) ? 0 : 1;
#else
      ops_unsigned = 1;
#endif

      signed_type = lang_hooks.types.type_for_mode (operand_mode, 0);
      unsigned_type = lang_hooks.types.type_for_mode (operand_mode, 1);
      intermediate_type = ops_unsigned ? unsigned_type : signed_type;
      inner = fold_convert (intermediate_type, inner);

      if (bitnum != 0)
	inner = build2 (RSHIFT_EXPR, intermediate_type,
			inner, size_int (bitnum));

      if (code == EQ_EXPR)
	inner = fold_build2 (BIT_XOR_EXPR, intermediate_type,
			     inner, integer_one_node);

      /* Put the AND last so it can combine with more things.  */
      inner = build2 (BIT_AND_EXPR, intermediate_type,
		      inner, integer_one_node);

      /* Make sure to return the proper type.  */
      inner = fold_convert (result_type, inner);

      return inner;
    }
  return NULL_TREE;
}

/* Check whether we are allowed to reorder operands arg0 and arg1,
   such that the evaluation of arg1 occurs before arg0.  */

static bool
reorder_operands_p (tree arg0, tree arg1)
{
  if (! flag_evaluation_order)
      return true;
  if (TREE_CONSTANT (arg0) || TREE_CONSTANT (arg1))
    return true;
  return ! TREE_SIDE_EFFECTS (arg0)
	 && ! TREE_SIDE_EFFECTS (arg1);
}

/* Test whether it is preferable two swap two operands, ARG0 and
   ARG1, for example because ARG0 is an integer constant and ARG1
   isn't.  If REORDER is true, only recommend swapping if we can
   evaluate the operands in reverse order.  */

bool
tree_swap_operands_p (tree arg0, tree arg1, bool reorder)
{
  STRIP_SIGN_NOPS (arg0);
  STRIP_SIGN_NOPS (arg1);

  if (TREE_CODE (arg1) == INTEGER_CST)
    return 0;
  if (TREE_CODE (arg0) == INTEGER_CST)
    return 1;

  if (TREE_CODE (arg1) == REAL_CST)
    return 0;
  if (TREE_CODE (arg0) == REAL_CST)
    return 1;

  if (TREE_CODE (arg1) == COMPLEX_CST)
    return 0;
  if (TREE_CODE (arg0) == COMPLEX_CST)
    return 1;

  if (TREE_CONSTANT (arg1))
    return 0;
  if (TREE_CONSTANT (arg0))
    return 1;

  if (optimize_size)
    return 0;

  if (reorder && flag_evaluation_order
      && (TREE_SIDE_EFFECTS (arg0) || TREE_SIDE_EFFECTS (arg1)))
    return 0;

  if (DECL_P (arg1))
    return 0;
  if (DECL_P (arg0))
    return 1;

  /* It is preferable to swap two SSA_NAME to ensure a canonical form
     for commutative and comparison operators.  Ensuring a canonical
     form allows the optimizers to find additional redundancies without
     having to explicitly check for both orderings.  */
  if (TREE_CODE (arg0) == SSA_NAME
      && TREE_CODE (arg1) == SSA_NAME
      && SSA_NAME_VERSION (arg0) > SSA_NAME_VERSION (arg1))
    return 1;

  return 0;
}

/* Fold comparison ARG0 CODE ARG1 (with result in TYPE), where
   ARG0 is extended to a wider type.  */

static tree
fold_widened_comparison (enum tree_code code, tree type, tree arg0, tree arg1)
{
  tree arg0_unw = get_unwidened (arg0, NULL_TREE);
  tree arg1_unw;
  tree shorter_type, outer_type;
  tree min, max;
  bool above, below;

  if (arg0_unw == arg0)
    return NULL_TREE;
  shorter_type = TREE_TYPE (arg0_unw);

#ifdef HAVE_canonicalize_funcptr_for_compare
  /* Disable this optimization if we're casting a function pointer
     type on targets that require function pointer canonicalization.  */
  if (HAVE_canonicalize_funcptr_for_compare
      && TREE_CODE (shorter_type) == POINTER_TYPE
      && TREE_CODE (TREE_TYPE (shorter_type)) == FUNCTION_TYPE)
    return NULL_TREE;
#endif

  if (TYPE_PRECISION (TREE_TYPE (arg0)) <= TYPE_PRECISION (shorter_type))
    return NULL_TREE;

  arg1_unw = get_unwidened (arg1, shorter_type);

  /* If possible, express the comparison in the shorter mode.  */
  if ((code == EQ_EXPR || code == NE_EXPR
       || TYPE_UNSIGNED (TREE_TYPE (arg0)) == TYPE_UNSIGNED (shorter_type))
      && (TREE_TYPE (arg1_unw) == shorter_type
	  || (TREE_CODE (arg1_unw) == INTEGER_CST
	      && (TREE_CODE (shorter_type) == INTEGER_TYPE
		  || TREE_CODE (shorter_type) == BOOLEAN_TYPE)
	      && int_fits_type_p (arg1_unw, shorter_type))))
    return fold_build2 (code, type, arg0_unw,
		       fold_convert (shorter_type, arg1_unw));

  if (TREE_CODE (arg1_unw) != INTEGER_CST
      || TREE_CODE (shorter_type) != INTEGER_TYPE
      || !int_fits_type_p (arg1_unw, shorter_type))
    return NULL_TREE;

  /* If we are comparing with the integer that does not fit into the range
     of the shorter type, the result is known.  */
  outer_type = TREE_TYPE (arg1_unw);
  min = lower_bound_in_type (outer_type, shorter_type);
  max = upper_bound_in_type (outer_type, shorter_type);

  above = integer_nonzerop (fold_relational_const (LT_EXPR, type,
						   max, arg1_unw));
  below = integer_nonzerop (fold_relational_const (LT_EXPR, type,
						   arg1_unw, min));

  switch (code)
    {
    case EQ_EXPR:
      if (above || below)
	return omit_one_operand (type, integer_zero_node, arg0);
      break;

    case NE_EXPR:
      if (above || below)
	return omit_one_operand (type, integer_one_node, arg0);
      break;

    case LT_EXPR:
    case LE_EXPR:
      if (above)
	return omit_one_operand (type, integer_one_node, arg0);
      else if (below)
	return omit_one_operand (type, integer_zero_node, arg0);

    case GT_EXPR:
    case GE_EXPR:
      if (above)
	return omit_one_operand (type, integer_zero_node, arg0);
      else if (below)
	return omit_one_operand (type, integer_one_node, arg0);

    default:
      break;
    }

  return NULL_TREE;
}

/* Fold comparison ARG0 CODE ARG1 (with result in TYPE), where for
   ARG0 just the signedness is changed.  */

static tree
fold_sign_changed_comparison (enum tree_code code, tree type,
			      tree arg0, tree arg1)
{
  tree arg0_inner, tmp;
  tree inner_type, outer_type;

  if (TREE_CODE (arg0) != NOP_EXPR
      && TREE_CODE (arg0) != CONVERT_EXPR)
    return NULL_TREE;

  outer_type = TREE_TYPE (arg0);
  arg0_inner = TREE_OPERAND (arg0, 0);
  inner_type = TREE_TYPE (arg0_inner);

#ifdef HAVE_canonicalize_funcptr_for_compare
  /* Disable this optimization if we're casting a function pointer
     type on targets that require function pointer canonicalization.  */
  if (HAVE_canonicalize_funcptr_for_compare
      && TREE_CODE (inner_type) == POINTER_TYPE
      && TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE)
    return NULL_TREE;
#endif

  if (TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
    return NULL_TREE;

  if (TREE_CODE (arg1) != INTEGER_CST
      && !((TREE_CODE (arg1) == NOP_EXPR
	    || TREE_CODE (arg1) == CONVERT_EXPR)
	   && TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type))
    return NULL_TREE;

  if (TYPE_UNSIGNED (inner_type) != TYPE_UNSIGNED (outer_type)
      && code != NE_EXPR
      && code != EQ_EXPR)
    return NULL_TREE;

  if (TREE_CODE (arg1) == INTEGER_CST)
    {
      tmp = build_int_cst_wide (inner_type,
				TREE_INT_CST_LOW (arg1),
				TREE_INT_CST_HIGH (arg1));
      arg1 = force_fit_type (tmp, 0,
			     TREE_OVERFLOW (arg1),
			     TREE_CONSTANT_OVERFLOW (arg1));
    }
  else
    arg1 = fold_convert (inner_type, arg1);

  return fold_build2 (code, type, arg0_inner, arg1);
}

/* Tries to replace &a[idx] CODE s * delta with &a[idx CODE delta], if s is
   step of the array.  Reconstructs s and delta in the case of s * delta
   being an integer constant (and thus already folded).
   ADDR is the address. MULT is the multiplicative expression.
   If the function succeeds, the new address expression is returned.  Otherwise
   NULL_TREE is returned.  */

static tree
try_move_mult_to_index (enum tree_code code, tree addr, tree op1)
{
  tree s, delta, step;
  tree ref = TREE_OPERAND (addr, 0), pref;
  tree ret, pos;
  tree itype;

  /* Canonicalize op1 into a possibly non-constant delta
     and an INTEGER_CST s.  */
  if (TREE_CODE (op1) == MULT_EXPR)
    {
      tree arg0 = TREE_OPERAND (op1, 0), arg1 = TREE_OPERAND (op1, 1);

      STRIP_NOPS (arg0);
      STRIP_NOPS (arg1);
  
      if (TREE_CODE (arg0) == INTEGER_CST)
        {
          s = arg0;
          delta = arg1;
        }
      else if (TREE_CODE (arg1) == INTEGER_CST)
        {
          s = arg1;
          delta = arg0;
        }
      else
        return NULL_TREE;
    }
  else if (TREE_CODE (op1) == INTEGER_CST)
    {
      delta = op1;
      s = NULL_TREE;
    }
  else
    {
      /* Simulate we are delta * 1.  */
      delta = op1;
      s = integer_one_node;
    }

  for (;; ref = TREE_OPERAND (ref, 0))
    {
      if (TREE_CODE (ref) == ARRAY_REF
          /* LLVM LOCAL begin */      
#if ENABLE_LLVM
          /* LLVM extends ARRAY_REF to allow pointers to be the base value. */
          && (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == ARRAY_TYPE)
#endif
          /* LLVM LOCAL end */
         )
	{
	  itype = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
	  if (! itype)
	    continue;

	  step = array_ref_element_size (ref);
	  if (TREE_CODE (step) != INTEGER_CST)
	    continue;

	  if (s)
	    {
	      if (! tree_int_cst_equal (step, s))
                continue;
	    }
	  else
	    {
	      /* Try if delta is a multiple of step.  */
	      tree tmp = div_if_zero_remainder (EXACT_DIV_EXPR, delta, step);
	      if (! tmp)
		continue;
	      delta = tmp;
	    }

	  break;
	}

      if (!handled_component_p (ref))
	return NULL_TREE;
    }

  /* We found the suitable array reference.  So copy everything up to it,
     and replace the index.  */

  pref = TREE_OPERAND (addr, 0);
  ret = copy_node (pref);
  pos = ret;

  while (pref != ref)
    {
      pref = TREE_OPERAND (pref, 0);
      TREE_OPERAND (pos, 0) = copy_node (pref);
      pos = TREE_OPERAND (pos, 0);
    }

  TREE_OPERAND (pos, 1) = fold_build2 (code, itype,
				       fold_convert (itype,
						     TREE_OPERAND (pos, 1)),
				       fold_convert (itype, delta));

  return fold_build1 (ADDR_EXPR, TREE_TYPE (addr), ret);
}


/* Fold A < X && A + 1 > Y to A < X && A >= Y.  Normally A + 1 > Y
   means A >= Y && A != MAX, but in this case we know that
   A < X <= MAX.  INEQ is A + 1 > Y, BOUND is A < X.  */

static tree
fold_to_nonsharp_ineq_using_bound (tree ineq, tree bound)
{
  tree a, typea, type = TREE_TYPE (ineq), a1, diff, y;

  if (TREE_CODE (bound) == LT_EXPR)
    a = TREE_OPERAND (bound, 0);
  else if (TREE_CODE (bound) == GT_EXPR)
    a = TREE_OPERAND (bound, 1);
  else
    return NULL_TREE;

  typea = TREE_TYPE (a);
  if (!INTEGRAL_TYPE_P (typea)
      && !POINTER_TYPE_P (typea))
    return NULL_TREE;

  if (TREE_CODE (ineq) == LT_EXPR)
    {
      a1 = TREE_OPERAND (ineq, 1);
      y = TREE_OPERAND (ineq, 0);
    }
  else if (TREE_CODE (ineq) == GT_EXPR)
    {
      a1 = TREE_OPERAND (ineq, 0);
      y = TREE_OPERAND (ineq, 1);
    }
  else
    return NULL_TREE;

  if (TREE_TYPE (a1) != typea)
    return NULL_TREE;

  diff = fold_build2 (MINUS_EXPR, typea, a1, a);
  if (!integer_onep (diff))
    return NULL_TREE;

  return fold_build2 (GE_EXPR, type, a, y);
}

/* Fold a sum or difference of at least one multiplication.
   Returns the folded tree or NULL if no simplification could be made.  */

static tree
fold_plusminus_mult_expr (enum tree_code code, tree type, tree arg0, tree arg1)
{
  tree arg00, arg01, arg10, arg11;
  tree alt0 = NULL_TREE, alt1 = NULL_TREE, same;

  /* (A * C) +- (B * C) -> (A+-B) * C.
     (A * C) +- A -> A * (C+-1).
     We are most concerned about the case where C is a constant,
     but other combinations show up during loop reduction.  Since
     it is not difficult, try all four possibilities.  */

  if (TREE_CODE (arg0) == MULT_EXPR)
    {
      arg00 = TREE_OPERAND (arg0, 0);
      arg01 = TREE_OPERAND (arg0, 1);
    }
  else
    {
      arg00 = arg0;
      arg01 = build_one_cst (type);
    }
  if (TREE_CODE (arg1) == MULT_EXPR)
    {
      arg10 = TREE_OPERAND (arg1, 0);
      arg11 = TREE_OPERAND (arg1, 1);
    }
  else
    {
      arg10 = arg1;
      arg11 = build_one_cst (type);
    }
  same = NULL_TREE;

  if (operand_equal_p (arg01, arg11, 0))
    same = arg01, alt0 = arg00, alt1 = arg10;
  else if (operand_equal_p (arg00, arg10, 0))
    same = arg00, alt0 = arg01, alt1 = arg11;
  else if (operand_equal_p (arg00, arg11, 0))
    same = arg00, alt0 = arg01, alt1 = arg10;
  else if (operand_equal_p (arg01, arg10, 0))
    same = arg01, alt0 = arg00, alt1 = arg11;

  /* No identical multiplicands; see if we can find a common
     power-of-two factor in non-power-of-two multiplies.  This
     can help in multi-dimensional array access.  */
  else if (host_integerp (arg01, 0)
	   && host_integerp (arg11, 0))
    {
      HOST_WIDE_INT int01, int11, tmp;
      bool swap = false;
      tree maybe_same;
      int01 = TREE_INT_CST_LOW (arg01);
      int11 = TREE_INT_CST_LOW (arg11);

      /* Move min of absolute values to int11.  */
      if ((int01 >= 0 ? int01 : -int01)
	  < (int11 >= 0 ? int11 : -int11))
        {
	  tmp = int01, int01 = int11, int11 = tmp;
	  alt0 = arg00, arg00 = arg10, arg10 = alt0;
	  maybe_same = arg01;
	  swap = true;
	}
      else
	maybe_same = arg11;

      if (exact_log2 (int11) > 0 && int01 % int11 == 0)
        {
	  alt0 = fold_build2 (MULT_EXPR, TREE_TYPE (arg00), arg00,
			      build_int_cst (TREE_TYPE (arg00),
					     int01 / int11));
	  alt1 = arg10;
	  same = maybe_same;
	  if (swap)
	    maybe_same = alt0, alt0 = alt1, alt1 = maybe_same;
	}
    }

  if (same)
    return fold_build2 (MULT_EXPR, type,
			fold_build2 (code, type,
				     fold_convert (type, alt0),
				     fold_convert (type, alt1)),
			fold_convert (type, same));

  return NULL_TREE;
}

/* Subroutine of native_encode_expr.  Encode the INTEGER_CST
   specified by EXPR into the buffer PTR of length LEN bytes.
   Return the number of bytes placed in the buffer, or zero
   upon failure.  */

static int
native_encode_int (tree expr, unsigned char *ptr, int len)
{
  tree type = TREE_TYPE (expr);
  int total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
  int byte, offset, word, words;
  unsigned char value;

  if (total_bytes > len)
    return 0;
  words = total_bytes / UNITS_PER_WORD;

  for (byte = 0; byte < total_bytes; byte++)
    {
      int bitpos = byte * BITS_PER_UNIT;
      if (bitpos < HOST_BITS_PER_WIDE_INT)
	value = (unsigned char) (TREE_INT_CST_LOW (expr) >> bitpos);
      else
	value = (unsigned char) (TREE_INT_CST_HIGH (expr)
				 >> (bitpos - HOST_BITS_PER_WIDE_INT));

      if (total_bytes > UNITS_PER_WORD)
	{
	  word = byte / UNITS_PER_WORD;
	  if (WORDS_BIG_ENDIAN)
	    word = (words - 1) - word;
	  offset = word * UNITS_PER_WORD;
	  if (BYTES_BIG_ENDIAN)
	    offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
	  else
	    offset += byte % UNITS_PER_WORD;
	}
      else
	offset = BYTES_BIG_ENDIAN ? (total_bytes - 1) - byte : byte;
      ptr[offset] = value;
    }
  return total_bytes;
}


/* Subroutine of native_encode_expr.  Encode the REAL_CST
   specified by EXPR into the buffer PTR of length LEN bytes.
   Return the number of bytes placed in the buffer, or zero
   upon failure.  */

static int
native_encode_real (tree expr, unsigned char *ptr, int len)
{
  tree type = TREE_TYPE (expr);
  int total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
  int byte, offset, word, words, bitpos;
  unsigned char value;

  /* There are always 32 bits in each long, no matter the size of
     the hosts long.  We handle floating point representations with
     up to 192 bits.  */
  long tmp[6];

  if (total_bytes > len)
    return 0;
  words = 32 / UNITS_PER_WORD;

  real_to_target (tmp, TREE_REAL_CST_PTR (expr), TYPE_MODE (type));

  for (bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
       bitpos += BITS_PER_UNIT)
    {
      byte = (bitpos / BITS_PER_UNIT) & 3;
      value = (unsigned char) (tmp[bitpos / 32] >> (bitpos & 31));

      if (UNITS_PER_WORD < 4)
	{
	  word = byte / UNITS_PER_WORD;
	  if (WORDS_BIG_ENDIAN)
	    word = (words - 1) - word;
	  offset = word * UNITS_PER_WORD;
	  if (BYTES_BIG_ENDIAN)
	    offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
	  else
	    offset += byte % UNITS_PER_WORD;
	}
      else
	offset = BYTES_BIG_ENDIAN ? 3 - byte : byte;
      ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)] = value;
    }
  return total_bytes;
}

/* Subroutine of native_encode_expr.  Encode the COMPLEX_CST
   specified by EXPR into the buffer PTR of length LEN bytes.
   Return the number of bytes placed in the buffer, or zero
   upon failure.  */

static int
native_encode_complex (tree expr, unsigned char *ptr, int len)
{
  int rsize, isize;
  tree part;

  part = TREE_REALPART (expr);
  rsize = native_encode_expr (part, ptr, len);
  if (rsize == 0)
    return 0;
  part = TREE_IMAGPART (expr);
  isize = native_encode_expr (part, ptr+rsize, len-rsize);
  if (isize != rsize)
    return 0;
  return rsize + isize;
}


/* Subroutine of native_encode_expr.  Encode the VECTOR_CST
   specified by EXPR into the buffer PTR of length LEN bytes.
   Return the number of bytes placed in the buffer, or zero
   upon failure.  */

static int
native_encode_vector (tree expr, unsigned char *ptr, int len)
{
  int i, size, offset, count;
  tree itype, elem, elements;

  offset = 0;
  elements = TREE_VECTOR_CST_ELTS (expr);
  count = TYPE_VECTOR_SUBPARTS (TREE_TYPE (expr));
  itype = TREE_TYPE (TREE_TYPE (expr));
  size = GET_MODE_SIZE (TYPE_MODE (itype));
  for (i = 0; i < count; i++)
    {
      if (elements)
	{
	  elem = TREE_VALUE (elements);
	  elements = TREE_CHAIN (elements);
	}
      else
	elem = NULL_TREE;

      if (elem)
	{
	  if (native_encode_expr (elem, ptr+offset, len-offset) != size)
	    return 0;
	}
      else
	{
	  if (offset + size > len)
	    return 0;
	  memset (ptr+offset, 0, size);
	}
      offset += size;
    }
  return offset;
}


/* Subroutine of fold_view_convert_expr.  Encode the INTEGER_CST,
   REAL_CST, COMPLEX_CST or VECTOR_CST specified by EXPR into the
   buffer PTR of length LEN bytes.  Return the number of bytes
   placed in the buffer, or zero upon failure.  */

static int
native_encode_expr (tree expr, unsigned char *ptr, int len)
{
  switch (TREE_CODE (expr))
    {
    case INTEGER_CST:
      return native_encode_int (expr, ptr, len);

    case REAL_CST:
      return native_encode_real (expr, ptr, len);

    case COMPLEX_CST:
      return native_encode_complex (expr, ptr, len);

    case VECTOR_CST:
      return native_encode_vector (expr, ptr, len);

    default:
      return 0;
    }
}


/* Subroutine of native_interpret_expr.  Interpret the contents of
   the buffer PTR of length LEN as an INTEGER_CST of type TYPE.
   If the buffer cannot be interpreted, return NULL_TREE.  */

static tree
native_interpret_int (tree type, unsigned char *ptr, int len)
{
  int total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
  int byte, offset, word, words;
  unsigned char value;
  unsigned int HOST_WIDE_INT lo = 0;
  HOST_WIDE_INT hi = 0;

  if (total_bytes > len)
    return NULL_TREE;
  if (total_bytes * BITS_PER_UNIT > 2 * HOST_BITS_PER_WIDE_INT)
    return NULL_TREE;
  words = total_bytes / UNITS_PER_WORD;

  for (byte = 0; byte < total_bytes; byte++)
    {
      int bitpos = byte * BITS_PER_UNIT;
      if (total_bytes > UNITS_PER_WORD)
	{
	  word = byte / UNITS_PER_WORD;
	  if (WORDS_BIG_ENDIAN)
	    word = (words - 1) - word;
	  offset = word * UNITS_PER_WORD;
	  if (BYTES_BIG_ENDIAN)
	    offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
	  else
	    offset += byte % UNITS_PER_WORD;
	}
      else
	offset = BYTES_BIG_ENDIAN ? (total_bytes - 1) - byte : byte;
      value = ptr[offset];

      if (bitpos < HOST_BITS_PER_WIDE_INT)
	lo |= (unsigned HOST_WIDE_INT) value << bitpos;
      else
	hi |= (unsigned HOST_WIDE_INT) value
	      << (bitpos - HOST_BITS_PER_WIDE_INT);
    }

  return force_fit_type (build_int_cst_wide (type, lo, hi),
			 0, false, false);
}


/* Subroutine of native_interpret_expr.  Interpret the contents of
   the buffer PTR of length LEN as a REAL_CST of type TYPE.
   If the buffer cannot be interpreted, return NULL_TREE.  */

static tree
native_interpret_real (tree type, unsigned char *ptr, int len)
{
  enum machine_mode mode = TYPE_MODE (type);
  int total_bytes = GET_MODE_SIZE (mode);
  int byte, offset, word, words, bitpos;
  unsigned char value;
  /* There are always 32 bits in each long, no matter the size of
     the hosts long.  We handle floating point representations with
     up to 192 bits.  */
  REAL_VALUE_TYPE r;
  long tmp[6];

  total_bytes = GET_MODE_SIZE (TYPE_MODE (type));
  if (total_bytes > len || total_bytes > 24)
    return NULL_TREE;
  words = 32 / UNITS_PER_WORD;

  memset (tmp, 0, sizeof (tmp));
  for (bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
       bitpos += BITS_PER_UNIT)
    {
      byte = (bitpos / BITS_PER_UNIT) & 3;
      if (UNITS_PER_WORD < 4)
	{
	  word = byte / UNITS_PER_WORD;
	  if (WORDS_BIG_ENDIAN)
	    word = (words - 1) - word;
	  offset = word * UNITS_PER_WORD;
	  if (BYTES_BIG_ENDIAN)
	    offset += (UNITS_PER_WORD - 1) - (byte % UNITS_PER_WORD);
	  else
	    offset += byte % UNITS_PER_WORD;
	}
      else
	offset = BYTES_BIG_ENDIAN ? 3 - byte : byte;
      value = ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)];

      tmp[bitpos / 32] |= (unsigned long)value << (bitpos & 31);
    }

  real_from_target (&r, tmp, mode);
  return build_real (type, r);
}


/* Subroutine of native_interpret_expr.  Interpret the contents of
   the buffer PTR of length LEN as a COMPLEX_CST of type TYPE.
   If the buffer cannot be interpreted, return NULL_TREE.  */

static tree
native_interpret_complex (tree type, unsigned char *ptr, int len)
{
  tree etype, rpart, ipart;
  int size;

  etype = TREE_TYPE (type);
  size = GET_MODE_SIZE (TYPE_MODE (etype));
  if (size * 2 > len)
    return NULL_TREE;
  rpart = native_interpret_expr (etype, ptr, size);
  if (!rpart)
    return NULL_TREE;
  ipart = native_interpret_expr (etype, ptr+size, size);
  if (!ipart)
    return NULL_TREE;
  return build_complex (type, rpart, ipart);
}


/* Subroutine of native_interpret_expr.  Interpret the contents of
   the buffer PTR of length LEN as a VECTOR_CST of type TYPE.
   If the buffer cannot be interpreted, return NULL_TREE.  */

static tree
native_interpret_vector (tree type, unsigned char *ptr, int len)
{
  tree etype, elem, elements;
  int i, size, count;

  etype = TREE_TYPE (type);
  size = GET_MODE_SIZE (TYPE_MODE (etype));
  count = TYPE_VECTOR_SUBPARTS (type);
  if (size * count > len)
    return NULL_TREE;

  elements = NULL_TREE;
  for (i = count - 1; i >= 0; i--)
    {
      elem = native_interpret_expr (etype, ptr+(i*size), size);
      if (!elem)
	return NULL_TREE;
      elements = tree_cons (NULL_TREE, elem, elements);
    }
  return build_vector (type, elements);
}


/* Subroutine of fold_view_convert_expr.  Interpret the contents of
   the buffer PTR of length LEN as a constant of type TYPE.  For
   INTEGRAL_TYPE_P we return an INTEGER_CST, for SCALAR_FLOAT_TYPE_P
   we return a REAL_CST, etc...  If the buffer cannot be interpreted,
   return NULL_TREE.  */

static tree
native_interpret_expr (tree type, unsigned char *ptr, int len)
{
  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
      return native_interpret_int (type, ptr, len);

    case REAL_TYPE:
      return native_interpret_real (type, ptr, len);

    case COMPLEX_TYPE:
      return native_interpret_complex (type, ptr, len);

    case VECTOR_TYPE:
      return native_interpret_vector (type, ptr, len);

    default:
      return NULL_TREE;
    }
}


/* Fold a VIEW_CONVERT_EXPR of a constant expression EXPR to type
   TYPE at compile-time.  If we're unable to perform the conversion
   return NULL_TREE.  */

static tree
fold_view_convert_expr (tree type, tree expr)
{
  /* We support up to 512-bit values (for V8DFmode).  */
  unsigned char buffer[64];
  int len;

  /* Check that the host and target are sane.  */
  if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
    return NULL_TREE;

  len = native_encode_expr (expr, buffer, sizeof (buffer));
  if (len == 0)
    return NULL_TREE;

  return native_interpret_expr (type, buffer, len);
}


/* Fold a unary expression of code CODE and type TYPE with operand
   OP0.  Return the folded expression if folding is successful.
   Otherwise, return NULL_TREE.  */

tree
fold_unary (enum tree_code code, tree type, tree op0)
{
  tree tem;
  tree arg0;
  enum tree_code_class kind = TREE_CODE_CLASS (code);

  gcc_assert (IS_EXPR_CODE_CLASS (kind)
	      && TREE_CODE_LENGTH (code) == 1);

  arg0 = op0;
  if (arg0)
    {
      if (code == NOP_EXPR || code == CONVERT_EXPR
	  || code == FLOAT_EXPR || code == ABS_EXPR)
	{
	  /* Don't use STRIP_NOPS, because signedness of argument type
	     matters.  */
	  STRIP_SIGN_NOPS (arg0);
	}
      else
	{
	  /* Strip any conversions that don't change the mode.  This
	     is safe for every expression, except for a comparison
	     expression because its signedness is derived from its
	     operands.

	     Note that this is done as an internal manipulation within
	     the constant folder, in order to find the simplest
	     representation of the arguments so that their form can be
	     studied.  In any cases, the appropriate type conversions
	     should be put back in the tree that will get out of the
	     constant folder.  */
	  STRIP_NOPS (arg0);
	}
    }

  if (TREE_CODE_CLASS (code) == tcc_unary)
    {
      if (TREE_CODE (arg0) == COMPOUND_EXPR)
	return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
		       fold_build1 (code, type, TREE_OPERAND (arg0, 1)));
      else if (TREE_CODE (arg0) == COND_EXPR)
	{
	  tree arg01 = TREE_OPERAND (arg0, 1);
	  tree arg02 = TREE_OPERAND (arg0, 2);
	  if (! VOID_TYPE_P (TREE_TYPE (arg01)))
	    arg01 = fold_build1 (code, type, arg01);
	  if (! VOID_TYPE_P (TREE_TYPE (arg02)))
	    arg02 = fold_build1 (code, type, arg02);
	  tem = fold_build3 (COND_EXPR, type, TREE_OPERAND (arg0, 0),
			     arg01, arg02);

	  /* If this was a conversion, and all we did was to move into
	     inside the COND_EXPR, bring it back out.  But leave it if
	     it is a conversion from integer to integer and the
	     result precision is no wider than a word since such a
	     conversion is cheap and may be optimized away by combine,
	     while it couldn't if it were outside the COND_EXPR.  Then return
	     so we don't get into an infinite recursion loop taking the
	     conversion out and then back in.  */

	  if ((code == NOP_EXPR || code == CONVERT_EXPR
	       || code == NON_LVALUE_EXPR)
	      && TREE_CODE (tem) == COND_EXPR
	      && TREE_CODE (TREE_OPERAND (tem, 1)) == code
	      && TREE_CODE (TREE_OPERAND (tem, 2)) == code
	      && ! VOID_TYPE_P (TREE_OPERAND (tem, 1))
	      && ! VOID_TYPE_P (TREE_OPERAND (tem, 2))
	      && (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))
		  == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 2), 0)))
	      && (! (INTEGRAL_TYPE_P (TREE_TYPE (tem))
		     && (INTEGRAL_TYPE_P
			 (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))))
		     && TYPE_PRECISION (TREE_TYPE (tem)) <= BITS_PER_WORD)
		  || flag_syntax_only))
	    tem = build1 (code, type,
			  build3 (COND_EXPR,
				  TREE_TYPE (TREE_OPERAND
					     (TREE_OPERAND (tem, 1), 0)),
				  TREE_OPERAND (tem, 0),
				  TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
				  TREE_OPERAND (TREE_OPERAND (tem, 2), 0)));
	  return tem;
	}
      else if (COMPARISON_CLASS_P (arg0))
	{
	  if (TREE_CODE (type) == BOOLEAN_TYPE)
	    {
	      arg0 = copy_node (arg0);
	      TREE_TYPE (arg0) = type;
	      return arg0;
	    }
	  else if (TREE_CODE (type) != INTEGER_TYPE)
	    return fold_build3 (COND_EXPR, type, arg0,
				fold_build1 (code, type,
					     integer_one_node),
				fold_build1 (code, type,
					     integer_zero_node));
	}
   }

  switch (code)
    {
    case NOP_EXPR:
    case FLOAT_EXPR:
    case CONVERT_EXPR:
    case FIX_TRUNC_EXPR:
    case FIX_CEIL_EXPR:
    case FIX_FLOOR_EXPR:
    case FIX_ROUND_EXPR:
      if (TREE_TYPE (op0) == type)
	return op0;
      
      /* If we have (type) (a CMP b) and type is an integral type, return
         new expression involving the new type.  */
      if (COMPARISON_CLASS_P (op0) && INTEGRAL_TYPE_P (type))
	return fold_build2 (TREE_CODE (op0), type, TREE_OPERAND (op0, 0),
			    TREE_OPERAND (op0, 1));

      /* Handle cases of two conversions in a row.  */
      if (TREE_CODE (op0) == NOP_EXPR
	  || TREE_CODE (op0) == CONVERT_EXPR)
	{
	  tree inside_type = TREE_TYPE (TREE_OPERAND (op0, 0));
	  tree inter_type = TREE_TYPE (op0);
	  int inside_int = INTEGRAL_TYPE_P (inside_type);
	  int inside_ptr = POINTER_TYPE_P (inside_type);
	  int inside_float = FLOAT_TYPE_P (inside_type);
	  int inside_vec = TREE_CODE (inside_type) == VECTOR_TYPE;
	  unsigned int inside_prec = TYPE_PRECISION (inside_type);
	  int inside_unsignedp = TYPE_UNSIGNED (inside_type);
	  int inter_int = INTEGRAL_TYPE_P (inter_type);
	  int inter_ptr = POINTER_TYPE_P (inter_type);
	  int inter_float = FLOAT_TYPE_P (inter_type);
	  int inter_vec = TREE_CODE (inter_type) == VECTOR_TYPE;
	  unsigned int inter_prec = TYPE_PRECISION (inter_type);
	  int inter_unsignedp = TYPE_UNSIGNED (inter_type);
	  int final_int = INTEGRAL_TYPE_P (type);
	  int final_ptr = POINTER_TYPE_P (type);
	  int final_float = FLOAT_TYPE_P (type);
	  int final_vec = TREE_CODE (type) == VECTOR_TYPE;
	  unsigned int final_prec = TYPE_PRECISION (type);
	  int final_unsignedp = TYPE_UNSIGNED (type);

	  /* In addition to the cases of two conversions in a row
	     handled below, if we are converting something to its own
	     type via an object of identical or wider precision, neither
	     conversion is needed.  */
	  if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type)
	      && (((inter_int || inter_ptr) && final_int)
		  || (inter_float && final_float))
	      && inter_prec >= final_prec)
	    return fold_build1 (code, type, TREE_OPERAND (op0, 0));

	  /* Likewise, if the intermediate and final types are either both
	     float or both integer, we don't need the middle conversion if
	     it is wider than the final type and doesn't change the signedness
	     (for integers).  Avoid this if the final type is a pointer
	     since then we sometimes need the inner conversion.  Likewise if
	     the outer has a precision not equal to the size of its mode.  */
	  if ((((inter_int || inter_ptr) && (inside_int || inside_ptr))
	       || (inter_float && inside_float)
	       || (inter_vec && inside_vec))
	      && inter_prec >= inside_prec
	      && (inter_float || inter_vec
		  || inter_unsignedp == inside_unsignedp)
	      && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
		    && TYPE_MODE (type) == TYPE_MODE (inter_type))
	      && ! final_ptr
	      && (! final_vec || inter_prec == inside_prec))
	    return fold_build1 (code, type, TREE_OPERAND (op0, 0));

	  /* If we have a sign-extension of a zero-extended value, we can
	     replace that by a single zero-extension.  */
	  if (inside_int && inter_int && final_int
	      && inside_prec < inter_prec && inter_prec < final_prec
	      && inside_unsignedp && !inter_unsignedp)
	    return fold_build1 (code, type, TREE_OPERAND (op0, 0));

	  /* Two conversions in a row are not needed unless:
	     - some conversion is floating-point (overstrict for now), or
	     - some conversion is a vector (overstrict for now), or
	     - the intermediate type is narrower than both initial and
	       final, or
	     - the intermediate type and innermost type differ in signedness,
	       and the outermost type is wider than the intermediate, or
	     - the initial type is a pointer type and the precisions of the
	       intermediate and final types differ, or
	     - the final type is a pointer type and the precisions of the
	       initial and intermediate types differ.
	     - the final type is a pointer type and the initial type not
	     - the initial type is a pointer to an array and the final type
	       not.  */
	  /* Java pointer type conversions generate checks in some
	     cases, so we explicitly disallow this optimization.  */
	  if (! inside_float && ! inter_float && ! final_float
	      && ! inside_vec && ! inter_vec && ! final_vec
	      && (inter_prec >= inside_prec || inter_prec >= final_prec)
	      && ! (inside_int && inter_int
		    && inter_unsignedp != inside_unsignedp
		    && inter_prec < final_prec)
	      && ((inter_unsignedp && inter_prec > inside_prec)
		  == (final_unsignedp && final_prec > inter_prec))
	      && ! (inside_ptr && inter_prec != final_prec)
	      && ! (final_ptr && inside_prec != inter_prec)
	      && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
		    && TYPE_MODE (type) == TYPE_MODE (inter_type))
	      && final_ptr == inside_ptr
	      && ! (inside_ptr
		    && TREE_CODE (TREE_TYPE (inside_type)) == ARRAY_TYPE
		    && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)
	      && ! ((strcmp (lang_hooks.name, "GNU Java") == 0)
		    && final_ptr))
	    return fold_build1 (code, type, TREE_OPERAND (op0, 0));
	}

      /* Handle (T *)&A.B.C for A being of type T and B and C
	 living at offset zero.  This occurs frequently in
	 C++ upcasting and then accessing the base.  */
      if (TREE_CODE (op0) == ADDR_EXPR
	  && POINTER_TYPE_P (type)
	  && handled_component_p (TREE_OPERAND (op0, 0)))
        {
	  HOST_WIDE_INT bitsize, bitpos;
	  tree offset;
	  enum machine_mode mode;
	  int unsignedp, volatilep;
          tree base = TREE_OPERAND (op0, 0);
	  base = get_inner_reference (base, &bitsize, &bitpos, &offset,
				      &mode, &unsignedp, &volatilep, false);
	  /* If the reference was to a (constant) zero offset, we can use
	     the address of the base if it has the same base type
	     as the result type.  */
	  if (! offset && bitpos == 0
	      && TYPE_MAIN_VARIANT (TREE_TYPE (type))
		  == TYPE_MAIN_VARIANT (TREE_TYPE (base)))
	    return fold_convert (type, build_fold_addr_expr (base));
        }

      if (TREE_CODE (op0) == MODIFY_EXPR
	  && TREE_CONSTANT (TREE_OPERAND (op0, 1))
	  /* Detect assigning a bitfield.  */
	  && !(TREE_CODE (TREE_OPERAND (op0, 0)) == COMPONENT_REF
	       && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (op0, 0), 1))))
	{
	  /* Don't leave an assignment inside a conversion
	     unless assigning a bitfield.  */
	  tem = fold_build1 (code, type, TREE_OPERAND (op0, 1));
	  /* First do the assignment, then return converted constant.  */
	  tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), op0, tem);
	  TREE_NO_WARNING (tem) = 1;
	  TREE_USED (tem) = 1;
	  return tem;
	}

      /* Convert (T)(x & c) into (T)x & (T)c, if c is an integer
	 constants (if x has signed type, the sign bit cannot be set
	 in c).  This folds extension into the BIT_AND_EXPR.  */
      if (INTEGRAL_TYPE_P (type)
	  && TREE_CODE (type) != BOOLEAN_TYPE
	  && TREE_CODE (op0) == BIT_AND_EXPR
	  && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
	{
	  tree and = op0;
	  tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1);
	  int change = 0;

	  if (TYPE_UNSIGNED (TREE_TYPE (and))
	      || (TYPE_PRECISION (type)
		  <= TYPE_PRECISION (TREE_TYPE (and))))
	    change = 1;
	  else if (TYPE_PRECISION (TREE_TYPE (and1))
		   <= HOST_BITS_PER_WIDE_INT
		   && host_integerp (and1, 1))
	    {
	      unsigned HOST_WIDE_INT cst;

	      cst = tree_low_cst (and1, 1);
	      cst &= (HOST_WIDE_INT) -1
		     << (TYPE_PRECISION (TREE_TYPE (and1)) - 1);
	      change = (cst == 0);
#ifdef LOAD_EXTEND_OP
	      if (change
		  && !flag_syntax_only
		  && (LOAD_EXTEND_OP (TYPE_MODE (TREE_TYPE (and0)))
		      == ZERO_EXTEND))
		{
		  tree uns = lang_hooks.types.unsigned_type (TREE_TYPE (and0));
		  and0 = fold_convert (uns, and0);
		  and1 = fold_convert (uns, and1);
		}
#endif
	    }
	  if (change)
	    {
	      tem = build_int_cst_wide (type, TREE_INT_CST_LOW (and1),
					TREE_INT_CST_HIGH (and1));
	      tem = force_fit_type (tem, 0, TREE_OVERFLOW (and1),
				    TREE_CONSTANT_OVERFLOW (and1));
	      return fold_build2 (BIT_AND_EXPR, type,
				  fold_convert (type, and0), tem);
	    }
	}

      /* Convert (T1)((T2)X op Y) into (T1)X op Y, for pointer types T1 and
	 T2 being pointers to types of the same size.  */
      if (POINTER_TYPE_P (type)
	  && BINARY_CLASS_P (arg0)
	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
	  && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0))))
	{
	  tree arg00 = TREE_OPERAND (arg0, 0);
	  tree t0 = type;
	  tree t1 = TREE_TYPE (arg00);
	  tree tt0 = TREE_TYPE (t0);
	  tree tt1 = TREE_TYPE (t1);
	  tree s0 = TYPE_SIZE (tt0);
	  tree s1 = TYPE_SIZE (tt1);

	  if (s0 && s1 && operand_equal_p (s0, s1, OEP_ONLY_CONST))
	    return build2 (TREE_CODE (arg0), t0, fold_convert (t0, arg00),
			   TREE_OPERAND (arg0, 1));
	}

      /* Convert (T1)(~(T2)X) into ~(T1)X if T1 and T2 are integral types
	 of the same precision, and X is a integer type not narrower than
	 types T1 or T2, i.e. the cast (T2)X isn't an extension.  */
      if (INTEGRAL_TYPE_P (type)
	  && TREE_CODE (op0) == BIT_NOT_EXPR
	  && INTEGRAL_TYPE_P (TREE_TYPE (op0))
	  && (TREE_CODE (TREE_OPERAND (op0, 0)) == NOP_EXPR
	      || TREE_CODE (TREE_OPERAND (op0, 0)) == CONVERT_EXPR)
	  && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0)))
	{
	  tem = TREE_OPERAND (TREE_OPERAND (op0, 0), 0);
	  if (INTEGRAL_TYPE_P (TREE_TYPE (tem))
	      && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (tem)))
	    return fold_build1 (BIT_NOT_EXPR, type, fold_convert (type, tem));
	}

      tem = fold_convert_const (code, type, op0);
      return tem ? tem : NULL_TREE;

    case VIEW_CONVERT_EXPR:
      if (TREE_CODE (op0) == VIEW_CONVERT_EXPR)
	return fold_build1 (VIEW_CONVERT_EXPR, type, TREE_OPERAND (op0, 0));
      return fold_view_convert_expr (type, op0);

    case NEGATE_EXPR:
      tem = fold_negate_expr (arg0);
      if (tem)
	return fold_convert (type, tem);
      return NULL_TREE;

    case ABS_EXPR:
      if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST)
	return fold_abs_const (arg0, type);
      else if (TREE_CODE (arg0) == NEGATE_EXPR)
	return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg0, 0));
      /* Convert fabs((double)float) into (double)fabsf(float).  */
      else if (TREE_CODE (arg0) == NOP_EXPR
	       && TREE_CODE (type) == REAL_TYPE)
	{
	  tree targ0 = strip_float_extensions (arg0);
	  if (targ0 != arg0)
	    return fold_convert (type, fold_build1 (ABS_EXPR,
						    TREE_TYPE (targ0),
						    targ0));
	}
      /* ABS_EXPR<ABS_EXPR<x>> = ABS_EXPR<x> even if flag_wrapv is on.  */
      else if (TREE_CODE (arg0) == ABS_EXPR)
	return arg0;
      else if (tree_expr_nonnegative_p (arg0))
	return arg0;

      /* Strip sign ops from argument.  */
      if (TREE_CODE (type) == REAL_TYPE)
	{
	  tem = fold_strip_sign_ops (arg0);
	  if (tem)
	    return fold_build1 (ABS_EXPR, type, fold_convert (type, tem));
	}
      return NULL_TREE;

    case CONJ_EXPR:
      if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
	return fold_convert (type, arg0);
      if (TREE_CODE (arg0) == COMPLEX_EXPR)
	{
	  tree itype = TREE_TYPE (type);
	  tree rpart = fold_convert (itype, TREE_OPERAND (arg0, 0));
	  tree ipart = fold_convert (itype, TREE_OPERAND (arg0, 1));
	  return fold_build2 (COMPLEX_EXPR, type, rpart, negate_expr (ipart));
	}
      if (TREE_CODE (arg0) == COMPLEX_CST)
	{
	  tree itype = TREE_TYPE (type);
	  tree rpart = fold_convert (itype, TREE_REALPART (arg0));
	  tree ipart = fold_convert (itype, TREE_IMAGPART (arg0));
	  return build_complex (type, rpart, negate_expr (ipart));
	}
      if (TREE_CODE (arg0) == CONJ_EXPR)
	return fold_convert (type, TREE_OPERAND (arg0, 0));
      return NULL_TREE;

    case BIT_NOT_EXPR:
      if (TREE_CODE (arg0) == INTEGER_CST)
        return fold_not_const (arg0, type);
      else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
	return TREE_OPERAND (arg0, 0);
      /* Convert ~ (-A) to A - 1.  */
      else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
	return fold_build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0),
			    build_int_cst (type, 1));
      /* Convert ~ (A - 1) or ~ (A + -1) to -A.  */
      else if (INTEGRAL_TYPE_P (type)
	       && ((TREE_CODE (arg0) == MINUS_EXPR
		    && integer_onep (TREE_OPERAND (arg0, 1)))
		   || (TREE_CODE (arg0) == PLUS_EXPR
		       && integer_all_onesp (TREE_OPERAND (arg0, 1)))))
	return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0));
      /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify.  */
      else if (TREE_CODE (arg0) == BIT_XOR_EXPR
	       && (tem = fold_unary (BIT_NOT_EXPR, type,
			       	     fold_convert (type,
					     	   TREE_OPERAND (arg0, 0)))))
	return fold_build2 (BIT_XOR_EXPR, type, tem,
			    fold_convert (type, TREE_OPERAND (arg0, 1)));
      else if (TREE_CODE (arg0) == BIT_XOR_EXPR
	       && (tem = fold_unary (BIT_NOT_EXPR, type,
			       	     fold_convert (type,
					     	   TREE_OPERAND (arg0, 1)))))
	return fold_build2 (BIT_XOR_EXPR, type,
			    fold_convert (type, TREE_OPERAND (arg0, 0)), tem);

      return NULL_TREE;

    case TRUTH_NOT_EXPR:
      /* The argument to invert_truthvalue must have Boolean type.  */
      if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE)
          arg0 = fold_convert (boolean_type_node, arg0);

      /* Note that the operand of this must be an int
	 and its values must be 0 or 1.
	 ("true" is a fixed value perhaps depending on the language,
	 but we don't handle values other than 1 correctly yet.)  */
      tem = fold_truth_not_expr (arg0);
      if (!tem)
	return NULL_TREE;
      return fold_convert (type, tem);

    case REALPART_EXPR:
      if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
	return fold_convert (type, arg0);
      if (TREE_CODE (arg0) == COMPLEX_EXPR)
	return omit_one_operand (type, TREE_OPERAND (arg0, 0),
				 TREE_OPERAND (arg0, 1));
      if (TREE_CODE (arg0) == COMPLEX_CST)
	return fold_convert (type, TREE_REALPART (arg0));
      if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
	{
	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
	  tem = fold_build2 (TREE_CODE (arg0), itype,
			     fold_build1 (REALPART_EXPR, itype,
					  TREE_OPERAND (arg0, 0)),
			     fold_build1 (REALPART_EXPR, itype,
					  TREE_OPERAND (arg0, 1)));
	  return fold_convert (type, tem);
	}
      if (TREE_CODE (arg0) == CONJ_EXPR)
	{
	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
	  tem = fold_build1 (REALPART_EXPR, itype, TREE_OPERAND (arg0, 0));
	  return fold_convert (type, tem);
	}
      return NULL_TREE;

    case IMAGPART_EXPR:
      if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
	return fold_convert (type, integer_zero_node);
      if (TREE_CODE (arg0) == COMPLEX_EXPR)
	return omit_one_operand (type, TREE_OPERAND (arg0, 1),
				 TREE_OPERAND (arg0, 0));
      if (TREE_CODE (arg0) == COMPLEX_CST)
	return fold_convert (type, TREE_IMAGPART (arg0));
      if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
	{
	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
	  tem = fold_build2 (TREE_CODE (arg0), itype,
			     fold_build1 (IMAGPART_EXPR, itype,
					  TREE_OPERAND (arg0, 0)),
			     fold_build1 (IMAGPART_EXPR, itype,
					  TREE_OPERAND (arg0, 1)));
	  return fold_convert (type, tem);
	}
      if (TREE_CODE (arg0) == CONJ_EXPR)
	{
	  tree itype = TREE_TYPE (TREE_TYPE (arg0));
	  tem = fold_build1 (IMAGPART_EXPR, itype, TREE_OPERAND (arg0, 0));
	  return fold_convert (type, negate_expr (tem));
	}
      return NULL_TREE;

    default:
      return NULL_TREE;
    } /* switch (code) */
}

/* Fold a binary expression of code CODE and type TYPE with operands
   OP0 and OP1, containing either a MIN-MAX or a MAX-MIN combination.
   Return the folded expression if folding is successful.  Otherwise,
   return NULL_TREE.  */

static tree
fold_minmax (enum tree_code code, tree type, tree op0, tree op1)
{
  enum tree_code compl_code;

  if (code == MIN_EXPR)
    compl_code = MAX_EXPR;
  else if (code == MAX_EXPR)
    compl_code = MIN_EXPR;
  else
    gcc_unreachable ();

  /* MIN (MAX (a, b), b) == b.  */
  if (TREE_CODE (op0) == compl_code
      && operand_equal_p (TREE_OPERAND (op0, 1), op1, 0))
    return omit_one_operand (type, op1, TREE_OPERAND (op0, 0));

  /* MIN (MAX (b, a), b) == b.  */
  if (TREE_CODE (op0) == compl_code
      && operand_equal_p (TREE_OPERAND (op0, 0), op1, 0)
      && reorder_operands_p (TREE_OPERAND (op0, 1), op1))
    return omit_one_operand (type, op1, TREE_OPERAND (op0, 1));

  /* MIN (a, MAX (a, b)) == a.  */
  if (TREE_CODE (op1) == compl_code
      && operand_equal_p (op0, TREE_OPERAND (op1, 0), 0)
      && reorder_operands_p (op0, TREE_OPERAND (op1, 1)))
    return omit_one_operand (type, op0, TREE_OPERAND (op1, 1));

  /* MIN (a, MAX (b, a)) == a.  */
  if (TREE_CODE (op1) == compl_code
      && operand_equal_p (op0, TREE_OPERAND (op1, 1), 0)
      && reorder_operands_p (op0, TREE_OPERAND (op1, 0)))
    return omit_one_operand (type, op0, TREE_OPERAND (op1, 0));

  return NULL_TREE;
}

/* Subroutine of fold_binary.  This routine performs all of the
   transformations that are common to the equality/inequality
   operators (EQ_EXPR and NE_EXPR) and the ordering operators
   (LT_EXPR, LE_EXPR, GE_EXPR and GT_EXPR).  Callers other than
   fold_binary should call fold_binary.  Fold a comparison with
   tree code CODE and type TYPE with operands OP0 and OP1.  Return
   the folded comparison or NULL_TREE.  */

static tree
fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
{
  tree arg0, arg1, tem;

  arg0 = op0;
  arg1 = op1;

  STRIP_SIGN_NOPS (arg0);
  STRIP_SIGN_NOPS (arg1);

  tem = fold_relational_const (code, type, arg0, arg1);
  if (tem != NULL_TREE)
    return tem;

  /* If one arg is a real or integer constant, put it last.  */
  if (tree_swap_operands_p (arg0, arg1, true))
    return fold_build2 (swap_tree_comparison (code), type, op1, op0);

  /* Transform comparisons of the form X +- C1 CMP C2 to X CMP C2 +- C1.  */
  if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
      && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
	  && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
	  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
      && (TREE_CODE (arg1) == INTEGER_CST
	  && !TREE_OVERFLOW (arg1)))
    {
      tree const1 = TREE_OPERAND (arg0, 1);
      tree const2 = arg1;
      tree variable = TREE_OPERAND (arg0, 0);
      tree lhs;
      int lhs_add;
      lhs_add = TREE_CODE (arg0) != PLUS_EXPR;

      lhs = fold_build2 (lhs_add ? PLUS_EXPR : MINUS_EXPR,
			 TREE_TYPE (arg1), const2, const1);
      if (TREE_CODE (lhs) == TREE_CODE (arg1)
	  && (TREE_CODE (lhs) != INTEGER_CST
	      || !TREE_OVERFLOW (lhs)))
	{
	  fold_overflow_warning (("assuming signed overflow does not occur "
				  "when changing X +- C1 cmp C2 to "
				  "X cmp C1 +- C2"),
				 WARN_STRICT_OVERFLOW_COMPARISON);
	  return fold_build2 (code, type, variable, lhs);
	}
    }

  /* If this is a comparison of two exprs that look like an ARRAY_REF of the
     same object, then we can fold this to a comparison of the two offsets in
     signed size type.  This is possible because pointer arithmetic is
     restricted to retain within an object and overflow on pointer differences
     is undefined as of 6.5.6/8 and /9 with respect to the signed ptrdiff_t.

     We check flag_wrapv directly because pointers types are unsigned,
     and therefore TYPE_OVERFLOW_WRAPS returns true for them.  That is
     normally what we want to avoid certain odd overflow cases, but
     not here.  */
  if (POINTER_TYPE_P (TREE_TYPE (arg0))
      && !flag_wrapv
      && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (arg0)))
    {
      tree base0, offset0, base1, offset1;

      if (extract_array_ref (arg0, &base0, &offset0)
	  && extract_array_ref (arg1, &base1, &offset1)
	  && operand_equal_p (base0, base1, 0))
        {
	  tree signed_size_type_node;
	  signed_size_type_node = signed_type_for (size_type_node);

	  /* By converting to signed size type we cover middle-end pointer
	     arithmetic which operates on unsigned pointer types of size
	     type size and ARRAY_REF offsets which are properly sign or
	     zero extended from their type in case it is narrower than
	     size type.  */
	  if (offset0 == NULL_TREE)
	    offset0 = build_int_cst (signed_size_type_node, 0);
	  else
	    offset0 = fold_convert (signed_size_type_node, offset0);
	  if (offset1 == NULL_TREE)
	    offset1 = build_int_cst (signed_size_type_node, 0);
	  else
	    offset1 = fold_convert (signed_size_type_node, offset1);

	  return fold_build2 (code, type, offset0, offset1);
	}
    }

  if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
    {
      tree targ0 = strip_float_extensions (arg0);
      tree targ1 = strip_float_extensions (arg1);
      tree newtype = TREE_TYPE (targ0);

      if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
	newtype = TREE_TYPE (targ1);

      /* Fold (double)float1 CMP (double)float2 into float1 CMP float2.  */
      if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
	return fold_build2 (code, type, fold_convert (newtype, targ0),
			    fold_convert (newtype, targ1));

      /* (-a) CMP (-b) -> b CMP a  */
      if (TREE_CODE (arg0) == NEGATE_EXPR
	  && TREE_CODE (arg1) == NEGATE_EXPR)
	return fold_build2 (code, type, TREE_OPERAND (arg1, 0),
			    TREE_OPERAND (arg0, 0));

      if (TREE_CODE (arg1) == REAL_CST)
	{
	  REAL_VALUE_TYPE cst;
	  cst = TREE_REAL_CST (arg1);

	  /* (-a) CMP CST -> a swap(CMP) (-CST)  */
	  if (TREE_CODE (arg0) == NEGATE_EXPR)
	    return fold_build2 (swap_tree_comparison (code), type,
				TREE_OPERAND (arg0, 0),
				build_real (TREE_TYPE (arg1),
					    REAL_VALUE_NEGATE (cst)));

	  /* IEEE doesn't distinguish +0 and -0 in comparisons.  */
	  /* a CMP (-0) -> a CMP 0  */
	  if (REAL_VALUE_MINUS_ZERO (cst))
	    return fold_build2 (code, type, arg0,
				build_real (TREE_TYPE (arg1), dconst0));

	  /* x != NaN is always true, other ops are always false.  */
	  if (REAL_VALUE_ISNAN (cst)
	      && ! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))))
	    {
	      tem = (code == NE_EXPR) ? integer_one_node : integer_zero_node;
	      return omit_one_operand (type, tem, arg0);
	    }

	  /* Fold comparisons against infinity.  */
	  if (REAL_VALUE_ISINF (cst))
	    {
	      tem = fold_inf_compare (code, type, arg0, arg1);
	      if (tem != NULL_TREE)
		return tem;
	    }
	}

      /* If this is a comparison of a real constant with a PLUS_EXPR
	 or a MINUS_EXPR of a real constant, we can convert it into a
	 comparison with a revised real constant as long as no overflow
	 occurs when unsafe_math_optimizations are enabled.  */
      if (flag_unsafe_math_optimizations
	  && TREE_CODE (arg1) == REAL_CST
	  && (TREE_CODE (arg0) == PLUS_EXPR
	      || TREE_CODE (arg0) == MINUS_EXPR)
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
	  && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
				      ? MINUS_EXPR : PLUS_EXPR,
				      arg1, TREE_OPERAND (arg0, 1), 0))
	  && ! TREE_CONSTANT_OVERFLOW (tem))
	return fold_build2 (code, type, TREE_OPERAND (arg0, 0), tem);

      /* Likewise, we can simplify a comparison of a real constant with
         a MINUS_EXPR whose first operand is also a real constant, i.e.
         (c1 - x) < c2 becomes x > c1-c2.  */
      if (flag_unsafe_math_optimizations
	  && TREE_CODE (arg1) == REAL_CST
	  && TREE_CODE (arg0) == MINUS_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST
	  && 0 != (tem = const_binop (MINUS_EXPR, TREE_OPERAND (arg0, 0),
				      arg1, 0))
	  && ! TREE_CONSTANT_OVERFLOW (tem))
	return fold_build2 (swap_tree_comparison (code), type,
			    TREE_OPERAND (arg0, 1), tem);

      /* Fold comparisons against built-in math functions.  */
      if (TREE_CODE (arg1) == REAL_CST
	  && flag_unsafe_math_optimizations
	  && ! flag_errno_math)
	{
	  enum built_in_function fcode = builtin_mathfn_code (arg0);

	  if (fcode != END_BUILTINS)
	    {
	      tem = fold_mathfn_compare (fcode, code, type, arg0, arg1);
	      if (tem != NULL_TREE)
		return tem;
	    }
	}
    }

  /* Convert foo++ == CONST into ++foo == CONST + INCR.  */
  if (TREE_CONSTANT (arg1)
      && (TREE_CODE (arg0) == POSTINCREMENT_EXPR
	  || TREE_CODE (arg0) == POSTDECREMENT_EXPR)
      /* This optimization is invalid for ordered comparisons
         if CONST+INCR overflows or if foo+incr might overflow.
	 This optimization is invalid for floating point due to rounding.
	 For pointer types we assume overflow doesn't happen.  */
      && (POINTER_TYPE_P (TREE_TYPE (arg0))
	  || (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
	      && (code == EQ_EXPR || code == NE_EXPR))))
    {
      tree varop, newconst;

      if (TREE_CODE (arg0) == POSTINCREMENT_EXPR)
	{
	  newconst = fold_build2 (PLUS_EXPR, TREE_TYPE (arg0),
				  arg1, TREE_OPERAND (arg0, 1));
	  varop = build2 (PREINCREMENT_EXPR, TREE_TYPE (arg0),
			  TREE_OPERAND (arg0, 0),
			  TREE_OPERAND (arg0, 1));
	}
      else
	{
	  newconst = fold_build2 (MINUS_EXPR, TREE_TYPE (arg0),
				  arg1, TREE_OPERAND (arg0, 1));
	  varop = build2 (PREDECREMENT_EXPR, TREE_TYPE (arg0),
			  TREE_OPERAND (arg0, 0),
			  TREE_OPERAND (arg0, 1));
	}


      /* If VAROP is a reference to a bitfield, we must mask
	 the constant by the width of the field.  */
      if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
	  && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1))
	  && host_integerp (DECL_SIZE (TREE_OPERAND
					 (TREE_OPERAND (varop, 0), 1)), 1))
	{
	  tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
	  HOST_WIDE_INT size = tree_low_cst (DECL_SIZE (fielddecl), 1);
	  tree folded_compare, shift;

	  /* First check whether the comparison would come out
	     always the same.  If we don't do that we would
	     change the meaning with the masking.  */
	  folded_compare = fold_build2 (code, type,
					TREE_OPERAND (varop, 0), arg1);
	  if (TREE_CODE (folded_compare) == INTEGER_CST)
	    return omit_one_operand (type, folded_compare, varop);

	  shift = build_int_cst (NULL_TREE,
				 TYPE_PRECISION (TREE_TYPE (varop)) - size);
	  shift = fold_convert (TREE_TYPE (varop), shift);
	  newconst = fold_build2 (LSHIFT_EXPR, TREE_TYPE (varop),
				  newconst, shift);
	  newconst = fold_build2 (RSHIFT_EXPR, TREE_TYPE (varop),
				  newconst, shift);
	}

      return fold_build2 (code, type, varop, newconst);
    }

  if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
      && (TREE_CODE (arg0) == NOP_EXPR
	  || TREE_CODE (arg0) == CONVERT_EXPR))
    {
      /* If we are widening one operand of an integer comparison,
	 see if the other operand is similarly being widened.  Perhaps we
	 can do the comparison in the narrower type.  */
      tem = fold_widened_comparison (code, type, arg0, arg1);
      if (tem)
	return tem;

      /* Or if we are changing signedness.  */
      tem = fold_sign_changed_comparison (code, type, arg0, arg1);
      if (tem)
	return tem;
    }

  /* If this is comparing a constant with a MIN_EXPR or a MAX_EXPR of a
     constant, we can simplify it.  */
  if (TREE_CODE (arg1) == INTEGER_CST
      && (TREE_CODE (arg0) == MIN_EXPR
	  || TREE_CODE (arg0) == MAX_EXPR)
      && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
    {
      tem = optimize_minmax_comparison (code, type, op0, op1);
      if (tem)
	return tem;
    }

  /* Simplify comparison of something with itself.  (For IEEE
     floating-point, we can only do some of these simplifications.)  */
  if (operand_equal_p (arg0, arg1, 0))
    {
      switch (code)
	{
	case EQ_EXPR:
	  if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
	      || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
	    return constant_boolean_node (1, type);
	  break;

	case GE_EXPR:
	case LE_EXPR:
	  if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
	      || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
	    return constant_boolean_node (1, type);
	  return fold_build2 (EQ_EXPR, type, arg0, arg1);

	case NE_EXPR:
	  /* For NE, we can only do this simplification if integer
	     or we don't honor IEEE floating point NaNs.  */
	  if (FLOAT_TYPE_P (TREE_TYPE (arg0))
	      && HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
	    break;
	  /* ... fall through ...  */
	case GT_EXPR:
	case LT_EXPR:
	  return constant_boolean_node (0, type);
	default:
	  gcc_unreachable ();
	}
    }

  /* If we are comparing an expression that just has comparisons
     of two integer values, arithmetic expressions of those comparisons,
     and constants, we can simplify it.  There are only three cases
     to check: the two values can either be equal, the first can be
     greater, or the second can be greater.  Fold the expression for
     those three values.  Since each value must be 0 or 1, we have
     eight possibilities, each of which corresponds to the constant 0
     or 1 or one of the six possible comparisons.

     This handles common cases like (a > b) == 0 but also handles
     expressions like  ((x > y) - (y > x)) > 0, which supposedly
     occur in macroized code.  */

  if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) != INTEGER_CST)
    {
      tree cval1 = 0, cval2 = 0;
      int save_p = 0;

      if (twoval_comparison_p (arg0, &cval1, &cval2, &save_p)
	  /* Don't handle degenerate cases here; they should already
	     have been handled anyway.  */
	  && cval1 != 0 && cval2 != 0
	  && ! (TREE_CONSTANT (cval1) && TREE_CONSTANT (cval2))
	  && TREE_TYPE (cval1) == TREE_TYPE (cval2)
	  && INTEGRAL_TYPE_P (TREE_TYPE (cval1))
	  && TYPE_MAX_VALUE (TREE_TYPE (cval1))
	  && TYPE_MAX_VALUE (TREE_TYPE (cval2))
	  && ! operand_equal_p (TYPE_MIN_VALUE (TREE_TYPE (cval1)),
				TYPE_MAX_VALUE (TREE_TYPE (cval2)), 0))
	{
	  tree maxval = TYPE_MAX_VALUE (TREE_TYPE (cval1));
	  tree minval = TYPE_MIN_VALUE (TREE_TYPE (cval1));

	  /* We can't just pass T to eval_subst in case cval1 or cval2
	     was the same as ARG1.  */

	  tree high_result
		= fold_build2 (code, type,
			       eval_subst (arg0, cval1, maxval,
					   cval2, minval),
			       arg1);
	  tree equal_result
		= fold_build2 (code, type,
			       eval_subst (arg0, cval1, maxval,
					   cval2, maxval),
			       arg1);
	  tree low_result
		= fold_build2 (code, type,
			       eval_subst (arg0, cval1, minval,
					   cval2, maxval),
			       arg1);

	  /* All three of these results should be 0 or 1.  Confirm they are.
	     Then use those values to select the proper code to use.  */

	  if (TREE_CODE (high_result) == INTEGER_CST
	      && TREE_CODE (equal_result) == INTEGER_CST
	      && TREE_CODE (low_result) == INTEGER_CST)
	    {
	      /* Make a 3-bit mask with the high-order bit being the
		 value for `>', the next for '=', and the low for '<'.  */
	      switch ((integer_onep (high_result) * 4)
		      + (integer_onep (equal_result) * 2)
		      + integer_onep (low_result))
		{
		case 0:
		  /* Always false.  */
		  return omit_one_operand (type, integer_zero_node, arg0);
		case 1:
		  code = LT_EXPR;
		  break;
		case 2:
		  code = EQ_EXPR;
		  break;
		case 3:
		  code = LE_EXPR;
		  break;
		case 4:
		  code = GT_EXPR;
		  break;
		case 5:
		  code = NE_EXPR;
		  break;
		case 6:
		  code = GE_EXPR;
		  break;
		case 7:
		  /* Always true.  */
		  return omit_one_operand (type, integer_one_node, arg0);
		}

	      if (save_p)
		return save_expr (build2 (code, type, cval1, cval2));
	      return fold_build2 (code, type, cval1, cval2);
	    }
	}
    }

  /* Fold a comparison of the address of COMPONENT_REFs with the same
     type and component to a comparison of the address of the base
     object.  In short, &x->a OP &y->a to x OP y and
     &x->a OP &y.a to x OP &y  */
  if (TREE_CODE (arg0) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (arg0, 0)) == COMPONENT_REF
      && TREE_CODE (arg1) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (arg1, 0)) == COMPONENT_REF)
    {
      tree cref0 = TREE_OPERAND (arg0, 0);
      tree cref1 = TREE_OPERAND (arg1, 0);
      if (TREE_OPERAND (cref0, 1) == TREE_OPERAND (cref1, 1))
	{
	  tree op0 = TREE_OPERAND (cref0, 0);
	  tree op1 = TREE_OPERAND (cref1, 0);
	  return fold_build2 (code, type,
			      build_fold_addr_expr (op0),
			      build_fold_addr_expr (op1));
	}
    }

  /* We can fold X/C1 op C2 where C1 and C2 are integer constants
     into a single range test.  */
  if ((TREE_CODE (arg0) == TRUNC_DIV_EXPR
       || TREE_CODE (arg0) == EXACT_DIV_EXPR)
      && TREE_CODE (arg1) == INTEGER_CST
      && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
      && !integer_zerop (TREE_OPERAND (arg0, 1))
      && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
      && !TREE_OVERFLOW (arg1))
    {
      tem = fold_div_compare (code, type, arg0, arg1);
      if (tem != NULL_TREE)
	return tem;
    }

  return NULL_TREE;
}


/* Subroutine of fold_binary.  Optimize complex multiplications of the
   form z * conj(z), as pow(realpart(z),2) + pow(imagpart(z),2).  The
   argument EXPR represents the expression "z" of type TYPE.  */

static tree
fold_mult_zconjz (tree type, tree expr)
{
  tree itype = TREE_TYPE (type);
  tree rpart, ipart, tem;

  if (TREE_CODE (expr) == COMPLEX_EXPR)
    {
      rpart = TREE_OPERAND (expr, 0);
      ipart = TREE_OPERAND (expr, 1);
    }
  else if (TREE_CODE (expr) == COMPLEX_CST)
    {
      rpart = TREE_REALPART (expr);
      ipart = TREE_IMAGPART (expr);
    }
  else
    {
      expr = save_expr (expr);
      rpart = fold_build1 (REALPART_EXPR, itype, expr);
      ipart = fold_build1 (IMAGPART_EXPR, itype, expr);
    }

  rpart = save_expr (rpart);
  ipart = save_expr (ipart);
  tem = fold_build2 (PLUS_EXPR, itype,
		     fold_build2 (MULT_EXPR, itype, rpart, rpart),
		     fold_build2 (MULT_EXPR, itype, ipart, ipart));
  return fold_build2 (COMPLEX_EXPR, type, tem,
		      fold_convert (itype, integer_zero_node));
}


/* Fold a binary expression of code CODE and type TYPE with operands
   OP0 and OP1.  Return the folded expression if folding is
   successful.  Otherwise, return NULL_TREE.  */

tree
fold_binary (enum tree_code code, tree type, tree op0, tree op1)
{
  enum tree_code_class kind = TREE_CODE_CLASS (code);
  tree arg0, arg1, tem;
  tree t1 = NULL_TREE;
  bool strict_overflow_p;

  gcc_assert (IS_EXPR_CODE_CLASS (kind)
	      && TREE_CODE_LENGTH (code) == 2
	      && op0 != NULL_TREE
	      && op1 != NULL_TREE);

  arg0 = op0;
  arg1 = op1;

  /* Strip any conversions that don't change the mode.  This is
     safe for every expression, except for a comparison expression
     because its signedness is derived from its operands.  So, in
     the latter case, only strip conversions that don't change the
     signedness.

     Note that this is done as an internal manipulation within the
     constant folder, in order to find the simplest representation
     of the arguments so that their form can be studied.  In any
     cases, the appropriate type conversions should be put back in
     the tree that will get out of the constant folder.  */

  if (kind == tcc_comparison)
    {
      STRIP_SIGN_NOPS (arg0);
      STRIP_SIGN_NOPS (arg1);
    }
  else
    {
      STRIP_NOPS (arg0);
      STRIP_NOPS (arg1);
    }

  /* Note that TREE_CONSTANT isn't enough: static var addresses are
     constant but we can't do arithmetic on them.  */
  if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
      || (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
      || (TREE_CODE (arg0) == COMPLEX_CST && TREE_CODE (arg1) == COMPLEX_CST)
      || (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST))
    {
      if (kind == tcc_binary)
	tem = const_binop (code, arg0, arg1, 0);
      else if (kind == tcc_comparison)
	tem = fold_relational_const (code, type, arg0, arg1);
      else
	tem = NULL_TREE;

      if (tem != NULL_TREE)
	{
	  if (TREE_TYPE (tem) != type)
	    tem = fold_convert (type, tem);
	  return tem;
	}
    }

  /* If this is a commutative operation, and ARG0 is a constant, move it
     to ARG1 to reduce the number of tests below.  */
  if (commutative_tree_code (code)
      && tree_swap_operands_p (arg0, arg1, true))
    return fold_build2 (code, type, op1, op0);

  /* ARG0 is the first operand of EXPR, and ARG1 is the second operand.

     First check for cases where an arithmetic operation is applied to a
     compound, conditional, or comparison operation.  Push the arithmetic
     operation inside the compound or conditional to see if any folding
     can then be done.  Convert comparison to conditional for this purpose.
     The also optimizes non-constant cases that used to be done in
     expand_expr.

     Before we do that, see if this is a BIT_AND_EXPR or a BIT_IOR_EXPR,
     one of the operands is a comparison and the other is a comparison, a
     BIT_AND_EXPR with the constant 1, or a truth value.  In that case, the
     code below would make the expression more complex.  Change it to a
     TRUTH_{AND,OR}_EXPR.  Likewise, convert a similar NE_EXPR to
     TRUTH_XOR_EXPR and an EQ_EXPR to the inversion of a TRUTH_XOR_EXPR.  */

  if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
       || code == EQ_EXPR || code == NE_EXPR)
      && ((truth_value_p (TREE_CODE (arg0))
	   && (truth_value_p (TREE_CODE (arg1))
	       || (TREE_CODE (arg1) == BIT_AND_EXPR
		   && integer_onep (TREE_OPERAND (arg1, 1)))))
	  || (truth_value_p (TREE_CODE (arg1))
	      && (truth_value_p (TREE_CODE (arg0))
		  || (TREE_CODE (arg0) == BIT_AND_EXPR
		      && integer_onep (TREE_OPERAND (arg0, 1)))))))
    {
      tem = fold_build2 (code == BIT_AND_EXPR ? TRUTH_AND_EXPR
			 : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
			 : TRUTH_XOR_EXPR,
			 boolean_type_node,
			 fold_convert (boolean_type_node, arg0),
			 fold_convert (boolean_type_node, arg1));

      if (code == EQ_EXPR)
	tem = invert_truthvalue (tem);

      return fold_convert (type, tem);
    }

  if (TREE_CODE_CLASS (code) == tcc_binary
      || TREE_CODE_CLASS (code) == tcc_comparison)
    {
      if (TREE_CODE (arg0) == COMPOUND_EXPR)
	return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
		       fold_build2 (code, type,
				    TREE_OPERAND (arg0, 1), op1));
      if (TREE_CODE (arg1) == COMPOUND_EXPR
	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
	return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
		       fold_build2 (code, type,
				    op0, TREE_OPERAND (arg1, 1)));

      if (TREE_CODE (arg0) == COND_EXPR || COMPARISON_CLASS_P (arg0))
	{
	  tem = fold_binary_op_with_conditional_arg (code, type, op0, op1,
						     arg0, arg1, 
						     /*cond_first_p=*/1);
	  if (tem != NULL_TREE)
	    return tem;
	}

      if (TREE_CODE (arg1) == COND_EXPR || COMPARISON_CLASS_P (arg1))
	{
	  tem = fold_binary_op_with_conditional_arg (code, type, op0, op1,
						     arg1, arg0, 
					             /*cond_first_p=*/0);
	  if (tem != NULL_TREE)
	    return tem;
	}
    }

  switch (code)
    {
    case PLUS_EXPR:
      /* A + (-B) -> A - B */
      if (TREE_CODE (arg1) == NEGATE_EXPR)
	return fold_build2 (MINUS_EXPR, type,
			    fold_convert (type, arg0),
			    fold_convert (type, TREE_OPERAND (arg1, 0)));
      /* (-A) + B -> B - A */
      if (TREE_CODE (arg0) == NEGATE_EXPR
	  && reorder_operands_p (TREE_OPERAND (arg0, 0), arg1))
	return fold_build2 (MINUS_EXPR, type,
			    fold_convert (type, arg1),
			    fold_convert (type, TREE_OPERAND (arg0, 0)));
      /* Convert ~A + 1 to -A.  */
      if (INTEGRAL_TYPE_P (type)
	  && TREE_CODE (arg0) == BIT_NOT_EXPR
	  && integer_onep (arg1))
	return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0));

      /* Handle (A1 * C1) + (A2 * C2) with A1, A2 or C1, C2 being the
	 same or one.  */
      if ((TREE_CODE (arg0) == MULT_EXPR
	   || TREE_CODE (arg1) == MULT_EXPR)
	  && (!FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
        {
	  tree tem = fold_plusminus_mult_expr (code, type, arg0, arg1);
	  if (tem)
	    return tem;
	}

      if (! FLOAT_TYPE_P (type))
	{
	  if (integer_zerop (arg1))
	    return non_lvalue (fold_convert (type, arg0));

	  /* If we are adding two BIT_AND_EXPR's, both of which are and'ing
	     with a constant, and the two constants have no bits in common,
	     we should treat this as a BIT_IOR_EXPR since this may produce more
	     simplifications.  */
	  if (TREE_CODE (arg0) == BIT_AND_EXPR
	      && TREE_CODE (arg1) == BIT_AND_EXPR
	      && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
	      && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
	      && integer_zerop (const_binop (BIT_AND_EXPR,
					     TREE_OPERAND (arg0, 1),
					     TREE_OPERAND (arg1, 1), 0)))
	    {
	      code = BIT_IOR_EXPR;
	      goto bit_ior;
	    }

	  /* Reassociate (plus (plus (mult) (foo)) (mult)) as
	     (plus (plus (mult) (mult)) (foo)) so that we can
	     take advantage of the factoring cases below.  */
	  if (((TREE_CODE (arg0) == PLUS_EXPR
		|| TREE_CODE (arg0) == MINUS_EXPR)
	       && TREE_CODE (arg1) == MULT_EXPR)
	      || ((TREE_CODE (arg1) == PLUS_EXPR
		   || TREE_CODE (arg1) == MINUS_EXPR)
		  && TREE_CODE (arg0) == MULT_EXPR))
	    {
	      tree parg0, parg1, parg, marg;
	      enum tree_code pcode;

	      if (TREE_CODE (arg1) == MULT_EXPR)
		parg = arg0, marg = arg1;
	      else
		parg = arg1, marg = arg0;
	      pcode = TREE_CODE (parg);
	      parg0 = TREE_OPERAND (parg, 0);
	      parg1 = TREE_OPERAND (parg, 1);
	      STRIP_NOPS (parg0);
	      STRIP_NOPS (parg1);

	      if (TREE_CODE (parg0) == MULT_EXPR
		  && TREE_CODE (parg1) != MULT_EXPR)
		return fold_build2 (pcode, type,
				    fold_build2 (PLUS_EXPR, type,
						 fold_convert (type, parg0),
						 fold_convert (type, marg)),
				    fold_convert (type, parg1));
	      if (TREE_CODE (parg0) != MULT_EXPR
		  && TREE_CODE (parg1) == MULT_EXPR)
		return fold_build2 (PLUS_EXPR, type,
				    fold_convert (type, parg0),
				    fold_build2 (pcode, type,
						 fold_convert (type, marg),
						 fold_convert (type,
							       parg1)));
	    }

	  /* Try replacing &a[i1] + c * i2 with &a[i1 + i2], if c is step
	     of the array.  Loop optimizer sometimes produce this type of
	     expressions.  */
	  if (TREE_CODE (arg0) == ADDR_EXPR)
	    {
	      tem = try_move_mult_to_index (PLUS_EXPR, arg0, arg1);
	      if (tem)
		return fold_convert (type, tem);
	    }
	  else if (TREE_CODE (arg1) == ADDR_EXPR)
	    {
	      tem = try_move_mult_to_index (PLUS_EXPR, arg1, arg0);
	      if (tem)
		return fold_convert (type, tem);
	    }
	}
      else
	{
	  /* See if ARG1 is zero and X + ARG1 reduces to X.  */
	  if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 0))
	    return non_lvalue (fold_convert (type, arg0));

	  /* Likewise if the operands are reversed.  */
	  if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
	    return non_lvalue (fold_convert (type, arg1));

	  /* Convert X + -C into X - C.  */
	  if (TREE_CODE (arg1) == REAL_CST
	      && REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1)))
	    {
	      tem = fold_negate_const (arg1, type);
	      if (!TREE_OVERFLOW (arg1) || !flag_trapping_math)
		return fold_build2 (MINUS_EXPR, type,
				    fold_convert (type, arg0),
				    fold_convert (type, tem));
	    }

          if (flag_unsafe_math_optimizations
	      && (TREE_CODE (arg0) == RDIV_EXPR || TREE_CODE (arg0) == MULT_EXPR)
	      && (TREE_CODE (arg1) == RDIV_EXPR || TREE_CODE (arg1) == MULT_EXPR)
	      && (tem = distribute_real_division (code, type, arg0, arg1)))
	    return tem;

	  /* Convert x+x into x*2.0.  */
	  if (operand_equal_p (arg0, arg1, 0)
	      && SCALAR_FLOAT_TYPE_P (type))
	    return fold_build2 (MULT_EXPR, type, arg0,
				build_real (type, dconst2));

          /* Convert a + (b*c + d*e) into (a + b*c) + d*e.  */
          if (flag_unsafe_math_optimizations
              && TREE_CODE (arg1) == PLUS_EXPR
              && TREE_CODE (arg0) != MULT_EXPR)
            {
              tree tree10 = TREE_OPERAND (arg1, 0);
              tree tree11 = TREE_OPERAND (arg1, 1);
              if (TREE_CODE (tree11) == MULT_EXPR
		  && TREE_CODE (tree10) == MULT_EXPR)
                {
                  tree tree0;
                  tree0 = fold_build2 (PLUS_EXPR, type, arg0, tree10);
                  return fold_build2 (PLUS_EXPR, type, tree0, tree11);
                }
            }
          /* Convert (b*c + d*e) + a into b*c + (d*e +a).  */
          if (flag_unsafe_math_optimizations
              && TREE_CODE (arg0) == PLUS_EXPR
              && TREE_CODE (arg1) != MULT_EXPR)
            {
              tree tree00 = TREE_OPERAND (arg0, 0);
              tree tree01 = TREE_OPERAND (arg0, 1);
              if (TREE_CODE (tree01) == MULT_EXPR
		  && TREE_CODE (tree00) == MULT_EXPR)
                {
                  tree tree0;
                  tree0 = fold_build2 (PLUS_EXPR, type, tree01, arg1);
                  return fold_build2 (PLUS_EXPR, type, tree00, tree0);
                }
            }
	}

     bit_rotate:
      /* (A << C1) + (A >> C2) if A is unsigned and C1+C2 is the size of A
	 is a rotate of A by C1 bits.  */
      /* (A << B) + (A >> (Z - B)) if A is unsigned and Z is the size of A
	 is a rotate of A by B bits.  */
      {
	enum tree_code code0, code1;
	code0 = TREE_CODE (arg0);
	code1 = TREE_CODE (arg1);
	if (((code0 == RSHIFT_EXPR && code1 == LSHIFT_EXPR)
	     || (code1 == RSHIFT_EXPR && code0 == LSHIFT_EXPR))
	    && operand_equal_p (TREE_OPERAND (arg0, 0),
			        TREE_OPERAND (arg1, 0), 0)
	    && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
	  {
	    tree tree01, tree11;
	    enum tree_code code01, code11;

	    tree01 = TREE_OPERAND (arg0, 1);
	    tree11 = TREE_OPERAND (arg1, 1);
	    STRIP_NOPS (tree01);
	    STRIP_NOPS (tree11);
	    code01 = TREE_CODE (tree01);
	    code11 = TREE_CODE (tree11);
	    if (code01 == INTEGER_CST
		&& code11 == INTEGER_CST
		&& TREE_INT_CST_HIGH (tree01) == 0
		&& TREE_INT_CST_HIGH (tree11) == 0
		&& ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
		    == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
	      return build2 (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
			     code0 == LSHIFT_EXPR ? tree01 : tree11);
	    else if (code11 == MINUS_EXPR)
	      {
		tree tree110, tree111;
		tree110 = TREE_OPERAND (tree11, 0);
		tree111 = TREE_OPERAND (tree11, 1);
		STRIP_NOPS (tree110);
		STRIP_NOPS (tree111);
		if (TREE_CODE (tree110) == INTEGER_CST
		    && 0 == compare_tree_int (tree110,
					      TYPE_PRECISION
					      (TREE_TYPE (TREE_OPERAND
							  (arg0, 0))))
		    && operand_equal_p (tree01, tree111, 0))
		  return build2 ((code0 == LSHIFT_EXPR
				  ? LROTATE_EXPR
				  : RROTATE_EXPR),
				 type, TREE_OPERAND (arg0, 0), tree01);
	      }
	    else if (code01 == MINUS_EXPR)
	      {
		tree tree010, tree011;
		tree010 = TREE_OPERAND (tree01, 0);
		tree011 = TREE_OPERAND (tree01, 1);
		STRIP_NOPS (tree010);
		STRIP_NOPS (tree011);
		if (TREE_CODE (tree010) == INTEGER_CST
		    && 0 == compare_tree_int (tree010,
					      TYPE_PRECISION
					      (TREE_TYPE (TREE_OPERAND
							  (arg0, 0))))
		    && operand_equal_p (tree11, tree011, 0))
		  return build2 ((code0 != LSHIFT_EXPR
				  ? LROTATE_EXPR
				  : RROTATE_EXPR),
				 type, TREE_OPERAND (arg0, 0), tree11);
	      }
	  }
      }

    associate:
      /* In most languages, can't associate operations on floats through
	 parentheses.  Rather than remember where the parentheses were, we
	 don't associate floats at all, unless the user has specified
	 -funsafe-math-optimizations.  */

      if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
	{
	  tree var0, con0, lit0, minus_lit0;
	  tree var1, con1, lit1, minus_lit1;
	  bool ok = true;

	  /* Split both trees into variables, constants, and literals.  Then
	     associate each group together, the constants with literals,
	     then the result with variables.  This increases the chances of
	     literals being recombined later and of generating relocatable
	     expressions for the sum of a constant and literal.  */
	  var0 = split_tree (arg0, code, &con0, &lit0, &minus_lit0, 0);
	  var1 = split_tree (arg1, code, &con1, &lit1, &minus_lit1,
			     code == MINUS_EXPR);

	  /* With undefined overflow we can only associate constants
	     with one variable.  */
	  if ((POINTER_TYPE_P (type)
	       || (INTEGRAL_TYPE_P (type)
		   && !(TYPE_UNSIGNED (type) || flag_wrapv)))
	      && var0 && var1)
	    {
	      tree tmp0 = var0;
	      tree tmp1 = var1;

	      if (TREE_CODE (tmp0) == NEGATE_EXPR)
	        tmp0 = TREE_OPERAND (tmp0, 0);
	      if (TREE_CODE (tmp1) == NEGATE_EXPR)
	        tmp1 = TREE_OPERAND (tmp1, 0);
	      /* The only case we can still associate with two variables
		 is if they are the same, modulo negation.  */
	      if (!operand_equal_p (tmp0, tmp1, 0))
	        ok = false;
	    }

	  /* Only do something if we found more than two objects.  Otherwise,
	     nothing has changed and we risk infinite recursion.  */
	  if (ok
	      && (2 < ((var0 != 0) + (var1 != 0)
		       + (con0 != 0) + (con1 != 0)
		       + (lit0 != 0) + (lit1 != 0)
		       + (minus_lit0 != 0) + (minus_lit1 != 0))))
	    {
	      /* Recombine MINUS_EXPR operands by using PLUS_EXPR.  */
	      if (code == MINUS_EXPR)
		code = PLUS_EXPR;

	      var0 = associate_trees (var0, var1, code, type);
	      con0 = associate_trees (con0, con1, code, type);
	      lit0 = associate_trees (lit0, lit1, code, type);
	      minus_lit0 = associate_trees (minus_lit0, minus_lit1, code, type);

	      /* Preserve the MINUS_EXPR if the negative part of the literal is
		 greater than the positive part.  Otherwise, the multiplicative
		 folding code (i.e extract_muldiv) may be fooled in case
		 unsigned constants are subtracted, like in the following
		 example: ((X*2 + 4) - 8U)/2.  */
	      if (minus_lit0 && lit0)
		{
		  if (TREE_CODE (lit0) == INTEGER_CST
		      && TREE_CODE (minus_lit0) == INTEGER_CST
		      && tree_int_cst_lt (lit0, minus_lit0))
		    {
		      minus_lit0 = associate_trees (minus_lit0, lit0,
						    MINUS_EXPR, type);
		      lit0 = 0;
		    }
		  else
		    {
		      lit0 = associate_trees (lit0, minus_lit0,
					      MINUS_EXPR, type);
		      minus_lit0 = 0;
		    }
		}
	      if (minus_lit0)
		{
		  if (con0 == 0)
		    return fold_convert (type,
					 associate_trees (var0, minus_lit0,
							  MINUS_EXPR, type));
		  else
		    {
		      con0 = associate_trees (con0, minus_lit0,
					      MINUS_EXPR, type);
		      return fold_convert (type,
					   associate_trees (var0, con0,
							    PLUS_EXPR, type));
		    }
		}

	      con0 = associate_trees (con0, lit0, code, type);
	      return fold_convert (type, associate_trees (var0, con0,
							  code, type));
	    }
	}

      return NULL_TREE;

    case MINUS_EXPR:
      /* A - (-B) -> A + B */
      if (TREE_CODE (arg1) == NEGATE_EXPR)
	return fold_build2 (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0));
      /* (-A) - B -> (-B) - A  where B is easily negated and we can swap.  */
      if (TREE_CODE (arg0) == NEGATE_EXPR
	  && (FLOAT_TYPE_P (type)
	      || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv))
	  && negate_expr_p (arg1)
	  && reorder_operands_p (arg0, arg1))
	return fold_build2 (MINUS_EXPR, type, negate_expr (arg1),
			    TREE_OPERAND (arg0, 0));
      /* Convert -A - 1 to ~A.  */
      if (INTEGRAL_TYPE_P (type)
	  && TREE_CODE (arg0) == NEGATE_EXPR
	  && integer_onep (arg1))
	return fold_build1 (BIT_NOT_EXPR, type,
			    fold_convert (type, TREE_OPERAND (arg0, 0)));

      /* Convert -1 - A to ~A.  */
      if (INTEGRAL_TYPE_P (type)
	  && integer_all_onesp (arg0))
	return fold_build1 (BIT_NOT_EXPR, type, arg1);

      if (! FLOAT_TYPE_P (type))
	{
	  if (integer_zerop (arg0))
	    return negate_expr (fold_convert (type, arg1));
	  if (integer_zerop (arg1))
	    return non_lvalue (fold_convert (type, arg0));

	  /* Fold A - (A & B) into ~B & A.  */
	  if (!TREE_SIDE_EFFECTS (arg0)
	      && TREE_CODE (arg1) == BIT_AND_EXPR)
	    {
	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0))
		return fold_build2 (BIT_AND_EXPR, type,
				    fold_build1 (BIT_NOT_EXPR, type,
						 TREE_OPERAND (arg1, 0)),
				    arg0);
	      if (operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
		return fold_build2 (BIT_AND_EXPR, type,
				    fold_build1 (BIT_NOT_EXPR, type,
						 TREE_OPERAND (arg1, 1)),
				    arg0);
	    }

	  /* Fold (A & ~B) - (A & B) into (A ^ B) - B, where B is
	     any power of 2 minus 1.  */
	  if (TREE_CODE (arg0) == BIT_AND_EXPR
	      && TREE_CODE (arg1) == BIT_AND_EXPR
	      && operand_equal_p (TREE_OPERAND (arg0, 0),
				  TREE_OPERAND (arg1, 0), 0))
	    {
	      tree mask0 = TREE_OPERAND (arg0, 1);
	      tree mask1 = TREE_OPERAND (arg1, 1);
	      tree tem = fold_build1 (BIT_NOT_EXPR, type, mask0);

	      if (operand_equal_p (tem, mask1, 0))
		{
		  tem = fold_build2 (BIT_XOR_EXPR, type,
				     TREE_OPERAND (arg0, 0), mask1);
		  return fold_build2 (MINUS_EXPR, type, tem, mask1);
		}
	    }
	}

      /* See if ARG1 is zero and X - ARG1 reduces to X.  */
      else if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 1))
	return non_lvalue (fold_convert (type, arg0));

      /* (ARG0 - ARG1) is the same as (-ARG1 + ARG0).  So check whether
	 ARG0 is zero and X + ARG0 reduces to X, since that would mean
	 (-ARG1 + ARG0) reduces to -ARG1.  */
      else if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
	return negate_expr (fold_convert (type, arg1));

      /* Fold &x - &x.  This can happen from &x.foo - &x.
	 This is unsafe for certain floats even in non-IEEE formats.
	 In IEEE, it is unsafe because it does wrong for NaNs.
	 Also note that operand_equal_p is always false if an operand
	 is volatile.  */

      if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
	  && operand_equal_p (arg0, arg1, 0))
	return fold_convert (type, integer_zero_node);

      /* A - B -> A + (-B) if B is easily negatable.  */
      if (negate_expr_p (arg1)
	  && ((FLOAT_TYPE_P (type)
               /* Avoid this transformation if B is a positive REAL_CST.  */
	       && (TREE_CODE (arg1) != REAL_CST
		   ||  REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
	      || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
	return fold_build2 (PLUS_EXPR, type,
			    fold_convert (type, arg0),
			    fold_convert (type, negate_expr (arg1)));

      /* Try folding difference of addresses.  */
      {
	HOST_WIDE_INT diff;

	if ((TREE_CODE (arg0) == ADDR_EXPR
	     || TREE_CODE (arg1) == ADDR_EXPR)
	    && ptr_difference_const (arg0, arg1, &diff))
	  return build_int_cst_type (type, diff);
      }

      /* Fold &a[i] - &a[j] to i-j.  */
      if (TREE_CODE (arg0) == ADDR_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == ARRAY_REF
	  && TREE_CODE (arg1) == ADDR_EXPR
	  && TREE_CODE (TREE_OPERAND (arg1, 0)) == ARRAY_REF)
        {
	  tree aref0 = TREE_OPERAND (arg0, 0);
	  tree aref1 = TREE_OPERAND (arg1, 0);
	  if (operand_equal_p (TREE_OPERAND (aref0, 0),
			       TREE_OPERAND (aref1, 0), 0))
	    {
	      tree op0 = fold_convert (type, TREE_OPERAND (aref0, 1));
	      tree op1 = fold_convert (type, TREE_OPERAND (aref1, 1));
	      tree esz = array_ref_element_size (aref0);
	      tree diff = build2 (MINUS_EXPR, type, op0, op1);
	      return fold_build2 (MULT_EXPR, type, diff,
			          fold_convert (type, esz));
			          
	    }
	}

      /* Try replacing &a[i1] - c * i2 with &a[i1 - i2], if c is step
	 of the array.  Loop optimizer sometimes produce this type of
	 expressions.  */
      if (TREE_CODE (arg0) == ADDR_EXPR)
	{
	  tem = try_move_mult_to_index (MINUS_EXPR, arg0, arg1);
	  if (tem)
	    return fold_convert (type, tem);
	}

      if (flag_unsafe_math_optimizations
	  && (TREE_CODE (arg0) == RDIV_EXPR || TREE_CODE (arg0) == MULT_EXPR)
	  && (TREE_CODE (arg1) == RDIV_EXPR || TREE_CODE (arg1) == MULT_EXPR)
	  && (tem = distribute_real_division (code, type, arg0, arg1)))
	return tem;

      /* Handle (A1 * C1) - (A2 * C2) with A1, A2 or C1, C2 being the
	 same or one.  */
      if ((TREE_CODE (arg0) == MULT_EXPR
	   || TREE_CODE (arg1) == MULT_EXPR)
	  && (!FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
        {
	  tree tem = fold_plusminus_mult_expr (code, type, arg0, arg1);
	  if (tem)
	    return tem;
	}

      goto associate;

    case MULT_EXPR:
      /* (-A) * (-B) -> A * B  */
      if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
	return fold_build2 (MULT_EXPR, type,
			    fold_convert (type, TREE_OPERAND (arg0, 0)),
			    fold_convert (type, negate_expr (arg1)));
      if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
	return fold_build2 (MULT_EXPR, type,
			    fold_convert (type, negate_expr (arg0)),
			    fold_convert (type, TREE_OPERAND (arg1, 0)));

      if (! FLOAT_TYPE_P (type))
	{
	  if (integer_zerop (arg1))
	    return omit_one_operand (type, arg1, arg0);
	  if (integer_onep (arg1))
	    return non_lvalue (fold_convert (type, arg0));
	  /* Transform x * -1 into -x.  */
	  if (integer_all_onesp (arg1))
	    return fold_convert (type, negate_expr (arg0));

	  /* (a * (1 << b)) is (a << b)  */
	  if (TREE_CODE (arg1) == LSHIFT_EXPR
	      && integer_onep (TREE_OPERAND (arg1, 0)))
	    return fold_build2 (LSHIFT_EXPR, type, arg0,
				TREE_OPERAND (arg1, 1));
	  if (TREE_CODE (arg0) == LSHIFT_EXPR
	      && integer_onep (TREE_OPERAND (arg0, 0)))
	    return fold_build2 (LSHIFT_EXPR, type, arg1,
				TREE_OPERAND (arg0, 1));

	  strict_overflow_p = false;
	  if (TREE_CODE (arg1) == INTEGER_CST
	      && 0 != (tem = extract_muldiv (op0,
					     fold_convert (type, arg1),
					     code, NULL_TREE,
					     &strict_overflow_p)))
	    {
	      if (strict_overflow_p)
		fold_overflow_warning (("assuming signed overflow does not "
					"occur when simplifying "
					"multiplication"),
				       WARN_STRICT_OVERFLOW_MISC);
	      return fold_convert (type, tem);
	    }

	  /* Optimize z * conj(z) for integer complex numbers.  */
	  if (TREE_CODE (arg0) == CONJ_EXPR
	      && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
	    return fold_mult_zconjz (type, arg1);
	  if (TREE_CODE (arg1) == CONJ_EXPR
	      && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	    return fold_mult_zconjz (type, arg0);
	}
      else
	{
	  /* Maybe fold x * 0 to 0.  The expressions aren't the same
	     when x is NaN, since x * 0 is also NaN.  Nor are they the
	     same in modes with signed zeros, since multiplying a
	     negative value by 0 gives -0, not +0.  */
	  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
	      && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))
	      && real_zerop (arg1))
	    return omit_one_operand (type, arg1, arg0);
	  /* In IEEE floating point, x*1 is not equivalent to x for snans.  */
	  if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
	      && real_onep (arg1))
	    return non_lvalue (fold_convert (type, arg0));

	  /* Transform x * -1.0 into -x.  */
	  if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
	      && real_minus_onep (arg1))
	    return fold_convert (type, negate_expr (arg0));

	  /* Convert (C1/X)*C2 into (C1*C2)/X.  */
	  if (flag_unsafe_math_optimizations
	      && TREE_CODE (arg0) == RDIV_EXPR
	      && TREE_CODE (arg1) == REAL_CST
	      && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST)
	    {
	      tree tem = const_binop (MULT_EXPR, TREE_OPERAND (arg0, 0),
				      arg1, 0);
	      if (tem)
		return fold_build2 (RDIV_EXPR, type, tem,
				    TREE_OPERAND (arg0, 1));
	    }

          /* Strip sign operations from X in X*X, i.e. -Y*-Y -> Y*Y.  */
	  if (operand_equal_p (arg0, arg1, 0))
	    {
	      tree tem = fold_strip_sign_ops (arg0);
	      if (tem != NULL_TREE)
		{
		  tem = fold_convert (type, tem);
		  return fold_build2 (MULT_EXPR, type, tem, tem);
		}
	    }

	  /* Optimize z * conj(z) for floating point complex numbers.
	     Guarded by flag_unsafe_math_optimizations as non-finite
	     imaginary components don't produce scalar results.  */
	  if (flag_unsafe_math_optimizations
	      && TREE_CODE (arg0) == CONJ_EXPR
	      && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
	    return fold_mult_zconjz (type, arg1);
	  if (flag_unsafe_math_optimizations
	      && TREE_CODE (arg1) == CONJ_EXPR
	      && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	    return fold_mult_zconjz (type, arg0);

	  if (flag_unsafe_math_optimizations)
	    {
	      enum built_in_function fcode0 = builtin_mathfn_code (arg0);
	      enum built_in_function fcode1 = builtin_mathfn_code (arg1);

	      /* Optimizations of root(...)*root(...).  */
	      if (fcode0 == fcode1 && BUILTIN_ROOT_P (fcode0))
		{
		  tree rootfn, arg, arglist;
		  tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
		  tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));

		  /* Optimize sqrt(x)*sqrt(x) as x.  */
		  if (BUILTIN_SQRT_P (fcode0)
		      && operand_equal_p (arg00, arg10, 0)
		      && ! HONOR_SNANS (TYPE_MODE (type)))
		    return arg00;

	          /* Optimize root(x)*root(y) as root(x*y).  */
		  rootfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
		  arg = fold_build2 (MULT_EXPR, type, arg00, arg10);
		  arglist = build_tree_list (NULL_TREE, arg);
		  return build_function_call_expr (rootfn, arglist);
		}

	      /* Optimize expN(x)*expN(y) as expN(x+y).  */
	      if (fcode0 == fcode1 && BUILTIN_EXPONENT_P (fcode0))
		{
		  tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
		  tree arg = fold_build2 (PLUS_EXPR, type,
					  TREE_VALUE (TREE_OPERAND (arg0, 1)),
					  TREE_VALUE (TREE_OPERAND (arg1, 1)));
		  tree arglist = build_tree_list (NULL_TREE, arg);
		  return build_function_call_expr (expfn, arglist);
		}

	      /* Optimizations of pow(...)*pow(...).  */
	      if ((fcode0 == BUILT_IN_POW && fcode1 == BUILT_IN_POW)
		  || (fcode0 == BUILT_IN_POWF && fcode1 == BUILT_IN_POWF)
		  || (fcode0 == BUILT_IN_POWL && fcode1 == BUILT_IN_POWL))
		{
		  tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
		  tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
								     1)));
		  tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
		  tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
								     1)));

		  /* Optimize pow(x,y)*pow(z,y) as pow(x*z,y).  */
		  if (operand_equal_p (arg01, arg11, 0))
		    {
		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
		      tree arg = fold_build2 (MULT_EXPR, type, arg00, arg10);
		      tree arglist = tree_cons (NULL_TREE, arg,
						build_tree_list (NULL_TREE,
								 arg01));
		      return build_function_call_expr (powfn, arglist);
		    }

		  /* Optimize pow(x,y)*pow(x,z) as pow(x,y+z).  */
		  if (operand_equal_p (arg00, arg10, 0))
		    {
		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
		      tree arg = fold_build2 (PLUS_EXPR, type, arg01, arg11);
		      tree arglist = tree_cons (NULL_TREE, arg00,
						build_tree_list (NULL_TREE,
								 arg));
		      return build_function_call_expr (powfn, arglist);
		    }
		}

	      /* Optimize tan(x)*cos(x) as sin(x).  */
	      if (((fcode0 == BUILT_IN_TAN && fcode1 == BUILT_IN_COS)
		   || (fcode0 == BUILT_IN_TANF && fcode1 == BUILT_IN_COSF)
		   || (fcode0 == BUILT_IN_TANL && fcode1 == BUILT_IN_COSL)
		   || (fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_TAN)
		   || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_TANF)
		   || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_TANL))
		  && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
				      TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
		{
		  tree sinfn = mathfn_built_in (type, BUILT_IN_SIN);

		  if (sinfn != NULL_TREE)
		    return build_function_call_expr (sinfn,
						     TREE_OPERAND (arg0, 1));
		}

	      /* Optimize x*pow(x,c) as pow(x,c+1).  */
	      if (fcode1 == BUILT_IN_POW
		  || fcode1 == BUILT_IN_POWF
		  || fcode1 == BUILT_IN_POWL)
		{
		  tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
		  tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
								     1)));
		  if (TREE_CODE (arg11) == REAL_CST
		      && ! TREE_CONSTANT_OVERFLOW (arg11)
		      && operand_equal_p (arg0, arg10, 0))
		    {
		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
		      REAL_VALUE_TYPE c;
		      tree arg, arglist;

		      c = TREE_REAL_CST (arg11);
		      real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
		      arg = build_real (type, c);
		      arglist = build_tree_list (NULL_TREE, arg);
		      arglist = tree_cons (NULL_TREE, arg0, arglist);
		      return build_function_call_expr (powfn, arglist);
		    }
		}

	      /* Optimize pow(x,c)*x as pow(x,c+1).  */
	      if (fcode0 == BUILT_IN_POW
		  || fcode0 == BUILT_IN_POWF
		  || fcode0 == BUILT_IN_POWL)
		{
		  tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
		  tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
								     1)));
		  if (TREE_CODE (arg01) == REAL_CST
		      && ! TREE_CONSTANT_OVERFLOW (arg01)
		      && operand_equal_p (arg1, arg00, 0))
		    {
		      tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
		      REAL_VALUE_TYPE c;
		      tree arg, arglist;

		      c = TREE_REAL_CST (arg01);
		      real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
		      arg = build_real (type, c);
		      arglist = build_tree_list (NULL_TREE, arg);
		      arglist = tree_cons (NULL_TREE, arg1, arglist);
		      return build_function_call_expr (powfn, arglist);
		    }
		}

              /* LLVM LOCAL Disable pow generation (FIXME: PR1631) */
#ifndef ENABLE_LLVM
              
	      /* Optimize x*x as pow(x,2.0), which is expanded as x*x.  */
	      if (! optimize_size
		  && operand_equal_p (arg0, arg1, 0))
		{
		  tree powfn = mathfn_built_in (type, BUILT_IN_POW);

		  if (powfn)
		    {
		      tree arg = build_real (type, dconst2);
		      tree arglist = build_tree_list (NULL_TREE, arg);
		      arglist = tree_cons (NULL_TREE, arg0, arglist);
		      return build_function_call_expr (powfn, arglist);
		    }
		}
              /* LLVM LOCAL Disable pow generation (FIXME: PR1631) */
#endif /*ENABLE_LLVM*/
	    }
	}
      goto associate;

    case BIT_IOR_EXPR:
    bit_ior:
      if (integer_all_onesp (arg1))
	return omit_one_operand (type, arg1, arg0);
      if (integer_zerop (arg1))
	return non_lvalue (fold_convert (type, arg0));
      if (operand_equal_p (arg0, arg1, 0))
	return non_lvalue (fold_convert (type, arg0));

      /* ~X | X is -1.  */
      if (TREE_CODE (arg0) == BIT_NOT_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
	{
	  t1 = build_int_cst (type, -1);
	  t1 = force_fit_type (t1, 0, false, false);
	  return omit_one_operand (type, t1, arg1);
	}

      /* X | ~X is -1.  */
      if (TREE_CODE (arg1) == BIT_NOT_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	{
	  t1 = build_int_cst (type, -1);
	  t1 = force_fit_type (t1, 0, false, false);
	  return omit_one_operand (type, t1, arg0);
	}

      /* Canonicalize (X & C1) | C2.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
	{
	  unsigned HOST_WIDE_INT hi1, lo1, hi2, lo2, mlo, mhi;
	  int width = TYPE_PRECISION (type);
	  hi1 = TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1));
	  lo1 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1));
	  hi2 = TREE_INT_CST_HIGH (arg1);
	  lo2 = TREE_INT_CST_LOW (arg1);

	  /* If (C1&C2) == C1, then (X&C1)|C2 becomes (X,C2).  */
	  if ((hi1 & hi2) == hi1 && (lo1 & lo2) == lo1)
	    return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 0));

	  if (width > HOST_BITS_PER_WIDE_INT)
	    {
	      mhi = (unsigned HOST_WIDE_INT) -1 
		    >> (2 * HOST_BITS_PER_WIDE_INT - width);
	      mlo = -1;
	    }
	  else
	    {
	      mhi = 0;
	      mlo = (unsigned HOST_WIDE_INT) -1
		    >> (HOST_BITS_PER_WIDE_INT - width);
	    }

	  /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2.  */
	  if ((~(hi1 | hi2) & mhi) == 0 && (~(lo1 | lo2) & mlo) == 0)
	    return fold_build2 (BIT_IOR_EXPR, type,
				TREE_OPERAND (arg0, 0), arg1);

	  /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2.  */
	  hi1 &= mhi;
	  lo1 &= mlo;
	  if ((hi1 & ~hi2) != hi1 || (lo1 & ~lo2) != lo1)
	    return fold_build2 (BIT_IOR_EXPR, type,
				fold_build2 (BIT_AND_EXPR, type,
					     TREE_OPERAND (arg0, 0),
					     build_int_cst_wide (type,
								 lo1 & ~lo2,
								 hi1 & ~hi2)),
				arg1);
	}

      /* (X & Y) | Y is (X, Y).  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
	return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 0));
      /* (X & Y) | X is (Y, X).  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
	  && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
	return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 1));
      /* X | (X & Y) is (Y, X).  */
      if (TREE_CODE (arg1) == BIT_AND_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)
	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 1)))
	return omit_one_operand (type, arg0, TREE_OPERAND (arg1, 1));
      /* X | (Y & X) is (Y, X).  */
      if (TREE_CODE (arg1) == BIT_AND_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
	return omit_one_operand (type, arg0, TREE_OPERAND (arg1, 0));

      t1 = distribute_bit_expr (code, type, arg0, arg1);
      if (t1 != NULL_TREE)
	return t1;

      /* Convert (or (not arg0) (not arg1)) to (not (and (arg0) (arg1))).

	 This results in more efficient code for machines without a NAND
	 instruction.  Combine will canonicalize to the first form
	 which will allow use of NAND instructions provided by the
	 backend if they exist.  */
      if (TREE_CODE (arg0) == BIT_NOT_EXPR
	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
	{
	  return fold_build1 (BIT_NOT_EXPR, type,
			      build2 (BIT_AND_EXPR, type,
				      TREE_OPERAND (arg0, 0),
				      TREE_OPERAND (arg1, 0)));
	}

      /* See if this can be simplified into a rotate first.  If that
	 is unsuccessful continue in the association code.  */
      goto bit_rotate;

    case BIT_XOR_EXPR:
      if (integer_zerop (arg1))
	return non_lvalue (fold_convert (type, arg0));
      if (integer_all_onesp (arg1))
	return fold_build1 (BIT_NOT_EXPR, type, arg0);
      if (operand_equal_p (arg0, arg1, 0))
	return omit_one_operand (type, integer_zero_node, arg0);

      /* ~X ^ X is -1.  */
      if (TREE_CODE (arg0) == BIT_NOT_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
	{
	  t1 = build_int_cst (type, -1);
	  t1 = force_fit_type (t1, 0, false, false);
	  return omit_one_operand (type, t1, arg1);
	}

      /* X ^ ~X is -1.  */
      if (TREE_CODE (arg1) == BIT_NOT_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	{
	  t1 = build_int_cst (type, -1);
	  t1 = force_fit_type (t1, 0, false, false);
	  return omit_one_operand (type, t1, arg0);
	}

      /* If we are XORing two BIT_AND_EXPR's, both of which are and'ing
         with a constant, and the two constants have no bits in common,
	 we should treat this as a BIT_IOR_EXPR since this may produce more
	 simplifications.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && TREE_CODE (arg1) == BIT_AND_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
	  && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
	  && integer_zerop (const_binop (BIT_AND_EXPR,
					 TREE_OPERAND (arg0, 1),
					 TREE_OPERAND (arg1, 1), 0)))
	{
	  code = BIT_IOR_EXPR;
	  goto bit_ior;
	}

      /* (X | Y) ^ X -> Y & ~ X*/
      if (TREE_CODE (arg0) == BIT_IOR_EXPR
          && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
        {
	  tree t2 = TREE_OPERAND (arg0, 1);
	  t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1),
			    arg1);
	  t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
			    fold_convert (type, t1));
	  return t1;
	}

      /* (Y | X) ^ X -> Y & ~ X*/
      if (TREE_CODE (arg0) == BIT_IOR_EXPR
          && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
        {
	  tree t2 = TREE_OPERAND (arg0, 0);
	  t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1),
			    arg1);
	  t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
			    fold_convert (type, t1));
	  return t1;
	}

      /* X ^ (X | Y) -> Y & ~ X*/
      if (TREE_CODE (arg1) == BIT_IOR_EXPR
          && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0))
        {
	  tree t2 = TREE_OPERAND (arg1, 1);
	  t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg0),
			    arg0);
	  t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
			    fold_convert (type, t1));
	  return t1;
	}

      /* X ^ (Y | X) -> Y & ~ X*/
      if (TREE_CODE (arg1) == BIT_IOR_EXPR
          && operand_equal_p (TREE_OPERAND (arg1, 1), arg0, 0))
        {
	  tree t2 = TREE_OPERAND (arg1, 0);
	  t1 = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg0),
			    arg0);
	  t1 = fold_build2 (BIT_AND_EXPR, type, fold_convert (type, t2),
			    fold_convert (type, t1));
	  return t1;
	}
	
      /* Convert ~X ^ ~Y to X ^ Y.  */
      if (TREE_CODE (arg0) == BIT_NOT_EXPR
	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
	return fold_build2 (code, type,
			    fold_convert (type, TREE_OPERAND (arg0, 0)),
			    fold_convert (type, TREE_OPERAND (arg1, 0)));

      /* Fold (X & 1) ^ 1 as (X & 1) == 0.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && integer_onep (TREE_OPERAND (arg0, 1))
	  && integer_onep (arg1))
	return fold_build2 (EQ_EXPR, type, arg0,
			    build_int_cst (TREE_TYPE (arg0), 0));

      /* Fold (X & Y) ^ Y as ~X & Y.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
	{
	  tem = fold_convert (type, TREE_OPERAND (arg0, 0));
	  return fold_build2 (BIT_AND_EXPR, type, 
			      fold_build1 (BIT_NOT_EXPR, type, tem),
			      fold_convert (type, arg1));
	}
      /* Fold (X & Y) ^ X as ~Y & X.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
	  && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
	{
	  tem = fold_convert (type, TREE_OPERAND (arg0, 1));
	  return fold_build2 (BIT_AND_EXPR, type,
			      fold_build1 (BIT_NOT_EXPR, type, tem),
			      fold_convert (type, arg1));
	}
      /* Fold X ^ (X & Y) as X & ~Y.  */
      if (TREE_CODE (arg1) == BIT_AND_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	{
	  tem = fold_convert (type, TREE_OPERAND (arg1, 1));
	  return fold_build2 (BIT_AND_EXPR, type,
			      fold_convert (type, arg0),
			      fold_build1 (BIT_NOT_EXPR, type, tem));
	}
      /* Fold X ^ (Y & X) as ~Y & X.  */
      if (TREE_CODE (arg1) == BIT_AND_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
	{
	  tem = fold_convert (type, TREE_OPERAND (arg1, 0));
	  return fold_build2 (BIT_AND_EXPR, type,
			      fold_build1 (BIT_NOT_EXPR, type, tem),
			      fold_convert (type, arg0));
	}

      /* See if this can be simplified into a rotate first.  If that
	 is unsuccessful continue in the association code.  */
      goto bit_rotate;

    case BIT_AND_EXPR:
      if (integer_all_onesp (arg1))
	return non_lvalue (fold_convert (type, arg0));
      if (integer_zerop (arg1))
	return omit_one_operand (type, arg1, arg0);
      if (operand_equal_p (arg0, arg1, 0))
	return non_lvalue (fold_convert (type, arg0));

      /* ~X & X is always zero.  */
      if (TREE_CODE (arg0) == BIT_NOT_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
	return omit_one_operand (type, integer_zero_node, arg1);

      /* X & ~X is always zero.  */
      if (TREE_CODE (arg1) == BIT_NOT_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	return omit_one_operand (type, integer_zero_node, arg0);

      /* Canonicalize (X | C1) & C2 as (X & C2) | (C1 & C2).  */
      if (TREE_CODE (arg0) == BIT_IOR_EXPR
	  && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
	return fold_build2 (BIT_IOR_EXPR, type,
			    fold_build2 (BIT_AND_EXPR, type,
					 TREE_OPERAND (arg0, 0), arg1),
			    fold_build2 (BIT_AND_EXPR, type,
					 TREE_OPERAND (arg0, 1), arg1));

      /* (X | Y) & Y is (X, Y).  */
      if (TREE_CODE (arg0) == BIT_IOR_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
	return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 0));
      /* (X | Y) & X is (Y, X).  */
      if (TREE_CODE (arg0) == BIT_IOR_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
	  && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
	return omit_one_operand (type, arg1, TREE_OPERAND (arg0, 1));
      /* X & (X | Y) is (Y, X).  */
      if (TREE_CODE (arg1) == BIT_IOR_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0)
	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 1)))
	return omit_one_operand (type, arg0, TREE_OPERAND (arg1, 1));
      /* X & (Y | X) is (Y, X).  */
      if (TREE_CODE (arg1) == BIT_IOR_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
	return omit_one_operand (type, arg0, TREE_OPERAND (arg1, 0));

      /* Fold (X ^ 1) & 1 as (X & 1) == 0.  */
      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && integer_onep (TREE_OPERAND (arg0, 1))
	  && integer_onep (arg1))
	{
	  tem = TREE_OPERAND (arg0, 0);
	  return fold_build2 (EQ_EXPR, type,
			      fold_build2 (BIT_AND_EXPR, TREE_TYPE (tem), tem,
					   build_int_cst (TREE_TYPE (tem), 1)),
			      build_int_cst (TREE_TYPE (tem), 0));
	}
      /* Fold ~X & 1 as (X & 1) == 0.  */
      if (TREE_CODE (arg0) == BIT_NOT_EXPR
	  && integer_onep (arg1))
	{
	  tem = TREE_OPERAND (arg0, 0);
	  return fold_build2 (EQ_EXPR, type,
			      fold_build2 (BIT_AND_EXPR, TREE_TYPE (tem), tem,
					   build_int_cst (TREE_TYPE (tem), 1)),
			      build_int_cst (TREE_TYPE (tem), 0));
	}

      /* Fold (X ^ Y) & Y as ~X & Y.  */
      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
	{
	  tem = fold_convert (type, TREE_OPERAND (arg0, 0));
	  return fold_build2 (BIT_AND_EXPR, type, 
			      fold_build1 (BIT_NOT_EXPR, type, tem),
			      fold_convert (type, arg1));
	}
      /* Fold (X ^ Y) & X as ~Y & X.  */
      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
	  && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
	{
	  tem = fold_convert (type, TREE_OPERAND (arg0, 1));
	  return fold_build2 (BIT_AND_EXPR, type,
			      fold_build1 (BIT_NOT_EXPR, type, tem),
			      fold_convert (type, arg1));
	}
      /* Fold X & (X ^ Y) as X & ~Y.  */
      if (TREE_CODE (arg1) == BIT_XOR_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	{
	  tem = fold_convert (type, TREE_OPERAND (arg1, 1));
	  return fold_build2 (BIT_AND_EXPR, type,
			      fold_convert (type, arg0),
			      fold_build1 (BIT_NOT_EXPR, type, tem));
	}
      /* Fold X & (Y ^ X) as ~Y & X.  */
      if (TREE_CODE (arg1) == BIT_XOR_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
	{
	  tem = fold_convert (type, TREE_OPERAND (arg1, 0));
	  return fold_build2 (BIT_AND_EXPR, type,
			      fold_build1 (BIT_NOT_EXPR, type, tem),
			      fold_convert (type, arg0));
	}

      t1 = distribute_bit_expr (code, type, arg0, arg1);
      if (t1 != NULL_TREE)
	return t1;
      /* Simplify ((int)c & 0377) into (int)c, if c is unsigned char.  */
      if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
	  && TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
	{
	  unsigned int prec
	    = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));

	  if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
	      && (~TREE_INT_CST_LOW (arg1)
		  & (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
	    return fold_convert (type, TREE_OPERAND (arg0, 0));
	}

      /* Convert (and (not arg0) (not arg1)) to (not (or (arg0) (arg1))).

	 This results in more efficient code for machines without a NOR
	 instruction.  Combine will canonicalize to the first form
	 which will allow use of NOR instructions provided by the
	 backend if they exist.  */
      if (TREE_CODE (arg0) == BIT_NOT_EXPR
	  && TREE_CODE (arg1) == BIT_NOT_EXPR)
	{
	  return fold_build1 (BIT_NOT_EXPR, type,
			      build2 (BIT_IOR_EXPR, type,
				      TREE_OPERAND (arg0, 0),
				      TREE_OPERAND (arg1, 0)));
	}

      goto associate;

    case RDIV_EXPR:
      /* Don't touch a floating-point divide by zero unless the mode
	 of the constant can represent infinity.  */
      if (TREE_CODE (arg1) == REAL_CST
	  && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg1)))
	  && real_zerop (arg1))
	return NULL_TREE;

      /* Optimize A / A to 1.0 if we don't care about
	 NaNs or Infinities.  Skip the transformation
	 for non-real operands.  */
      if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg0))
	  && ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
	  && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg0)))
	  && operand_equal_p (arg0, arg1, 0))
	{
	  tree r = build_real (TREE_TYPE (arg0), dconst1);

	  return omit_two_operands (type, r, arg0, arg1);
	}

      /* The complex version of the above A / A optimization.  */
      if (COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0))
	  && operand_equal_p (arg0, arg1, 0))
	{
	  tree elem_type = TREE_TYPE (TREE_TYPE (arg0));
	  if (! HONOR_NANS (TYPE_MODE (elem_type))
	      && ! HONOR_INFINITIES (TYPE_MODE (elem_type)))
	    {
	      tree r = build_real (elem_type, dconst1);
	      /* omit_two_operands will call fold_convert for us.  */
	      return omit_two_operands (type, r, arg0, arg1);
	    }
	}

      /* (-A) / (-B) -> A / B  */
      if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
	return fold_build2 (RDIV_EXPR, type,
			    TREE_OPERAND (arg0, 0),
			    negate_expr (arg1));
      if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
	return fold_build2 (RDIV_EXPR, type,
			    negate_expr (arg0),
			    TREE_OPERAND (arg1, 0));

      /* In IEEE floating point, x/1 is not equivalent to x for snans.  */
      if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
	  && real_onep (arg1))
	return non_lvalue (fold_convert (type, arg0));

      /* In IEEE floating point, x/-1 is not equivalent to -x for snans.  */
      if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
	  && real_minus_onep (arg1))
	return non_lvalue (fold_convert (type, negate_expr (arg0)));

      /* If ARG1 is a constant, we can convert this to a multiply by the
	 reciprocal.  This does not have the same rounding properties,
	 so only do this if -funsafe-math-optimizations.  We can actually
	 always safely do it if ARG1 is a power of two, but it's hard to
	 tell if it is or not in a portable manner.  */
      if (TREE_CODE (arg1) == REAL_CST)
	{
	  if (flag_unsafe_math_optimizations
	      && 0 != (tem = const_binop (code, build_real (type, dconst1),
					  arg1, 0)))
	    return fold_build2 (MULT_EXPR, type, arg0, tem);
	  /* Find the reciprocal if optimizing and the result is exact.  */
	  if (optimize)
	    {
	      REAL_VALUE_TYPE r;
	      r = TREE_REAL_CST (arg1);
	      if (exact_real_inverse (TYPE_MODE(TREE_TYPE(arg0)), &r))
		{
		  tem = build_real (type, r);
		  return fold_build2 (MULT_EXPR, type,
				      fold_convert (type, arg0), tem);
		}
	    }
	}
      /* Convert A/B/C to A/(B*C).  */
      if (flag_unsafe_math_optimizations
	  && TREE_CODE (arg0) == RDIV_EXPR)
	return fold_build2 (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
			    fold_build2 (MULT_EXPR, type,
					 TREE_OPERAND (arg0, 1), arg1));

      /* Convert A/(B/C) to (A/B)*C.  */
      if (flag_unsafe_math_optimizations
	  && TREE_CODE (arg1) == RDIV_EXPR)
	return fold_build2 (MULT_EXPR, type,
			    fold_build2 (RDIV_EXPR, type, arg0,
					 TREE_OPERAND (arg1, 0)),
			    TREE_OPERAND (arg1, 1));

      /* Convert C1/(X*C2) into (C1/C2)/X.  */
      if (flag_unsafe_math_optimizations
	  && TREE_CODE (arg1) == MULT_EXPR
	  && TREE_CODE (arg0) == REAL_CST
	  && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
	{
	  tree tem = const_binop (RDIV_EXPR, arg0,
				  TREE_OPERAND (arg1, 1), 0);
	  if (tem)
	    return fold_build2 (RDIV_EXPR, type, tem,
				TREE_OPERAND (arg1, 0));
	}

      if (flag_unsafe_math_optimizations)
	{
	  enum built_in_function fcode0 = builtin_mathfn_code (arg0);
	  enum built_in_function fcode1 = builtin_mathfn_code (arg1);

	  /* Optimize sin(x)/cos(x) as tan(x).  */
	  if (((fcode0 == BUILT_IN_SIN && fcode1 == BUILT_IN_COS)
	       || (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_COSF)
	       || (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_COSL))
	      && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
				  TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
	    {
	      tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);

	      if (tanfn != NULL_TREE)
		return build_function_call_expr (tanfn,
						 TREE_OPERAND (arg0, 1));
	    }

	  /* Optimize cos(x)/sin(x) as 1.0/tan(x).  */
	  if (((fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_SIN)
	       || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_SINF)
	       || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_SINL))
	      && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
				  TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
	    {
	      tree tanfn = mathfn_built_in (type, BUILT_IN_TAN);

	      if (tanfn != NULL_TREE)
		{
		  tree tmp = TREE_OPERAND (arg0, 1);
		  tmp = build_function_call_expr (tanfn, tmp);
		  return fold_build2 (RDIV_EXPR, type,
				      build_real (type, dconst1), tmp);
		}
	    }

 	  /* Optimize sin(x)/tan(x) as cos(x) if we don't care about
	     NaNs or Infinities.  */
 	  if (((fcode0 == BUILT_IN_SIN && fcode1 == BUILT_IN_TAN)
 	       || (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_TANF)
 	       || (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_TANL)))
	    {
	      tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
	      tree arg01 = TREE_VALUE (TREE_OPERAND (arg1, 1));

	      if (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg00)))
		  && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg00)))
		  && operand_equal_p (arg00, arg01, 0))
		{
		  tree cosfn = mathfn_built_in (type, BUILT_IN_COS);

		  if (cosfn != NULL_TREE)
		    return build_function_call_expr (cosfn,
						     TREE_OPERAND (arg0, 1));
		}
	    }

 	  /* Optimize tan(x)/sin(x) as 1.0/cos(x) if we don't care about
	     NaNs or Infinities.  */
 	  if (((fcode0 == BUILT_IN_TAN && fcode1 == BUILT_IN_SIN)
 	       || (fcode0 == BUILT_IN_TANF && fcode1 == BUILT_IN_SINF)
 	       || (fcode0 == BUILT_IN_TANL && fcode1 == BUILT_IN_SINL)))
	    {
	      tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
	      tree arg01 = TREE_VALUE (TREE_OPERAND (arg1, 1));

	      if (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg00)))
		  && ! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg00)))
		  && operand_equal_p (arg00, arg01, 0))
		{
		  tree cosfn = mathfn_built_in (type, BUILT_IN_COS);

		  if (cosfn != NULL_TREE)
		    {
		      tree tmp = TREE_OPERAND (arg0, 1);
		      tmp = build_function_call_expr (cosfn, tmp);
		      return fold_build2 (RDIV_EXPR, type,
					  build_real (type, dconst1),
					  tmp);
		    }
		}
	    }

	  /* Optimize pow(x,c)/x as pow(x,c-1).  */
	  if (fcode0 == BUILT_IN_POW
	      || fcode0 == BUILT_IN_POWF
	      || fcode0 == BUILT_IN_POWL)
	    {
	      tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
	      tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
	      if (TREE_CODE (arg01) == REAL_CST
		  && ! TREE_CONSTANT_OVERFLOW (arg01)
		  && operand_equal_p (arg1, arg00, 0))
		{
		  tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
		  REAL_VALUE_TYPE c;
		  tree arg, arglist;

		  c = TREE_REAL_CST (arg01);
		  real_arithmetic (&c, MINUS_EXPR, &c, &dconst1);
		  arg = build_real (type, c);
		  arglist = build_tree_list (NULL_TREE, arg);
		  arglist = tree_cons (NULL_TREE, arg1, arglist);
		  return build_function_call_expr (powfn, arglist);
		}
	    }

	  /* Optimize x/expN(y) into x*expN(-y).  */
	  if (BUILTIN_EXPONENT_P (fcode1))
	    {
	      tree expfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
	      tree arg = negate_expr (TREE_VALUE (TREE_OPERAND (arg1, 1)));
	      tree arglist = build_tree_list (NULL_TREE,
					      fold_convert (type, arg));
	      arg1 = build_function_call_expr (expfn, arglist);
	      return fold_build2 (MULT_EXPR, type, arg0, arg1);
	    }

	  /* Optimize x/pow(y,z) into x*pow(y,-z).  */
	  if (fcode1 == BUILT_IN_POW
	      || fcode1 == BUILT_IN_POWF
	      || fcode1 == BUILT_IN_POWL)
	    {
	      tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
	      tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
	      tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1, 1)));
	      tree neg11 = fold_convert (type, negate_expr (arg11));
	      tree arglist = tree_cons(NULL_TREE, arg10,
				       build_tree_list (NULL_TREE, neg11));
	      arg1 = build_function_call_expr (powfn, arglist);
	      return fold_build2 (MULT_EXPR, type, arg0, arg1);
	    }
	}
      return NULL_TREE;

    case TRUNC_DIV_EXPR:
    case FLOOR_DIV_EXPR:
      /* Simplify A / (B << N) where A and B are positive and B is
	 a power of 2, to A >> (N + log2(B)).  */
      strict_overflow_p = false;
      if (TREE_CODE (arg1) == LSHIFT_EXPR
	  && (TYPE_UNSIGNED (type)
	      || tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p)))
	{
	  tree sval = TREE_OPERAND (arg1, 0);
	  if (integer_pow2p (sval) && tree_int_cst_sgn (sval) > 0)
	    {
	      tree sh_cnt = TREE_OPERAND (arg1, 1);
	      unsigned long pow2 = exact_log2 (TREE_INT_CST_LOW (sval));

	      if (strict_overflow_p)
		fold_overflow_warning (("assuming signed overflow does not "
					"occur when simplifying A / (B << N)"),
				       WARN_STRICT_OVERFLOW_MISC);

	      sh_cnt = fold_build2 (PLUS_EXPR, TREE_TYPE (sh_cnt),
				    sh_cnt, build_int_cst (NULL_TREE, pow2));
	      return fold_build2 (RSHIFT_EXPR, type,
				  fold_convert (type, arg0), sh_cnt);
	    }
	}
      /* Fall thru */

    case ROUND_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case EXACT_DIV_EXPR:
      if (integer_onep (arg1))
	return non_lvalue (fold_convert (type, arg0));
      if (integer_zerop (arg1))
	return NULL_TREE;
      /* X / -1 is -X.  */
      if (!TYPE_UNSIGNED (type)
	  && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
	  && TREE_INT_CST_HIGH (arg1) == -1)
	return fold_convert (type, negate_expr (arg0));

      /* Convert -A / -B to A / B when the type is signed and overflow is
	 undefined.  */
      if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
	  && TREE_CODE (arg0) == NEGATE_EXPR
	  && negate_expr_p (arg1))
	{
	  if (INTEGRAL_TYPE_P (type))
	    fold_overflow_warning (("assuming signed overflow does not occur "
				    "when distributing negation across "
				    "division"),
				   WARN_STRICT_OVERFLOW_MISC);
	  return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
			      negate_expr (arg1));
	}
      if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
	  && TREE_CODE (arg1) == NEGATE_EXPR
	  && negate_expr_p (arg0))
	{
	  if (INTEGRAL_TYPE_P (type))
	    fold_overflow_warning (("assuming signed overflow does not occur "
				    "when distributing negation across "
				    "division"),
				   WARN_STRICT_OVERFLOW_MISC);
	  return fold_build2 (code, type, negate_expr (arg0),
			      TREE_OPERAND (arg1, 0));
	}

      /* If arg0 is a multiple of arg1, then rewrite to the fastest div
	 operation, EXACT_DIV_EXPR.

	 Note that only CEIL_DIV_EXPR and FLOOR_DIV_EXPR are rewritten now.
	 At one time others generated faster code, it's not clear if they do
	 after the last round to changes to the DIV code in expmed.c.  */
      if ((code == CEIL_DIV_EXPR || code == FLOOR_DIV_EXPR)
	  && multiple_of_p (type, arg0, arg1))
	return fold_build2 (EXACT_DIV_EXPR, type, arg0, arg1);

      strict_overflow_p = false;
      if (TREE_CODE (arg1) == INTEGER_CST
	  && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
					 &strict_overflow_p)))
	{
	  if (strict_overflow_p)
	    fold_overflow_warning (("assuming signed overflow does not occur "
				    "when simplifying division"),
				   WARN_STRICT_OVERFLOW_MISC);
	  return fold_convert (type, tem);
	}

      return NULL_TREE;

    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case TRUNC_MOD_EXPR:
      /* X % 1 is always zero, but be sure to preserve any side
	 effects in X.  */
      if (integer_onep (arg1))
	return omit_one_operand (type, integer_zero_node, arg0);

      /* X % 0, return X % 0 unchanged so that we can get the
	 proper warnings and errors.  */
      if (integer_zerop (arg1))
	return NULL_TREE;

      /* 0 % X is always zero, but be sure to preserve any side
	 effects in X.  Place this after checking for X == 0.  */
      if (integer_zerop (arg0))
	return omit_one_operand (type, integer_zero_node, arg1);

      /* X % -1 is zero.  */
      if (!TYPE_UNSIGNED (type)
	  && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
	  && TREE_INT_CST_HIGH (arg1) == -1)
	return omit_one_operand (type, integer_zero_node, arg0);

      /* Optimize TRUNC_MOD_EXPR by a power of two into a BIT_AND_EXPR,
         i.e. "X % C" into "X & (C - 1)", if X and C are positive.  */
      strict_overflow_p = false;
      if ((code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR)
	  && (TYPE_UNSIGNED (type)
	      || tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p)))
	{
	  tree c = arg1;
	  /* Also optimize A % (C << N)  where C is a power of 2,
	     to A & ((C << N) - 1).  */
	  if (TREE_CODE (arg1) == LSHIFT_EXPR)
	    c = TREE_OPERAND (arg1, 0);

	  if (integer_pow2p (c) && tree_int_cst_sgn (c) > 0)
	    {
	      tree mask = fold_build2 (MINUS_EXPR, TREE_TYPE (arg1),
				       arg1, integer_one_node);
	      if (strict_overflow_p)
		fold_overflow_warning (("assuming signed overflow does not "
					"occur when simplifying "
					"X % (power of two)"),
				       WARN_STRICT_OVERFLOW_MISC);
	      return fold_build2 (BIT_AND_EXPR, type,
				  fold_convert (type, arg0),
				  fold_convert (type, mask));
	    }
	}

      /* X % -C is the same as X % C.  */
      if (code == TRUNC_MOD_EXPR
	  && !TYPE_UNSIGNED (type)
	  && TREE_CODE (arg1) == INTEGER_CST
	  && !TREE_CONSTANT_OVERFLOW (arg1)
	  && TREE_INT_CST_HIGH (arg1) < 0
	  && !TYPE_OVERFLOW_TRAPS (type)
	  /* Avoid this transformation if C is INT_MIN, i.e. C == -C.  */
	  && !sign_bit_p (arg1, arg1))
	return fold_build2 (code, type, fold_convert (type, arg0),
			    fold_convert (type, negate_expr (arg1)));

      /* X % -Y is the same as X % Y.  */
      if (code == TRUNC_MOD_EXPR
	  && !TYPE_UNSIGNED (type)
	  && TREE_CODE (arg1) == NEGATE_EXPR
	  && !TYPE_OVERFLOW_TRAPS (type))
	return fold_build2 (code, type, fold_convert (type, arg0),
			    fold_convert (type, TREE_OPERAND (arg1, 0)));

      if (TREE_CODE (arg1) == INTEGER_CST
	  && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
					 &strict_overflow_p)))
	{
	  if (strict_overflow_p)
	    fold_overflow_warning (("assuming signed overflow does not occur "
				    "when simplifying modulos"),
				   WARN_STRICT_OVERFLOW_MISC);
	  return fold_convert (type, tem);
	}

      return NULL_TREE;

    case LROTATE_EXPR:
    case RROTATE_EXPR:
      if (integer_all_onesp (arg0))
	return omit_one_operand (type, arg0, arg1);
      goto shift;

    case RSHIFT_EXPR:
      /* Optimize -1 >> x for arithmetic right shifts.  */
      if (integer_all_onesp (arg0) && !TYPE_UNSIGNED (type))
	return omit_one_operand (type, arg0, arg1);
      /* ... fall through ...  */

    case LSHIFT_EXPR:
    shift:
      if (integer_zerop (arg1))
	return non_lvalue (fold_convert (type, arg0));
      if (integer_zerop (arg0))
	return omit_one_operand (type, arg0, arg1);

      /* Since negative shift count is not well-defined,
	 don't try to compute it in the compiler.  */
      if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) < 0)
	return NULL_TREE;

      /* Turn (a OP c1) OP c2 into a OP (c1+c2).  */
      if (TREE_CODE (op0) == code && host_integerp (arg1, false)
	  && TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type)
	  && host_integerp (TREE_OPERAND (arg0, 1), false)
	  && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < TYPE_PRECISION (type))
	{
	  HOST_WIDE_INT low = (TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1))
			       + TREE_INT_CST_LOW (arg1));

	  /* Deal with a OP (c1 + c2) being undefined but (a OP c1) OP c2
	     being well defined.  */
	  if (low >= TYPE_PRECISION (type))
	    {
	      if (code == LROTATE_EXPR || code == RROTATE_EXPR)
	        low = low % TYPE_PRECISION (type);
	      else if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR)
	        return build_int_cst (type, 0);
	      else
		low = TYPE_PRECISION (type) - 1;
	    }

	  return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
			      build_int_cst (type, low));
	}

      /* Transform (x >> c) << c into x & (-1<<c), or transform (x << c) >> c
         into x & ((unsigned)-1 >> c) for unsigned types.  */
      if (((code == LSHIFT_EXPR && TREE_CODE (arg0) == RSHIFT_EXPR)
           || (TYPE_UNSIGNED (type)
	       && code == RSHIFT_EXPR && TREE_CODE (arg0) == LSHIFT_EXPR))
	  && host_integerp (arg1, false)
	  && TREE_INT_CST_LOW (arg1) < TYPE_PRECISION (type)
	  && host_integerp (TREE_OPERAND (arg0, 1), false)
	  && TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)) < TYPE_PRECISION (type))
	{
	  HOST_WIDE_INT low0 = TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1));
	  HOST_WIDE_INT low1 = TREE_INT_CST_LOW (arg1);
	  tree lshift;
	  tree arg00;

	  if (low0 == low1)
	    {
	      arg00 = fold_convert (type, TREE_OPERAND (arg0, 0));

	      lshift = build_int_cst (type, -1);
	      lshift = int_const_binop (code, lshift, arg1, 0);

	      return fold_build2 (BIT_AND_EXPR, type, arg00, lshift);
	    }
	}

      /* Rewrite an LROTATE_EXPR by a constant into an
	 RROTATE_EXPR by a new constant.  */
      if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
	{
	  tree tem = build_int_cst (NULL_TREE,
				    GET_MODE_BITSIZE (TYPE_MODE (type)));
	  tem = fold_convert (TREE_TYPE (arg1), tem);
	  tem = const_binop (MINUS_EXPR, tem, arg1, 0);
	  return fold_build2 (RROTATE_EXPR, type, arg0, tem);
	}

      /* If we have a rotate of a bit operation with the rotate count and
	 the second operand of the bit operation both constant,
	 permute the two operations.  */
      if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
	  && (TREE_CODE (arg0) == BIT_AND_EXPR
	      || TREE_CODE (arg0) == BIT_IOR_EXPR
	      || TREE_CODE (arg0) == BIT_XOR_EXPR)
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
	return fold_build2 (TREE_CODE (arg0), type,
			    fold_build2 (code, type,
					 TREE_OPERAND (arg0, 0), arg1),
			    fold_build2 (code, type,
					 TREE_OPERAND (arg0, 1), arg1));

      /* Two consecutive rotates adding up to the width of the mode can
	 be ignored.  */
      if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (arg0) == RROTATE_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
	  && TREE_INT_CST_HIGH (arg1) == 0
	  && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0
	  && ((TREE_INT_CST_LOW (arg1)
	       + TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1)))
	      == (unsigned int) GET_MODE_BITSIZE (TYPE_MODE (type))))
	return TREE_OPERAND (arg0, 0);

      return NULL_TREE;

    case MIN_EXPR:
      if (operand_equal_p (arg0, arg1, 0))
	return omit_one_operand (type, arg0, arg1);
      if (INTEGRAL_TYPE_P (type)
	  && operand_equal_p (arg1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
	return omit_one_operand (type, arg1, arg0);
      tem = fold_minmax (MIN_EXPR, type, arg0, arg1);
      if (tem)
	return tem;
      goto associate;

    case MAX_EXPR:
      if (operand_equal_p (arg0, arg1, 0))
	return omit_one_operand (type, arg0, arg1);
      if (INTEGRAL_TYPE_P (type)
	  && TYPE_MAX_VALUE (type)
	  && operand_equal_p (arg1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
	return omit_one_operand (type, arg1, arg0);
      tem = fold_minmax (MAX_EXPR, type, arg0, arg1);
      if (tem)
	return tem;
      goto associate;

    case TRUTH_ANDIF_EXPR:
      /* Note that the operands of this must be ints
	 and their values must be 0 or 1.
	 ("true" is a fixed value perhaps depending on the language.)  */
      /* If first arg is constant zero, return it.  */
      if (integer_zerop (arg0))
	return fold_convert (type, arg0);
    case TRUTH_AND_EXPR:
      /* If either arg is constant true, drop it.  */
      if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
	return non_lvalue (fold_convert (type, arg1));
      if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)
	  /* Preserve sequence points.  */
	  && (code != TRUTH_ANDIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
	return non_lvalue (fold_convert (type, arg0));
      /* If second arg is constant zero, result is zero, but first arg
	 must be evaluated.  */
      if (integer_zerop (arg1))
	return omit_one_operand (type, arg1, arg0);
      /* Likewise for first arg, but note that only the TRUTH_AND_EXPR
	 case will be handled here.  */
      if (integer_zerop (arg0))
	return omit_one_operand (type, arg0, arg1);

      /* !X && X is always false.  */
      if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
	return omit_one_operand (type, integer_zero_node, arg1);
      /* X && !X is always false.  */
      if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	return omit_one_operand (type, integer_zero_node, arg0);

      /* A < X && A + 1 > Y ==> A < X && A >= Y.  Normally A + 1 > Y
	 means A >= Y && A != MAX, but in this case we know that
	 A < X <= MAX.  */

      if (!TREE_SIDE_EFFECTS (arg0)
	  && !TREE_SIDE_EFFECTS (arg1))
	{
	  tem = fold_to_nonsharp_ineq_using_bound (arg0, arg1);
	  if (tem && !operand_equal_p (tem, arg0, 0))
	    return fold_build2 (code, type, tem, arg1);

	  tem = fold_to_nonsharp_ineq_using_bound (arg1, arg0);
	  if (tem && !operand_equal_p (tem, arg1, 0))
	    return fold_build2 (code, type, arg0, tem);
	}

    truth_andor:
      /* We only do these simplifications if we are optimizing.  */
      if (!optimize)
	return NULL_TREE;

      /* Check for things like (A || B) && (A || C).  We can convert this
	 to A || (B && C).  Note that either operator can be any of the four
	 truth and/or operations and the transformation will still be
	 valid.   Also note that we only care about order for the
	 ANDIF and ORIF operators.  If B contains side effects, this
	 might change the truth-value of A.  */
      if (TREE_CODE (arg0) == TREE_CODE (arg1)
	  && (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
	      || TREE_CODE (arg0) == TRUTH_ORIF_EXPR
	      || TREE_CODE (arg0) == TRUTH_AND_EXPR
	      || TREE_CODE (arg0) == TRUTH_OR_EXPR)
	  && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
	{
	  tree a00 = TREE_OPERAND (arg0, 0);
	  tree a01 = TREE_OPERAND (arg0, 1);
	  tree a10 = TREE_OPERAND (arg1, 0);
	  tree a11 = TREE_OPERAND (arg1, 1);
	  int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
			      || TREE_CODE (arg0) == TRUTH_AND_EXPR)
			     && (code == TRUTH_AND_EXPR
				 || code == TRUTH_OR_EXPR));

	  if (operand_equal_p (a00, a10, 0))
	    return fold_build2 (TREE_CODE (arg0), type, a00,
				fold_build2 (code, type, a01, a11));
	  else if (commutative && operand_equal_p (a00, a11, 0))
	    return fold_build2 (TREE_CODE (arg0), type, a00,
				fold_build2 (code, type, a01, a10));
	  else if (commutative && operand_equal_p (a01, a10, 0))
	    return fold_build2 (TREE_CODE (arg0), type, a01,
				fold_build2 (code, type, a00, a11));

	  /* This case if tricky because we must either have commutative
	     operators or else A10 must not have side-effects.  */

	  else if ((commutative || ! TREE_SIDE_EFFECTS (a10))
		   && operand_equal_p (a01, a11, 0))
	    return fold_build2 (TREE_CODE (arg0), type,
				fold_build2 (code, type, a00, a10),
				a01);
	}

      /* See if we can build a range comparison.  */
      if (0 != (tem = fold_range_test (code, type, op0, op1)))
	return tem;

      /* Check for the possibility of merging component references.  If our
	 lhs is another similar operation, try to merge its rhs with our
	 rhs.  Then try to merge our lhs and rhs.  */
      if (TREE_CODE (arg0) == code
	  && 0 != (tem = fold_truthop (code, type,
				       TREE_OPERAND (arg0, 1), arg1)))
	return fold_build2 (code, type, TREE_OPERAND (arg0, 0), tem);

      if ((tem = fold_truthop (code, type, arg0, arg1)) != 0)
	return tem;

      return NULL_TREE;

    case TRUTH_ORIF_EXPR:
      /* Note that the operands of this must be ints
	 and their values must be 0 or true.
	 ("true" is a fixed value perhaps depending on the language.)  */
      /* If first arg is constant true, return it.  */
      if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
	return fold_convert (type, arg0);
    case TRUTH_OR_EXPR:
      /* If either arg is constant zero, drop it.  */
      if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
	return non_lvalue (fold_convert (type, arg1));
      if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1)
	  /* Preserve sequence points.  */
	  && (code != TRUTH_ORIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
	return non_lvalue (fold_convert (type, arg0));
      /* If second arg is constant true, result is true, but we must
	 evaluate first arg.  */
      if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
	return omit_one_operand (type, arg1, arg0);
      /* Likewise for first arg, but note this only occurs here for
	 TRUTH_OR_EXPR.  */
      if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
	return omit_one_operand (type, arg0, arg1);

      /* !X || X is always true.  */
      if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
	return omit_one_operand (type, integer_one_node, arg1);
      /* X || !X is always true.  */
      if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	return omit_one_operand (type, integer_one_node, arg0);

      goto truth_andor;

    case TRUTH_XOR_EXPR:
      /* If the second arg is constant zero, drop it.  */
      if (integer_zerop (arg1))
	return non_lvalue (fold_convert (type, arg0));
      /* If the second arg is constant true, this is a logical inversion.  */
      if (integer_onep (arg1))
	{
	  /* Only call invert_truthvalue if operand is a truth value.  */
	  if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE)
	    tem = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg0), arg0);
	  else
	    tem = invert_truthvalue (arg0);
	  return non_lvalue (fold_convert (type, tem));
	}
      /* Identical arguments cancel to zero.  */
      if (operand_equal_p (arg0, arg1, 0))
	return omit_one_operand (type, integer_zero_node, arg0);

      /* !X ^ X is always true.  */
      if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
	return omit_one_operand (type, integer_one_node, arg1);

      /* X ^ !X is always true.  */
      if (TREE_CODE (arg1) == TRUTH_NOT_EXPR
	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	return omit_one_operand (type, integer_one_node, arg0);

      return NULL_TREE;

    case EQ_EXPR:
    case NE_EXPR:
      tem = fold_comparison (code, type, op0, op1);
      if (tem != NULL_TREE)
	return tem;

      /* bool_var != 0 becomes bool_var. */
      if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_zerop (arg1)
          && code == NE_EXPR)
        return non_lvalue (fold_convert (type, arg0));

      /* bool_var == 1 becomes bool_var. */
      if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_onep (arg1)
          && code == EQ_EXPR)
        return non_lvalue (fold_convert (type, arg0));

      /* bool_var != 1 becomes !bool_var. */
      if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_onep (arg1)
          && code == NE_EXPR)
        return fold_build1 (TRUTH_NOT_EXPR, type, arg0);

      /* bool_var == 0 becomes !bool_var. */
      if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_zerop (arg1)
          && code == EQ_EXPR)
        return fold_build1 (TRUTH_NOT_EXPR, type, arg0);

      /*  ~a != C becomes a != ~C where C is a constant.  Likewise for ==.  */
      if (TREE_CODE (arg0) == BIT_NOT_EXPR
	  && TREE_CODE (arg1) == INTEGER_CST)
	{
	  tree cmp_type = TREE_TYPE (TREE_OPERAND (arg0, 0));
	  return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
			      fold_build1 (BIT_NOT_EXPR, cmp_type, 
					   fold_convert (cmp_type, arg1)));
	}

      /* If this is an equality comparison of the address of a non-weak
	 object against zero, then we know the result.  */
      if (TREE_CODE (arg0) == ADDR_EXPR
	  && VAR_OR_FUNCTION_DECL_P (TREE_OPERAND (arg0, 0))
	  && ! DECL_WEAK (TREE_OPERAND (arg0, 0))
	  && integer_zerop (arg1))
	return constant_boolean_node (code != EQ_EXPR, type);

      /* If this is an equality comparison of the address of two non-weak,
	 unaliased symbols neither of which are extern (since we do not
	 have access to attributes for externs), then we know the result.  */
      if (TREE_CODE (arg0) == ADDR_EXPR
	  && VAR_OR_FUNCTION_DECL_P (TREE_OPERAND (arg0, 0))
	  && ! DECL_WEAK (TREE_OPERAND (arg0, 0))
	  && ! lookup_attribute ("alias",
				 DECL_ATTRIBUTES (TREE_OPERAND (arg0, 0)))
	  && ! DECL_EXTERNAL (TREE_OPERAND (arg0, 0))
	  && TREE_CODE (arg1) == ADDR_EXPR
	  && VAR_OR_FUNCTION_DECL_P (TREE_OPERAND (arg1, 0))
	  && ! DECL_WEAK (TREE_OPERAND (arg1, 0))
	  && ! lookup_attribute ("alias",
				 DECL_ATTRIBUTES (TREE_OPERAND (arg1, 0)))
	  && ! DECL_EXTERNAL (TREE_OPERAND (arg1, 0)))
	{
	  /* We know that we're looking at the address of two
	     non-weak, unaliased, static _DECL nodes.

	     It is both wasteful and incorrect to call operand_equal_p
	     to compare the two ADDR_EXPR nodes.  It is wasteful in that
	     all we need to do is test pointer equality for the arguments
	     to the two ADDR_EXPR nodes.  It is incorrect to use
	     operand_equal_p as that function is NOT equivalent to a
	     C equality test.  It can in fact return false for two
	     objects which would test as equal using the C equality
	     operator.  */
	  bool equal = TREE_OPERAND (arg0, 0) == TREE_OPERAND (arg1, 0);
	  return constant_boolean_node (equal
				        ? code == EQ_EXPR : code != EQ_EXPR,
				        type);
	}

      /* If this is an EQ or NE comparison of a constant with a PLUS_EXPR or
	 a MINUS_EXPR of a constant, we can convert it into a comparison with
	 a revised constant as long as no overflow occurs.  */
      if (TREE_CODE (arg1) == INTEGER_CST
	  && (TREE_CODE (arg0) == PLUS_EXPR
	      || TREE_CODE (arg0) == MINUS_EXPR)
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
	  && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR
				      ? MINUS_EXPR : PLUS_EXPR,
				      fold_convert (TREE_TYPE (arg0), arg1),
				      TREE_OPERAND (arg0, 1), 0))
	  && ! TREE_CONSTANT_OVERFLOW (tem))
	return fold_build2 (code, type, TREE_OPERAND (arg0, 0), tem);

      /* Similarly for a NEGATE_EXPR.  */
      if (TREE_CODE (arg0) == NEGATE_EXPR
	  && TREE_CODE (arg1) == INTEGER_CST
	  && 0 != (tem = negate_expr (arg1))
	  && TREE_CODE (tem) == INTEGER_CST
	  && ! TREE_CONSTANT_OVERFLOW (tem))
	return fold_build2 (code, type, TREE_OPERAND (arg0, 0), tem);

      /* If we have X - Y == 0, we can convert that to X == Y and similarly
	 for !=.  Don't do this for ordered comparisons due to overflow.  */
      if (TREE_CODE (arg0) == MINUS_EXPR
	  && integer_zerop (arg1))
	return fold_build2 (code, type,
			    TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1));

      /* Convert ABS_EXPR<x> == 0 or ABS_EXPR<x> != 0 to x == 0 or x != 0.  */
      if (TREE_CODE (arg0) == ABS_EXPR
	  && (integer_zerop (arg1) || real_zerop (arg1)))
	return fold_build2 (code, type, TREE_OPERAND (arg0, 0), arg1);

      /* If this is an EQ or NE comparison with zero and ARG0 is
	 (1 << foo) & bar, convert it to (bar >> foo) & 1.  Both require
	 two operations, but the latter can be done in one less insn
	 on machines that have only two-operand insns or on which a
	 constant cannot be the first operand.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && integer_zerop (arg1))
	{
	  tree arg00 = TREE_OPERAND (arg0, 0);
	  tree arg01 = TREE_OPERAND (arg0, 1);
	  if (TREE_CODE (arg00) == LSHIFT_EXPR
	      && integer_onep (TREE_OPERAND (arg00, 0)))
	    return
	      fold_build2 (code, type,
			   build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
				   build2 (RSHIFT_EXPR, TREE_TYPE (arg00),
					   arg01, TREE_OPERAND (arg00, 1)),
				   fold_convert (TREE_TYPE (arg0),
						 integer_one_node)),
			   arg1);
	  else if (TREE_CODE (TREE_OPERAND (arg0, 1)) == LSHIFT_EXPR
		   && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 1), 0)))
	    return
	      fold_build2 (code, type,
			   build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
				   build2 (RSHIFT_EXPR, TREE_TYPE (arg01),
					   arg00, TREE_OPERAND (arg01, 1)),
				   fold_convert (TREE_TYPE (arg0),
						 integer_one_node)),
			   arg1);
	}

      /* If this is an NE or EQ comparison of zero against the result of a
	 signed MOD operation whose second operand is a power of 2, make
	 the MOD operation unsigned since it is simpler and equivalent.  */
      if (integer_zerop (arg1)
	  && !TYPE_UNSIGNED (TREE_TYPE (arg0))
	  && (TREE_CODE (arg0) == TRUNC_MOD_EXPR
	      || TREE_CODE (arg0) == CEIL_MOD_EXPR
	      || TREE_CODE (arg0) == FLOOR_MOD_EXPR
	      || TREE_CODE (arg0) == ROUND_MOD_EXPR)
	  && integer_pow2p (TREE_OPERAND (arg0, 1)))
	{
	  tree newtype = lang_hooks.types.unsigned_type (TREE_TYPE (arg0));
	  tree newmod = fold_build2 (TREE_CODE (arg0), newtype,
				     fold_convert (newtype,
						   TREE_OPERAND (arg0, 0)),
				     fold_convert (newtype,
						   TREE_OPERAND (arg0, 1)));

	  return fold_build2 (code, type, newmod,
			      fold_convert (newtype, arg1));
	}

      /* Fold ((X >> C1) & C2) == 0 and ((X >> C1) & C2) != 0 where
	 C1 is a valid shift constant, and C2 is a power of two, i.e.
	 a single bit.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == RSHIFT_EXPR
	  && TREE_CODE (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1))
	     == INTEGER_CST
	  && integer_pow2p (TREE_OPERAND (arg0, 1))
	  && integer_zerop (arg1))
	{
	  tree itype = TREE_TYPE (arg0);
	  unsigned HOST_WIDE_INT prec = TYPE_PRECISION (itype);
	  tree arg001 = TREE_OPERAND (TREE_OPERAND (arg0, 0), 1);

	  /* Check for a valid shift count.  */
	  if (TREE_INT_CST_HIGH (arg001) == 0
	      && TREE_INT_CST_LOW (arg001) < prec)
	    {
	      tree arg01 = TREE_OPERAND (arg0, 1);
	      tree arg000 = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
	      unsigned HOST_WIDE_INT log2 = tree_log2 (arg01);
	      /* If (C2 << C1) doesn't overflow, then ((X >> C1) & C2) != 0
		 can be rewritten as (X & (C2 << C1)) != 0.  */
	      if ((log2 + TREE_INT_CST_LOW (arg001)) < prec)
		{
		  tem = fold_build2 (LSHIFT_EXPR, itype, arg01, arg001);
		  tem = fold_build2 (BIT_AND_EXPR, itype, arg000, tem);
		  return fold_build2 (code, type, tem, arg1);
		}
	      /* Otherwise, for signed (arithmetic) shifts,
		 ((X >> C1) & C2) != 0 is rewritten as X < 0, and
		 ((X >> C1) & C2) == 0 is rewritten as X >= 0.  */
	      else if (!TYPE_UNSIGNED (itype))
		return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR, type,
				    arg000, build_int_cst (itype, 0));
	      /* Otherwise, of unsigned (logical) shifts,
		 ((X >> C1) & C2) != 0 is rewritten as (X,false), and
		 ((X >> C1) & C2) == 0 is rewritten as (X,true).  */
	      else
		return omit_one_operand (type,
					 code == EQ_EXPR ? integer_one_node
							 : integer_zero_node,
					 arg000);
	    }
	}

      /* If this is an NE comparison of zero with an AND of one, remove the
	 comparison since the AND will give the correct value.  */
      if (code == NE_EXPR
	  && integer_zerop (arg1)
	  && TREE_CODE (arg0) == BIT_AND_EXPR
	  && integer_onep (TREE_OPERAND (arg0, 1)))
	return fold_convert (type, arg0);

      /* If we have (A & C) == C where C is a power of 2, convert this into
	 (A & C) != 0.  Similarly for NE_EXPR.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && integer_pow2p (TREE_OPERAND (arg0, 1))
	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
	return fold_build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
			    arg0, fold_convert (TREE_TYPE (arg0),
						integer_zero_node));

      /* If we have (A & C) != 0 or (A & C) == 0 and C is the sign
	 bit, then fold the expression into A < 0 or A >= 0.  */
      tem = fold_single_bit_test_into_sign_test (code, arg0, arg1, type);
      if (tem)
	return tem;

      /* If we have (A & C) == D where D & ~C != 0, convert this into 0.
	 Similarly for NE_EXPR.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
	{
	  tree notc = fold_build1 (BIT_NOT_EXPR,
				   TREE_TYPE (TREE_OPERAND (arg0, 1)),
				   TREE_OPERAND (arg0, 1));
	  tree dandnotc = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
				       arg1, notc);
	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
	  if (integer_nonzerop (dandnotc))
	    return omit_one_operand (type, rslt, arg0);
	}

      /* If we have (A | C) == D where C & ~D != 0, convert this into 0.
	 Similarly for NE_EXPR.  */
      if (TREE_CODE (arg0) == BIT_IOR_EXPR
	  && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
	{
	  tree notd = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1);
	  tree candnotd = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
				       TREE_OPERAND (arg0, 1), notd);
	  tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
	  if (integer_nonzerop (candnotd))
	    return omit_one_operand (type, rslt, arg0);
	}

      /* If this is a comparison of a field, we may be able to simplify it.  */
      if (((TREE_CODE (arg0) == COMPONENT_REF
        /* LLVM LOCAL begin */
#ifdef ENABLE_LLVM
            && 0/* disable creation of BIT_FIELD_REF, which pessimizes code. */
#endif
        /* LLVM LOCAL end */
	    && lang_hooks.can_use_bit_fields_p ())
	   || TREE_CODE (arg0) == BIT_FIELD_REF)
	  /* Handle the constant case even without -O
	     to make sure the warnings are given.  */
	  && (optimize || TREE_CODE (arg1) == INTEGER_CST))
	{
	  t1 = optimize_bit_field_compare (code, type, arg0, arg1);
	  if (t1)
	    return t1;
	}

      /* Optimize comparisons of strlen vs zero to a compare of the
	 first character of the string vs zero.  To wit,
		strlen(ptr) == 0   =>  *ptr == 0
		strlen(ptr) != 0   =>  *ptr != 0
	 Other cases should reduce to one of these two (or a constant)
	 due to the return value of strlen being unsigned.  */
      if (TREE_CODE (arg0) == CALL_EXPR
	  && integer_zerop (arg1))
	{
	  tree fndecl = get_callee_fndecl (arg0);
	  tree arglist;

	  if (fndecl
	      && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
	      && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
	      && (arglist = TREE_OPERAND (arg0, 1))
	      && TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE
	      && ! TREE_CHAIN (arglist))
	    {
	      tree iref = build_fold_indirect_ref (TREE_VALUE (arglist));
	      return fold_build2 (code, type, iref,
				  build_int_cst (TREE_TYPE (iref), 0));
	    }
	}

      /* Fold (X >> C) != 0 into X < 0 if C is one less than the width
	 of X.  Similarly fold (X >> C) == 0 into X >= 0.  */
      if (TREE_CODE (arg0) == RSHIFT_EXPR
	  && integer_zerop (arg1)
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
	{
	  tree arg00 = TREE_OPERAND (arg0, 0);
	  tree arg01 = TREE_OPERAND (arg0, 1);
	  tree itype = TREE_TYPE (arg00);
	  if (TREE_INT_CST_HIGH (arg01) == 0
	      && TREE_INT_CST_LOW (arg01)
		 == (unsigned HOST_WIDE_INT) (TYPE_PRECISION (itype) - 1))
	    {
	      if (TYPE_UNSIGNED (itype))
		{
		  itype = lang_hooks.types.signed_type (itype);
		  arg00 = fold_convert (itype, arg00);
		}
	      return fold_build2 (code == EQ_EXPR ? GE_EXPR : LT_EXPR,
				  type, arg00, build_int_cst (itype, 0));
	    }
	}

      /* (X ^ Y) == 0 becomes X == Y, and (X ^ Y) != 0 becomes X != Y.  */
      if (integer_zerop (arg1)
	  && TREE_CODE (arg0) == BIT_XOR_EXPR)
	return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
			    TREE_OPERAND (arg0, 1));

      /* (X ^ Y) == Y becomes X == 0.  We know that Y has no side-effects.  */
      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
	return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
			    build_int_cst (TREE_TYPE (arg1), 0));
      /* Likewise (X ^ Y) == X becomes Y == 0.  X has no side-effects.  */
      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
	  && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
	return fold_build2 (code, type, TREE_OPERAND (arg0, 1),
			    build_int_cst (TREE_TYPE (arg1), 0));

      /* (X ^ C1) op C2 can be rewritten as X op (C1 ^ C2).  */
      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
	return fold_build2 (code, type, TREE_OPERAND (arg0, 0),
			    fold_build2 (BIT_XOR_EXPR, TREE_TYPE (arg1),
					 TREE_OPERAND (arg0, 1), arg1));

      /* Fold (~X & C) == 0 into (X & C) != 0 and (~X & C) != 0 into
	 (X & C) == 0 when C is a single bit.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_NOT_EXPR
	  && integer_zerop (arg1)
	  && integer_pow2p (TREE_OPERAND (arg0, 1)))
	{
	  tem = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg0),
			     TREE_OPERAND (TREE_OPERAND (arg0, 0), 0),
			     TREE_OPERAND (arg0, 1));
	  return fold_build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR,
			      type, tem, arg1);
	}

      /* Fold ((X & C) ^ C) eq/ne 0 into (X & C) ne/eq 0, when the
	 constant C is a power of two, i.e. a single bit.  */
      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
	  && integer_zerop (arg1)
	  && integer_pow2p (TREE_OPERAND (arg0, 1))
	  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
			      TREE_OPERAND (arg0, 1), OEP_ONLY_CONST))
	{
	  tree arg00 = TREE_OPERAND (arg0, 0);
	  return fold_build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
			      arg00, build_int_cst (TREE_TYPE (arg00), 0));
	}

      /* Likewise, fold ((X ^ C) & C) eq/ne 0 into (X & C) ne/eq 0,
	 when is C is a power of two, i.e. a single bit.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_XOR_EXPR
	  && integer_zerop (arg1)
	  && integer_pow2p (TREE_OPERAND (arg0, 1))
	  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
			      TREE_OPERAND (arg0, 1), OEP_ONLY_CONST))
	{
	  tree arg000 = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
	  tem = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg000),
			     arg000, TREE_OPERAND (arg0, 1));
	  return fold_build2 (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
			      tem, build_int_cst (TREE_TYPE (tem), 0));
	}

      if (integer_zerop (arg1)
	  && tree_expr_nonzero_p (arg0))
        {
	  tree res = constant_boolean_node (code==NE_EXPR, type);
	  return omit_one_operand (type, res, arg0);
	}
      return NULL_TREE;

    case LT_EXPR:
    case GT_EXPR:
    case LE_EXPR:
    case GE_EXPR:
      tem = fold_comparison (code, type, op0, op1);
      if (tem != NULL_TREE)
	return tem;

      /* Transform comparisons of the form X +- C CMP X.  */
      if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
	  && ((TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
	       && !HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))))
	      || (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
		  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))))
	{
	  tree arg01 = TREE_OPERAND (arg0, 1);
	  enum tree_code code0 = TREE_CODE (arg0);
	  int is_positive;

	  if (TREE_CODE (arg01) == REAL_CST)
	    is_positive = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg01)) ? -1 : 1;
	  else
	    is_positive = tree_int_cst_sgn (arg01);

	  /* (X - c) > X becomes false.  */
	  if (code == GT_EXPR
	      && ((code0 == MINUS_EXPR && is_positive >= 0)
		  || (code0 == PLUS_EXPR && is_positive <= 0)))
	    {
	      if (TREE_CODE (arg01) == INTEGER_CST
		  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
		fold_overflow_warning (("assuming signed overflow does not "
					"occur when assuming that (X - c) > X "
					"is always false"),
				       WARN_STRICT_OVERFLOW_ALL);
	      return constant_boolean_node (0, type);
	    }

	  /* Likewise (X + c) < X becomes false.  */
	  if (code == LT_EXPR
	      && ((code0 == PLUS_EXPR && is_positive >= 0)
		  || (code0 == MINUS_EXPR && is_positive <= 0)))
	    {
	      if (TREE_CODE (arg01) == INTEGER_CST
		  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
		fold_overflow_warning (("assuming signed overflow does not "
					"occur when assuming that "
					"(X + c) < X is always false"),
				       WARN_STRICT_OVERFLOW_ALL);
	      return constant_boolean_node (0, type);
	    }

	  /* Convert (X - c) <= X to true.  */
	  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))
	      && code == LE_EXPR
	      && ((code0 == MINUS_EXPR && is_positive >= 0)
		  || (code0 == PLUS_EXPR && is_positive <= 0)))
	    {
	      if (TREE_CODE (arg01) == INTEGER_CST
		  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
		fold_overflow_warning (("assuming signed overflow does not "
					"occur when assuming that "
					"(X - c) <= X is always true"),
				       WARN_STRICT_OVERFLOW_ALL);
	      return constant_boolean_node (1, type);
	    }

	  /* Convert (X + c) >= X to true.  */
	  if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))
	      && code == GE_EXPR
	      && ((code0 == PLUS_EXPR && is_positive >= 0)
		  || (code0 == MINUS_EXPR && is_positive <= 0)))
	    {
	      if (TREE_CODE (arg01) == INTEGER_CST
		  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
		fold_overflow_warning (("assuming signed overflow does not "
					"occur when assuming that "
					"(X + c) >= X is always true"),
				       WARN_STRICT_OVERFLOW_ALL);
	      return constant_boolean_node (1, type);
	    }

	  if (TREE_CODE (arg01) == INTEGER_CST)
	    {
	      /* Convert X + c > X and X - c < X to true for integers.  */
	      if (code == GT_EXPR
	          && ((code0 == PLUS_EXPR && is_positive > 0)
		      || (code0 == MINUS_EXPR && is_positive < 0)))
		{
		  if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
		    fold_overflow_warning (("assuming signed overflow does "
					    "not occur when assuming that "
					    "(X + c) > X is always true"),
					   WARN_STRICT_OVERFLOW_ALL);
		  return constant_boolean_node (1, type);
		}

	      if (code == LT_EXPR
	          && ((code0 == MINUS_EXPR && is_positive > 0)
		      || (code0 == PLUS_EXPR && is_positive < 0)))
		{
		  if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
		    fold_overflow_warning (("assuming signed overflow does "
					    "not occur when assuming that "
					    "(X - c) < X is always true"),
					   WARN_STRICT_OVERFLOW_ALL);
		  return constant_boolean_node (1, type);
		}

	      /* Convert X + c <= X and X - c >= X to false for integers.  */
	      if (code == LE_EXPR
	          && ((code0 == PLUS_EXPR && is_positive > 0)
		      || (code0 == MINUS_EXPR && is_positive < 0)))
		{
		  if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
		    fold_overflow_warning (("assuming signed overflow does "
					    "not occur when assuming that "
					    "(X + c) <= X is always false"),
					   WARN_STRICT_OVERFLOW_ALL);
		  return constant_boolean_node (0, type);
		}

	      if (code == GE_EXPR
	          && ((code0 == MINUS_EXPR && is_positive > 0)
		      || (code0 == PLUS_EXPR && is_positive < 0)))
		{
		  if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1)))
		    fold_overflow_warning (("assuming signed overflow does "
					    "not occur when assuming that "
					    "(X - c) >= X is always true"),
					   WARN_STRICT_OVERFLOW_ALL);
		  return constant_boolean_node (0, type);
		}
	    }
	}

      /* Change X >= C to X > (C - 1) and X < C to X <= (C - 1) if C > 0.
	 This transformation affects the cases which are handled in later
	 optimizations involving comparisons with non-negative constants.  */
      if (TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (arg0) != INTEGER_CST
	  && tree_int_cst_sgn (arg1) > 0)
	{
	  if (code == GE_EXPR)
	    {
	      arg1 = const_binop (MINUS_EXPR, arg1,
			          build_int_cst (TREE_TYPE (arg1), 1), 0);
	      return fold_build2 (GT_EXPR, type, arg0,
				  fold_convert (TREE_TYPE (arg0), arg1));
	    }
	  if (code == LT_EXPR)
	    {
	      arg1 = const_binop (MINUS_EXPR, arg1,
			          build_int_cst (TREE_TYPE (arg1), 1), 0);
	      return fold_build2 (LE_EXPR, type, arg0,
				  fold_convert (TREE_TYPE (arg0), arg1));
	    }
	}

      /* Comparisons with the highest or lowest possible integer of
	 the specified size will have known values.  */
      {
	int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));

	if (TREE_CODE (arg1) == INTEGER_CST
	    && ! TREE_CONSTANT_OVERFLOW (arg1)
	    && width <= 2 * HOST_BITS_PER_WIDE_INT
	    && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
		|| POINTER_TYPE_P (TREE_TYPE (arg1))))
	  {
	    HOST_WIDE_INT signed_max_hi;
	    unsigned HOST_WIDE_INT signed_max_lo;
	    unsigned HOST_WIDE_INT max_hi, max_lo, min_hi, min_lo;

	    if (width <= HOST_BITS_PER_WIDE_INT)
	      {
		signed_max_lo = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
				- 1;
		signed_max_hi = 0;
		max_hi = 0;

		if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
		  {
		    max_lo = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
		    min_lo = 0;
		    min_hi = 0;
		  }
		else
		  {
		    max_lo = signed_max_lo;
		    min_lo = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
		    min_hi = -1;
		  }
	      }
	    else
	      {
		width -= HOST_BITS_PER_WIDE_INT;
		signed_max_lo = -1;
		signed_max_hi = ((unsigned HOST_WIDE_INT) 1 << (width - 1))
				- 1;
		max_lo = -1;
		min_lo = 0;

		if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
		  {
		    max_hi = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
		    min_hi = 0;
		  }
		else
		  {
		    max_hi = signed_max_hi;
		    min_hi = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
		  }
	      }

	    if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1) == max_hi
		&& TREE_INT_CST_LOW (arg1) == max_lo)
	      switch (code)
		{
		case GT_EXPR:
		  return omit_one_operand (type, integer_zero_node, arg0);

		case GE_EXPR:
		  return fold_build2 (EQ_EXPR, type, op0, op1);

		case LE_EXPR:
		  return omit_one_operand (type, integer_one_node, arg0);

		case LT_EXPR:
		  return fold_build2 (NE_EXPR, type, op0, op1);

		/* The GE_EXPR and LT_EXPR cases above are not normally
		   reached because of previous transformations.  */

		default:
		  break;
		}
	    else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
		     == max_hi
		     && TREE_INT_CST_LOW (arg1) == max_lo - 1)
	      switch (code)
		{
		case GT_EXPR:
		  arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
		  return fold_build2 (EQ_EXPR, type,
				      fold_convert (TREE_TYPE (arg1), arg0),
				      arg1);
		case LE_EXPR:
		  arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
		  return fold_build2 (NE_EXPR, type,
				      fold_convert (TREE_TYPE (arg1), arg0),
				      arg1);
		default:
		  break;
		}
	    else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
		     == min_hi
		     && TREE_INT_CST_LOW (arg1) == min_lo)
	      switch (code)
		{
		case LT_EXPR:
		  return omit_one_operand (type, integer_zero_node, arg0);

		case LE_EXPR:
		  return fold_build2 (EQ_EXPR, type, op0, op1);

		case GE_EXPR:
		  return omit_one_operand (type, integer_one_node, arg0);

		case GT_EXPR:
		  return fold_build2 (NE_EXPR, type, op0, op1);

		default:
		  break;
		}
	    else if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (arg1)
		     == min_hi
		     && TREE_INT_CST_LOW (arg1) == min_lo + 1)
	      switch (code)
		{
		case GE_EXPR:
		  arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
		  return fold_build2 (NE_EXPR, type,
				      fold_convert (TREE_TYPE (arg1), arg0),
				      arg1);
		case LT_EXPR:
		  arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
		  return fold_build2 (EQ_EXPR, type,
				      fold_convert (TREE_TYPE (arg1), arg0),
				      arg1);
		default:
		  break;
		}

	    else if (!in_gimple_form
		     && TREE_INT_CST_HIGH (arg1) == signed_max_hi
		     && TREE_INT_CST_LOW (arg1) == signed_max_lo
		     && TYPE_UNSIGNED (TREE_TYPE (arg1))
		     /* signed_type does not work on pointer types.  */
		     && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
	      {
		/* The following case also applies to X < signed_max+1
		   and X >= signed_max+1 because previous transformations.  */
		if (code == LE_EXPR || code == GT_EXPR)
		  {
		    tree st;
		    st = lang_hooks.types.signed_type (TREE_TYPE (arg1));
		    return fold_build2 (code == LE_EXPR ? GE_EXPR : LT_EXPR,
					type, fold_convert (st, arg0),
					build_int_cst (st, 0));
		  }
	      }
	  }
      }

      /* If we are comparing an ABS_EXPR with a constant, we can
	 convert all the cases into explicit comparisons, but they may
	 well not be faster than doing the ABS and one comparison.
	 But ABS (X) <= C is a range comparison, which becomes a subtraction
	 and a comparison, and is probably faster.  */
      if (code == LE_EXPR
	  && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (arg0) == ABS_EXPR
	  && ! TREE_SIDE_EFFECTS (arg0)
	  && (0 != (tem = negate_expr (arg1)))
	  && TREE_CODE (tem) == INTEGER_CST
	  && ! TREE_CONSTANT_OVERFLOW (tem))
	return fold_build2 (TRUTH_ANDIF_EXPR, type,
			    build2 (GE_EXPR, type,
				    TREE_OPERAND (arg0, 0), tem),
			    build2 (LE_EXPR, type,
				    TREE_OPERAND (arg0, 0), arg1));

      /* Convert ABS_EXPR<x> >= 0 to true.  */
      strict_overflow_p = false;
      if (code == GE_EXPR
	  && (integer_zerop (arg1)
	      || (! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0)))
		  && real_zerop (arg1)))
	  && tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p))
	{
	  if (strict_overflow_p)
	    fold_overflow_warning (("assuming signed overflow does not occur "
				    "when simplifying comparison of "
				    "absolute value and zero"),
				   WARN_STRICT_OVERFLOW_CONDITIONAL);
	  return omit_one_operand (type, integer_one_node, arg0);
	}

      /* Convert ABS_EXPR<x> < 0 to false.  */
      strict_overflow_p = false;
      if (code == LT_EXPR
	  && (integer_zerop (arg1) || real_zerop (arg1))
	  && tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p))
	{
	  if (strict_overflow_p)
	    fold_overflow_warning (("assuming signed overflow does not occur "
				    "when simplifying comparison of "
				    "absolute value and zero"),
				   WARN_STRICT_OVERFLOW_CONDITIONAL);
	  return omit_one_operand (type, integer_zero_node, arg0);
	}

      /* If X is unsigned, convert X < (1 << Y) into X >> Y == 0
	 and similarly for >= into !=.  */
      if ((code == LT_EXPR || code == GE_EXPR)
	  && TYPE_UNSIGNED (TREE_TYPE (arg0))
	  && TREE_CODE (arg1) == LSHIFT_EXPR
	  && integer_onep (TREE_OPERAND (arg1, 0)))
	return build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
		       build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
			       TREE_OPERAND (arg1, 1)),
		       build_int_cst (TREE_TYPE (arg0), 0));

      if ((code == LT_EXPR || code == GE_EXPR)
	  && TYPE_UNSIGNED (TREE_TYPE (arg0))
	  && (TREE_CODE (arg1) == NOP_EXPR
	      || TREE_CODE (arg1) == CONVERT_EXPR)
	  && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
	  && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
	return
	  build2 (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
		  fold_convert (TREE_TYPE (arg0),
				build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
					TREE_OPERAND (TREE_OPERAND (arg1, 0),
						      1))),
		  build_int_cst (TREE_TYPE (arg0), 0));

      return NULL_TREE;

    case UNORDERED_EXPR:
    case ORDERED_EXPR:
    case UNLT_EXPR:
    case UNLE_EXPR:
    case UNGT_EXPR:
    case UNGE_EXPR:
    case UNEQ_EXPR:
    case LTGT_EXPR:
      if (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
	{
	  t1 = fold_relational_const (code, type, arg0, arg1);
	  if (t1 != NULL_TREE)
	    return t1;
	}

      /* If the first operand is NaN, the result is constant.  */
      if (TREE_CODE (arg0) == REAL_CST
	  && REAL_VALUE_ISNAN (TREE_REAL_CST (arg0))
	  && (code != LTGT_EXPR || ! flag_trapping_math))
	{
	  t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
	       ? integer_zero_node
	       : integer_one_node;
	  return omit_one_operand (type, t1, arg1);
	}

      /* If the second operand is NaN, the result is constant.  */
      if (TREE_CODE (arg1) == REAL_CST
	  && REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
	  && (code != LTGT_EXPR || ! flag_trapping_math))
	{
	  t1 = (code == ORDERED_EXPR || code == LTGT_EXPR)
	       ? integer_zero_node
	       : integer_one_node;
	  return omit_one_operand (type, t1, arg0);
	}

      /* Simplify unordered comparison of something with itself.  */
      if ((code == UNLE_EXPR || code == UNGE_EXPR || code == UNEQ_EXPR)
	  && operand_equal_p (arg0, arg1, 0))
	return constant_boolean_node (1, type);

      if (code == LTGT_EXPR
	  && !flag_trapping_math
	  && operand_equal_p (arg0, arg1, 0))
	return constant_boolean_node (0, type);

      /* Fold (double)float1 CMP (double)float2 into float1 CMP float2.  */
      {
	tree targ0 = strip_float_extensions (arg0);
	tree targ1 = strip_float_extensions (arg1);
	tree newtype = TREE_TYPE (targ0);

	if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
	  newtype = TREE_TYPE (targ1);

	if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
	  return fold_build2 (code, type, fold_convert (newtype, targ0),
			      fold_convert (newtype, targ1));
      }

      return NULL_TREE;

    case COMPOUND_EXPR:
      /* When pedantic, a compound expression can be neither an lvalue
	 nor an integer constant expression.  */
      if (TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1))
	return NULL_TREE;
      /* Don't let (0, 0) be null pointer constant.  */
      tem = integer_zerop (arg1) ? build1 (NOP_EXPR, type, arg1)
				 : fold_convert (type, arg1);
      return pedantic_non_lvalue (tem);

    case COMPLEX_EXPR:
      if ((TREE_CODE (arg0) == REAL_CST
	   && TREE_CODE (arg1) == REAL_CST)
	  || (TREE_CODE (arg0) == INTEGER_CST
	      && TREE_CODE (arg1) == INTEGER_CST))
	return build_complex (type, arg0, arg1);
      return NULL_TREE;

    case ASSERT_EXPR:
      /* An ASSERT_EXPR should never be passed to fold_binary.  */
      gcc_unreachable ();

    default:
      return NULL_TREE;
    } /* switch (code) */
}

/* Callback for walk_tree, looking for LABEL_EXPR.
   Returns tree TP if it is LABEL_EXPR. Otherwise it returns NULL_TREE.
   Do not check the sub-tree of GOTO_EXPR.  */

static tree
contains_label_1 (tree *tp,
                  int *walk_subtrees,
                  void *data ATTRIBUTE_UNUSED)
{
  switch (TREE_CODE (*tp))
    {
    case LABEL_EXPR:
      return *tp;
    case GOTO_EXPR:
      *walk_subtrees = 0;
    /* no break */
    default:
      return NULL_TREE;
    }
}

/* Checks whether the sub-tree ST contains a label LABEL_EXPR which is
   accessible from outside the sub-tree. Returns NULL_TREE if no
   addressable label is found.  */

static bool
contains_label_p (tree st)
{
  return (walk_tree (&st, contains_label_1 , NULL, NULL) != NULL_TREE);
}

/* Fold a ternary expression of code CODE and type TYPE with operands
   OP0, OP1, and OP2.  Return the folded expression if folding is
   successful.  Otherwise, return NULL_TREE.  */

tree
fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2)
{
  tree tem;
  tree arg0 = NULL_TREE, arg1 = NULL_TREE;
  enum tree_code_class kind = TREE_CODE_CLASS (code);

  gcc_assert (IS_EXPR_CODE_CLASS (kind)
	      && TREE_CODE_LENGTH (code) == 3);

  /* Strip any conversions that don't change the mode.  This is safe
     for every expression, except for a comparison expression because
     its signedness is derived from its operands.  So, in the latter
     case, only strip conversions that don't change the signedness.

     Note that this is done as an internal manipulation within the
     constant folder, in order to find the simplest representation of
     the arguments so that their form can be studied.  In any cases,
     the appropriate type conversions should be put back in the tree
     that will get out of the constant folder.  */
  if (op0)
    {
      arg0 = op0;
      STRIP_NOPS (arg0);
    }

  if (op1)
    {
      arg1 = op1;
      STRIP_NOPS (arg1);
    }

  switch (code)
    {
    case COMPONENT_REF:
      if (TREE_CODE (arg0) == CONSTRUCTOR
	  && ! type_contains_placeholder_p (TREE_TYPE (arg0)))
	{
	  unsigned HOST_WIDE_INT idx;
	  tree field, value;
	  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (arg0), idx, field, value)
	    if (field == arg1)
	      return value;
	}
      return NULL_TREE;

    case COND_EXPR:
      /* Pedantic ANSI C says that a conditional expression is never an lvalue,
	 so all simple results must be passed through pedantic_non_lvalue.  */
      if (TREE_CODE (arg0) == INTEGER_CST)
	{
	  tree unused_op = integer_zerop (arg0) ? op1 : op2;
	  tem = integer_zerop (arg0) ? op2 : op1;
	  /* Only optimize constant conditions when the selected branch
	     has the same type as the COND_EXPR.  This avoids optimizing
             away "c ? x : throw", where the throw has a void type.
             Avoid throwing away that operand which contains label.  */
          if ((!TREE_SIDE_EFFECTS (unused_op)
               || !contains_label_p (unused_op))
              && (! VOID_TYPE_P (TREE_TYPE (tem))
                  || VOID_TYPE_P (type)))
	    return pedantic_non_lvalue (tem);
	  return NULL_TREE;
	}
      if (operand_equal_p (arg1, op2, 0))
	return pedantic_omit_one_operand (type, arg1, arg0);

      /* If we have A op B ? A : C, we may be able to convert this to a
	 simpler expression, depending on the operation and the values
	 of B and C.  Signed zeros prevent all of these transformations,
	 for reasons given above each one.

         Also try swapping the arguments and inverting the conditional.  */
      if (COMPARISON_CLASS_P (arg0)
	  && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
					     arg1, TREE_OPERAND (arg0, 1))
	  && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
	{
	  tem = fold_cond_expr_with_comparison (type, arg0, op1, op2);
	  if (tem)
	    return tem;
	}

      if (COMPARISON_CLASS_P (arg0)
	  && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
					     op2,
					     TREE_OPERAND (arg0, 1))
	  && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2))))
	{
	  tem = fold_truth_not_expr (arg0);
	  if (tem && COMPARISON_CLASS_P (tem))
	    {
	      tem = fold_cond_expr_with_comparison (type, tem, op2, op1);
	      if (tem)
		return tem;
	    }
	}

      /* If the second operand is simpler than the third, swap them
	 since that produces better jump optimization results.  */
      if (truth_value_p (TREE_CODE (arg0))
	  && tree_swap_operands_p (op1, op2, false))
	{
	  /* See if this can be inverted.  If it can't, possibly because
	     it was a floating-point inequality comparison, don't do
	     anything.  */
	  tem = fold_truth_not_expr (arg0);
	  if (tem)
	    return fold_build3 (code, type, tem, op2, op1);
	}

      /* Convert A ? 1 : 0 to simply A.  */
      if (integer_onep (op1)
	  && integer_zerop (op2)
	  /* If we try to convert OP0 to our type, the
	     call to fold will try to move the conversion inside
	     a COND, which will recurse.  In that case, the COND_EXPR
	     is probably the best choice, so leave it alone.  */
	  && type == TREE_TYPE (arg0))
	return pedantic_non_lvalue (arg0);

      /* Convert A ? 0 : 1 to !A.  This prefers the use of NOT_EXPR
	 over COND_EXPR in cases such as floating point comparisons.  */
      if (integer_zerop (op1)
	  && integer_onep (op2)
	  && truth_value_p (TREE_CODE (arg0)))
	return pedantic_non_lvalue (fold_convert (type,
						  invert_truthvalue (arg0)));

      /* A < 0 ? <sign bit of A> : 0 is simply (A & <sign bit of A>).  */
      if (TREE_CODE (arg0) == LT_EXPR
	  && integer_zerop (TREE_OPERAND (arg0, 1))
	  && integer_zerop (op2)
	  && (tem = sign_bit_p (TREE_OPERAND (arg0, 0), arg1)))
	{
	  /* sign_bit_p only checks ARG1 bits within A's precision.
	     If <sign bit of A> has wider type than A, bits outside
	     of A's precision in <sign bit of A> need to be checked.
	     If they are all 0, this optimization needs to be done
	     in unsigned A's type, if they are all 1 in signed A's type,
	     otherwise this can't be done.  */
	  if (TYPE_PRECISION (TREE_TYPE (tem))
	      < TYPE_PRECISION (TREE_TYPE (arg1))
	      && TYPE_PRECISION (TREE_TYPE (tem))
		 < TYPE_PRECISION (type))
	    {
	      unsigned HOST_WIDE_INT mask_lo;
	      HOST_WIDE_INT mask_hi;
	      int inner_width, outer_width;
	      tree tem_type;

	      inner_width = TYPE_PRECISION (TREE_TYPE (tem));
	      outer_width = TYPE_PRECISION (TREE_TYPE (arg1));
	      if (outer_width > TYPE_PRECISION (type))
		outer_width = TYPE_PRECISION (type);

	      if (outer_width > HOST_BITS_PER_WIDE_INT)
		{
		  mask_hi = ((unsigned HOST_WIDE_INT) -1
			     >> (2 * HOST_BITS_PER_WIDE_INT - outer_width));
		  mask_lo = -1;
		}
	      else
		{
		  mask_hi = 0;
		  mask_lo = ((unsigned HOST_WIDE_INT) -1
			     >> (HOST_BITS_PER_WIDE_INT - outer_width));
		}
	      if (inner_width > HOST_BITS_PER_WIDE_INT)
		{
		  mask_hi &= ~((unsigned HOST_WIDE_INT) -1
			       >> (HOST_BITS_PER_WIDE_INT - inner_width));
		  mask_lo = 0;
		}
	      else
		mask_lo &= ~((unsigned HOST_WIDE_INT) -1
			     >> (HOST_BITS_PER_WIDE_INT - inner_width));

	      if ((TREE_INT_CST_HIGH (arg1) & mask_hi) == mask_hi
		  && (TREE_INT_CST_LOW (arg1) & mask_lo) == mask_lo)
		{
		  tem_type = lang_hooks.types.signed_type (TREE_TYPE (tem));
		  tem = fold_convert (tem_type, tem);
		}
	      else if ((TREE_INT_CST_HIGH (arg1) & mask_hi) == 0
		       && (TREE_INT_CST_LOW (arg1) & mask_lo) == 0)
		{
		  tem_type = lang_hooks.types.unsigned_type (TREE_TYPE (tem));
		  tem = fold_convert (tem_type, tem);
		}
	      else
		tem = NULL;
	    }

	  if (tem)
	    return fold_convert (type,
				 fold_build2 (BIT_AND_EXPR,
					      TREE_TYPE (tem), tem,
					      fold_convert (TREE_TYPE (tem),
							    arg1)));
	}

      /* (A >> N) & 1 ? (1 << N) : 0 is simply A & (1 << N).  A & 1 was
	 already handled above.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && integer_onep (TREE_OPERAND (arg0, 1))
	  && integer_zerop (op2)
	  && integer_pow2p (arg1))
	{
	  tree tem = TREE_OPERAND (arg0, 0);
	  STRIP_NOPS (tem);
	  if (TREE_CODE (tem) == RSHIFT_EXPR
              && TREE_CODE (TREE_OPERAND (tem, 1)) == INTEGER_CST
              && (unsigned HOST_WIDE_INT) tree_log2 (arg1) ==
	         TREE_INT_CST_LOW (TREE_OPERAND (tem, 1)))
	    return fold_build2 (BIT_AND_EXPR, type,
				TREE_OPERAND (tem, 0), arg1);
	}

      /* A & N ? N : 0 is simply A & N if N is a power of two.  This
	 is probably obsolete because the first operand should be a
	 truth value (that's why we have the two cases above), but let's
	 leave it in until we can confirm this for all front-ends.  */
      if (integer_zerop (op2)
	  && TREE_CODE (arg0) == NE_EXPR
	  && integer_zerop (TREE_OPERAND (arg0, 1))
	  && integer_pow2p (arg1)
	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
	  && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
			      arg1, OEP_ONLY_CONST))
	return pedantic_non_lvalue (fold_convert (type,
						  TREE_OPERAND (arg0, 0)));

      /* Convert A ? B : 0 into A && B if A and B are truth values.  */
      if (integer_zerop (op2)
	  && truth_value_p (TREE_CODE (arg0))
	  && truth_value_p (TREE_CODE (arg1)))
	return fold_build2 (TRUTH_ANDIF_EXPR, type,
			    fold_convert (type, arg0),
			    arg1);

      /* Convert A ? B : 1 into !A || B if A and B are truth values.  */
      if (integer_onep (op2)
	  && truth_value_p (TREE_CODE (arg0))
	  && truth_value_p (TREE_CODE (arg1)))
	{
	  /* Only perform transformation if ARG0 is easily inverted.  */
	  tem = fold_truth_not_expr (arg0);
	  if (tem)
	    return fold_build2 (TRUTH_ORIF_EXPR, type,
				fold_convert (type, tem),
				arg1);
	}

      /* Convert A ? 0 : B into !A && B if A and B are truth values.  */
      if (integer_zerop (arg1)
	  && truth_value_p (TREE_CODE (arg0))
	  && truth_value_p (TREE_CODE (op2)))
	{
	  /* Only perform transformation if ARG0 is easily inverted.  */
	  tem = fold_truth_not_expr (arg0);
	  if (tem)
	    return fold_build2 (TRUTH_ANDIF_EXPR, type,
				fold_convert (type, tem),
				op2);
	}

      /* Convert A ? 1 : B into A || B if A and B are truth values.  */
      if (integer_onep (arg1)
	  && truth_value_p (TREE_CODE (arg0))
	  && truth_value_p (TREE_CODE (op2)))
	return fold_build2 (TRUTH_ORIF_EXPR, type,
			    fold_convert (type, arg0),
			    op2);

      return NULL_TREE;

    case CALL_EXPR:
      /* Check for a built-in function.  */
      if (TREE_CODE (op0) == ADDR_EXPR
	  && TREE_CODE (TREE_OPERAND (op0, 0)) == FUNCTION_DECL
	  && DECL_BUILT_IN (TREE_OPERAND (op0, 0)))
	return fold_builtin (TREE_OPERAND (op0, 0), op1, false);
      return NULL_TREE;

    case BIT_FIELD_REF:
      if (TREE_CODE (arg0) == VECTOR_CST
	  && type == TREE_TYPE (TREE_TYPE (arg0))
	  && host_integerp (arg1, 1)
	  && host_integerp (op2, 1))
	{
	  unsigned HOST_WIDE_INT width = tree_low_cst (arg1, 1);
	  unsigned HOST_WIDE_INT idx = tree_low_cst (op2, 1);

	  if (width != 0
	      && simple_cst_equal (arg1, TYPE_SIZE (type)) == 1
	      && (idx % width) == 0
	      && (idx = idx / width)
		 < TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)))
	    {
	      tree elements = TREE_VECTOR_CST_ELTS (arg0);
	      while (idx-- > 0 && elements)
		elements = TREE_CHAIN (elements);
	      if (elements)
		return TREE_VALUE (elements);
	      else
		return fold_convert (type, integer_zero_node);
	    }
	}
      return NULL_TREE;

    default:
      return NULL_TREE;
    } /* switch (code) */
}

/* Perform constant folding and related simplification of EXPR.
   The related simplifications include x*1 => x, x*0 => 0, etc.,
   and application of the associative law.
   NOP_EXPR conversions may be removed freely (as long as we
   are careful not to change the type of the overall expression).
   We cannot simplify through a CONVERT_EXPR, FIX_EXPR or FLOAT_EXPR,
   but we can constant-fold them if they have constant operands.  */

#ifdef ENABLE_FOLD_CHECKING
# define fold(x) fold_1 (x)
static tree fold_1 (tree);
static
#endif
tree
fold (tree expr)
{
  const tree t = expr;
  enum tree_code code = TREE_CODE (t);
  enum tree_code_class kind = TREE_CODE_CLASS (code);
  tree tem;

  /* Return right away if a constant.  */
  if (kind == tcc_constant)
    return t;

  if (IS_EXPR_CODE_CLASS (kind))
    {
      tree type = TREE_TYPE (t);
      tree op0, op1, op2;

      switch (TREE_CODE_LENGTH (code))
	{
	case 1:
	  op0 = TREE_OPERAND (t, 0);
	  tem = fold_unary (code, type, op0);
	  return tem ? tem : expr;
	case 2:
	  op0 = TREE_OPERAND (t, 0);
	  op1 = TREE_OPERAND (t, 1);
	  tem = fold_binary (code, type, op0, op1);
	  return tem ? tem : expr;
	case 3:
	  op0 = TREE_OPERAND (t, 0);
	  op1 = TREE_OPERAND (t, 1);
	  op2 = TREE_OPERAND (t, 2);
	  tem = fold_ternary (code, type, op0, op1, op2);
	  return tem ? tem : expr;
	default:
	  break;
	}
    }

  switch (code)
    {
    case CONST_DECL:
      return fold (DECL_INITIAL (t));

    default:
      return t;
    } /* switch (code) */
}

#ifdef ENABLE_FOLD_CHECKING
#undef fold

static void fold_checksum_tree (tree, struct md5_ctx *, htab_t);
static void fold_check_failed (tree, tree);
void print_fold_checksum (tree);

/* When --enable-checking=fold, compute a digest of expr before
   and after actual fold call to see if fold did not accidentally
   change original expr.  */

tree
fold (tree expr)
{
  tree ret;
  struct md5_ctx ctx;
  unsigned char checksum_before[16], checksum_after[16];
  htab_t ht;

  ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
  md5_init_ctx (&ctx);
  fold_checksum_tree (expr, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_before);
  htab_empty (ht);

  ret = fold_1 (expr);

  md5_init_ctx (&ctx);
  fold_checksum_tree (expr, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_after);
  htab_delete (ht);

  if (memcmp (checksum_before, checksum_after, 16))
    fold_check_failed (expr, ret);

  return ret;
}

void
print_fold_checksum (tree expr)
{
  struct md5_ctx ctx;
  unsigned char checksum[16], cnt;
  htab_t ht;

  ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
  md5_init_ctx (&ctx);
  fold_checksum_tree (expr, &ctx, ht);
  md5_finish_ctx (&ctx, checksum);
  htab_delete (ht);
  for (cnt = 0; cnt < 16; ++cnt)
    fprintf (stderr, "%02x", checksum[cnt]);
  putc ('\n', stderr);
}

static void
fold_check_failed (tree expr ATTRIBUTE_UNUSED, tree ret ATTRIBUTE_UNUSED)
{
  internal_error ("fold check: original tree changed by fold");
}

static void
fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
{
  void **slot;
  enum tree_code code;
  struct tree_function_decl buf;
  int i, len;
  
recursive_label:

  gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
	       <= sizeof (struct tree_function_decl))
	      && sizeof (struct tree_type) <= sizeof (struct tree_function_decl));
  if (expr == NULL)
    return;
  slot = htab_find_slot (ht, expr, INSERT);
  if (*slot != NULL)
    return;
  *slot = expr;
  code = TREE_CODE (expr);
  if (TREE_CODE_CLASS (code) == tcc_declaration
      && DECL_ASSEMBLER_NAME_SET_P (expr))
    {
      /* Allow DECL_ASSEMBLER_NAME to be modified.  */
      memcpy ((char *) &buf, expr, tree_size (expr));
      expr = (tree) &buf;
      SET_DECL_ASSEMBLER_NAME (expr, NULL);
    }
  else if (TREE_CODE_CLASS (code) == tcc_type
	   && (TYPE_POINTER_TO (expr) || TYPE_REFERENCE_TO (expr)
	       || TYPE_CACHED_VALUES_P (expr)
	       || TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr)))
    {
      /* Allow these fields to be modified.  */
      memcpy ((char *) &buf, expr, tree_size (expr));
      expr = (tree) &buf;
      TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr) = 0;
      TYPE_POINTER_TO (expr) = NULL;
      TYPE_REFERENCE_TO (expr) = NULL;
      if (TYPE_CACHED_VALUES_P (expr))
	{
	  TYPE_CACHED_VALUES_P (expr) = 0;
	  TYPE_CACHED_VALUES (expr) = NULL;
	}
    }
  md5_process_bytes (expr, tree_size (expr), ctx);
  fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
  if (TREE_CODE_CLASS (code) != tcc_type
      && TREE_CODE_CLASS (code) != tcc_declaration
      && code != TREE_LIST)
    fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
  switch (TREE_CODE_CLASS (code))
    {
    case tcc_constant:
      switch (code)
	{
	case STRING_CST:
	  md5_process_bytes (TREE_STRING_POINTER (expr),
			     TREE_STRING_LENGTH (expr), ctx);
	  break;
	case COMPLEX_CST:
	  fold_checksum_tree (TREE_REALPART (expr), ctx, ht);
	  fold_checksum_tree (TREE_IMAGPART (expr), ctx, ht);
	  break;
	case VECTOR_CST:
	  fold_checksum_tree (TREE_VECTOR_CST_ELTS (expr), ctx, ht);
	  break;
	default:
	  break;
	}
      break;
    case tcc_exceptional:
      switch (code)
	{
	case TREE_LIST:
	  fold_checksum_tree (TREE_PURPOSE (expr), ctx, ht);
	  fold_checksum_tree (TREE_VALUE (expr), ctx, ht);
	  expr = TREE_CHAIN (expr);
	  goto recursive_label;
	  break;
	case TREE_VEC:
	  for (i = 0; i < TREE_VEC_LENGTH (expr); ++i)
	    fold_checksum_tree (TREE_VEC_ELT (expr, i), ctx, ht);
	  break;
	default:
	  break;
	}
      break;
    case tcc_expression:
    case tcc_reference:
    case tcc_comparison:
    case tcc_unary:
    case tcc_binary:
    case tcc_statement:
      len = TREE_CODE_LENGTH (code);
      for (i = 0; i < len; ++i)
	fold_checksum_tree (TREE_OPERAND (expr, i), ctx, ht);
      break;
    case tcc_declaration:
      fold_checksum_tree (DECL_NAME (expr), ctx, ht);
      fold_checksum_tree (DECL_CONTEXT (expr), ctx, ht);
      if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_COMMON))
	{
	  fold_checksum_tree (DECL_SIZE (expr), ctx, ht);
	  fold_checksum_tree (DECL_SIZE_UNIT (expr), ctx, ht);
	  fold_checksum_tree (DECL_INITIAL (expr), ctx, ht);
	  fold_checksum_tree (DECL_ABSTRACT_ORIGIN (expr), ctx, ht);
	  fold_checksum_tree (DECL_ATTRIBUTES (expr), ctx, ht);
	}
      if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_WITH_VIS))
	fold_checksum_tree (DECL_SECTION_NAME (expr), ctx, ht);
	  
      if (CODE_CONTAINS_STRUCT (TREE_CODE (expr), TS_DECL_NON_COMMON))
	{
	  fold_checksum_tree (DECL_VINDEX (expr), ctx, ht);
	  fold_checksum_tree (DECL_RESULT_FLD (expr), ctx, ht);
	  fold_checksum_tree (DECL_ARGUMENT_FLD (expr), ctx, ht);
	}
      break;
    case tcc_type:
      if (TREE_CODE (expr) == ENUMERAL_TYPE)
        fold_checksum_tree (TYPE_VALUES (expr), ctx, ht);
      fold_checksum_tree (TYPE_SIZE (expr), ctx, ht);
      fold_checksum_tree (TYPE_SIZE_UNIT (expr), ctx, ht);
      fold_checksum_tree (TYPE_ATTRIBUTES (expr), ctx, ht);
      fold_checksum_tree (TYPE_NAME (expr), ctx, ht);
      if (INTEGRAL_TYPE_P (expr)
          || SCALAR_FLOAT_TYPE_P (expr))
	{
	  fold_checksum_tree (TYPE_MIN_VALUE (expr), ctx, ht);
	  fold_checksum_tree (TYPE_MAX_VALUE (expr), ctx, ht);
	}
      fold_checksum_tree (TYPE_MAIN_VARIANT (expr), ctx, ht);
      if (TREE_CODE (expr) == RECORD_TYPE
	  || TREE_CODE (expr) == UNION_TYPE
	  || TREE_CODE (expr) == QUAL_UNION_TYPE)
	fold_checksum_tree (TYPE_BINFO (expr), ctx, ht);
      fold_checksum_tree (TYPE_CONTEXT (expr), ctx, ht);
      break;
    default:
      break;
    }
}

#endif

/* Fold a unary tree expression with code CODE of type TYPE with an
   operand OP0.  Return a folded expression if successful.  Otherwise,
   return a tree expression with code CODE of type TYPE with an
   operand OP0.  */

tree
fold_build1_stat (enum tree_code code, tree type, tree op0 MEM_STAT_DECL)
{
  tree tem;
#ifdef ENABLE_FOLD_CHECKING
  unsigned char checksum_before[16], checksum_after[16];
  struct md5_ctx ctx;
  htab_t ht;

  ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
  md5_init_ctx (&ctx);
  fold_checksum_tree (op0, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_before);
  htab_empty (ht);
#endif
  
  tem = fold_unary (code, type, op0);
  if (!tem)
    tem = build1_stat (code, type, op0 PASS_MEM_STAT);
  
#ifdef ENABLE_FOLD_CHECKING
  md5_init_ctx (&ctx);
  fold_checksum_tree (op0, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_after);
  htab_delete (ht);

  if (memcmp (checksum_before, checksum_after, 16))
    fold_check_failed (op0, tem);
#endif
  return tem;
}

/* Fold a binary tree expression with code CODE of type TYPE with
   operands OP0 and OP1.  Return a folded expression if successful.
   Otherwise, return a tree expression with code CODE of type TYPE
   with operands OP0 and OP1.  */

tree
fold_build2_stat (enum tree_code code, tree type, tree op0, tree op1
		  MEM_STAT_DECL)
{
  tree tem;
#ifdef ENABLE_FOLD_CHECKING
  unsigned char checksum_before_op0[16],
                checksum_before_op1[16],
		checksum_after_op0[16],
		checksum_after_op1[16];
  struct md5_ctx ctx;
  htab_t ht;

  ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
  md5_init_ctx (&ctx);
  fold_checksum_tree (op0, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_before_op0);
  htab_empty (ht);

  md5_init_ctx (&ctx);
  fold_checksum_tree (op1, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_before_op1);
  htab_empty (ht);
#endif

  tem = fold_binary (code, type, op0, op1);
  if (!tem)
    tem = build2_stat (code, type, op0, op1 PASS_MEM_STAT);
  
#ifdef ENABLE_FOLD_CHECKING
  md5_init_ctx (&ctx);
  fold_checksum_tree (op0, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_after_op0);
  htab_empty (ht);

  if (memcmp (checksum_before_op0, checksum_after_op0, 16))
    fold_check_failed (op0, tem);
  
  md5_init_ctx (&ctx);
  fold_checksum_tree (op1, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_after_op1);
  htab_delete (ht);

  if (memcmp (checksum_before_op1, checksum_after_op1, 16))
    fold_check_failed (op1, tem);
#endif
  return tem;
}

/* Fold a ternary tree expression with code CODE of type TYPE with
   operands OP0, OP1, and OP2.  Return a folded expression if
   successful.  Otherwise, return a tree expression with code CODE of
   type TYPE with operands OP0, OP1, and OP2.  */

tree
fold_build3_stat (enum tree_code code, tree type, tree op0, tree op1, tree op2
	     MEM_STAT_DECL)
{
  tree tem;
#ifdef ENABLE_FOLD_CHECKING
  unsigned char checksum_before_op0[16],
                checksum_before_op1[16],
                checksum_before_op2[16],
		checksum_after_op0[16],
		checksum_after_op1[16],
		checksum_after_op2[16];
  struct md5_ctx ctx;
  htab_t ht;

  ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
  md5_init_ctx (&ctx);
  fold_checksum_tree (op0, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_before_op0);
  htab_empty (ht);

  md5_init_ctx (&ctx);
  fold_checksum_tree (op1, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_before_op1);
  htab_empty (ht);

  md5_init_ctx (&ctx);
  fold_checksum_tree (op2, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_before_op2);
  htab_empty (ht);
#endif
  
  tem = fold_ternary (code, type, op0, op1, op2);
  if (!tem)
    tem =  build3_stat (code, type, op0, op1, op2 PASS_MEM_STAT);
      
#ifdef ENABLE_FOLD_CHECKING
  md5_init_ctx (&ctx);
  fold_checksum_tree (op0, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_after_op0);
  htab_empty (ht);

  if (memcmp (checksum_before_op0, checksum_after_op0, 16))
    fold_check_failed (op0, tem);
  
  md5_init_ctx (&ctx);
  fold_checksum_tree (op1, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_after_op1);
  htab_empty (ht);

  if (memcmp (checksum_before_op1, checksum_after_op1, 16))
    fold_check_failed (op1, tem);
  
  md5_init_ctx (&ctx);
  fold_checksum_tree (op2, &ctx, ht);
  md5_finish_ctx (&ctx, checksum_after_op2);
  htab_delete (ht);

  if (memcmp (checksum_before_op2, checksum_after_op2, 16))
    fold_check_failed (op2, tem);
#endif
  return tem;
}

/* Perform constant folding and related simplification of initializer
   expression EXPR.  These behave identically to "fold_buildN" but ignore
   potential run-time traps and exceptions that fold must preserve.  */

#define START_FOLD_INIT \
  int saved_signaling_nans = flag_signaling_nans;\
  int saved_trapping_math = flag_trapping_math;\
  int saved_rounding_math = flag_rounding_math;\
  int saved_trapv = flag_trapv;\
  int saved_folding_initializer = folding_initializer;\
  flag_signaling_nans = 0;\
  flag_trapping_math = 0;\
  flag_rounding_math = 0;\
  flag_trapv = 0;\
  folding_initializer = 1;

#define END_FOLD_INIT \
  flag_signaling_nans = saved_signaling_nans;\
  flag_trapping_math = saved_trapping_math;\
  flag_rounding_math = saved_rounding_math;\
  flag_trapv = saved_trapv;\
  folding_initializer = saved_folding_initializer;

tree
fold_build1_initializer (enum tree_code code, tree type, tree op)
{
  tree result;
  START_FOLD_INIT;

  result = fold_build1 (code, type, op);

  END_FOLD_INIT;
  return result;
}

tree
fold_build2_initializer (enum tree_code code, tree type, tree op0, tree op1)
{
  tree result;
  START_FOLD_INIT;

  result = fold_build2 (code, type, op0, op1);

  END_FOLD_INIT;
  return result;
}

tree
fold_build3_initializer (enum tree_code code, tree type, tree op0, tree op1,
			 tree op2)
{
  tree result;
  START_FOLD_INIT;

  result = fold_build3 (code, type, op0, op1, op2);

  END_FOLD_INIT;
  return result;
}

#undef START_FOLD_INIT
#undef END_FOLD_INIT

/* Determine if first argument is a multiple of second argument.  Return 0 if
   it is not, or we cannot easily determined it to be.

   An example of the sort of thing we care about (at this point; this routine
   could surely be made more general, and expanded to do what the *_DIV_EXPR's
   fold cases do now) is discovering that

     SAVE_EXPR (I) * SAVE_EXPR (J * 8)

   is a multiple of

     SAVE_EXPR (J * 8)

   when we know that the two SAVE_EXPR (J * 8) nodes are the same node.

   This code also handles discovering that

     SAVE_EXPR (I) * SAVE_EXPR (J * 8)

   is a multiple of 8 so we don't have to worry about dealing with a
   possible remainder.

   Note that we *look* inside a SAVE_EXPR only to determine how it was
   calculated; it is not safe for fold to do much of anything else with the
   internals of a SAVE_EXPR, since it cannot know when it will be evaluated
   at run time.  For example, the latter example above *cannot* be implemented
   as SAVE_EXPR (I) * J or any variant thereof, since the value of J at
   evaluation time of the original SAVE_EXPR is not necessarily the same at
   the time the new expression is evaluated.  The only optimization of this
   sort that would be valid is changing

     SAVE_EXPR (I) * SAVE_EXPR (SAVE_EXPR (J) * 8)

   divided by 8 to

     SAVE_EXPR (I) * SAVE_EXPR (J)

   (where the same SAVE_EXPR (J) is used in the original and the
   transformed version).  */

static int
multiple_of_p (tree type, tree top, tree bottom)
{
  if (operand_equal_p (top, bottom, 0))
    return 1;

  if (TREE_CODE (type) != INTEGER_TYPE)
    return 0;

  switch (TREE_CODE (top))
    {
    case BIT_AND_EXPR:
      /* Bitwise and provides a power of two multiple.  If the mask is
	 a multiple of BOTTOM then TOP is a multiple of BOTTOM.  */
      if (!integer_pow2p (bottom))
	return 0;
      /* FALLTHRU */

    case MULT_EXPR:
      return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
	      || multiple_of_p (type, TREE_OPERAND (top, 1), bottom));

    case PLUS_EXPR:
    case MINUS_EXPR:
      return (multiple_of_p (type, TREE_OPERAND (top, 0), bottom)
	      && multiple_of_p (type, TREE_OPERAND (top, 1), bottom));

    case LSHIFT_EXPR:
      if (TREE_CODE (TREE_OPERAND (top, 1)) == INTEGER_CST)
	{
	  tree op1, t1;

	  op1 = TREE_OPERAND (top, 1);
	  /* const_binop may not detect overflow correctly,
	     so check for it explicitly here.  */
	  if (TYPE_PRECISION (TREE_TYPE (size_one_node))
	      > TREE_INT_CST_LOW (op1)
	      && TREE_INT_CST_HIGH (op1) == 0
	      && 0 != (t1 = fold_convert (type,
					  const_binop (LSHIFT_EXPR,
						       size_one_node,
						       op1, 0)))
	      && ! TREE_OVERFLOW (t1))
	    return multiple_of_p (type, t1, bottom);
	}
      return 0;

    case NOP_EXPR:
      /* Can't handle conversions from non-integral or wider integral type.  */
      if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (top, 0))) != INTEGER_TYPE)
	  || (TYPE_PRECISION (type)
	      < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (top, 0)))))
	return 0;

      /* .. fall through ...  */

    case SAVE_EXPR:
      return multiple_of_p (type, TREE_OPERAND (top, 0), bottom);

    case INTEGER_CST:
      if (TREE_CODE (bottom) != INTEGER_CST
	  || (TYPE_UNSIGNED (type)
	      && (tree_int_cst_sgn (top) < 0
		  || tree_int_cst_sgn (bottom) < 0)))
	return 0;
      return integer_zerop (const_binop (TRUNC_MOD_EXPR,
					 top, bottom, 0));

    default:
      return 0;
    }
}

/* Return true if `t' is known to be non-negative.  If the return
   value is based on the assumption that signed overflow is undefined,
   set *STRICT_OVERFLOW_P to true; otherwise, don't change
   *STRICT_OVERFLOW_P.  */

int
tree_expr_nonnegative_warnv_p (tree t, bool *strict_overflow_p)
{
  if (t == error_mark_node)
    return 0;

  if (TYPE_UNSIGNED (TREE_TYPE (t)))
    return 1;

  switch (TREE_CODE (t))
    {
    case SSA_NAME:
      /* Query VRP to see if it has recorded any information about
	 the range of this object.  */
      return ssa_name_nonnegative_p (t);

    case ABS_EXPR:
      /* We can't return 1 if flag_wrapv is set because
	 ABS_EXPR<INT_MIN> = INT_MIN.  */
      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
	return 1;
      if (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)))
	{
	  *strict_overflow_p = true;
	  return 1;
	}
      break;

    case INTEGER_CST:
      return tree_int_cst_sgn (t) >= 0;

    case REAL_CST:
      return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));

    case PLUS_EXPR:
      if (FLOAT_TYPE_P (TREE_TYPE (t)))
	return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
					       strict_overflow_p)
		&& tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
						  strict_overflow_p));

      /* zero_extend(x) + zero_extend(y) is non-negative if x and y are
	 both unsigned and at least 2 bits shorter than the result.  */
      if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
	  && TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
	  && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
	{
	  tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
	  tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
	  if (TREE_CODE (inner1) == INTEGER_TYPE && TYPE_UNSIGNED (inner1)
	      && TREE_CODE (inner2) == INTEGER_TYPE && TYPE_UNSIGNED (inner2))
	    {
	      unsigned int prec = MAX (TYPE_PRECISION (inner1),
				       TYPE_PRECISION (inner2)) + 1;
	      return prec < TYPE_PRECISION (TREE_TYPE (t));
	    }
	}
      break;

    case MULT_EXPR:
      if (FLOAT_TYPE_P (TREE_TYPE (t)))
	{
	  /* x * x for floating point x is always non-negative.  */
	  if (operand_equal_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1), 0))
	    return 1;
	  return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
						 strict_overflow_p)
		  && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
						    strict_overflow_p));
	}

      /* zero_extend(x) * zero_extend(y) is non-negative if x and y are
	 both unsigned and their total bits is shorter than the result.  */
      if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
	  && TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
	  && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
	{
	  tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
	  tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
	  if (TREE_CODE (inner1) == INTEGER_TYPE && TYPE_UNSIGNED (inner1)
	      && TREE_CODE (inner2) == INTEGER_TYPE && TYPE_UNSIGNED (inner2))
	    return TYPE_PRECISION (inner1) + TYPE_PRECISION (inner2)
		   < TYPE_PRECISION (TREE_TYPE (t));
	}
      return 0;

    case BIT_AND_EXPR:
    case MAX_EXPR:
      return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
					     strict_overflow_p)
	      || tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
						strict_overflow_p));

    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
    case MIN_EXPR:
    case RDIV_EXPR:
    case TRUNC_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case ROUND_DIV_EXPR:
      return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
					     strict_overflow_p)
	      && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
						strict_overflow_p));

    case TRUNC_MOD_EXPR:
    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case SAVE_EXPR:
    case NON_LVALUE_EXPR:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
      return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
					    strict_overflow_p);

    case COMPOUND_EXPR:
    case MODIFY_EXPR:
      return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
					    strict_overflow_p);

    case BIND_EXPR:
      return tree_expr_nonnegative_warnv_p (expr_last (TREE_OPERAND (t, 1)),
					    strict_overflow_p);

    case COND_EXPR:
      return (tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
					     strict_overflow_p)
	      && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 2),
						strict_overflow_p));

    case NOP_EXPR:
      {
	tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
	tree outer_type = TREE_TYPE (t);

	if (TREE_CODE (outer_type) == REAL_TYPE)
	  {
	    if (TREE_CODE (inner_type) == REAL_TYPE)
	      return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
						    strict_overflow_p);
	    if (TREE_CODE (inner_type) == INTEGER_TYPE)
	      {
		if (TYPE_UNSIGNED (inner_type))
		  return 1;
		return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
						      strict_overflow_p);
	      }
	  }
	else if (TREE_CODE (outer_type) == INTEGER_TYPE)
	  {
	    if (TREE_CODE (inner_type) == REAL_TYPE)
	      return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t,0),
						    strict_overflow_p);
	    if (TREE_CODE (inner_type) == INTEGER_TYPE)
	      return TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type)
		      && TYPE_UNSIGNED (inner_type);
	  }
      }
      break;

    case TARGET_EXPR:
      {
	tree temp = TARGET_EXPR_SLOT (t);
	t = TARGET_EXPR_INITIAL (t);

	/* If the initializer is non-void, then it's a normal expression
	   that will be assigned to the slot.  */
	if (!VOID_TYPE_P (t))
	  return tree_expr_nonnegative_warnv_p (t, strict_overflow_p);

	/* Otherwise, the initializer sets the slot in some way.  One common
	   way is an assignment statement at the end of the initializer.  */
	while (1)
	  {
	    if (TREE_CODE (t) == BIND_EXPR)
	      t = expr_last (BIND_EXPR_BODY (t));
	    else if (TREE_CODE (t) == TRY_FINALLY_EXPR
		     || TREE_CODE (t) == TRY_CATCH_EXPR)
	      t = expr_last (TREE_OPERAND (t, 0));
	    else if (TREE_CODE (t) == STATEMENT_LIST)
	      t = expr_last (t);
	    else
	      break;
	  }
	if (TREE_CODE (t) == MODIFY_EXPR
	    && TREE_OPERAND (t, 0) == temp)
	  return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
						strict_overflow_p);

	return 0;
      }

    case CALL_EXPR:
      {
	tree fndecl = get_callee_fndecl (t);
	tree arglist = TREE_OPERAND (t, 1);
	if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
	  switch (DECL_FUNCTION_CODE (fndecl))
	    {
	    CASE_FLT_FN (BUILT_IN_ACOS):
	    CASE_FLT_FN (BUILT_IN_ACOSH):
	    CASE_FLT_FN (BUILT_IN_CABS):
	    CASE_FLT_FN (BUILT_IN_COSH):
	    CASE_FLT_FN (BUILT_IN_ERFC):
	    CASE_FLT_FN (BUILT_IN_EXP):
	    CASE_FLT_FN (BUILT_IN_EXP10):
	    CASE_FLT_FN (BUILT_IN_EXP2):
	    CASE_FLT_FN (BUILT_IN_FABS):
	    CASE_FLT_FN (BUILT_IN_FDIM):
	    CASE_FLT_FN (BUILT_IN_HYPOT):
	    CASE_FLT_FN (BUILT_IN_POW10):
	    CASE_INT_FN (BUILT_IN_FFS):
	    CASE_INT_FN (BUILT_IN_PARITY):
	    CASE_INT_FN (BUILT_IN_POPCOUNT):
	    /* APPLE LOCAL begin mainline bswap */
	    case BUILT_IN_BSWAP32:
	    case BUILT_IN_BSWAP64:
	    /* APPLE LOCAL end mainline bswap */
	      /* Always true.  */
	      return 1;

	    CASE_FLT_FN (BUILT_IN_SQRT):
	      /* sqrt(-0.0) is -0.0.  */
	      if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (t))))
		return 1;
	      return tree_expr_nonnegative_warnv_p (TREE_VALUE (arglist),
						    strict_overflow_p);

	    CASE_FLT_FN (BUILT_IN_ASINH):
	    CASE_FLT_FN (BUILT_IN_ATAN):
	    CASE_FLT_FN (BUILT_IN_ATANH):
	    CASE_FLT_FN (BUILT_IN_CBRT):
	    CASE_FLT_FN (BUILT_IN_CEIL):
	    CASE_FLT_FN (BUILT_IN_ERF):
	    CASE_FLT_FN (BUILT_IN_EXPM1):
	    CASE_FLT_FN (BUILT_IN_FLOOR):
	    CASE_FLT_FN (BUILT_IN_FMOD):
	    CASE_FLT_FN (BUILT_IN_FREXP):
	    CASE_FLT_FN (BUILT_IN_LCEIL):
	    CASE_FLT_FN (BUILT_IN_LDEXP):
	    CASE_FLT_FN (BUILT_IN_LFLOOR):
	    CASE_FLT_FN (BUILT_IN_LLCEIL):
	    CASE_FLT_FN (BUILT_IN_LLFLOOR):
	    CASE_FLT_FN (BUILT_IN_LLRINT):
	    CASE_FLT_FN (BUILT_IN_LLROUND):
	    CASE_FLT_FN (BUILT_IN_LRINT):
	    CASE_FLT_FN (BUILT_IN_LROUND):
	    CASE_FLT_FN (BUILT_IN_MODF):
	    CASE_FLT_FN (BUILT_IN_NEARBYINT):
	    CASE_FLT_FN (BUILT_IN_POW):
	    CASE_FLT_FN (BUILT_IN_RINT):
	    CASE_FLT_FN (BUILT_IN_ROUND):
	    CASE_FLT_FN (BUILT_IN_SIGNBIT):
	    CASE_FLT_FN (BUILT_IN_SINH):
	    CASE_FLT_FN (BUILT_IN_TANH):
	    CASE_FLT_FN (BUILT_IN_TRUNC):
	      /* True if the 1st argument is nonnegative.  */
	      return tree_expr_nonnegative_warnv_p (TREE_VALUE (arglist),
						    strict_overflow_p);

	    CASE_FLT_FN (BUILT_IN_FMAX):
	      /* True if the 1st OR 2nd arguments are nonnegative.  */
	      return (tree_expr_nonnegative_warnv_p (TREE_VALUE (arglist),
						     strict_overflow_p)
		      || (tree_expr_nonnegative_warnv_p
			  (TREE_VALUE (TREE_CHAIN (arglist)),
			   strict_overflow_p)));

	    CASE_FLT_FN (BUILT_IN_FMIN):
	      /* True if the 1st AND 2nd arguments are nonnegative.  */
	      return (tree_expr_nonnegative_warnv_p (TREE_VALUE (arglist),
						     strict_overflow_p)
		      && (tree_expr_nonnegative_warnv_p
			  (TREE_VALUE (TREE_CHAIN (arglist)),
			   strict_overflow_p)));

	    CASE_FLT_FN (BUILT_IN_COPYSIGN):
	      /* True if the 2nd argument is nonnegative.  */
	      return (tree_expr_nonnegative_warnv_p
		      (TREE_VALUE (TREE_CHAIN (arglist)),
		       strict_overflow_p));

	    default:
	      break;
	    }
      }

      /* ... fall through ...  */

    default:
      {
	tree type = TREE_TYPE (t);
	if ((TYPE_PRECISION (type) != 1 || TYPE_UNSIGNED (type))
	    && truth_value_p (TREE_CODE (t)))
	  /* Truth values evaluate to 0 or 1, which is nonnegative unless we
             have a signed:1 type (where the value is -1 and 0).  */
	  return true;
      }
    }

  /* We don't know sign of `t', so be conservative and return false.  */
  return 0;
}

/* Return true if `t' is known to be non-negative.  Handle warnings
   about undefined signed overflow.  */

int
tree_expr_nonnegative_p (tree t)
{
  int ret;
  bool strict_overflow_p;

  strict_overflow_p = false;
  ret = tree_expr_nonnegative_warnv_p (t, &strict_overflow_p);
  if (strict_overflow_p)
    fold_overflow_warning (("assuming signed overflow does not occur when "
			    "determining that expression is always "
			    "non-negative"),
			   WARN_STRICT_OVERFLOW_MISC);
  return ret;
}

/* Return true when T is an address and is known to be nonzero.
   For floating point we further ensure that T is not denormal.
   Similar logic is present in nonzero_address in rtlanal.h.

   If the return value is based on the assumption that signed overflow
   is undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't
   change *STRICT_OVERFLOW_P.  */

bool
tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
{
  tree type = TREE_TYPE (t);
  bool sub_strict_overflow_p;

  /* Doing something useful for floating point would need more work.  */
  if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
    return false;

  switch (TREE_CODE (t))
    {
    case SSA_NAME:
      /* Query VRP to see if it has recorded any information about
	 the range of this object.  */
      return ssa_name_nonzero_p (t);

    case ABS_EXPR:
      return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
					strict_overflow_p);

    case INTEGER_CST:
      /* We used to test for !integer_zerop here.  This does not work correctly
	 if TREE_CONSTANT_OVERFLOW (t).  */
      return (TREE_INT_CST_LOW (t) != 0
	      || TREE_INT_CST_HIGH (t) != 0);

    case PLUS_EXPR:
      if (TYPE_OVERFLOW_UNDEFINED (type))
	{
	  /* With the presence of negative values it is hard
	     to say something.  */
	  sub_strict_overflow_p = false;
	  if (!tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
					      &sub_strict_overflow_p)
	      || !tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
						 &sub_strict_overflow_p))
	    return false;
	  /* One of operands must be positive and the other non-negative.  */
	  /* We don't set *STRICT_OVERFLOW_P here: even if this value
	     overflows, on a twos-complement machine the sum of two
	     nonnegative numbers can never be zero.  */
	  return (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
					     strict_overflow_p)
	          || tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
						strict_overflow_p));
	}
      break;

    case MULT_EXPR:
      if (TYPE_OVERFLOW_UNDEFINED (type))
	{
	  if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
					 strict_overflow_p)
	      && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
					    strict_overflow_p))
	    {
	      *strict_overflow_p = true;
	      return true;
	    }
	}
      break;

    case NOP_EXPR:
      {
	tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
	tree outer_type = TREE_TYPE (t);

	return (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
		&& tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
					      strict_overflow_p));
      }
      break;

   case ADDR_EXPR:
      {
	tree base = get_base_address (TREE_OPERAND (t, 0));

	if (!base)
	  return false;

	/* Weak declarations may link to NULL.  */
	if (VAR_OR_FUNCTION_DECL_P (base))
	  return !DECL_WEAK (base);

	/* Constants are never weak.  */
	if (CONSTANT_CLASS_P (base))
	  return true;

	return false;
      }

    case COND_EXPR:
      sub_strict_overflow_p = false;
      if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
				     &sub_strict_overflow_p)
	  && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 2),
					&sub_strict_overflow_p))
	{
	  if (sub_strict_overflow_p)
	    *strict_overflow_p = true;
	  return true;
	}
      break;

    case MIN_EXPR:
      sub_strict_overflow_p = false;
      if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
				     &sub_strict_overflow_p)
	  && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
					&sub_strict_overflow_p))
	{
	  if (sub_strict_overflow_p)
	    *strict_overflow_p = true;
	}
      break;

    case MAX_EXPR:
      sub_strict_overflow_p = false;
      if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
				     &sub_strict_overflow_p))
	{
	  if (sub_strict_overflow_p)
	    *strict_overflow_p = true;

	  /* When both operands are nonzero, then MAX must be too.  */
	  if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
					 strict_overflow_p))
	    return true;

	  /* MAX where operand 0 is positive is positive.  */
	  return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
					       strict_overflow_p);
	}
      /* MAX where operand 1 is positive is positive.  */
      else if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
					  &sub_strict_overflow_p)
	       && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
						 &sub_strict_overflow_p))
	{
	  if (sub_strict_overflow_p)
	    *strict_overflow_p = true;
	  return true;
	}
      break;

    case COMPOUND_EXPR:
    case MODIFY_EXPR:
    case BIND_EXPR:
      return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
					strict_overflow_p);

    case SAVE_EXPR:
    case NON_LVALUE_EXPR:
      return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
					strict_overflow_p);

    case BIT_IOR_EXPR:
      return (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
					strict_overflow_p)
	      || tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
					    strict_overflow_p));

    case CALL_EXPR:
      return alloca_call_p (t);

    default:
      break;
    }
  return false;
}

/* Return true when T is an address and is known to be nonzero.
   Handle warnings about undefined signed overflow.  */

bool
tree_expr_nonzero_p (tree t)
{
  bool ret, strict_overflow_p;

  strict_overflow_p = false;
  ret = tree_expr_nonzero_warnv_p (t, &strict_overflow_p);
  if (strict_overflow_p)
    fold_overflow_warning (("assuming signed overflow does not occur when "
			    "determining that expression is always "
			    "non-zero"),
			   WARN_STRICT_OVERFLOW_MISC);
  return ret;
}

/* Given the components of a binary expression CODE, TYPE, OP0 and OP1,
   attempt to fold the expression to a constant without modifying TYPE,
   OP0 or OP1.

   If the expression could be simplified to a constant, then return
   the constant.  If the expression would not be simplified to a
   constant, then return NULL_TREE.  */

tree
fold_binary_to_constant (enum tree_code code, tree type, tree op0, tree op1)
{
  tree tem = fold_binary (code, type, op0, op1);
  return (tem && TREE_CONSTANT (tem)) ? tem : NULL_TREE;
}

/* Given the components of a unary expression CODE, TYPE and OP0,
   attempt to fold the expression to a constant without modifying
   TYPE or OP0.

   If the expression could be simplified to a constant, then return
   the constant.  If the expression would not be simplified to a
   constant, then return NULL_TREE.  */

tree
fold_unary_to_constant (enum tree_code code, tree type, tree op0)
{
  tree tem = fold_unary (code, type, op0);
  return (tem && TREE_CONSTANT (tem)) ? tem : NULL_TREE;
}

/* If EXP represents referencing an element in a constant string
   (either via pointer arithmetic or array indexing), return the
   tree representing the value accessed, otherwise return NULL.  */

tree
fold_read_from_constant_string (tree exp)
{
  if ((TREE_CODE (exp) == INDIRECT_REF
       || TREE_CODE (exp) == ARRAY_REF)
      && TREE_CODE (TREE_TYPE (exp)) == INTEGER_TYPE
/* LLVM LOCAL begin */      
#if ENABLE_LLVM
    /* LLVM extends ARRAY_REF to allow pointers to be the base value. */
      && (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == ARRAY_TYPE)
#endif
/* LLVM LOCAL end */      
    )
    {
      tree exp1 = TREE_OPERAND (exp, 0);
      tree index;
      tree string;

      if (TREE_CODE (exp) == INDIRECT_REF)
	string = string_constant (exp1, &index);
      else
	{
	  tree low_bound = array_ref_low_bound (exp);
	  index = fold_convert (sizetype, TREE_OPERAND (exp, 1));

	  /* Optimize the special-case of a zero lower bound.

	     We convert the low_bound to sizetype to avoid some problems
	     with constant folding.  (E.g. suppose the lower bound is 1,
	     and its mode is QI.  Without the conversion,l (ARRAY
	     +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
	     +INDEX), which becomes (ARRAY+255+INDEX).  Opps!)  */
	  if (! integer_zerop (low_bound))
	    index = size_diffop (index, fold_convert (sizetype, low_bound));

	  string = exp1;
	}

      if (string
	  && TYPE_MODE (TREE_TYPE (exp)) == TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))
	  && TREE_CODE (string) == STRING_CST
	  && TREE_CODE (index) == INTEGER_CST
	  && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
	  && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (string))))
	      == MODE_INT)
	  && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))) == 1))
	return fold_convert (TREE_TYPE (exp),
			     build_int_cst (NULL_TREE,
					    (TREE_STRING_POINTER (string)
					     [TREE_INT_CST_LOW (index)])));
    }
  return NULL;
}

/* Return the tree for neg (ARG0) when ARG0 is known to be either
   an integer constant or real constant.

   TYPE is the type of the result.  */

static tree
fold_negate_const (tree arg0, tree type)
{
  tree t = NULL_TREE;

  switch (TREE_CODE (arg0))
    {
    case INTEGER_CST:
      {
	unsigned HOST_WIDE_INT low;
	HOST_WIDE_INT high;
	int overflow = neg_double (TREE_INT_CST_LOW (arg0),
				   TREE_INT_CST_HIGH (arg0),
				   &low, &high);
	t = build_int_cst_wide (type, low, high);
	t = force_fit_type (t, 1,
			    (overflow | TREE_OVERFLOW (arg0))
			    && !TYPE_UNSIGNED (type),
			    TREE_CONSTANT_OVERFLOW (arg0));
	break;
      }

    case REAL_CST:
      t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
      break;

    default:
      gcc_unreachable ();
    }

  return t;
}

/* Return the tree for abs (ARG0) when ARG0 is known to be either
   an integer constant or real constant.

   TYPE is the type of the result.  */

tree
fold_abs_const (tree arg0, tree type)
{
  tree t = NULL_TREE;

  switch (TREE_CODE (arg0))
    {
    case INTEGER_CST:
      /* If the value is unsigned, then the absolute value is
	 the same as the ordinary value.  */
      if (TYPE_UNSIGNED (type))
	t = arg0;
      /* Similarly, if the value is non-negative.  */
      else if (INT_CST_LT (integer_minus_one_node, arg0))
	t = arg0;
      /* If the value is negative, then the absolute value is
	 its negation.  */
      else
	{
	  unsigned HOST_WIDE_INT low;
	  HOST_WIDE_INT high;
	  int overflow = neg_double (TREE_INT_CST_LOW (arg0),
				     TREE_INT_CST_HIGH (arg0),
				     &low, &high);
	  t = build_int_cst_wide (type, low, high);
	  t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg0),
			      TREE_CONSTANT_OVERFLOW (arg0));
	}
      break;

    case REAL_CST:
      if (REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg0)))
	t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
      else
	t =  arg0;
      break;

    default:
      gcc_unreachable ();
    }

  return t;
}

/* Return the tree for not (ARG0) when ARG0 is known to be an integer
   constant.  TYPE is the type of the result.  */

static tree
fold_not_const (tree arg0, tree type)
{
  tree t = NULL_TREE;

  gcc_assert (TREE_CODE (arg0) == INTEGER_CST);

  t = build_int_cst_wide (type,
			  ~ TREE_INT_CST_LOW (arg0),
			  ~ TREE_INT_CST_HIGH (arg0));
  t = force_fit_type (t, 0, TREE_OVERFLOW (arg0),
		      TREE_CONSTANT_OVERFLOW (arg0));

  return t;
}

/* Given CODE, a relational operator, the target type, TYPE and two
   constant operands OP0 and OP1, return the result of the
   relational operation.  If the result is not a compile time
   constant, then return NULL_TREE.  */

static tree
fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
{
  int result, invert;

  /* From here on, the only cases we handle are when the result is
     known to be a constant.  */

  if (TREE_CODE (op0) == REAL_CST && TREE_CODE (op1) == REAL_CST)
    {
      const REAL_VALUE_TYPE *c0 = TREE_REAL_CST_PTR (op0);
      const REAL_VALUE_TYPE *c1 = TREE_REAL_CST_PTR (op1);

      /* Handle the cases where either operand is a NaN.  */
      if (real_isnan (c0) || real_isnan (c1))
	{
	  switch (code)
	    {
	    case EQ_EXPR:
	    case ORDERED_EXPR:
	      result = 0;
	      break;

	    case NE_EXPR:
	    case UNORDERED_EXPR:
	    case UNLT_EXPR:
	    case UNLE_EXPR:
	    case UNGT_EXPR:
	    case UNGE_EXPR:
	    case UNEQ_EXPR:
              result = 1;
	      break;

	    case LT_EXPR:
	    case LE_EXPR:
	    case GT_EXPR:
	    case GE_EXPR:
	    case LTGT_EXPR:
	      if (flag_trapping_math)
		return NULL_TREE;
	      result = 0;
	      break;

	    default:
	      gcc_unreachable ();
	    }

	  return constant_boolean_node (result, type);
	}

      return constant_boolean_node (real_compare (code, c0, c1), type);
    }

  /* Handle equality/inequality of complex constants.  */
  if (TREE_CODE (op0) == COMPLEX_CST && TREE_CODE (op1) == COMPLEX_CST)
    {
      tree rcond = fold_relational_const (code, type,
					  TREE_REALPART (op0),
					  TREE_REALPART (op1));
      tree icond = fold_relational_const (code, type,
					  TREE_IMAGPART (op0),
					  TREE_IMAGPART (op1));
      if (code == EQ_EXPR)
	return fold_build2 (TRUTH_ANDIF_EXPR, type, rcond, icond);
      else if (code == NE_EXPR)
	return fold_build2 (TRUTH_ORIF_EXPR, type, rcond, icond);
      else
	return NULL_TREE;
    }

  /* From here on we only handle LT, LE, GT, GE, EQ and NE.

     To compute GT, swap the arguments and do LT.
     To compute GE, do LT and invert the result.
     To compute LE, swap the arguments, do LT and invert the result.
     To compute NE, do EQ and invert the result.

     Therefore, the code below must handle only EQ and LT.  */

  if (code == LE_EXPR || code == GT_EXPR)
    {
      tree tem = op0;
      op0 = op1;
      op1 = tem;
      code = swap_tree_comparison (code);
    }

  /* Note that it is safe to invert for real values here because we
     have already handled the one case that it matters.  */

  invert = 0;
  if (code == NE_EXPR || code == GE_EXPR)
    {
      invert = 1;
      code = invert_tree_comparison (code, false);
    }

  /* Compute a result for LT or EQ if args permit;
     Otherwise return T.  */
  if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
    {
      if (code == EQ_EXPR)
	result = tree_int_cst_equal (op0, op1);
      else if (TYPE_UNSIGNED (TREE_TYPE (op0)))
	result = INT_CST_LT_UNSIGNED (op0, op1);
      else
	result = INT_CST_LT (op0, op1);
    }
  else
    return NULL_TREE;

  if (invert)
    result ^= 1;
  return constant_boolean_node (result, type);
}

/* Build an expression for the a clean point containing EXPR with type TYPE.
   Don't build a cleanup point expression for EXPR which don't have side
   effects.  */

tree
fold_build_cleanup_point_expr (tree type, tree expr)
{
  /* If the expression does not have side effects then we don't have to wrap
     it with a cleanup point expression.  */
  if (!TREE_SIDE_EFFECTS (expr))
    return expr;

  /* If the expression is a return, check to see if the expression inside the
     return has no side effects or the right hand side of the modify expression
     inside the return. If either don't have side effects set we don't need to
     wrap the expression in a cleanup point expression.  Note we don't check the
     left hand side of the modify because it should always be a return decl.  */
  if (TREE_CODE (expr) == RETURN_EXPR)
    {
      tree op = TREE_OPERAND (expr, 0);
      if (!op || !TREE_SIDE_EFFECTS (op))
        return expr;
      op = TREE_OPERAND (op, 1);
      if (!TREE_SIDE_EFFECTS (op))
        return expr;
    }
  
  return build1 (CLEANUP_POINT_EXPR, type, expr);
}

/* Build an expression for the address of T.  Folds away INDIRECT_REF to
   avoid confusing the gimplify process.  */

tree
build_fold_addr_expr_with_type (tree t, tree ptrtype)
{
  /* The size of the object is not relevant when talking about its address.  */
  if (TREE_CODE (t) == WITH_SIZE_EXPR)
    t = TREE_OPERAND (t, 0);

  /* Note: doesn't apply to ALIGN_INDIRECT_REF */
  if (TREE_CODE (t) == INDIRECT_REF
      || TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
    {
      t = TREE_OPERAND (t, 0);
      if (TREE_TYPE (t) != ptrtype)
	t = build1 (NOP_EXPR, ptrtype, t);
    }
  else
    {
      tree base = t;

      while (handled_component_p (base))
	base = TREE_OPERAND (base, 0);
      if (DECL_P (base))
	TREE_ADDRESSABLE (base) = 1;

      t = build1 (ADDR_EXPR, ptrtype, t);
    }

  return t;
}

tree
build_fold_addr_expr (tree t)
{
  return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
}

/* Given a pointer value OP0 and a type TYPE, return a simplified version
   of an indirection through OP0, or NULL_TREE if no simplification is
   possible.  */

tree
fold_indirect_ref_1 (tree type, tree op0)
{
  tree sub = op0;
  tree subtype;

  STRIP_NOPS (sub);
  subtype = TREE_TYPE (sub);
  if (!POINTER_TYPE_P (subtype))
    return NULL_TREE;

  if (TREE_CODE (sub) == ADDR_EXPR)
    {
      tree op = TREE_OPERAND (sub, 0);
      tree optype = TREE_TYPE (op);
      /* *&CONST_DECL -> to the value of the const decl.  */
      if (TREE_CODE (op) == CONST_DECL)
	return DECL_INITIAL (op);
      /* *&p => p;  make sure to handle *&"str"[cst] here.  */
      if (type == optype)
	{
	  tree fop = fold_read_from_constant_string (op);
	  if (fop)
	    return fop;
	  else
	    return op;
	}
      /* *(foo *)&fooarray => fooarray[0] */
      else if (TREE_CODE (optype) == ARRAY_TYPE
	       && type == TREE_TYPE (optype))
	{
	  tree type_domain = TYPE_DOMAIN (optype);
	  tree min_val = size_zero_node;
	  if (type_domain && TYPE_MIN_VALUE (type_domain))
	    min_val = TYPE_MIN_VALUE (type_domain);
	  return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
	}
      /* *(foo *)&complexfoo => __real__ complexfoo */
      else if (TREE_CODE (optype) == COMPLEX_TYPE
	       && type == TREE_TYPE (optype))
	return fold_build1 (REALPART_EXPR, type, op);
    }

  /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
  if (TREE_CODE (sub) == PLUS_EXPR
      && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
    {
      tree op00 = TREE_OPERAND (sub, 0);
      tree op01 = TREE_OPERAND (sub, 1);
      tree op00type;

      STRIP_NOPS (op00);
      op00type = TREE_TYPE (op00);
      if (TREE_CODE (op00) == ADDR_EXPR
 	  && TREE_CODE (TREE_TYPE (op00type)) == COMPLEX_TYPE
	  && type == TREE_TYPE (TREE_TYPE (op00type)))
	{
	  tree size = TYPE_SIZE_UNIT (type);
	  if (tree_int_cst_equal (size, op01))
	    return fold_build1 (IMAGPART_EXPR, type, TREE_OPERAND (op00, 0));
	}
    }
  
  /* *(foo *)fooarrptr => (*fooarrptr)[0] */
  if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
      && type == TREE_TYPE (TREE_TYPE (subtype)))
    {
      tree type_domain;
      tree min_val = size_zero_node;
      sub = build_fold_indirect_ref (sub);
      type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
      if (type_domain && TYPE_MIN_VALUE (type_domain))
	min_val = TYPE_MIN_VALUE (type_domain);
      return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
    }

  return NULL_TREE;
}

/* Builds an expression for an indirection through T, simplifying some
   cases.  */

tree
build_fold_indirect_ref (tree t)
{
  tree type = TREE_TYPE (TREE_TYPE (t));
  tree sub = fold_indirect_ref_1 (type, t);

  if (sub)
    return sub;
  else
    return build1 (INDIRECT_REF, type, t);
}

/* Given an INDIRECT_REF T, return either T or a simplified version.  */

tree
fold_indirect_ref (tree t)
{
  tree sub = fold_indirect_ref_1 (TREE_TYPE (t), TREE_OPERAND (t, 0));

  if (sub)
    return sub;
  else
    return t;
}

/* Strip non-trapping, non-side-effecting tree nodes from an expression
   whose result is ignored.  The type of the returned tree need not be
   the same as the original expression.  */

tree
fold_ignored_result (tree t)
{
  if (!TREE_SIDE_EFFECTS (t))
    return integer_zero_node;

  for (;;)
    switch (TREE_CODE_CLASS (TREE_CODE (t)))
      {
      case tcc_unary:
	t = TREE_OPERAND (t, 0);
	break;

      case tcc_binary:
      case tcc_comparison:
	if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
	  t = TREE_OPERAND (t, 0);
	else if (!TREE_SIDE_EFFECTS (TREE_OPERAND (t, 0)))
	  t = TREE_OPERAND (t, 1);
	else
	  return t;
	break;

      case tcc_expression:
	switch (TREE_CODE (t))
	  {
	  case COMPOUND_EXPR:
	    if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1)))
	      return t;
	    t = TREE_OPERAND (t, 0);
	    break;

	  case COND_EXPR:
	    if (TREE_SIDE_EFFECTS (TREE_OPERAND (t, 1))
		|| TREE_SIDE_EFFECTS (TREE_OPERAND (t, 2)))
	      return t;
	    t = TREE_OPERAND (t, 0);
	    break;

	  default:
	    return t;
	  }
	break;

      default:
	return t;
      }
}

/* Return the value of VALUE, rounded up to a multiple of DIVISOR.
   This can only be applied to objects of a sizetype.  */

tree
round_up (tree value, int divisor)
{
  tree div = NULL_TREE;

  gcc_assert (divisor > 0);
  if (divisor == 1)
    return value;

  /* See if VALUE is already a multiple of DIVISOR.  If so, we don't
     have to do anything.  Only do this when we are not given a const,
     because in that case, this check is more expensive than just
     doing it.  */
  if (TREE_CODE (value) != INTEGER_CST)
    {
      div = build_int_cst (TREE_TYPE (value), divisor);

      if (multiple_of_p (TREE_TYPE (value), value, div))
	return value;
    }

  /* If divisor is a power of two, simplify this to bit manipulation.  */
  if (divisor == (divisor & -divisor))
    {
      tree t;

      t = build_int_cst (TREE_TYPE (value), divisor - 1);
      value = size_binop (PLUS_EXPR, value, t);
      t = build_int_cst (TREE_TYPE (value), -divisor);
      value = size_binop (BIT_AND_EXPR, value, t);
    }
  else
    {
      if (!div)
	div = build_int_cst (TREE_TYPE (value), divisor);
      value = size_binop (CEIL_DIV_EXPR, value, div);
      value = size_binop (MULT_EXPR, value, div);
    }

  return value;
}

/* Likewise, but round down.  */

tree
round_down (tree value, int divisor)
{
  tree div = NULL_TREE;

  gcc_assert (divisor > 0);
  if (divisor == 1)
    return value;

  /* See if VALUE is already a multiple of DIVISOR.  If so, we don't
     have to do anything.  Only do this when we are not given a const,
     because in that case, this check is more expensive than just
     doing it.  */
  if (TREE_CODE (value) != INTEGER_CST)
    {
      div = build_int_cst (TREE_TYPE (value), divisor);

      if (multiple_of_p (TREE_TYPE (value), value, div))
	return value;
    }

  /* If divisor is a power of two, simplify this to bit manipulation.  */
  if (divisor == (divisor & -divisor))
    {
      tree t;

      t = build_int_cst (TREE_TYPE (value), -divisor);
      value = size_binop (BIT_AND_EXPR, value, t);
    }
  else
    {
      if (!div)
	div = build_int_cst (TREE_TYPE (value), divisor);
      value = size_binop (FLOOR_DIV_EXPR, value, div);
      value = size_binop (MULT_EXPR, value, div);
    }

  return value;
}

/* Returns the pointer to the base of the object addressed by EXP and
   extracts the information about the offset of the access, storing it
   to PBITPOS and POFFSET.  */

static tree
split_address_to_core_and_offset (tree exp,
				  HOST_WIDE_INT *pbitpos, tree *poffset)
{
  tree core;
  enum machine_mode mode;
  int unsignedp, volatilep;
  HOST_WIDE_INT bitsize;

  if (TREE_CODE (exp) == ADDR_EXPR)
    {
      core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
				  poffset, &mode, &unsignedp, &volatilep,
				  false);
      core = build_fold_addr_expr (core);
    }
  else
    {
      core = exp;
      *pbitpos = 0;
      *poffset = NULL_TREE;
    }

  return core;
}

/* Returns true if addresses of E1 and E2 differ by a constant, false
   otherwise.  If they do, E1 - E2 is stored in *DIFF.  */

bool
ptr_difference_const (tree e1, tree e2, HOST_WIDE_INT *diff)
{
  tree core1, core2;
  HOST_WIDE_INT bitpos1, bitpos2;
  tree toffset1, toffset2, tdiff, type;

  core1 = split_address_to_core_and_offset (e1, &bitpos1, &toffset1);
  core2 = split_address_to_core_and_offset (e2, &bitpos2, &toffset2);

  if (bitpos1 % BITS_PER_UNIT != 0
      || bitpos2 % BITS_PER_UNIT != 0
      || !operand_equal_p (core1, core2, 0))
    return false;

  if (toffset1 && toffset2)
    {
      type = TREE_TYPE (toffset1);
      if (type != TREE_TYPE (toffset2))
	toffset2 = fold_convert (type, toffset2);

      tdiff = fold_build2 (MINUS_EXPR, type, toffset1, toffset2);
      if (!cst_and_fits_in_hwi (tdiff))
	return false;

      *diff = int_cst_value (tdiff);
    }
  else if (toffset1 || toffset2)
    {
      /* If only one of the offsets is non-constant, the difference cannot
	 be a constant.  */
      return false;
    }
  else
    *diff = 0;

  *diff += (bitpos1 - bitpos2) / BITS_PER_UNIT;
  return true;
}

/* Simplify the floating point expression EXP when the sign of the
   result is not significant.  Return NULL_TREE if no simplification
   is possible.  */

tree
fold_strip_sign_ops (tree exp)
{
  tree arg0, arg1;

  switch (TREE_CODE (exp))
    {
    case ABS_EXPR:
    case NEGATE_EXPR:
      arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 0));
      return arg0 ? arg0 : TREE_OPERAND (exp, 0);

    case MULT_EXPR:
    case RDIV_EXPR:
      if (HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (exp))))
	return NULL_TREE;
      arg0 = fold_strip_sign_ops (TREE_OPERAND (exp, 0));
      arg1 = fold_strip_sign_ops (TREE_OPERAND (exp, 1));
      if (arg0 != NULL_TREE || arg1 != NULL_TREE)
	return fold_build2 (TREE_CODE (exp), TREE_TYPE (exp),
			    arg0 ? arg0 : TREE_OPERAND (exp, 0),
			    arg1 ? arg1 : TREE_OPERAND (exp, 1));
      break;

    default:
      break;
    }
  return NULL_TREE;
}

