/* Fold a constant sub-tree into a single node for C-compiler
   Copyright (C) 1987-2021 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

/*@@ This 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 and size_binop.

   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'.

   Note: Since the folders get called on non-gimple code as well as
   gimple code, we need to handle GIMPLE tuples as well as their
   corresponding tree equivalents.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "predict.h"
#include "memmodel.h"
#include "tm_p.h"
#include "tree-ssa-operands.h"
#include "optabs-query.h"
#include "cgraph.h"
#include "diagnostic-core.h"
#include "flags.h"
#include "alias.h"
#include "fold-const.h"
#include "fold-const-call.h"
#include "stor-layout.h"
#include "calls.h"
#include "tree-iterator.h"
#include "expr.h"
#include "intl.h"
#include "langhooks.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "tree-dfa.h"
#include "builtins.h"
#include "generic-match.h"
#include "gimple-fold.h"
#include "tree-into-ssa.h"
#include "md5.h"
#include "case-cfn-macros.h"
#include "stringpool.h"
#include "tree-vrp.h"
#include "tree-ssanames.h"
#include "selftest.h"
#include "stringpool.h"
#include "attribs.h"
#include "tree-vector-builder.h"
#include "vec-perm-indices.h"
#include "asan.h"
#include "gimple-range.h"

/* Nonzero 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 bool negate_expr_p (tree);
static tree negate_expr (tree);
static tree associate_trees (location_t, tree, tree, enum tree_code, tree);
static enum comparison_code comparison_to_compcode (enum tree_code);
static enum tree_code compcode_to_comparison (enum comparison_code);
static bool twoval_comparison_p (tree, tree *, tree *);
static tree eval_subst (location_t, tree, tree, tree, tree, tree);
static tree optimize_bit_field_compare (location_t, enum tree_code,
					tree, tree, tree);
static bool simple_operand_p (const_tree);
static bool simple_operand_p_2 (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 fold_range_test (location_t, enum tree_code, tree, tree, tree);
static tree fold_cond_expr_with_comparison (location_t, tree, tree, tree, tree);
static tree unextend (tree, int, int, 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 tree fold_binary_op_with_conditional_arg (location_t,
						 enum tree_code, tree,
						 tree, tree,
						 tree, tree, int);
static tree fold_negate_const (tree, tree);
static tree fold_not_const (const_tree, tree);
static tree fold_relational_const (enum tree_code, tree, tree, tree);
static tree fold_convert_const (enum tree_code, tree, tree);
static tree fold_view_convert_expr (tree, tree);
static tree fold_negate_expr (location_t, tree);


/* Return EXPR_LOCATION of T if it is not UNKNOWN_LOCATION.
   Otherwise, return LOC.  */

static location_t
expr_location_or (tree t, location_t loc)
{
  location_t tloc = EXPR_LOCATION (t);
  return tloc == UNKNOWN_LOCATION ? loc : tloc;
}

/* Similar to protected_set_expr_location, but never modify x in place,
   if location can and needs to be set, unshare it.  */

static inline tree
protected_set_expr_location_unshare (tree x, location_t loc)
{
  if (CAN_HAVE_LOCATION_P (x)
      && EXPR_LOCATION (x) != loc
      && !(TREE_CODE (x) == SAVE_EXPR
	   || TREE_CODE (x) == TARGET_EXPR
	   || TREE_CODE (x) == BIND_EXPR))
    {
      x = copy_node (x);
      SET_EXPR_LOCATION (x, loc);
    }
  return x;
}

/* If ARG2 divides ARG1 with zero remainder, carries out the exact
   division and returns the quotient.  Otherwise returns
   NULL_TREE.  */

tree
div_if_zero_remainder (const_tree arg1, const_tree arg2)
{
  widest_int quo;

  if (wi::multiple_of_p (wi::to_widest (arg1), wi::to_widest (arg2),
			 SIGNED, &quo))
    return wide_int_to_tree (TREE_TYPE (arg1), quo);

  return NULL_TREE; 
}

/* This is nonzero 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, const gimple *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 = (enum warn_strict_overflow_code) code;
      return;
    }

  warnmsg = fold_deferred_overflow_warning;
  fold_deferred_overflow_warning = NULL;

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

  if (gimple_no_warning_p (stmt))
    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)
    locus = input_location;
  else
    locus = gimple_location (stmt);
  warning_at (locus, OPT_Wstrict_overflow, "%s", warnmsg);
}

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

void
fold_undefer_and_ignore_overflow_warnings (void)
{
  fold_undefer_overflow_warnings (false, NULL, 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.  */

void
fold_overflow_warning (const char* gmsgid, enum warn_strict_overflow_code wc)
{
  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).  */

bool
negate_mathfn_p (combined_fn fn)
{
  switch (fn)
    {
    CASE_CFN_ASIN:
    CASE_CFN_ASINH:
    CASE_CFN_ATAN:
    CASE_CFN_ATANH:
    CASE_CFN_CASIN:
    CASE_CFN_CASINH:
    CASE_CFN_CATAN:
    CASE_CFN_CATANH:
    CASE_CFN_CBRT:
    CASE_CFN_CPROJ:
    CASE_CFN_CSIN:
    CASE_CFN_CSINH:
    CASE_CFN_CTAN:
    CASE_CFN_CTANH:
    CASE_CFN_ERF:
    CASE_CFN_LLROUND:
    CASE_CFN_LROUND:
    CASE_CFN_ROUND:
    CASE_CFN_ROUNDEVEN:
    CASE_CFN_ROUNDEVEN_FN:
    CASE_CFN_SIN:
    CASE_CFN_SINH:
    CASE_CFN_TAN:
    CASE_CFN_TANH:
    CASE_CFN_TRUNC:
      return true;

    CASE_CFN_LLRINT:
    CASE_CFN_LRINT:
    CASE_CFN_NEARBYINT:
    CASE_CFN_RINT:
      return !flag_rounding_math;

    default:
      break;
    }
  return false;
}

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

bool
may_negate_without_overflow_p (const_tree t)
{
  tree type;

  gcc_assert (TREE_CODE (t) == INTEGER_CST);

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

  return !wi::only_sign_bit_p (wi::to_wide (t));
}

/* 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 (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (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 FIXED_CST:
      return true;

    case NEGATE_EXPR:
      return !TYPE_OVERFLOW_SANITIZED (type);

    case REAL_CST:
      /* We want to canonicalize to positive real constants.  Pretend
         that only negative ones can be easily negated.  */
      return REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));

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

    case VECTOR_CST:
      {
	if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type))
	  return true;

	/* Steps don't prevent negation.  */
	unsigned int count = vector_cst_encoded_nelts (t);
	for (unsigned int i = 0; i < count; ++i)
	  if (!negate_expr_p (VECTOR_CST_ENCODED_ELT (t, i)))
	    return false;

	return true;
      }

    case COMPLEX_EXPR:
      return negate_expr_p (TREE_OPERAND (t, 0))
	     && negate_expr_p (TREE_OPERAND (t, 1));

    case CONJ_EXPR:
      return negate_expr_p (TREE_OPERAND (t, 0));

    case PLUS_EXPR:
      if (HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
	  || HONOR_SIGNED_ZEROS (element_mode (type))
	  || (ANY_INTEGRAL_TYPE_P (type)
	      && ! TYPE_OVERFLOW_WRAPS (type)))
	return false;
      /* -(A + B) -> (-B) - A.  */
      if (negate_expr_p (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 !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
	     && !HONOR_SIGNED_ZEROS (element_mode (type))
	     && (! ANY_INTEGRAL_TYPE_P (type)
		 || TYPE_OVERFLOW_WRAPS (type));

    case MULT_EXPR:
      if (TYPE_UNSIGNED (type))
	break;
      /* INT_MIN/n * n doesn't overflow while negating one operand it does
         if n is a (negative) power of two.  */
      if (INTEGRAL_TYPE_P (TREE_TYPE (t))
	  && ! TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
	  && ! ((TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
		 && (wi::popcount
		     (wi::abs (wi::to_wide (TREE_OPERAND (t, 0))))) != 1)
		|| (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
		    && (wi::popcount
			(wi::abs (wi::to_wide (TREE_OPERAND (t, 1))))) != 1)))
	break;

      /* Fall through.  */

    case RDIV_EXPR:
      if (! HONOR_SIGN_DEPENDENT_ROUNDING (element_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 EXACT_DIV_EXPR:
      if (TYPE_UNSIGNED (type))
	break;
      /* In general we can't negate A in A / B, because if A is INT_MIN and
         B is not 1 we change the sign of the result.  */
      if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
	  && negate_expr_p (TREE_OPERAND (t, 0)))
	return true;
      /* In general we can't negate B in 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.  */
      if (! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t))
	  || TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
	  || (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
	      && ! integer_onep (TREE_OPERAND (t, 1))))
	return negate_expr_p (TREE_OPERAND (t, 1));
      break;

    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 (get_call_combined_fn (t)))
	return negate_expr_p (CALL_EXPR_ARG (t, 0));
      break;

    case RSHIFT_EXPR:
      /* Optimize -((int)x >> 31) into (unsigned)x >> 31 for int.  */
      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
	{
	  tree op1 = TREE_OPERAND (t, 1);
	  if (wi::to_wide (op1) == element_precision (type) - 1)
	    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_1 (location_t loc, 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_loc (loc, PLUS_EXPR, type, TREE_OPERAND (t, 0),
				build_one_cst (type));
      break;

    case INTEGER_CST:
      tem = fold_negate_const (t, type);
      if (TREE_OVERFLOW (tem) == TREE_OVERFLOW (t)
	  || (ANY_INTEGRAL_TYPE_P (type)
	      && !TYPE_OVERFLOW_TRAPS (type)
	      && TYPE_OVERFLOW_WRAPS (type))
	  || (flag_sanitize & SANITIZE_SI_OVERFLOW) == 0)
	return tem;
      break;

    case POLY_INT_CST:
    case REAL_CST:
    case FIXED_CST:
      tem = fold_negate_const (t, type);
      return tem;

    case COMPLEX_CST:
      {
	tree rpart = fold_negate_expr (loc, TREE_REALPART (t));
	tree ipart = fold_negate_expr (loc, TREE_IMAGPART (t));
	if (rpart && ipart)
	  return build_complex (type, rpart, ipart);
      }
      break;

    case VECTOR_CST:
      {
	tree_vector_builder elts;
	elts.new_unary_operation (type, t, true);
	unsigned int count = elts.encoded_nelts ();
	for (unsigned int i = 0; i < count; ++i)
	  {
	    tree elt = fold_negate_expr (loc, VECTOR_CST_ELT (t, i));
	    if (elt == NULL_TREE)
	      return NULL_TREE;
	    elts.quick_push (elt);
	  }

	return elts.build ();
      }

    case COMPLEX_EXPR:
      if (negate_expr_p (t))
	return fold_build2_loc (loc, COMPLEX_EXPR, type,
				fold_negate_expr (loc, TREE_OPERAND (t, 0)),
				fold_negate_expr (loc, TREE_OPERAND (t, 1)));
      break;

    case CONJ_EXPR:
      if (negate_expr_p (t))
	return fold_build1_loc (loc, CONJ_EXPR, type,
				fold_negate_expr (loc, TREE_OPERAND (t, 0)));
      break;

    case NEGATE_EXPR:
      if (!TYPE_OVERFLOW_SANITIZED (type))
	return TREE_OPERAND (t, 0);
      break;

    case PLUS_EXPR:
      if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
	  && !HONOR_SIGNED_ZEROS (element_mode (type)))
	{
	  /* -(A + B) -> (-B) - A.  */
	  if (negate_expr_p (TREE_OPERAND (t, 1)))
	    {
	      tem = negate_expr (TREE_OPERAND (t, 1));
	      return fold_build2_loc (loc, 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_loc (loc, MINUS_EXPR, type,
				      tem, TREE_OPERAND (t, 1));
	    }
	}
      break;

    case MINUS_EXPR:
      /* - (A - B) -> B - A  */
      if (!HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type))
	  && !HONOR_SIGNED_ZEROS (element_mode (type)))
	return fold_build2_loc (loc, 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 (element_mode (type)))
	{
	  tem = TREE_OPERAND (t, 1);
	  if (negate_expr_p (tem))
	    return fold_build2_loc (loc, TREE_CODE (t), type,
				    TREE_OPERAND (t, 0), negate_expr (tem));
	  tem = TREE_OPERAND (t, 0);
	  if (negate_expr_p (tem))
	    return fold_build2_loc (loc, TREE_CODE (t), type,
				    negate_expr (tem), TREE_OPERAND (t, 1));
	}
      break;

    case TRUNC_DIV_EXPR:
    case ROUND_DIV_EXPR:
    case EXACT_DIV_EXPR:
      if (TYPE_UNSIGNED (type))
	break;
      /* In general we can't negate A in A / B, because if A is INT_MIN and
	 B is not 1 we change the sign of the result.  */
      if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
	  && negate_expr_p (TREE_OPERAND (t, 0)))
	return fold_build2_loc (loc, TREE_CODE (t), type,
				negate_expr (TREE_OPERAND (t, 0)),
				TREE_OPERAND (t, 1));
      /* In general we can't negate B in 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.  */
      if ((! ANY_INTEGRAL_TYPE_P (TREE_TYPE (t))
	   || TYPE_OVERFLOW_WRAPS (TREE_TYPE (t))
	   || (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
	       && ! integer_onep (TREE_OPERAND (t, 1))))
	  && negate_expr_p (TREE_OPERAND (t, 1)))
	return fold_build2_loc (loc, TREE_CODE (t), type,
				TREE_OPERAND (t, 0),
				negate_expr (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 fold_convert_loc (loc, type, negate_expr (tem));
	}
      break;

    case CALL_EXPR:
      /* Negate -f(x) as f(-x).  */
      if (negate_mathfn_p (get_call_combined_fn (t))
	  && negate_expr_p (CALL_EXPR_ARG (t, 0)))
	{
	  tree fndecl, arg;

	  fndecl = get_callee_fndecl (t);
	  arg = negate_expr (CALL_EXPR_ARG (t, 0));
	  return build_call_expr_loc (loc, fndecl, 1, arg);
	}
      break;

    case RSHIFT_EXPR:
      /* Optimize -((int)x >> 31) into (unsigned)x >> 31 for int.  */
      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
	{
	  tree op1 = TREE_OPERAND (t, 1);
	  if (wi::to_wide (op1) == element_precision (type) - 1)
	    {
	      tree ntype = TYPE_UNSIGNED (type)
			   ? signed_type_for (type)
			   : unsigned_type_for (type);
	      tree temp = fold_convert_loc (loc, ntype, TREE_OPERAND (t, 0));
	      temp = fold_build2_loc (loc, RSHIFT_EXPR, ntype, temp, op1);
	      return fold_convert_loc (loc, type, temp);
	    }
	}
      break;

    default:
      break;
    }

  return NULL_TREE;
}

/* A wrapper for fold_negate_expr_1.  */

static tree
fold_negate_expr (location_t loc, tree t)
{
  tree type = TREE_TYPE (t);
  STRIP_SIGN_NOPS (t);
  tree tem = fold_negate_expr_1 (loc, t);
  if (tem == NULL_TREE)
    return NULL_TREE;
  return fold_convert_loc (loc, type, tem);
}

/* Like fold_negate_expr, but return a NEGATE_EXPR tree, if T cannot 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;
  location_t loc;

  if (t == NULL_TREE)
    return NULL_TREE;

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

  tem = fold_negate_expr (loc, t);
  if (!tem)
    tem = build1_loc (loc, NEGATE_EXPR, TREE_TYPE (t), t);
  return fold_convert_loc (loc, 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 a variable part is of pointer
   type, it is negated after converting to TYPE.  This prevents us from
   generating illegal MINUS pointer expression.  LOC is the location of
   the converted variable part.

   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, tree type, enum tree_code code,
	    tree *minus_varp, tree *conp, tree *minus_conp,
	    tree *litp, tree *minus_litp, int negate_p)
{
  tree var = 0;
  *minus_varp = 0;
  *conp = 0;
  *minus_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
      || TREE_CODE (in) == FIXED_CST)
    *litp = in;
  else if (TREE_CODE (in) == code
	   || ((! FLOAT_TYPE_P (TREE_TYPE (in)) || flag_associative_math)
	       && ! SAT_FIXED_POINT_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) == POINTER_PLUS_EXPR)
		   || (code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR)
		   || (code == MINUS_EXPR
		       && (TREE_CODE (in) == PLUS_EXPR
			   || TREE_CODE (in) == POINTER_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
	  || TREE_CODE (op0) == FIXED_CST)
	*litp = op0, op0 = 0;
      else if (TREE_CODE (op1) == INTEGER_CST || TREE_CODE (op1) == REAL_CST
	       || TREE_CODE (op1) == FIXED_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)
	*minus_conp = *conp, *conp = 0;
      if (neg_var_p && var)
	*minus_varp = var, var = 0;
    }
  else if (TREE_CONSTANT (in))
    *conp = in;
  else if (TREE_CODE (in) == BIT_NOT_EXPR
	   && code == PLUS_EXPR)
    {
      /* -1 - X is folded to ~X, undo that here.  Do _not_ do this
         when IN is constant.  */
      *litp = build_minus_one_cst (type);
      *minus_varp = TREE_OPERAND (in, 0);
    }
  else
    var = in;

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

  if (*litp
      && TREE_OVERFLOW_P (*litp))
    *litp = drop_tree_overflow (*litp);
  if (*minus_litp
      && TREE_OVERFLOW_P (*minus_litp))
    *minus_litp = drop_tree_overflow (*minus_litp);

  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.  LOC is the location of the new expression.  If
   we build an operation, do it in TYPE and with CODE.  */

static tree
associate_trees (location_t loc, tree t1, tree t2, enum tree_code code, tree type)
{
  if (t1 == 0)
    {
      gcc_assert (t2 == 0 || code != MINUS_EXPR);
      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) == PLUS_EXPR || TREE_CODE (t2) == PLUS_EXPR
      || TREE_CODE (t1) == MINUS_EXPR || TREE_CODE (t2) == MINUS_EXPR)
    {
      if (code == PLUS_EXPR)
	{
	  if (TREE_CODE (t1) == NEGATE_EXPR)
	    return build2_loc (loc, MINUS_EXPR, type,
			       fold_convert_loc (loc, type, t2),
			       fold_convert_loc (loc, type,
						 TREE_OPERAND (t1, 0)));
	  else if (TREE_CODE (t2) == NEGATE_EXPR)
	    return build2_loc (loc, MINUS_EXPR, type,
			       fold_convert_loc (loc, type, t1),
			       fold_convert_loc (loc, type,
						 TREE_OPERAND (t2, 0)));
	  else if (integer_zerop (t2))
	    return fold_convert_loc (loc, type, t1);
	}
      else if (code == MINUS_EXPR)
	{
	  if (integer_zerop (t2))
	    return fold_convert_loc (loc, type, t1);
	}

      return build2_loc (loc, code, type, fold_convert_loc (loc, type, t1),
			 fold_convert_loc (loc, type, t2));
    }

  return fold_build2_loc (loc, code, type, fold_convert_loc (loc, type, t1),
			  fold_convert_loc (loc, type, t2));
}

/* Check whether TYPE1 and TYPE2 are equivalent integer types, suitable
   for use in int_const_binop, size_binop and size_diffop.  */

static bool
int_binop_types_match_p (enum tree_code code, const_tree type1, const_tree type2)
{
  if (!INTEGRAL_TYPE_P (type1) && !POINTER_TYPE_P (type1))
    return false;
  if (!INTEGRAL_TYPE_P (type2) && !POINTER_TYPE_P (type2))
    return false;

  switch (code)
    {
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:
    case LROTATE_EXPR:
    case RROTATE_EXPR:
      return true;

    default:
      break;
    }

  return TYPE_UNSIGNED (type1) == TYPE_UNSIGNED (type2)
	 && TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
	 && TYPE_MODE (type1) == TYPE_MODE (type2);
}

/* Combine two wide ints ARG1 and ARG2 under operation CODE to produce
   a new constant in RES.  Return FALSE if we don't know how to
   evaluate CODE at compile-time.  */

bool
wide_int_binop (wide_int &res,
		enum tree_code code, const wide_int &arg1, const wide_int &arg2,
		signop sign, wi::overflow_type *overflow)
{
  wide_int tmp;
  *overflow = wi::OVF_NONE;
  switch (code)
    {
    case BIT_IOR_EXPR:
      res = wi::bit_or (arg1, arg2);
      break;

    case BIT_XOR_EXPR:
      res = wi::bit_xor (arg1, arg2);
      break;

    case BIT_AND_EXPR:
      res = wi::bit_and (arg1, arg2);
      break;

    case LSHIFT_EXPR:
      if (wi::neg_p (arg2))
	return false;
      res = wi::lshift (arg1, arg2);
      break;

    case RSHIFT_EXPR:
      if (wi::neg_p (arg2))
	return false;
      /* It's unclear from the C standard whether shifts can overflow.
	 The following code ignores overflow; perhaps a C standard
	 interpretation ruling is needed.  */
      res = wi::rshift (arg1, arg2, sign);
      break;

    case RROTATE_EXPR:
    case LROTATE_EXPR:
      if (wi::neg_p (arg2))
	{
	  tmp = -arg2;
	  if (code == RROTATE_EXPR)
	    code = LROTATE_EXPR;
	  else
	    code = RROTATE_EXPR;
	}
      else
        tmp = arg2;

      if (code == RROTATE_EXPR)
	res = wi::rrotate (arg1, tmp);
      else
	res = wi::lrotate (arg1, tmp);
      break;

    case PLUS_EXPR:
      res = wi::add (arg1, arg2, sign, overflow);
      break;

    case MINUS_EXPR:
      res = wi::sub (arg1, arg2, sign, overflow);
      break;

    case MULT_EXPR:
      res = wi::mul (arg1, arg2, sign, overflow);
      break;

    case MULT_HIGHPART_EXPR:
      res = wi::mul_high (arg1, arg2, sign);
      break;

    case TRUNC_DIV_EXPR:
    case EXACT_DIV_EXPR:
      if (arg2 == 0)
	return false;
      res = wi::div_trunc (arg1, arg2, sign, overflow);
      break;

    case FLOOR_DIV_EXPR:
      if (arg2 == 0)
	return false;
      res = wi::div_floor (arg1, arg2, sign, overflow);
      break;

    case CEIL_DIV_EXPR:
      if (arg2 == 0)
	return false;
      res = wi::div_ceil (arg1, arg2, sign, overflow);
      break;

    case ROUND_DIV_EXPR:
      if (arg2 == 0)
	return false;
      res = wi::div_round (arg1, arg2, sign, overflow);
      break;

    case TRUNC_MOD_EXPR:
      if (arg2 == 0)
	return false;
      res = wi::mod_trunc (arg1, arg2, sign, overflow);
      break;

    case FLOOR_MOD_EXPR:
      if (arg2 == 0)
	return false;
      res = wi::mod_floor (arg1, arg2, sign, overflow);
      break;

    case CEIL_MOD_EXPR:
      if (arg2 == 0)
	return false;
      res = wi::mod_ceil (arg1, arg2, sign, overflow);
      break;

    case ROUND_MOD_EXPR:
      if (arg2 == 0)
	return false;
      res = wi::mod_round (arg1, arg2, sign, overflow);
      break;

    case MIN_EXPR:
      res = wi::min (arg1, arg2, sign);
      break;

    case MAX_EXPR:
      res = wi::max (arg1, arg2, sign);
      break;

    default:
      return false;
    }
  return true;
}

/* Combine two poly int's ARG1 and ARG2 under operation CODE to
   produce a new constant in RES.  Return FALSE if we don't know how
   to evaluate CODE at compile-time.  */

static bool
poly_int_binop (poly_wide_int &res, enum tree_code code,
		const_tree arg1, const_tree arg2,
		signop sign, wi::overflow_type *overflow)
{
  gcc_assert (NUM_POLY_INT_COEFFS != 1);
  gcc_assert (poly_int_tree_p (arg1) && poly_int_tree_p (arg2));
  switch (code)
    {
    case PLUS_EXPR:
      res = wi::add (wi::to_poly_wide (arg1),
		     wi::to_poly_wide (arg2), sign, overflow);
      break;

    case MINUS_EXPR:
      res = wi::sub (wi::to_poly_wide (arg1),
		     wi::to_poly_wide (arg2), sign, overflow);
      break;

    case MULT_EXPR:
      if (TREE_CODE (arg2) == INTEGER_CST)
	res = wi::mul (wi::to_poly_wide (arg1),
		       wi::to_wide (arg2), sign, overflow);
      else if (TREE_CODE (arg1) == INTEGER_CST)
	res = wi::mul (wi::to_poly_wide (arg2),
		       wi::to_wide (arg1), sign, overflow);
      else
	return NULL_TREE;
      break;

    case LSHIFT_EXPR:
      if (TREE_CODE (arg2) == INTEGER_CST)
	res = wi::to_poly_wide (arg1) << wi::to_wide (arg2);
      else
	return false;
      break;

    case BIT_IOR_EXPR:
      if (TREE_CODE (arg2) != INTEGER_CST
	  || !can_ior_p (wi::to_poly_wide (arg1), wi::to_wide (arg2),
			 &res))
	return false;
      break;

    default:
      return false;
    }
  return true;
}

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

tree
int_const_binop (enum tree_code code, const_tree arg1, const_tree arg2,
		 int overflowable)
{
  poly_wide_int poly_res;
  tree type = TREE_TYPE (arg1);
  signop sign = TYPE_SIGN (type);
  wi::overflow_type overflow = wi::OVF_NONE;

  if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg2) == INTEGER_CST)
    {
      wide_int warg1 = wi::to_wide (arg1), res;
      wide_int warg2 = wi::to_wide (arg2, TYPE_PRECISION (type));
      if (!wide_int_binop (res, code, warg1, warg2, sign, &overflow))
	return NULL_TREE;
      poly_res = res;
    }
  else if (!poly_int_tree_p (arg1)
	   || !poly_int_tree_p (arg2)
	   || !poly_int_binop (poly_res, code, arg1, arg2, sign, &overflow))
    return NULL_TREE;
  return force_fit_type (type, poly_res, overflowable,
			 (((sign == SIGNED || overflowable == -1)
			   && overflow)
			  | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2)));
}

/* Return true if binary operation OP distributes over addition in operand
   OPNO, with the other operand being held constant.  OPNO counts from 1.  */

static bool
distributes_over_addition_p (tree_code op, int opno)
{
  switch (op)
    {
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
      return true;

    case LSHIFT_EXPR:
      return opno == 1;

    default:
      return false;
    }
}

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

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

  STRIP_NOPS (arg1);
  STRIP_NOPS (arg2);

  if (poly_int_tree_p (arg1) && poly_int_tree_p (arg2))
    {
      if (code == POINTER_PLUS_EXPR)
	return int_const_binop (PLUS_EXPR,
				arg1, fold_convert (TREE_TYPE (arg1), arg2));

      return int_const_binop (code, arg1, arg2);
    }

  if (TREE_CODE (arg1) == REAL_CST && TREE_CODE (arg2) == REAL_CST)
    {
      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 signaling NaN.  */
      if (HONOR_SNANS (mode)
	  && (REAL_VALUE_ISSIGNALING_NAN (d1)
	      || REAL_VALUE_ISSIGNALING_NAN (d2)))
	return NULL_TREE;

      /* Don't perform operation if it would raise a division
	 by zero exception.  */
      if (code == RDIV_EXPR
	  && real_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))
      {
	/* Make resulting NaN value to be qNaN when flag_signaling_nans
	   is off.  */
	d1.signalling = 0;
	t = build_real (type, d1);
	return t;
      }
      else if (REAL_VALUE_ISNAN (d2))
      {
	/* Make resulting NaN value to be qNaN when flag_signaling_nans
	   is off.  */
	d2.signalling = 0;
	t = build_real (type, d2);
	return t;
      }

      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
	   || (MODE_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);
      return t;
    }

  if (TREE_CODE (arg1) == FIXED_CST)
    {
      FIXED_VALUE_TYPE f1;
      FIXED_VALUE_TYPE f2;
      FIXED_VALUE_TYPE result;
      tree t, type;
      int sat_p;
      bool overflow_p;

      /* The following codes are handled by fixed_arithmetic.  */
      switch (code)
        {
	case PLUS_EXPR:
	case MINUS_EXPR:
	case MULT_EXPR:
	case TRUNC_DIV_EXPR:
	  if (TREE_CODE (arg2) != FIXED_CST)
	    return NULL_TREE;
	  f2 = TREE_FIXED_CST (arg2);
	  break;

	case LSHIFT_EXPR:
	case RSHIFT_EXPR:
	  {
	    if (TREE_CODE (arg2) != INTEGER_CST)
	      return NULL_TREE;
	    wi::tree_to_wide_ref w2 = wi::to_wide (arg2);
	    f2.data.high = w2.elt (1);
	    f2.data.low = w2.ulow ();
	    f2.mode = SImode;
	  }
	  break;

        default:
	  return NULL_TREE;
        }

      f1 = TREE_FIXED_CST (arg1);
      type = TREE_TYPE (arg1);
      sat_p = TYPE_SATURATING (type);
      overflow_p = fixed_arithmetic (&result, code, &f1, &f2, sat_p);
      t = build_fixed (type, result);
      /* Propagate overflow flags.  */
      if (overflow_p | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))
	TREE_OVERFLOW (t) = 1;
      return t;
    }

  if (TREE_CODE (arg1) == COMPLEX_CST && TREE_CODE (arg2) == 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);
	  imag = const_binop (code, i1, i2);
	  break;

	case MULT_EXPR:
	  if (COMPLEX_FLOAT_TYPE_P (type))
	    return do_mpc_arg2 (arg1, arg2, type,
				/* do_nonfinite= */ folding_initializer,
				mpc_mul);

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

	case RDIV_EXPR:
	  if (COMPLEX_FLOAT_TYPE_P (type))
	    return do_mpc_arg2 (arg1, arg2, type,
                                /* do_nonfinite= */ folding_initializer,
				mpc_div);
	  /* Fallthru. */
	case TRUNC_DIV_EXPR:
	case CEIL_DIV_EXPR:
	case FLOOR_DIV_EXPR:
	case ROUND_DIV_EXPR:
	  if (flag_complex_method == 0)
	  {
	    /* Keep this algorithm in sync with
	       tree-complex.c:expand_complex_div_straight().

	       Expand complex division to scalars, straightforward algorithm.
	       a / b = ((ar*br + ai*bi)/t) + i((ai*br - ar*bi)/t)
	       t = br*br + bi*bi
	    */
	    tree magsquared
	      = const_binop (PLUS_EXPR,
			     const_binop (MULT_EXPR, r2, r2),
			     const_binop (MULT_EXPR, i2, i2));
	    tree t1
	      = const_binop (PLUS_EXPR,
			     const_binop (MULT_EXPR, r1, r2),
			     const_binop (MULT_EXPR, i1, i2));
	    tree t2
	      = const_binop (MINUS_EXPR,
			     const_binop (MULT_EXPR, i1, r2),
			     const_binop (MULT_EXPR, r1, i2));

	    real = const_binop (code, t1, magsquared);
	    imag = const_binop (code, t2, magsquared);
	  }
	  else
	  {
	    /* Keep this algorithm in sync with
               tree-complex.c:expand_complex_div_wide().

	       Expand complex division to scalars, modified algorithm to minimize
	       overflow with wide input ranges.  */
	    tree compare = fold_build2 (LT_EXPR, boolean_type_node,
					fold_abs_const (r2, TREE_TYPE (type)),
					fold_abs_const (i2, TREE_TYPE (type)));

	    if (integer_nonzerop (compare))
	      {
		/* In the TRUE branch, we compute
		   ratio = br/bi;
		   div = (br * ratio) + bi;
		   tr = (ar * ratio) + ai;
		   ti = (ai * ratio) - ar;
		   tr = tr / div;
		   ti = ti / div;  */
		tree ratio = const_binop (code, r2, i2);
		tree div = const_binop (PLUS_EXPR, i2,
					const_binop (MULT_EXPR, r2, ratio));
		real = const_binop (MULT_EXPR, r1, ratio);
		real = const_binop (PLUS_EXPR, real, i1);
		real = const_binop (code, real, div);

		imag = const_binop (MULT_EXPR, i1, ratio);
		imag = const_binop (MINUS_EXPR, imag, r1);
		imag = const_binop (code, imag, div);
	      }
	    else
	      {
		/* In the FALSE branch, we compute
		   ratio = d/c;
		   divisor = (d * ratio) + c;
		   tr = (b * ratio) + a;
		   ti = b - (a * ratio);
		   tr = tr / div;
		   ti = ti / div;  */
		tree ratio = const_binop (code, i2, r2);
		tree div = const_binop (PLUS_EXPR, r2,
                                        const_binop (MULT_EXPR, i2, ratio));

		real = const_binop (MULT_EXPR, i1, ratio);
		real = const_binop (PLUS_EXPR, real, r1);
		real = const_binop (code, real, div);

		imag = const_binop (MULT_EXPR, r1, ratio);
		imag = const_binop (MINUS_EXPR, i1, imag);
		imag = const_binop (code, imag, div);
	      }
	  }
	  break;

	default:
	  return NULL_TREE;
	}

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

  if (TREE_CODE (arg1) == VECTOR_CST
      && TREE_CODE (arg2) == VECTOR_CST
      && known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)),
		   TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg2))))
    {
      tree type = TREE_TYPE (arg1);
      bool step_ok_p;
      if (VECTOR_CST_STEPPED_P (arg1)
	  && VECTOR_CST_STEPPED_P (arg2))
	/* We can operate directly on the encoding if:

	      a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
	    implies
	      (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)

	   Addition and subtraction are the supported operators
	   for which this is true.  */
	step_ok_p = (code == PLUS_EXPR || code == MINUS_EXPR);
      else if (VECTOR_CST_STEPPED_P (arg1))
	/* We can operate directly on stepped encodings if:

	     a3 - a2 == a2 - a1
	   implies:
	     (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)

	   which is true if (x -> x op c) distributes over addition.  */
	step_ok_p = distributes_over_addition_p (code, 1);
      else
	/* Similarly in reverse.  */
	step_ok_p = distributes_over_addition_p (code, 2);
      tree_vector_builder elts;
      if (!elts.new_binary_operation (type, arg1, arg2, step_ok_p))
	return NULL_TREE;
      unsigned int count = elts.encoded_nelts ();
      for (unsigned int i = 0; i < count; ++i)
	{
	  tree elem1 = VECTOR_CST_ELT (arg1, i);
	  tree elem2 = VECTOR_CST_ELT (arg2, i);

	  tree elt = const_binop (code, elem1, elem2);

	  /* It is possible that const_binop cannot handle the given
	     code and return NULL_TREE */
	  if (elt == NULL_TREE)
	    return NULL_TREE;
	  elts.quick_push (elt);
	}

      return elts.build ();
    }

  /* Shifts allow a scalar offset for a vector.  */
  if (TREE_CODE (arg1) == VECTOR_CST
      && TREE_CODE (arg2) == INTEGER_CST)
    {
      tree type = TREE_TYPE (arg1);
      bool step_ok_p = distributes_over_addition_p (code, 1);
      tree_vector_builder elts;
      if (!elts.new_unary_operation (type, arg1, step_ok_p))
	return NULL_TREE;
      unsigned int count = elts.encoded_nelts ();
      for (unsigned int i = 0; i < count; ++i)
	{
	  tree elem1 = VECTOR_CST_ELT (arg1, i);

	  tree elt = const_binop (code, elem1, arg2);

	  /* It is possible that const_binop cannot handle the given
	     code and return NULL_TREE.  */
	  if (elt == NULL_TREE)
	    return NULL_TREE;
	  elts.quick_push (elt);
	}

      return elts.build ();
    }
  return NULL_TREE;
}

/* Overload that adds a TYPE parameter to be able to dispatch
   to fold_relational_const.  */

tree
const_binop (enum tree_code code, tree type, tree arg1, tree arg2)
{
  if (TREE_CODE_CLASS (code) == tcc_comparison)
    return fold_relational_const (code, type, arg1, arg2);

  /* ???  Until we make the const_binop worker take the type of the
     result as argument put those cases that need it here.  */
  switch (code)
    {
    case VEC_SERIES_EXPR:
      if (CONSTANT_CLASS_P (arg1)
	  && CONSTANT_CLASS_P (arg2))
	return build_vec_series (type, arg1, arg2);
      return NULL_TREE;

    case COMPLEX_EXPR:
      if ((TREE_CODE (arg1) == REAL_CST
	   && TREE_CODE (arg2) == REAL_CST)
	  || (TREE_CODE (arg1) == INTEGER_CST
	      && TREE_CODE (arg2) == INTEGER_CST))
	return build_complex (type, arg1, arg2);
      return NULL_TREE;

    case POINTER_DIFF_EXPR:
      if (poly_int_tree_p (arg1) && poly_int_tree_p (arg2))
	{
	  poly_offset_int res = (wi::to_poly_offset (arg1)
				 - wi::to_poly_offset (arg2));
	  return force_fit_type (type, res, 1,
				 TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2));
	}
      return NULL_TREE;

    case VEC_PACK_TRUNC_EXPR:
    case VEC_PACK_FIX_TRUNC_EXPR:
    case VEC_PACK_FLOAT_EXPR:
      {
	unsigned int HOST_WIDE_INT out_nelts, in_nelts, i;

	if (TREE_CODE (arg1) != VECTOR_CST
	    || TREE_CODE (arg2) != VECTOR_CST)
	  return NULL_TREE;

	if (!VECTOR_CST_NELTS (arg1).is_constant (&in_nelts))
	  return NULL_TREE;

	out_nelts = in_nelts * 2;
	gcc_assert (known_eq (in_nelts, VECTOR_CST_NELTS (arg2))
		    && known_eq (out_nelts, TYPE_VECTOR_SUBPARTS (type)));

	tree_vector_builder elts (type, out_nelts, 1);
	for (i = 0; i < out_nelts; i++)
	  {
	    tree elt = (i < in_nelts
			? VECTOR_CST_ELT (arg1, i)
			: VECTOR_CST_ELT (arg2, i - in_nelts));
	    elt = fold_convert_const (code == VEC_PACK_TRUNC_EXPR
				      ? NOP_EXPR
				      : code == VEC_PACK_FLOAT_EXPR
				      ? FLOAT_EXPR : FIX_TRUNC_EXPR,
				      TREE_TYPE (type), elt);
	    if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt))
	      return NULL_TREE;
	    elts.quick_push (elt);
	  }

	return elts.build ();
      }

    case VEC_WIDEN_MULT_LO_EXPR:
    case VEC_WIDEN_MULT_HI_EXPR:
    case VEC_WIDEN_MULT_EVEN_EXPR:
    case VEC_WIDEN_MULT_ODD_EXPR:
      {
	unsigned HOST_WIDE_INT out_nelts, in_nelts, out, ofs, scale;

	if (TREE_CODE (arg1) != VECTOR_CST || TREE_CODE (arg2) != VECTOR_CST)
	  return NULL_TREE;

	if (!VECTOR_CST_NELTS (arg1).is_constant (&in_nelts))
	  return NULL_TREE;
	out_nelts = in_nelts / 2;
	gcc_assert (known_eq (in_nelts, VECTOR_CST_NELTS (arg2))
		    && known_eq (out_nelts, TYPE_VECTOR_SUBPARTS (type)));

	if (code == VEC_WIDEN_MULT_LO_EXPR)
	  scale = 0, ofs = BYTES_BIG_ENDIAN ? out_nelts : 0;
	else if (code == VEC_WIDEN_MULT_HI_EXPR)
	  scale = 0, ofs = BYTES_BIG_ENDIAN ? 0 : out_nelts;
	else if (code == VEC_WIDEN_MULT_EVEN_EXPR)
	  scale = 1, ofs = 0;
	else /* if (code == VEC_WIDEN_MULT_ODD_EXPR) */
	  scale = 1, ofs = 1;

	tree_vector_builder elts (type, out_nelts, 1);
	for (out = 0; out < out_nelts; out++)
	  {
	    unsigned int in = (out << scale) + ofs;
	    tree t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type),
					  VECTOR_CST_ELT (arg1, in));
	    tree t2 = fold_convert_const (NOP_EXPR, TREE_TYPE (type),
					  VECTOR_CST_ELT (arg2, in));

	    if (t1 == NULL_TREE || t2 == NULL_TREE)
	      return NULL_TREE;
	    tree elt = const_binop (MULT_EXPR, t1, t2);
	    if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt))
	      return NULL_TREE;
	    elts.quick_push (elt);
	  }

	return elts.build ();
      }

    default:;
    }

  if (TREE_CODE_CLASS (code) != tcc_binary)
    return NULL_TREE;

  /* Make sure type and arg0 have the same saturating flag.  */
  gcc_checking_assert (TYPE_SATURATING (type)
		       == TYPE_SATURATING (TREE_TYPE (arg1)));

  return const_binop (code, arg1, arg2);
}

/* Compute CODE ARG1 with resulting type TYPE with ARG1 being constant.
   Return zero if computing the constants is not possible.  */

tree
const_unop (enum tree_code code, tree type, tree arg0)
{
  /* Don't perform the operation, other than NEGATE and ABS, if
     flag_signaling_nans is on and the operand is a signaling NaN.  */
  if (TREE_CODE (arg0) == REAL_CST
      && HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
      && REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg0))
      && code != NEGATE_EXPR
      && code != ABS_EXPR
      && code != ABSU_EXPR)
    return NULL_TREE;

  switch (code)
    {
    CASE_CONVERT:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
    case FIXED_CONVERT_EXPR:
      return fold_convert_const (code, type, arg0);

    case ADDR_SPACE_CONVERT_EXPR:
      /* If the source address is 0, and the source address space
	 cannot have a valid object at 0, fold to dest type null.  */
      if (integer_zerop (arg0)
	  && !(targetm.addr_space.zero_address_valid
	       (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0))))))
	return fold_convert_const (code, type, arg0);
      break;

    case VIEW_CONVERT_EXPR:
      return fold_view_convert_expr (type, arg0);

    case NEGATE_EXPR:
      {
	/* Can't call fold_negate_const directly here as that doesn't
	   handle all cases and we might not be able to negate some
	   constants.  */
	tree tem = fold_negate_expr (UNKNOWN_LOCATION, arg0);
	if (tem && CONSTANT_CLASS_P (tem))
	  return tem;
	break;
      }

    case ABS_EXPR:
    case ABSU_EXPR:
      if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST)
	return fold_abs_const (arg0, type);
      break;

    case CONJ_EXPR:
      if (TREE_CODE (arg0) == COMPLEX_CST)
	{
	  tree ipart = fold_negate_const (TREE_IMAGPART (arg0),
					  TREE_TYPE (type));
	  return build_complex (type, TREE_REALPART (arg0), ipart);
	}
      break;

    case BIT_NOT_EXPR:
      if (TREE_CODE (arg0) == INTEGER_CST)
	return fold_not_const (arg0, type);
      else if (POLY_INT_CST_P (arg0))
	return wide_int_to_tree (type, -poly_int_cst_value (arg0));
      /* Perform BIT_NOT_EXPR on each element individually.  */
      else if (TREE_CODE (arg0) == VECTOR_CST)
	{
	  tree elem;

	  /* This can cope with stepped encodings because ~x == -1 - x.  */
	  tree_vector_builder elements;
	  elements.new_unary_operation (type, arg0, true);
	  unsigned int i, count = elements.encoded_nelts ();
	  for (i = 0; i < count; ++i)
	    {
	      elem = VECTOR_CST_ELT (arg0, i);
	      elem = const_unop (BIT_NOT_EXPR, TREE_TYPE (type), elem);
	      if (elem == NULL_TREE)
		break;
	      elements.quick_push (elem);
	    }
	  if (i == count)
	    return elements.build ();
	}
      break;

    case TRUTH_NOT_EXPR:
      if (TREE_CODE (arg0) == INTEGER_CST)
	return constant_boolean_node (integer_zerop (arg0), type);
      break;

    case REALPART_EXPR:
      if (TREE_CODE (arg0) == COMPLEX_CST)
	return fold_convert (type, TREE_REALPART (arg0));
      break;

    case IMAGPART_EXPR:
      if (TREE_CODE (arg0) == COMPLEX_CST)
	return fold_convert (type, TREE_IMAGPART (arg0));
      break;

    case VEC_UNPACK_LO_EXPR:
    case VEC_UNPACK_HI_EXPR:
    case VEC_UNPACK_FLOAT_LO_EXPR:
    case VEC_UNPACK_FLOAT_HI_EXPR:
    case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
    case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
      {
	unsigned HOST_WIDE_INT out_nelts, in_nelts, i;
	enum tree_code subcode;

	if (TREE_CODE (arg0) != VECTOR_CST)
	  return NULL_TREE;

	if (!VECTOR_CST_NELTS (arg0).is_constant (&in_nelts))
	  return NULL_TREE;
	out_nelts = in_nelts / 2;
	gcc_assert (known_eq (out_nelts, TYPE_VECTOR_SUBPARTS (type)));

	unsigned int offset = 0;
	if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR
				   || code == VEC_UNPACK_FLOAT_LO_EXPR
				   || code == VEC_UNPACK_FIX_TRUNC_LO_EXPR))
	  offset = out_nelts;

	if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR)
	  subcode = NOP_EXPR;
	else if (code == VEC_UNPACK_FLOAT_LO_EXPR
		 || code == VEC_UNPACK_FLOAT_HI_EXPR)
	  subcode = FLOAT_EXPR;
	else
	  subcode = FIX_TRUNC_EXPR;

	tree_vector_builder elts (type, out_nelts, 1);
	for (i = 0; i < out_nelts; i++)
	  {
	    tree elt = fold_convert_const (subcode, TREE_TYPE (type),
					   VECTOR_CST_ELT (arg0, i + offset));
	    if (elt == NULL_TREE || !CONSTANT_CLASS_P (elt))
	      return NULL_TREE;
	    elts.quick_push (elt);
	  }

	return elts.build ();
      }

    case VEC_DUPLICATE_EXPR:
      if (CONSTANT_CLASS_P (arg0))
	return build_vector_from_val (type, arg0);
      return NULL_TREE;

    default:
      break;
    }

  return NULL_TREE;
}

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

tree
size_int_kind (poly_int64 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 equivalent integer types, ala int_binop_types_match_p.
   If the operands are constant, so is the result.  */

tree
size_binop_loc (location_t loc, 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 (int_binop_types_match_p (code, TREE_TYPE (arg0),
                                       TREE_TYPE (arg1)));

  /* Handle the special case of two poly_int constants faster.  */
  if (poly_int_tree_p (arg0) && poly_int_tree_p (arg1))
    {
      /* And some specific cases even faster than that.  */
      if (code == PLUS_EXPR)
	{
	  if (integer_zerop (arg0)
	      && !TREE_OVERFLOW (tree_strip_any_location_wrapper (arg0)))
	    return arg1;
	  if (integer_zerop (arg1)
	      && !TREE_OVERFLOW (tree_strip_any_location_wrapper (arg1)))
	    return arg0;
	}
      else if (code == MINUS_EXPR)
	{
	  if (integer_zerop (arg1)
	      && !TREE_OVERFLOW (tree_strip_any_location_wrapper (arg1)))
	    return arg0;
	}
      else if (code == MULT_EXPR)
	{
	  if (integer_onep (arg0)
	      && !TREE_OVERFLOW (tree_strip_any_location_wrapper (arg0)))
	    return arg1;
	}

      /* Handle general case of two integer constants.  For sizetype
         constant calculations we always want to know about overflow,
	 even in the unsigned case.  */
      tree res = int_const_binop (code, arg0, arg1, -1);
      if (res != NULL_TREE)
	return res;
    }

  return fold_build2_loc (loc, 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_loc (location_t loc, tree arg0, tree arg1)
{
  tree type = TREE_TYPE (arg0);
  tree ctype;

  gcc_assert (int_binop_types_match_p (MINUS_EXPR, TREE_TYPE (arg0),
				       TREE_TYPE (arg1)));

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

  if (type == sizetype)
    ctype = ssizetype;
  else if (type == bitsizetype)
    ctype = sbitsizetype;
  else
    ctype = signed_type_for (type);

  /* 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_loc (loc, MINUS_EXPR,
			   fold_convert_loc (loc, ctype, arg0),
			   fold_convert_loc (loc, 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_loc (loc, ctype,
			     size_binop_loc (loc, MINUS_EXPR, arg0, arg1));
  else
    return size_binop_loc (loc, MINUS_EXPR, build_int_cst (ctype, 0),
			   fold_convert_loc (loc, ctype,
					     size_binop_loc (loc,
							     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, const_tree arg1)
{
  /* Given an integer constant, make new constant with new type,
     appropriately sign-extended or truncated.  Use widest_int
     so that any extension is done according ARG1's type.  */
  return force_fit_type (type, wi::to_widest (arg1),
			 !POINTER_TYPE_P (TREE_TYPE (arg1)),
			 TREE_OVERFLOW (arg1));
}

/* 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, const_tree arg1)
{
  bool overflow = false;
  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.  */

  wide_int val;
  REAL_VALUE_TYPE r;
  REAL_VALUE_TYPE x = TREE_REAL_CST (arg1);

  switch (code)
    {
    case FIX_TRUNC_EXPR:
      real_trunc (&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 = true;
      val = wi::zero (TYPE_PRECISION (type));
    }

  /* 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_less (&r, &l))
	{
	  overflow = true;
	  val = wi::to_wide (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_less (&u, &r))
	    {
	      overflow = true;
	      val = wi::to_wide (ut);
	    }
	}
    }

  if (! overflow)
    val = real_to_integer (&r, &overflow, TYPE_PRECISION (type));

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

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

static tree
fold_convert_const_int_from_fixed (tree type, const_tree arg1)
{
  tree t;
  double_int temp, temp_trunc;
  scalar_mode mode;

  /* Right shift FIXED_CST to temp by fbit.  */
  temp = TREE_FIXED_CST (arg1).data;
  mode = TREE_FIXED_CST (arg1).mode;
  if (GET_MODE_FBIT (mode) < HOST_BITS_PER_DOUBLE_INT)
    {
      temp = temp.rshift (GET_MODE_FBIT (mode),
			  HOST_BITS_PER_DOUBLE_INT,
			  SIGNED_FIXED_POINT_MODE_P (mode));

      /* Left shift temp to temp_trunc by fbit.  */
      temp_trunc = temp.lshift (GET_MODE_FBIT (mode),
				HOST_BITS_PER_DOUBLE_INT,
				SIGNED_FIXED_POINT_MODE_P (mode));
    }
  else
    {
      temp = double_int_zero;
      temp_trunc = double_int_zero;
    }

  /* If FIXED_CST is negative, we need to round the value toward 0.
     By checking if the fractional bits are not zero to add 1 to temp.  */
  if (SIGNED_FIXED_POINT_MODE_P (mode)
      && temp_trunc.is_negative ()
      && TREE_FIXED_CST (arg1).data != temp_trunc)
    temp += double_int_one;

  /* Given a fixed-point constant, make new constant with new type,
     appropriately sign-extended or truncated.  */
  t = force_fit_type (type, temp, -1,
		      (temp.is_negative ()
		       && (TYPE_UNSIGNED (type)
			   < TYPE_UNSIGNED (TREE_TYPE (arg1))))
		      | TREE_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, const_tree arg1)
{
  REAL_VALUE_TYPE value;
  tree t;

  /* Don't perform the operation if flag_signaling_nans is on
     and the operand is a signaling NaN.  */
  if (HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
      && REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg1)))
    return NULL_TREE; 

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

  /* If converting an infinity or NAN to a representation that doesn't
     have one, set the overflow bit so that we can produce some kind of
     error message at the appropriate point if necessary.  It's not the
     most user-friendly message, but it's better than nothing.  */
  if (REAL_VALUE_ISINF (TREE_REAL_CST (arg1))
      && !MODE_HAS_INFINITIES (TYPE_MODE (type)))
    TREE_OVERFLOW (t) = 1;
  else if (REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
	   && !MODE_HAS_NANS (TYPE_MODE (type)))
    TREE_OVERFLOW (t) = 1;
  /* Regular overflow, conversion produced an infinity in a mode that
     can't represent them.  */
  else if (!MODE_HAS_INFINITIES (TYPE_MODE (type))
	   && REAL_VALUE_ISINF (value)
	   && !REAL_VALUE_ISINF (TREE_REAL_CST (arg1)))
    TREE_OVERFLOW (t) = 1;
  else
    TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
  return t;
}

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

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

  real_convert_from_fixed (&value, SCALAR_FLOAT_TYPE_MODE (type),
			   &TREE_FIXED_CST (arg1));
  t = build_real (type, value);

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

/* A subroutine of fold_convert_const handling conversions a FIXED_CST
   to another fixed-point type.  */

static tree
fold_convert_const_fixed_from_fixed (tree type, const_tree arg1)
{
  FIXED_VALUE_TYPE value;
  tree t;
  bool overflow_p;

  overflow_p = fixed_convert (&value, SCALAR_TYPE_MODE (type),
			      &TREE_FIXED_CST (arg1), TYPE_SATURATING (type));
  t = build_fixed (type, value);

  /* Propagate overflow flags.  */
  if (overflow_p | TREE_OVERFLOW (arg1))
    TREE_OVERFLOW (t) = 1;
  return t;
}

/* A subroutine of fold_convert_const handling conversions an INTEGER_CST
   to a fixed-point type.  */

static tree
fold_convert_const_fixed_from_int (tree type, const_tree arg1)
{
  FIXED_VALUE_TYPE value;
  tree t;
  bool overflow_p;
  double_int di;

  gcc_assert (TREE_INT_CST_NUNITS (arg1) <= 2);

  di.low = TREE_INT_CST_ELT (arg1, 0);
  if (TREE_INT_CST_NUNITS (arg1) == 1)
    di.high = (HOST_WIDE_INT) di.low < 0 ? HOST_WIDE_INT_M1 : 0;
  else
    di.high = TREE_INT_CST_ELT (arg1, 1);

  overflow_p = fixed_convert_from_int (&value, SCALAR_TYPE_MODE (type), di,
				       TYPE_UNSIGNED (TREE_TYPE (arg1)),
				       TYPE_SATURATING (type));
  t = build_fixed (type, value);

  /* Propagate overflow flags.  */
  if (overflow_p | TREE_OVERFLOW (arg1))
    TREE_OVERFLOW (t) = 1;
  return t;
}

/* A subroutine of fold_convert_const handling conversions a REAL_CST
   to a fixed-point type.  */

static tree
fold_convert_const_fixed_from_real (tree type, const_tree arg1)
{
  FIXED_VALUE_TYPE value;
  tree t;
  bool overflow_p;

  overflow_p = fixed_convert_from_real (&value, SCALAR_TYPE_MODE (type),
					&TREE_REAL_CST (arg1),
					TYPE_SATURATING (type));
  t = build_fixed (type, value);

  /* Propagate overflow flags.  */
  if (overflow_p | TREE_OVERFLOW (arg1))
    TREE_OVERFLOW (t) = 1;
  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)
{
  tree arg_type = TREE_TYPE (arg1);
  if (arg_type == type)
    return arg1;

  /* We can't widen types, since the runtime value could overflow the
     original type before being extended to the new type.  */
  if (POLY_INT_CST_P (arg1)
      && (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
      && TYPE_PRECISION (type) <= TYPE_PRECISION (arg_type))
    return build_poly_int_cst (type,
			       poly_wide_int::from (poly_int_cst_value (arg1),
						    TYPE_PRECISION (type),
						    TYPE_SIGN (arg_type)));

  if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type)
      || TREE_CODE (type) == OFFSET_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 (arg1) == FIXED_CST)
	return fold_convert_const_int_from_fixed (type, arg1);
    }
  else if (TREE_CODE (type) == REAL_TYPE)
    {
      if (TREE_CODE (arg1) == INTEGER_CST)
	return build_real_from_int_cst (type, arg1);
      else if (TREE_CODE (arg1) == REAL_CST)
	return fold_convert_const_real_from_real (type, arg1);
      else if (TREE_CODE (arg1) == FIXED_CST)
	return fold_convert_const_real_from_fixed (type, arg1);
    }
  else if (TREE_CODE (type) == FIXED_POINT_TYPE)
    {
      if (TREE_CODE (arg1) == FIXED_CST)
	return fold_convert_const_fixed_from_fixed (type, arg1);
      else if (TREE_CODE (arg1) == INTEGER_CST)
	return fold_convert_const_fixed_from_int (type, arg1);
      else if (TREE_CODE (arg1) == REAL_CST)
	return fold_convert_const_fixed_from_real (type, arg1);
    }
  else if (TREE_CODE (type) == VECTOR_TYPE)
    {
      if (TREE_CODE (arg1) == VECTOR_CST
	  && known_eq (TYPE_VECTOR_SUBPARTS (type), VECTOR_CST_NELTS (arg1)))
	{
	  tree elttype = TREE_TYPE (type);
	  tree arg1_elttype = TREE_TYPE (TREE_TYPE (arg1));
	  /* We can't handle steps directly when extending, since the
	     values need to wrap at the original precision first.  */
	  bool step_ok_p
	    = (INTEGRAL_TYPE_P (elttype)
	       && INTEGRAL_TYPE_P (arg1_elttype)
	       && TYPE_PRECISION (elttype) <= TYPE_PRECISION (arg1_elttype));
	  tree_vector_builder v;
	  if (!v.new_unary_operation (type, arg1, step_ok_p))
	    return NULL_TREE;
	  unsigned int len = v.encoded_nelts ();
	  for (unsigned int i = 0; i < len; ++i)
	    {
	      tree elt = VECTOR_CST_ELT (arg1, i);
	      tree cvt = fold_convert_const (code, elttype, elt);
	      if (cvt == NULL_TREE)
		return NULL_TREE;
	      v.quick_push (cvt);
	    }
	  return v.build ();
	}
    }
  return NULL_TREE;
}

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

static tree
build_zero_vector (tree type)
{
  tree t;

  t = fold_convert_const (NOP_EXPR, TREE_TYPE (type), integer_zero_node);
  return build_vector_from_val (type, t);
}

/* Returns true, if ARG is convertible to TYPE using a NOP_EXPR.  */

bool
fold_convertible_p (const_tree type, const_tree arg)
{
  tree orig = TREE_TYPE (arg);

  if (type == orig)
    return true;

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

  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig))
    return true;

  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
    case POINTER_TYPE: case REFERENCE_TYPE:
    case OFFSET_TYPE:
      return (INTEGRAL_TYPE_P (orig)
	      || (POINTER_TYPE_P (orig)
		  && TYPE_PRECISION (type) <= TYPE_PRECISION (orig))
	      || TREE_CODE (orig) == OFFSET_TYPE);

    case REAL_TYPE:
    case FIXED_POINT_TYPE:
    case VOID_TYPE:
      return TREE_CODE (type) == TREE_CODE (orig);

    case VECTOR_TYPE:
      return (VECTOR_TYPE_P (orig)
	      && known_eq (TYPE_VECTOR_SUBPARTS (type),
			   TYPE_VECTOR_SUBPARTS (orig))
	      && fold_convertible_p (TREE_TYPE (type), TREE_TYPE (orig)));

    default:
      return false;
    }
}

/* 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_loc (location_t loc, 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;

  switch (TREE_CODE (type))
    {
    case POINTER_TYPE:
    case REFERENCE_TYPE:
      /* Handle conversions between pointers to different address spaces.  */
      if (POINTER_TYPE_P (orig)
	  && (TYPE_ADDR_SPACE (TREE_TYPE (type))
	      != TYPE_ADDR_SPACE (TREE_TYPE (orig))))
	return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, arg);
      /* fall through */

    case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_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_loc (loc, NOP_EXPR, type, arg);
      if (TREE_CODE (orig) == COMPLEX_TYPE)
	return fold_convert_loc (loc, type,
				 fold_build1_loc (loc, REALPART_EXPR,
						  TREE_TYPE (orig), arg));
      gcc_assert (TREE_CODE (orig) == VECTOR_TYPE
		  && tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (orig)));
      return fold_build1_loc (loc, VIEW_CONVERT_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;
	}
      else if (TREE_CODE (arg) == FIXED_CST)
	{
	  tem = fold_convert_const (FIXED_CONVERT_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_loc (loc, FLOAT_EXPR, type, arg);

	case REAL_TYPE:
	  return fold_build1_loc (loc, NOP_EXPR, type, arg);

	case FIXED_POINT_TYPE:
	  return fold_build1_loc (loc, FIXED_CONVERT_EXPR, type, arg);

	case COMPLEX_TYPE:
	  tem = fold_build1_loc (loc, REALPART_EXPR, TREE_TYPE (orig), arg);
	  return fold_convert_loc (loc, type, tem);

	default:
	  gcc_unreachable ();
	}

    case FIXED_POINT_TYPE:
      if (TREE_CODE (arg) == FIXED_CST || TREE_CODE (arg) == INTEGER_CST
	  || TREE_CODE (arg) == REAL_CST)
	{
	  tem = fold_convert_const (FIXED_CONVERT_EXPR, type, arg);
	  if (tem != NULL_TREE)
	    goto fold_convert_exit;
	}

      switch (TREE_CODE (orig))
	{
	case FIXED_POINT_TYPE:
	case INTEGER_TYPE:
	case ENUMERAL_TYPE:
	case BOOLEAN_TYPE:
	case REAL_TYPE:
	  return fold_build1_loc (loc, FIXED_CONVERT_EXPR, type, arg);

	case COMPLEX_TYPE:
	  tem = fold_build1_loc (loc, REALPART_EXPR, TREE_TYPE (orig), arg);
	  return fold_convert_loc (loc, 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:
	case FIXED_POINT_TYPE:
	  return fold_build2_loc (loc, COMPLEX_EXPR, type,
			      fold_convert_loc (loc, TREE_TYPE (type), arg),
			      fold_convert_loc (loc, TREE_TYPE (type),
					    integer_zero_node));
	case COMPLEX_TYPE:
	  {
	    tree rpart, ipart;

	    if (TREE_CODE (arg) == COMPLEX_EXPR)
	      {
		rpart = fold_convert_loc (loc, TREE_TYPE (type),
				      TREE_OPERAND (arg, 0));
		ipart = fold_convert_loc (loc, TREE_TYPE (type),
				      TREE_OPERAND (arg, 1));
		return fold_build2_loc (loc, COMPLEX_EXPR, type, rpart, ipart);
	      }

	    arg = save_expr (arg);
	    rpart = fold_build1_loc (loc, REALPART_EXPR, TREE_TYPE (orig), arg);
	    ipart = fold_build1_loc (loc, IMAGPART_EXPR, TREE_TYPE (orig), arg);
	    rpart = fold_convert_loc (loc, TREE_TYPE (type), rpart);
	    ipart = fold_convert_loc (loc, TREE_TYPE (type), ipart);
	    return fold_build2_loc (loc, 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_loc (loc, VIEW_CONVERT_EXPR, type, arg);

    case VOID_TYPE:
      tem = fold_ignored_result (arg);
      return fold_build1_loc (loc, NOP_EXPR, type, tem);

    default:
      if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig))
	return fold_build1_loc (loc, NOP_EXPR, type, arg);
      gcc_unreachable ();
    }
 fold_convert_exit:
  protected_set_expr_location_unshare (tem, loc);
  return tem;
}

/* Return false if expr can be assumed not to be an lvalue, true
   otherwise.  */

static bool
maybe_lvalue_p (const_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 MEM_REF:
  case 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 VIEW_CONVERT_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_loc (location_t loc, 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_loc (loc, NON_LVALUE_EXPR, TREE_TYPE (x), x);
}

/* Given a tree comparison code, return the code that is the logical inverse.
   It is generally not safe to do this for floating-point comparisons, except
   for EQ_EXPR, NE_EXPR, ORDERED_EXPR and UNORDERED_EXPR, so we return
   ERROR_MARK in this case.  */

enum tree_code
invert_tree_comparison (enum tree_code code, bool honor_nans)
{
  if (honor_nans && flag_trapping_math && code != EQ_EXPR && code != NE_EXPR
      && code != ORDERED_EXPR && code != UNORDERED_EXPR)
    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 true if COND1 tests the opposite condition of COND2.  */

bool
inverse_conditions_p (const_tree cond1, const_tree cond2)
{
  return (COMPARISON_CLASS_P (cond1)
	  && COMPARISON_CLASS_P (cond2)
	  && (invert_tree_comparison
	      (TREE_CODE (cond1),
	       HONOR_NANS (TREE_OPERAND (cond1, 0))) == TREE_CODE (cond2))
	  && operand_equal_p (TREE_OPERAND (cond1, 0),
			      TREE_OPERAND (cond2, 0), 0)
	  && operand_equal_p (TREE_OPERAND (cond1, 1),
			      TREE_OPERAND (cond2, 1), 0));
}

/* 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 (location_t loc,
		     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 (ll_arg);
  enum comparison_code lcompcode = comparison_to_compcode (lcode);
  enum comparison_code rcompcode = comparison_to_compcode (rcode);
  int 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
    {
      enum tree_code tcode;

      tcode = compcode_to_comparison ((enum comparison_code) compcode);
      return fold_build2_loc (loc, tcode, truth_type, ll_arg, lr_arg);
    }
}

/* Return nonzero if two operands (typically of the same tree node)
   are necessarily equal. 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.

   If OEP_ADDRESS_OF is set, we are actually comparing addresses of objects,
   not values of expressions.

   If OEP_LEXICOGRAPHIC is set, then also handle expressions with side-effects
   such as MODIFY_EXPR, RETURN_EXPR, as well as STATEMENT_LISTs.

   If OEP_BITWISE is set, then require the values to be bitwise identical
   rather than simply numerically equal.  Do not take advantage of things
   like math-related flags or undefined behavior; only return true for
   values that are provably bitwise identical in all circumstances.

   Unless OEP_MATCH_SIDE_EFFECTS is set, the function returns false on
   any operand with side effect.  This is unnecesarily conservative in the
   case we know that arg0 and arg1 are in disjoint code paths (such as in
   ?: operator).  In addition OEP_MATCH_SIDE_EFFECTS is used when comparing
   addresses with TREE_CONSTANT flag set so we know that &var == &var
   even if var is volatile.  */

bool
operand_compare::operand_equal_p (const_tree arg0, const_tree arg1,
				  unsigned int flags)
{
  bool r;
  if (verify_hash_value (arg0, arg1, flags, &r))
    return r;

  STRIP_ANY_LOCATION_WRAPPER (arg0);
  STRIP_ANY_LOCATION_WRAPPER (arg1);

  /* If either is ERROR_MARK, they aren't equal.  */
  if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK
      || TREE_TYPE (arg0) == error_mark_node
      || TREE_TYPE (arg1) == error_mark_node)
    return false;

  /* Similar, if either does not have a type (like a template id),
     they aren't equal.  */
  if (!TREE_TYPE (arg0) || !TREE_TYPE (arg1))
    return false;

  /* Bitwise identity makes no sense if the values have different layouts.  */
  if ((flags & OEP_BITWISE)
      && !tree_nop_conversion_p (TREE_TYPE (arg0), TREE_TYPE (arg1)))
    return false;

  /* We cannot consider pointers to different address space equal.  */
  if (POINTER_TYPE_P (TREE_TYPE (arg0))
      && POINTER_TYPE_P (TREE_TYPE (arg1))
      && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0)))
	  != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1)))))
    return false;

  /* Check equality of integer constants before bailing out due to
     precision differences.  */
  if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
    {
      /* Address of INTEGER_CST is not defined; check that we did not forget
	 to drop the OEP_ADDRESS_OF flags.  */
      gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
      return tree_int_cst_equal (arg0, arg1);
    }

  if (!(flags & OEP_ADDRESS_OF))
    {
      /* 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.  As pointers
	 strictly don't have a signedness, require either two pointers or
	 two non-pointers as well.  */
      if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1))
	  || POINTER_TYPE_P (TREE_TYPE (arg0))
			     != POINTER_TYPE_P (TREE_TYPE (arg1)))
	return false;

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

      STRIP_NOPS (arg0);
      STRIP_NOPS (arg1);
    }
#if 0
  /* FIXME: Fortran FE currently produce ADDR_EXPR of NOP_EXPR. Enable the
     sanity check once the issue is solved.  */
  else
    /* Addresses of conversions and SSA_NAMEs (and many other things)
       are not defined.  Check that we did not forget to drop the
       OEP_ADDRESS_OF/OEP_CONSTANT_ADDRESS_OF flags.  */
    gcc_checking_assert (!CONVERT_EXPR_P (arg0) && !CONVERT_EXPR_P (arg1)
			 && TREE_CODE (arg0) != SSA_NAME);
#endif

  /* 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))
    {
      /* NOP_EXPR and CONVERT_EXPR are considered equal.  */
      if (CONVERT_EXPR_P (arg0) && CONVERT_EXPR_P (arg1))
	;
      else if (flags & OEP_ADDRESS_OF)
	{
	  /* If we are interested in comparing addresses ignore
	     MEM_REF wrappings of the base that can appear just for
	     TBAA reasons.  */
	  if (TREE_CODE (arg0) == MEM_REF
	      && DECL_P (arg1)
	      && TREE_CODE (TREE_OPERAND (arg0, 0)) == ADDR_EXPR
	      && TREE_OPERAND (TREE_OPERAND (arg0, 0), 0) == arg1
	      && integer_zerop (TREE_OPERAND (arg0, 1)))
	    return true;
	  else if (TREE_CODE (arg1) == MEM_REF
		   && DECL_P (arg0)
		   && TREE_CODE (TREE_OPERAND (arg1, 0)) == ADDR_EXPR
		   && TREE_OPERAND (TREE_OPERAND (arg1, 0), 0) == arg0
		   && integer_zerop (TREE_OPERAND (arg1, 1)))
	    return true;
	  return false;
	}
      else
	return false;
    }

  /* When not checking adddresses, this is needed for conversions and for
     COMPONENT_REF.  Might as well play it safe and always test this.  */
  if (TREE_CODE (TREE_TYPE (arg0)) == ERROR_MARK
      || TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK
      || (TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1))
	  && !(flags & OEP_ADDRESS_OF)))
    return false;

  /* 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 we are taking an invariant address of two identical objects
     they are necessarily equal as well.  */
  if (arg0 == arg1 && ! (flags & OEP_ONLY_CONST)
      && (TREE_CODE (arg0) == SAVE_EXPR
	  || (flags & OEP_MATCH_SIDE_EFFECTS)
	  || (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
    return true;

  /* 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_int_cst_equal (arg0, arg1);

      case FIXED_CST:
	return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (arg0),
				       TREE_FIXED_CST (arg1));

      case REAL_CST:
	if (real_identical (&TREE_REAL_CST (arg0), &TREE_REAL_CST (arg1)))
	  return true;

	if (!(flags & OEP_BITWISE) && !HONOR_SIGNED_ZEROS (arg0))
	  {
	    /* If we do not distinguish between signed and unsigned zero,
	       consider them equal.  */
	    if (real_zerop (arg0) && real_zerop (arg1))
	      return true;
	  }
	return false;

      case VECTOR_CST:
	{
	  if (VECTOR_CST_LOG2_NPATTERNS (arg0)
	      != VECTOR_CST_LOG2_NPATTERNS (arg1))
	    return false;

	  if (VECTOR_CST_NELTS_PER_PATTERN (arg0)
	      != VECTOR_CST_NELTS_PER_PATTERN (arg1))
	    return false;

	  unsigned int count = vector_cst_encoded_nelts (arg0);
	  for (unsigned int i = 0; i < count; ++i)
	    if (!operand_equal_p (VECTOR_CST_ENCODED_ELT (arg0, i),
				  VECTOR_CST_ENCODED_ELT (arg1, i), flags))
	      return false;
	  return true;
	}

      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:
	gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
	return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
				flags | OEP_ADDRESS_OF
				| OEP_MATCH_SIDE_EFFECTS);
      case CONSTRUCTOR:
	/* In GIMPLE empty constructors are allowed in initializers of
	   aggregates.  */
	return !CONSTRUCTOR_NELTS (arg0) && !CONSTRUCTOR_NELTS (arg1);
      default:
	break;
      }

  /* Don't handle more cases for OEP_BITWISE, since we can't guarantee that
     two instances of undefined behavior will give identical results.  */
  if (flags & (OEP_ONLY_CONST | OEP_BITWISE))
    return false;

/* 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_CONVERT:
        case FIX_TRUNC_EXPR:
	  if (TYPE_UNSIGNED (TREE_TYPE (arg0))
	      != TYPE_UNSIGNED (TREE_TYPE (arg1)))
	    return false;
	  break;
	default:
	  break;
	}

      return OP_SAME (0);


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

      /* 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,
	 but their addresses can be.  */
      if ((flags & OEP_MATCH_SIDE_EFFECTS) == 0
	  && (TREE_SIDE_EFFECTS (arg0)
	      || TREE_SIDE_EFFECTS (arg1)))
	return false;

      switch (TREE_CODE (arg0))
	{
	case INDIRECT_REF:
	  if (!(flags & OEP_ADDRESS_OF))
	    {
	      if (TYPE_ALIGN (TREE_TYPE (arg0))
		  != TYPE_ALIGN (TREE_TYPE (arg1)))
		return false;
	      /* Verify that the access types are compatible.  */
	      if (TYPE_MAIN_VARIANT (TREE_TYPE (arg0))
		  != TYPE_MAIN_VARIANT (TREE_TYPE (arg1)))
		return false;
	    }
	  flags &= ~OEP_ADDRESS_OF;
	  return OP_SAME (0);

	case IMAGPART_EXPR:
	  /* Require the same offset.  */
	  if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)),
				TYPE_SIZE (TREE_TYPE (arg1)),
				flags & ~OEP_ADDRESS_OF))
	    return false;

	/* Fallthru.  */
	case REALPART_EXPR:
	case VIEW_CONVERT_EXPR:
	  return OP_SAME (0);

	case TARGET_MEM_REF:
	case MEM_REF:
	  if (!(flags & OEP_ADDRESS_OF))
	    {
	      /* Require equal access sizes */
	      if (TYPE_SIZE (TREE_TYPE (arg0)) != TYPE_SIZE (TREE_TYPE (arg1))
		  && (!TYPE_SIZE (TREE_TYPE (arg0))
		      || !TYPE_SIZE (TREE_TYPE (arg1))
		      || !operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)),
					   TYPE_SIZE (TREE_TYPE (arg1)),
					   flags)))
		return false;
	      /* Verify that access happens in similar types.  */
	      if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1)))
		return false;
	      /* Verify that accesses are TBAA compatible.  */
	      if (!alias_ptr_types_compatible_p
		    (TREE_TYPE (TREE_OPERAND (arg0, 1)),
		     TREE_TYPE (TREE_OPERAND (arg1, 1)))
		  || (MR_DEPENDENCE_CLIQUE (arg0)
		      != MR_DEPENDENCE_CLIQUE (arg1))
		  || (MR_DEPENDENCE_BASE (arg0)
		      != MR_DEPENDENCE_BASE (arg1)))
		return false;
	     /* Verify that alignment is compatible.  */
	     if (TYPE_ALIGN (TREE_TYPE (arg0))
		 != TYPE_ALIGN (TREE_TYPE (arg1)))
		return false;
	    }
	  flags &= ~OEP_ADDRESS_OF;
	  return (OP_SAME (0) && OP_SAME (1)
		  /* TARGET_MEM_REF require equal extra operands.  */
		  && (TREE_CODE (arg0) != TARGET_MEM_REF
		      || (OP_SAME_WITH_NULL (2)
			  && OP_SAME_WITH_NULL (3)
			  && OP_SAME_WITH_NULL (4))));

	case ARRAY_REF:
	case ARRAY_RANGE_REF:
	  if (!OP_SAME (0))
	    return false;
	  flags &= ~OEP_ADDRESS_OF;
	  /* Compare the array index by value if it is constant first as we
	     may have different types but same value here.  */
	  return ((tree_int_cst_equal (TREE_OPERAND (arg0, 1),
				       TREE_OPERAND (arg1, 1))
		   || OP_SAME (1))
		  && OP_SAME_WITH_NULL (2)
		  && OP_SAME_WITH_NULL (3)
		  /* Compare low bound and element size as with OEP_ADDRESS_OF
		     we have to account for the offset of the ref.  */
		  && (TREE_TYPE (TREE_OPERAND (arg0, 0))
		      == TREE_TYPE (TREE_OPERAND (arg1, 0))
		      || (operand_equal_p (array_ref_low_bound
					     (CONST_CAST_TREE (arg0)),
					   array_ref_low_bound
					     (CONST_CAST_TREE (arg1)), flags)
			  && operand_equal_p (array_ref_element_size
					        (CONST_CAST_TREE (arg0)),
					      array_ref_element_size
					        (CONST_CAST_TREE (arg1)),
					      flags))));

	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.  */
	  if (!OP_SAME_WITH_NULL (0))
	    return false;
	  {
	    bool compare_address = flags & OEP_ADDRESS_OF;

	    /* Most of time we only need to compare FIELD_DECLs for equality.
	       However when determining address look into actual offsets.
	       These may match for unions and unshared record types.  */
	    flags &= ~OEP_ADDRESS_OF;
	    if (!OP_SAME (1))
	      {
		if (compare_address
		    && (flags & OEP_ADDRESS_OF_SAME_FIELD) == 0)
		  {
		    if (TREE_OPERAND (arg0, 2)
			|| TREE_OPERAND (arg1, 2))
		      return OP_SAME_WITH_NULL (2);
		    tree field0 = TREE_OPERAND (arg0, 1);
		    tree field1 = TREE_OPERAND (arg1, 1);

		    if (!operand_equal_p (DECL_FIELD_OFFSET (field0),
					  DECL_FIELD_OFFSET (field1), flags)
			|| !operand_equal_p (DECL_FIELD_BIT_OFFSET (field0),
					     DECL_FIELD_BIT_OFFSET (field1),
					     flags))
		      return false;
		  }
		else
		  return false;
	      }
	  }
	  return OP_SAME_WITH_NULL (2);

	case BIT_FIELD_REF:
	  if (!OP_SAME (0))
	    return false;
	  flags &= ~OEP_ADDRESS_OF;
	  return OP_SAME (1) && OP_SAME (2);

	default:
	  return false;
	}

    case tcc_expression:
      switch (TREE_CODE (arg0))
	{
	case ADDR_EXPR:
	  /* Be sure we pass right ADDRESS_OF flag.  */
	  gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
	  return operand_equal_p (TREE_OPERAND (arg0, 0),
				  TREE_OPERAND (arg1, 0),
				  flags | OEP_ADDRESS_OF);

	case TRUTH_NOT_EXPR:
	  return OP_SAME (0);

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

	case WIDEN_MULT_PLUS_EXPR:
	case WIDEN_MULT_MINUS_EXPR:
	  if (!OP_SAME (2))
	    return false;
	  /* The multiplcation operands are commutative.  */
	  /* FALLTHRU */

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

	  /* 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 COND_EXPR:
	  if (! OP_SAME (1) || ! OP_SAME_WITH_NULL (2))
	    return false;
	  flags &= ~OEP_ADDRESS_OF;
	  return OP_SAME (0);

	case BIT_INSERT_EXPR:
	  /* BIT_INSERT_EXPR has an implict operand as the type precision
	     of op1.  Need to check to make sure they are the same.  */
	  if (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
	      && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
	      && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 1)))
		 != TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 1))))
	    return false;
	  /* FALLTHRU */

	case VEC_COND_EXPR:
	case DOT_PROD_EXPR:
	  return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);

	case MODIFY_EXPR:
	case INIT_EXPR:
	case COMPOUND_EXPR:
	case PREDECREMENT_EXPR:
	case PREINCREMENT_EXPR:
	case POSTDECREMENT_EXPR:
	case POSTINCREMENT_EXPR:
	  if (flags & OEP_LEXICOGRAPHIC)
	    return OP_SAME (0) && OP_SAME (1);
	  return false;

	case CLEANUP_POINT_EXPR:
	case EXPR_STMT:
	case SAVE_EXPR:
	  if (flags & OEP_LEXICOGRAPHIC)
	    return OP_SAME (0);
	  return false;

	case OBJ_TYPE_REF:
	/* Virtual table reference.  */
	if (!operand_equal_p (OBJ_TYPE_REF_EXPR (arg0),
			      OBJ_TYPE_REF_EXPR (arg1), flags))
	  return false;
	flags &= ~OEP_ADDRESS_OF;
	if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg0))
	    != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg1)))
	  return false;
	if (!operand_equal_p (OBJ_TYPE_REF_OBJECT (arg0),
			      OBJ_TYPE_REF_OBJECT (arg1), flags))
	  return false;
	if (virtual_method_call_p (arg0))
	  {
	    if (!virtual_method_call_p (arg1))
	      return false;
	    return types_same_for_odr (obj_type_ref_class (arg0),
				       obj_type_ref_class (arg1));
	  }
	return false;

	default:
	  return false;
	}

    case tcc_vl_exp:
      switch (TREE_CODE (arg0))
	{
	case CALL_EXPR:
	  if ((CALL_EXPR_FN (arg0) == NULL_TREE)
	      != (CALL_EXPR_FN (arg1) == NULL_TREE))
	    /* If not both CALL_EXPRs are either internal or normal function
	       functions, then they are not equal.  */
	    return false;
	  else if (CALL_EXPR_FN (arg0) == NULL_TREE)
	    {
	      /* If the CALL_EXPRs call different internal functions, then they
		 are not equal.  */
	      if (CALL_EXPR_IFN (arg0) != CALL_EXPR_IFN (arg1))
		return false;
	    }
	  else
	    {
	      /* If the CALL_EXPRs call different functions, then they are not
		 equal.  */
	      if (! operand_equal_p (CALL_EXPR_FN (arg0), CALL_EXPR_FN (arg1),
				     flags))
		return false;
	    }

	  /* FIXME: We could skip this test for OEP_MATCH_SIDE_EFFECTS.  */
	  {
	    unsigned int cef = call_expr_flags (arg0);
	    if (flags & OEP_PURE_SAME)
	      cef &= ECF_CONST | ECF_PURE;
	    else
	      cef &= ECF_CONST;
	    if (!cef && !(flags & OEP_LEXICOGRAPHIC))
	      return false;
	  }

	  /* Now see if all the arguments are the same.  */
	  {
	    const_call_expr_arg_iterator iter0, iter1;
	    const_tree a0, a1;
	    for (a0 = first_const_call_expr_arg (arg0, &iter0),
		   a1 = first_const_call_expr_arg (arg1, &iter1);
		 a0 && a1;
		 a0 = next_const_call_expr_arg (&iter0),
		   a1 = next_const_call_expr_arg (&iter1))
	      if (! operand_equal_p (a0, a1, flags))
		return false;

	    /* If we get here and both argument lists are exhausted
	       then the CALL_EXPRs are equal.  */
	    return ! (a0 || a1);
	  }
	default:
	  return false;
	}

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

    case tcc_exceptional:
      if (TREE_CODE (arg0) == CONSTRUCTOR)
	{
	  if (CONSTRUCTOR_NO_CLEARING (arg0) != CONSTRUCTOR_NO_CLEARING (arg1))
	    return false;

	  /* In GIMPLE constructors are used only to build vectors from
	     elements.  Individual elements in the constructor must be
	     indexed in increasing order and form an initial sequence.

	     We make no effort to compare constructors in generic.
	     (see sem_variable::equals in ipa-icf which can do so for
	      constants).  */
	  if (!VECTOR_TYPE_P (TREE_TYPE (arg0))
	      || !VECTOR_TYPE_P (TREE_TYPE (arg1)))
	    return false;

	  /* Be sure that vectors constructed have the same representation.
	     We only tested element precision and modes to match.
	     Vectors may be BLKmode and thus also check that the number of
	     parts match.  */
	  if (maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)),
			TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1))))
	    return false;

	  vec<constructor_elt, va_gc> *v0 = CONSTRUCTOR_ELTS (arg0);
	  vec<constructor_elt, va_gc> *v1 = CONSTRUCTOR_ELTS (arg1);
	  unsigned int len = vec_safe_length (v0);

	  if (len != vec_safe_length (v1))
	    return false;

	  for (unsigned int i = 0; i < len; i++)
	    {
	      constructor_elt *c0 = &(*v0)[i];
	      constructor_elt *c1 = &(*v1)[i];

	      if (!operand_equal_p (c0->value, c1->value, flags)
		  /* In GIMPLE the indexes can be either NULL or matching i.
		     Double check this so we won't get false
		     positives for GENERIC.  */
		  || (c0->index
		      && (TREE_CODE (c0->index) != INTEGER_CST 
			  || compare_tree_int (c0->index, i)))
		  || (c1->index
		      && (TREE_CODE (c1->index) != INTEGER_CST 
			  || compare_tree_int (c1->index, i))))
		return false;
	    }
	  return true;
	}
      else if (TREE_CODE (arg0) == STATEMENT_LIST
	       && (flags & OEP_LEXICOGRAPHIC))
	{
	  /* Compare the STATEMENT_LISTs.  */
	  tree_stmt_iterator tsi1, tsi2;
	  tree body1 = CONST_CAST_TREE (arg0);
	  tree body2 = CONST_CAST_TREE (arg1);
	  for (tsi1 = tsi_start (body1), tsi2 = tsi_start (body2); ;
	       tsi_next (&tsi1), tsi_next (&tsi2))
	    {
	      /* The lists don't have the same number of statements.  */
	      if (tsi_end_p (tsi1) ^ tsi_end_p (tsi2))
		return false;
	      if (tsi_end_p (tsi1) && tsi_end_p (tsi2))
		return true;
	      if (!operand_equal_p (tsi_stmt (tsi1), tsi_stmt (tsi2),
				    flags & (OEP_LEXICOGRAPHIC
					     | OEP_NO_HASH_CHECK)))
		return false;
	    }
	}
      return false;

    case tcc_statement:
      switch (TREE_CODE (arg0))
	{
	case RETURN_EXPR:
	  if (flags & OEP_LEXICOGRAPHIC)
	    return OP_SAME_WITH_NULL (0);
	  return false;
	case DEBUG_BEGIN_STMT:
	  if (flags & OEP_LEXICOGRAPHIC)
	    return true;
	  return false;
	default:
	  return false;
	 }

    default:
      return false;
    }

#undef OP_SAME
#undef OP_SAME_WITH_NULL
}

/* Generate a hash value for an expression.  This can be used iteratively
   by passing a previous result as the HSTATE argument.  */

void
operand_compare::hash_operand (const_tree t, inchash::hash &hstate,
			       unsigned int flags)
{
  int i;
  enum tree_code code;
  enum tree_code_class tclass;

  if (t == NULL_TREE || t == error_mark_node)
    {
      hstate.merge_hash (0);
      return;
    }

  STRIP_ANY_LOCATION_WRAPPER (t);

  if (!(flags & OEP_ADDRESS_OF))
    STRIP_NOPS (t);

  code = TREE_CODE (t);

  switch (code)
    {
    /* Alas, constants aren't shared, so we can't rely on pointer
       identity.  */
    case VOID_CST:
      hstate.merge_hash (0);
      return;
    case INTEGER_CST:
      gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
      for (i = 0; i < TREE_INT_CST_EXT_NUNITS (t); i++)
	hstate.add_hwi (TREE_INT_CST_ELT (t, i));
      return;
    case REAL_CST:
      {
	unsigned int val2;
	if (!HONOR_SIGNED_ZEROS (t) && real_zerop (t))
	  val2 = rvc_zero;
	else
	  val2 = real_hash (TREE_REAL_CST_PTR (t));
	hstate.merge_hash (val2);
	return;
      }
    case FIXED_CST:
      {
	unsigned int val2 = fixed_hash (TREE_FIXED_CST_PTR (t));
	hstate.merge_hash (val2);
	return;
      }
    case STRING_CST:
      hstate.add ((const void *) TREE_STRING_POINTER (t),
		  TREE_STRING_LENGTH (t));
      return;
    case COMPLEX_CST:
      hash_operand (TREE_REALPART (t), hstate, flags);
      hash_operand (TREE_IMAGPART (t), hstate, flags);
      return;
    case VECTOR_CST:
      {
	hstate.add_int (VECTOR_CST_NPATTERNS (t));
	hstate.add_int (VECTOR_CST_NELTS_PER_PATTERN (t));
	unsigned int count = vector_cst_encoded_nelts (t);
	for (unsigned int i = 0; i < count; ++i)
	  hash_operand (VECTOR_CST_ENCODED_ELT (t, i), hstate, flags);
	return;
      }
    case SSA_NAME:
      /* We can just compare by pointer.  */
      hstate.add_hwi (SSA_NAME_VERSION (t));
      return;
    case PLACEHOLDER_EXPR:
      /* The node itself doesn't matter.  */
      return;
    case BLOCK:
    case OMP_CLAUSE:
      /* Ignore.  */
      return;
    case TREE_LIST:
      /* A list of expressions, for a CALL_EXPR or as the elements of a
	 VECTOR_CST.  */
      for (; t; t = TREE_CHAIN (t))
	hash_operand (TREE_VALUE (t), hstate, flags);
      return;
    case CONSTRUCTOR:
      {
	unsigned HOST_WIDE_INT idx;
	tree field, value;
	flags &= ~OEP_ADDRESS_OF;
	hstate.add_int (CONSTRUCTOR_NO_CLEARING (t));
	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), idx, field, value)
	  {
	    /* In GIMPLE the indexes can be either NULL or matching i.  */
	    if (field == NULL_TREE)
	      field = bitsize_int (idx);
	    hash_operand (field, hstate, flags);
	    hash_operand (value, hstate, flags);
	  }
	return;
      }
    case STATEMENT_LIST:
      {
	tree_stmt_iterator i;
	for (i = tsi_start (CONST_CAST_TREE (t));
	     !tsi_end_p (i); tsi_next (&i))
	  hash_operand (tsi_stmt (i), hstate, flags);
	return;
      }
    case TREE_VEC:
      for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
	hash_operand (TREE_VEC_ELT (t, i), hstate, flags);
      return;
    case IDENTIFIER_NODE:
      hstate.add_object (IDENTIFIER_HASH_VALUE (t));
      return;
    case FUNCTION_DECL:
      /* When referring to a built-in FUNCTION_DECL, use the __builtin__ form.
	 Otherwise nodes that compare equal according to operand_equal_p might
	 get different hash codes.  However, don't do this for machine specific
	 or front end builtins, since the function code is overloaded in those
	 cases.  */
      if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
	  && builtin_decl_explicit_p (DECL_FUNCTION_CODE (t)))
	{
	  t = builtin_decl_explicit (DECL_FUNCTION_CODE (t));
	  code = TREE_CODE (t);
	}
      /* FALL THROUGH */
    default:
      if (POLY_INT_CST_P (t))
	{
	  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
	    hstate.add_wide_int (wi::to_wide (POLY_INT_CST_COEFF (t, i)));
	  return;
	}
      tclass = TREE_CODE_CLASS (code);

      if (tclass == tcc_declaration)
	{
	  /* DECL's have a unique ID */
	  hstate.add_hwi (DECL_UID (t));
	}
      else if (tclass == tcc_comparison && !commutative_tree_code (code))
	{
	  /* For comparisons that can be swapped, use the lower
	     tree code.  */
	  enum tree_code ccode = swap_tree_comparison (code);
	  if (code < ccode)
	    ccode = code;
	  hstate.add_object (ccode);
	  hash_operand (TREE_OPERAND (t, ccode != code), hstate, flags);
	  hash_operand (TREE_OPERAND (t, ccode == code), hstate, flags);
	}
      else if (CONVERT_EXPR_CODE_P (code))
	{
	  /* NOP_EXPR and CONVERT_EXPR are considered equal by
	     operand_equal_p.  */
	  enum tree_code ccode = NOP_EXPR;
	  hstate.add_object (ccode);

	  /* Don't hash the type, that can lead to having nodes which
	     compare equal according to operand_equal_p, but which
	     have different hash codes.  Make sure to include signedness
	     in the hash computation.  */
	  hstate.add_int (TYPE_UNSIGNED (TREE_TYPE (t)));
	  hash_operand (TREE_OPERAND (t, 0), hstate, flags);
	}
      /* For OEP_ADDRESS_OF, hash MEM_EXPR[&decl, 0] the same as decl.  */
      else if (code == MEM_REF
	       && (flags & OEP_ADDRESS_OF) != 0
	       && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
	       && DECL_P (TREE_OPERAND (TREE_OPERAND (t, 0), 0))
	       && integer_zerop (TREE_OPERAND (t, 1)))
	hash_operand (TREE_OPERAND (TREE_OPERAND (t, 0), 0),
		      hstate, flags);
      /* Don't ICE on FE specific trees, or their arguments etc.
	 during operand_equal_p hash verification.  */
      else if (!IS_EXPR_CODE_CLASS (tclass))
	gcc_assert (flags & OEP_HASH_CHECK);
      else
	{
	  unsigned int sflags = flags;

	  hstate.add_object (code);

	  switch (code)
	    {
	    case ADDR_EXPR:
	      gcc_checking_assert (!(flags & OEP_ADDRESS_OF));
	      flags |= OEP_ADDRESS_OF;
	      sflags = flags;
	      break;

	    case INDIRECT_REF:
	    case MEM_REF:
	    case TARGET_MEM_REF:
	      flags &= ~OEP_ADDRESS_OF;
	      sflags = flags;
	      break;

	    case COMPONENT_REF:
	      if (sflags & OEP_ADDRESS_OF)
		{
		  hash_operand (TREE_OPERAND (t, 0), hstate, flags);
		  if (TREE_OPERAND (t, 2))
		    hash_operand (TREE_OPERAND (t, 2), hstate,
				  flags & ~OEP_ADDRESS_OF);
		  else
		    {
		      tree field = TREE_OPERAND (t, 1);
		      hash_operand (DECL_FIELD_OFFSET (field),
				    hstate, flags & ~OEP_ADDRESS_OF);
		      hash_operand (DECL_FIELD_BIT_OFFSET (field),
				    hstate, flags & ~OEP_ADDRESS_OF);
		    }
		  return;
		}
	      break;
	    case ARRAY_REF:
	    case ARRAY_RANGE_REF:
	    case BIT_FIELD_REF:
	      sflags &= ~OEP_ADDRESS_OF;
	      break;

	    case COND_EXPR:
	      flags &= ~OEP_ADDRESS_OF;
	      break;

	    case WIDEN_MULT_PLUS_EXPR:
	    case WIDEN_MULT_MINUS_EXPR:
	      {
		/* The multiplication operands are commutative.  */
		inchash::hash one, two;
		hash_operand (TREE_OPERAND (t, 0), one, flags);
		hash_operand (TREE_OPERAND (t, 1), two, flags);
		hstate.add_commutative (one, two);
		hash_operand (TREE_OPERAND (t, 2), two, flags);
		return;
	      }

	    case CALL_EXPR:
	      if (CALL_EXPR_FN (t) == NULL_TREE)
		hstate.add_int (CALL_EXPR_IFN (t));
	      break;

	    case TARGET_EXPR:
	      /* For TARGET_EXPR, just hash on the TARGET_EXPR_SLOT.
		 Usually different TARGET_EXPRs just should use
		 different temporaries in their slots.  */
	      hash_operand (TARGET_EXPR_SLOT (t), hstate, flags);
	      return;

	    case OBJ_TYPE_REF:
	    /* Virtual table reference.  */
	      inchash::add_expr (OBJ_TYPE_REF_EXPR (t), hstate, flags);
	      flags &= ~OEP_ADDRESS_OF;
	      inchash::add_expr (OBJ_TYPE_REF_TOKEN (t), hstate, flags);
	      inchash::add_expr (OBJ_TYPE_REF_OBJECT (t), hstate, flags);
	      if (!virtual_method_call_p (t))
		return;
	      if (tree c = obj_type_ref_class (t))
		{
		  c = TYPE_NAME (TYPE_MAIN_VARIANT (c));
		  /* We compute mangled names only when free_lang_data is run.
		     In that case we can hash precisely.  */
		  if (TREE_CODE (c) == TYPE_DECL
		      && DECL_ASSEMBLER_NAME_SET_P (c))
		    hstate.add_object
			   (IDENTIFIER_HASH_VALUE
				   (DECL_ASSEMBLER_NAME (c)));
		}
	      return;
	    default:
	      break;
	    }

	  /* Don't hash the type, that can lead to having nodes which
	     compare equal according to operand_equal_p, but which
	     have different hash codes.  */
	  if (code == NON_LVALUE_EXPR)
	    {
	      /* Make sure to include signness in the hash computation.  */
	      hstate.add_int (TYPE_UNSIGNED (TREE_TYPE (t)));
	      hash_operand (TREE_OPERAND (t, 0), hstate, flags);
	    }

	  else if (commutative_tree_code (code))
	    {
	      /* It's a commutative expression.  We want to hash it the same
		 however it appears.  We do this by first hashing both operands
		 and then rehashing based on the order of their independent
		 hashes.  */
	      inchash::hash one, two;
	      hash_operand (TREE_OPERAND (t, 0), one, flags);
	      hash_operand (TREE_OPERAND (t, 1), two, flags);
	      hstate.add_commutative (one, two);
	    }
	  else
	    for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
	      hash_operand (TREE_OPERAND (t, i), hstate,
			    i == 0 ? flags : sflags);
	}
      return;
    }
}

bool
operand_compare::verify_hash_value (const_tree arg0, const_tree arg1,
				    unsigned int flags, bool *ret)
{
  /* When checking, verify at the outermost operand_equal_p call that
     if operand_equal_p returns non-zero then ARG0 and ARG1 has the same
     hash value.  */
  if (flag_checking && !(flags & OEP_NO_HASH_CHECK))
    {
      if (operand_equal_p (arg0, arg1, flags | OEP_NO_HASH_CHECK))
	{
	  if (arg0 != arg1)
	    {
	      inchash::hash hstate0 (0), hstate1 (0);
	      hash_operand (arg0, hstate0, flags | OEP_HASH_CHECK);
	      hash_operand (arg1, hstate1, flags | OEP_HASH_CHECK);
	      hashval_t h0 = hstate0.end ();
	      hashval_t h1 = hstate1.end ();
	      gcc_assert (h0 == h1);
	    }
	  *ret = true;
	}
      else
	*ret = false;

      return true;
    }

  return false;
}


static operand_compare default_compare_instance;

/* Conveinece wrapper around operand_compare class because usually we do
   not need to play with the valueizer.  */

bool
operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
{
  return default_compare_instance.operand_equal_p (arg0, arg1, flags);
}

namespace inchash
{

/* Generate a hash value for an expression.  This can be used iteratively
   by passing a previous result as the HSTATE argument.

   This function is intended to produce the same hash for expressions which
   would compare equal using operand_equal_p.  */
void
add_expr (const_tree t, inchash::hash &hstate, unsigned int flags)
{
  default_compare_instance.hash_operand (t, hstate, flags);
}

}

/* Similar to operand_equal_p, but see if ARG0 might be a variant of ARG1
   with a different signedness or a narrower precision.  */

static bool
operand_equal_for_comparison_p (tree arg0, tree arg1)
{
  if (operand_equal_p (arg0, arg1, 0))
    return true;

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

  /* 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.  */
  tree op0 = arg0;
  tree op1 = arg1;
  STRIP_NOPS (op0);
  STRIP_NOPS (op1);
  if (operand_equal_p (op0, op1, 0))
    return true;

  /* Discard a single widening conversion from ARG1 and see if the inner
     value is the same as ARG0.  */
  if (CONVERT_EXPR_P (arg1)
      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0)))
      && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)))
         < TYPE_PRECISION (TREE_TYPE (arg1))
      && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
    return true;

  return false;
}

/* 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 this is true, return 1.  Otherwise, return zero.  */

static bool
twoval_comparison_p (tree arg, tree *cval1, tree *cval2)
{
  enum tree_code code = TREE_CODE (arg);
  enum tree_code_class tclass = TREE_CODE_CLASS (code);

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

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

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

    case tcc_constant:
      return true;

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

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

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

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

      return true;

    default:
      return false;
    }
}

/* 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 (location_t loc, 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 tclass = TREE_CODE_CLASS (code);

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

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

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

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

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

	case COND_EXPR:
	  return fold_build3_loc (loc, code, type,
			      eval_subst (loc, TREE_OPERAND (arg, 0),
					  old0, new0, old1, new1),
			      eval_subst (loc, TREE_OPERAND (arg, 1),
					  old0, new0, old1, new1),
			      eval_subst (loc, 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_loc (loc, 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_loc (location_t loc, tree type, tree result, tree omitted)
{
  tree t = fold_convert_loc (loc, type, result);

  /* If the resulting operand is an empty statement, just return the omitted
     statement casted to void. */
  if (IS_EMPTY_STMT (t) && TREE_SIDE_EFFECTS (omitted))
    return build1_loc (loc, NOP_EXPR, void_type_node,
		       fold_ignored_result (omitted));

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

  return non_lvalue_loc (loc, 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_loc (location_t loc, tree type, tree result,
		       tree omitted1, tree omitted2)
{
  tree t = fold_convert_loc (loc, type, result);

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

  return TREE_CODE (t) != COMPOUND_EXPR ? non_lvalue_loc (loc, 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.  */

static tree
fold_truth_not_expr (location_t loc, tree arg)
{
  tree type = TREE_TYPE (arg);
  enum tree_code code = TREE_CODE (arg);
  location_t loc1, loc2;

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

      code = invert_tree_comparison (code, HONOR_NANS (op_type));
      if (code == ERROR_MARK)
	return NULL_TREE;

      tree ret = build2_loc (loc, code, type, TREE_OPERAND (arg, 0),
			     TREE_OPERAND (arg, 1));
      if (TREE_NO_WARNING (arg))
	TREE_NO_WARNING (ret) = 1;
      return ret;
    }

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

    case TRUTH_AND_EXPR:
      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
      loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
      return build2_loc (loc, TRUTH_OR_EXPR, type,
			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
			 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));

    case TRUTH_OR_EXPR:
      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
      loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
      return build2_loc (loc, TRUTH_AND_EXPR, type,
			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
			 invert_truthvalue_loc (loc2, 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_loc (loc, TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
			   TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
      else
	return build2_loc (loc, TRUTH_XOR_EXPR, type,
			   invert_truthvalue_loc (loc, TREE_OPERAND (arg, 0)),
			   TREE_OPERAND (arg, 1));

    case TRUTH_ANDIF_EXPR:
      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
      loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
      return build2_loc (loc, TRUTH_ORIF_EXPR, type,
			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
			 invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));

    case TRUTH_ORIF_EXPR:
      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
      loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
      return build2_loc (loc, TRUTH_ANDIF_EXPR, type,
			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
			 invert_truthvalue_loc (loc2, 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);

	loc1 = expr_location_or (TREE_OPERAND (arg, 1), loc);
	loc2 = expr_location_or (TREE_OPERAND (arg, 2), loc);

	/* A COND_EXPR may have a throw as one operand, which
	   then has void type.  Just leave void operands
	   as they are.  */
	return build3_loc (loc, COND_EXPR, type, TREE_OPERAND (arg, 0),
			   VOID_TYPE_P (TREE_TYPE (arg1))
			   ? arg1 : invert_truthvalue_loc (loc1, arg1),
			   VOID_TYPE_P (TREE_TYPE (arg2))
			   ? arg2 : invert_truthvalue_loc (loc2, arg2));
      }

    case COMPOUND_EXPR:
      loc1 = expr_location_or (TREE_OPERAND (arg, 1), loc);
      return build2_loc (loc, COMPOUND_EXPR, type,
			 TREE_OPERAND (arg, 0),
			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 1)));

    case NON_LVALUE_EXPR:
      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
      return invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0));

    CASE_CONVERT:
      if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
	return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);

      /* fall through */

    case FLOAT_EXPR:
      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
      return build1_loc (loc, TREE_CODE (arg), type,
			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));

    case BIT_AND_EXPR:
      if (!integer_onep (TREE_OPERAND (arg, 1)))
	return NULL_TREE;
      return build2_loc (loc, EQ_EXPR, type, arg, build_int_cst (type, 0));

    case SAVE_EXPR:
      return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);

    case CLEANUP_POINT_EXPR:
      loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
      return build1_loc (loc, CLEANUP_POINT_EXPR, type,
			 invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));

    default:
      return NULL_TREE;
    }
}

/* Fold 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
   for scalars, 0 or -1 for vectors).  Return the folded expression if
   folding is successful.  Otherwise, return NULL_TREE.  */

static tree
fold_invert_truthvalue (location_t loc, tree arg)
{
  tree type = TREE_TYPE (arg);
  return fold_unary_loc (loc, VECTOR_TYPE_P (type)
			      ? BIT_NOT_EXPR
			      : TRUTH_NOT_EXPR,
			 type, arg);
}

/* 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 for scalars, 0 or -1 for vectors).  */

tree
invert_truthvalue_loc (location_t loc, tree arg)
{
  if (TREE_CODE (arg) == ERROR_MARK)
    return arg;

  tree type = TREE_TYPE (arg);
  return fold_build1_loc (loc, VECTOR_TYPE_P (type)
			       ? BIT_NOT_EXPR
			       : TRUTH_NOT_EXPR,
			  type, arg);
}

/* 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
   and uses reverse storage order if REVERSEP is nonzero.  ORIG_INNER
   is the original memory reference used to preserve the alias set of
   the access.  */

static tree
make_bit_field_ref (location_t loc, tree inner, tree orig_inner, tree type,
		    HOST_WIDE_INT bitsize, poly_int64 bitpos,
		    int unsignedp, int reversep)
{
  tree result, bftype;

  /* Attempt not to lose the access path if possible.  */
  if (TREE_CODE (orig_inner) == COMPONENT_REF)
    {
      tree ninner = TREE_OPERAND (orig_inner, 0);
      machine_mode nmode;
      poly_int64 nbitsize, nbitpos;
      tree noffset;
      int nunsignedp, nreversep, nvolatilep = 0;
      tree base = get_inner_reference (ninner, &nbitsize, &nbitpos,
				       &noffset, &nmode, &nunsignedp,
				       &nreversep, &nvolatilep);
      if (base == inner
	  && noffset == NULL_TREE
	  && known_subrange_p (bitpos, bitsize, nbitpos, nbitsize)
	  && !reversep
	  && !nreversep
	  && !nvolatilep)
	{
	  inner = ninner;
	  bitpos -= nbitpos;
	}
    }

  alias_set_type iset = get_alias_set (orig_inner);
  if (iset == 0 && get_alias_set (inner) != iset)
    inner = fold_build2 (MEM_REF, TREE_TYPE (inner),
			 build_fold_addr_expr (inner),
			 build_int_cst (ptr_type_node, 0));

  if (known_eq (bitpos, 0) && !reversep)
    {
      tree size = TYPE_SIZE (TREE_TYPE (inner));
      if ((INTEGRAL_TYPE_P (TREE_TYPE (inner))
	   || POINTER_TYPE_P (TREE_TYPE (inner)))
	  && tree_fits_shwi_p (size)
	  && tree_to_shwi (size) == bitsize)
	return fold_convert_loc (loc, type, inner);
    }

  bftype = type;
  if (TYPE_PRECISION (bftype) != bitsize
      || TYPE_UNSIGNED (bftype) == !unsignedp)
    bftype = build_nonstandard_integer_type (bitsize, 0);

  result = build3_loc (loc, BIT_FIELD_REF, bftype, inner,
		       bitsize_int (bitsize), bitsize_int (bitpos));
  REF_REVERSE_STORAGE_ORDER (result) = reversep;

  if (bftype != type)
    result = fold_convert_loc (loc, type, result);

  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 (location_t loc, enum tree_code code,
			    tree compare_type, tree lhs, tree rhs)
{
  poly_int64 plbitpos, plbitsize, rbitpos, rbitsize;
  HOST_WIDE_INT lbitpos, lbitsize, nbitpos, nbitsize;
  tree type = TREE_TYPE (lhs);
  tree unsigned_type;
  int const_p = TREE_CODE (rhs) == INTEGER_CST;
  machine_mode lmode, rmode;
  scalar_int_mode nmode;
  int lunsignedp, runsignedp;
  int lreversep, rreversep;
  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
     is 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, &plbitsize, &plbitpos, &offset, &lmode,
				&lunsignedp, &lreversep, &lvolatilep);
  if (linner == lhs
      || !known_size_p (plbitsize)
      || !plbitsize.is_constant (&lbitsize)
      || !plbitpos.is_constant (&lbitpos)
      || known_eq (lbitsize, GET_MODE_BITSIZE (lmode))
      || offset != 0
      || TREE_CODE (linner) == PLACEHOLDER_EXPR
      || lvolatilep)
    return 0;

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

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

  /* Honor the C++ memory model and mimic what RTL expansion does.  */
  poly_uint64 bitstart = 0;
  poly_uint64 bitend = 0;
  if (TREE_CODE (lhs) == COMPONENT_REF)
    {
      get_bit_range (&bitstart, &bitend, lhs, &plbitpos, &offset);
      if (!plbitpos.is_constant (&lbitpos) || offset != NULL_TREE)
	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.  */
  if (!get_best_mode (lbitsize, lbitpos, bitstart, bitend,
		      const_p ? TYPE_ALIGN (TREE_TYPE (linner))
		      : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
			     TYPE_ALIGN (TREE_TYPE (rinner))),
		      BITS_PER_WORD, false, &nmode))
    return 0;

  /* Set signed and unsigned types of the precision of this mode for the
     shifts below.  */
  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 (lreversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
    lbitpos = nbitsize - lbitsize - lbitpos;

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

  if (! const_p)
    {
      if (nbitpos < 0)
	return 0;

      /* If not comparing with constant, just rework the comparison
	 and return.  */
      tree t1 = make_bit_field_ref (loc, linner, lhs, unsigned_type,
				    nbitsize, nbitpos, 1, lreversep);
      t1 = fold_build2_loc (loc, BIT_AND_EXPR, unsigned_type, t1, mask);
      tree t2 = make_bit_field_ref (loc, rinner, rhs, unsigned_type,
				    nbitsize, nbitpos, 1, rreversep);
      t2 = fold_build2_loc (loc, BIT_AND_EXPR, unsigned_type, t2, mask);
      return fold_build2_loc (loc, code, compare_type, t1, t2);
    }

  /* Otherwise, we are handling the constant case.  See if the constant is too
     big for the field.  Warn and return a tree 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 (wi::lrshift (wi::to_wide (rhs), 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
    {
      wide_int tem = wi::arshift (wi::to_wide (rhs), lbitsize - 1);
      if (tem != 0 && tem != -1)
	{
	  warning (0, "comparison is always %d due to width of bit-field",
		   code == NE_EXPR);
	  return constant_boolean_node (code == NE_EXPR, compare_type);
	}
    }

  if (nbitpos < 0)
    return 0;

  /* 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 (loc, linner, lhs, unsigned_type,
			    nbitsize, nbitpos, 1, lreversep);

  rhs = const_binop (BIT_AND_EXPR,
		     const_binop (LSHIFT_EXPR,
				  fold_convert_loc (loc, unsigned_type, rhs),
				  size_int (lbitpos)),
		     mask);

  lhs = build2_loc (loc, code, compare_type,
		    build2 (BIT_AND_EXPR, unsigned_type, lhs, mask), rhs);
  return lhs;
}

/* Subroutine for fold_truth_andor_1: 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.

   *PREVERSEP is set to the storage order 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 (location_t loc, tree *exp_, HOST_WIDE_INT *pbitsize,
			HOST_WIDE_INT *pbitpos, machine_mode *pmode,
			int *punsignedp, int *preversep, int *pvolatilep,
			tree *pmask, tree *pand_mask)
{
  tree exp = *exp_;
  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 NULL_TREE;

  /* 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 (CONVERT_EXPR_P (exp)
      || 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 NULL_TREE;
    }

  poly_int64 poly_bitsize, poly_bitpos;
  inner = get_inner_reference (exp, &poly_bitsize, &poly_bitpos, &offset,
			       pmode, punsignedp, preversep, pvolatilep);
  if ((inner == exp && and_mask == 0)
      || !poly_bitsize.is_constant (pbitsize)
      || !poly_bitpos.is_constant (pbitpos)
      || *pbitsize < 0
      || offset != 0
      || TREE_CODE (inner) == PLACEHOLDER_EXPR
      /* Reject out-of-bound accesses (PR79731).  */
      || (! AGGREGATE_TYPE_P (TREE_TYPE (inner))
	  && compare_tree_int (TYPE_SIZE (TREE_TYPE (inner)),
			       *pbitpos + *pbitsize) < 0))
    return NULL_TREE;

  unsigned_type = lang_hooks.types.type_for_size (*pbitsize, 1);
  if (unsigned_type == NULL_TREE)
    return NULL_TREE;

  *exp_ = exp;

  /* 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.  */
  precision = TYPE_PRECISION (unsigned_type);

  mask = build_int_cst_type (unsigned_type, -1);

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

  /* Merge it with the mask we found in the BIT_AND_EXPR, if any.  */
  if (and_mask != 0)
    mask = fold_build2_loc (loc, BIT_AND_EXPR, unsigned_type,
			fold_convert_loc (loc, 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 and MASK is SIGNED.  */

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

  /* If this function returns true when the type of the mask is
     UNSIGNED, then there will be errors.  In particular see
     gcc.c-torture/execute/990326-1.c.  There does not appear to be
     any documentation paper trail as to why this is so.  But the pre
     wide-int worked with that restriction and it has been preserved
     here.  */
  if (size > precision || TYPE_SIGN (type) == UNSIGNED)
    return false;

  return wi::mask (size, false, precision) == wi::to_wide (mask);
}

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

tree
sign_bit_p (tree exp, const_tree val)
{
  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_OVERFLOW (val))
    return NULL_TREE;

  width = TYPE_PRECISION (t);
  if (wi::only_sign_bit_p (wi::to_wide (val), width))
    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_truth_andor_1: determine if an operand is simple enough
   to be evaluated unconditionally.  */

static bool
simple_operand_p (const_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)
	      /* Weakrefs are not safe to be read, since they can be NULL.
 		 They are !TREE_PUBLIC && !DECL_EXTERNAL but still
		 have DECL_WEAK flag set.  */
	      && (! VAR_OR_FUNCTION_DECL_P (exp) || ! DECL_WEAK (exp))
	      /* Loading a static variable is unduly expensive, but global
		 registers aren't expensive.  */
	      && (! TREE_STATIC (exp) || DECL_REGISTER (exp))));
}

/* Subroutine for fold_truth_andor: determine if an operand is simple enough
   to be evaluated unconditionally.
   I addition to simple_operand_p, we assume that comparisons, conversions,
   and logic-not operations are simple, if their operands are simple, too.  */

static bool
simple_operand_p_2 (tree exp)
{
  enum tree_code code;

  if (TREE_SIDE_EFFECTS (exp) || generic_expr_could_trap_p (exp))
    return false;

  while (CONVERT_EXPR_P (exp))
    exp = TREE_OPERAND (exp, 0);

  code = TREE_CODE (exp);

  if (TREE_CODE_CLASS (code) == tcc_comparison)
    return (simple_operand_p (TREE_OPERAND (exp, 0))
	    && simple_operand_p (TREE_OPERAND (exp, 1)));

  if (code == TRUTH_NOT_EXPR)
      return simple_operand_p_2 (TREE_OPERAND (exp, 0));

  return simple_operand_p (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);
}

/* Helper routine for make_range.  Perform one step for it, return
   new expression if the loop should continue or NULL_TREE if it should
   stop.  */

tree
make_range_step (location_t loc, enum tree_code code, tree arg0, tree arg1,
		 tree exp_type, tree *p_low, tree *p_high, int *p_in_p,
		 bool *strict_overflow_p)
{
  tree arg0_type = TREE_TYPE (arg0);
  tree n_low, n_high, low = *p_low, high = *p_high;
  int in_p = *p_in_p, n_in_p;

  switch (code)
    {
    case TRUTH_NOT_EXPR:
      /* We can only do something if the range is testing for zero.  */
      if (low == NULL_TREE || high == NULL_TREE
	  || ! integer_zerop (low) || ! integer_zerop (high))
	return NULL_TREE;
      *p_in_p = ! in_p;
      return arg0;

    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 == NULL_TREE || high == NULL_TREE
	  || ! integer_zerop (low) || ! integer_zerop (high)
	  || TREE_CODE (arg1) != INTEGER_CST)
	return NULL_TREE;

      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))
	    return NULL_TREE;

	  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,
				  build_int_cst (TREE_TYPE (low), 1), 0);
	      low = build_int_cst (arg0_type, 0);
	    }
	}

      *p_low = low;
      *p_high = high;
      *p_in_p = in_p;
      return arg0;

    case NEGATE_EXPR:
      /* If flag_wrapv and ARG0_TYPE is signed, make sure
	 low and high are non-NULL, then normalize will DTRT.  */
      if (!TYPE_UNSIGNED (arg0_type)
	  && !TYPE_OVERFLOW_UNDEFINED (arg0_type))
	{
	  if (low == NULL_TREE)
	    low = TYPE_MIN_VALUE (arg0_type);
	  if (high == NULL_TREE)
	    high = TYPE_MAX_VALUE (arg0_type);
	}

      /* (-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);
      if (n_high != 0 && TREE_OVERFLOW (n_high))
	return NULL_TREE;
      goto normalize;

    case BIT_NOT_EXPR:
      /* ~ X -> -X - 1  */
      return build2_loc (loc, MINUS_EXPR, exp_type, negate_expr (arg0),
			 build_int_cst (exp_type, 1));

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

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

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

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

      normalize:
	/* 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,
			       build_int_cst (TREE_TYPE (n_high), 1), 0);
	    high = range_binop (MINUS_EXPR, arg0_type, n_low, 0,
				build_int_cst (TREE_TYPE (n_low), 1), 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;

	*p_low = low;
	*p_high = high;
	*p_in_p = in_p;
	return arg0;

    CASE_CONVERT:
    case NON_LVALUE_EXPR:
      if (TYPE_PRECISION (arg0_type) > TYPE_PRECISION (exp_type))
	return NULL_TREE;

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

      n_low = low, n_high = high;

      if (n_low != 0)
	n_low = fold_convert_loc (loc, arg0_type, n_low);

      if (n_high != 0)
	n_high = fold_convert_loc (loc, 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;
	  /* For fixed-point modes, we need to pass the saturating flag
	     as the 2nd parameter.  */
	  if (ALL_FIXED_POINT_MODE_P (TYPE_MODE (arg0_type)))
	    equiv_type
	      = lang_hooks.types.type_for_mode (TYPE_MODE (arg0_type),
						TYPE_SATURATING (arg0_type));
	  else
	    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_loc (loc, RSHIFT_EXPR, arg0_type,
					     fold_convert_loc (loc, arg0_type,
							       high_positive),
					     build_int_cst (arg0_type, 1));

	  /* 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_loc (loc, arg0_type,
						       integer_zero_node),
				  high_positive))
		return NULL_TREE;

	      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_loc (loc, arg0_type,
						       integer_zero_node),
				  high_positive))
		return NULL_TREE;

	      in_p = (in_p != n_in_p);
	    }
	}

      *p_low = n_low;
      *p_high = n_high;
      *p_in_p = in_p;
      return arg0;

    default:
      return NULL_TREE;
    }
}

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

tree
make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
	    bool *strict_overflow_p)
{
  enum tree_code code;
  tree arg0, arg1 = NULL_TREE;
  tree exp_type, nexp;
  int in_p;
  tree low, high;
  location_t loc = EXPR_LOCATION (exp);

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

      if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
	{
	  if (TREE_OPERAND_LENGTH (exp) > 0)
	    arg0 = TREE_OPERAND (exp, 0);
	  if (TREE_CODE_CLASS (code) == tcc_binary
	      || TREE_CODE_CLASS (code) == tcc_comparison
	      || (TREE_CODE_CLASS (code) == tcc_expression
		  && TREE_OPERAND_LENGTH (exp) > 1))
	    arg1 = TREE_OPERAND (exp, 1);
	}
      if (arg0 == NULL_TREE)
	break;

      nexp = make_range_step (loc, code, arg0, arg1, exp_type, &low,
			      &high, &in_p, strict_overflow_p);
      if (nexp == NULL_TREE)
	break;
      exp = nexp;
    }

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

/* Returns TRUE if [LOW, HIGH] range check can be optimized to
   a bitwise check i.e. when
     LOW  == 0xXX...X00...0
     HIGH == 0xXX...X11...1
   Return corresponding mask in MASK and stem in VALUE.  */

static bool
maskable_range_p (const_tree low, const_tree high, tree type, tree *mask,
		  tree *value)
{
  if (TREE_CODE (low) != INTEGER_CST
      || TREE_CODE (high) != INTEGER_CST)
    return false;

  unsigned prec = TYPE_PRECISION (type);
  wide_int lo = wi::to_wide (low, prec);
  wide_int hi = wi::to_wide (high, prec);

  wide_int end_mask = lo ^ hi;
  if ((end_mask & (end_mask + 1)) != 0
      || (lo & end_mask) != 0)
    return false;

  wide_int stem_mask = ~end_mask;
  wide_int stem = lo & stem_mask;
  if (stem != (hi & stem_mask))
    return false;

  *mask = wide_int_to_tree (type, stem_mask);
  *value = wide_int_to_tree (type, stem);

  return true;
}

/* Helper routine for build_range_check and match.pd.  Return the type to
   perform the check or NULL if it shouldn't be optimized.  */

tree
range_check_type (tree etype)
{
  /* First make sure that arithmetics in this type is valid, then make sure
     that it wraps around.  */
  if (TREE_CODE (etype) == ENUMERAL_TYPE || TREE_CODE (etype) == BOOLEAN_TYPE)
    etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype), 1);

  if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_UNSIGNED (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 = unsigned_type_for (etype);
      maxv = fold_convert (utype, TYPE_MAX_VALUE (etype));
      maxv = range_binop (PLUS_EXPR, NULL_TREE, maxv, 1,
			  build_int_cst (TREE_TYPE (maxv), 1), 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 NULL_TREE;
    }
  else if (POINTER_TYPE_P (etype))
    etype = unsigned_type_for (etype);
  return etype;
}

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

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

  /* Disable this optimization for function pointer expressions
     on targets that require function pointer canonicalization.  */
  if (targetm.have_canonicalize_funcptr_for_compare ()
      && POINTER_TYPE_P (etype)
      && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (etype)))
    return NULL_TREE;

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

      return 0;
    }

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

  if (low == 0)
    return fold_build2_loc (loc, LE_EXPR, type, exp,
			    fold_convert_loc (loc, etype, high));

  if (high == 0)
    return fold_build2_loc (loc, GE_EXPR, type, exp,
			    fold_convert_loc (loc, etype, low));

  if (operand_equal_p (low, high, 0))
    return fold_build2_loc (loc, EQ_EXPR, type, exp,
			    fold_convert_loc (loc, etype, low));

  if (TREE_CODE (exp) == BIT_AND_EXPR
      && maskable_range_p (low, high, etype, &mask, &value))
    return fold_build2_loc (loc, EQ_EXPR, type,
			    fold_build2_loc (loc, BIT_AND_EXPR, etype,
					     exp, mask),
			    value);

  if (integer_zerop (low))
    {
      if (! TYPE_UNSIGNED (etype))
	{
	  etype = unsigned_type_for (etype);
	  high = fold_convert_loc (loc, etype, high);
	  exp = fold_convert_loc (loc, etype, exp);
	}
      return build_range_check (loc, type, exp, 1, 0, high);
    }

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

      if (wi::mask <widest_int> (prec - 1, false) == wi::to_widest (high))
	{
	  if (TYPE_UNSIGNED (etype))
	    {
	      tree signed_etype = signed_type_for (etype);
	      if (TYPE_PRECISION (signed_etype) != TYPE_PRECISION (etype))
		etype
		  = build_nonstandard_integer_type (TYPE_PRECISION (etype), 0);
	      else
		etype = signed_etype;
	      exp = fold_convert_loc (loc, etype, exp);
	    }
	  return fold_build2_loc (loc, 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.  */
  etype = range_check_type (etype);
  if (etype == NULL_TREE)
    return NULL_TREE;

  high = fold_convert_loc (loc, etype, high);
  low = fold_convert_loc (loc, etype, low);
  exp = fold_convert_loc (loc, etype, exp);

  value = const_binop (MINUS_EXPR, high, low);

  if (value != 0 && !TREE_OVERFLOW (value))
    return build_range_check (loc, type,
			      fold_build2_loc (loc, 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,
			build_int_cst (TREE_TYPE (val), 1), 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,
			build_int_cst (TREE_TYPE (val), 1), 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.  */

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

  /* If the second range is != high1 where high1 is the type maximum of
     the type, try first merging with < high1 range.  */
  if (low1
      && high1
      && TREE_CODE (low1) == INTEGER_CST
      && (TREE_CODE (TREE_TYPE (low1)) == INTEGER_TYPE
	  || (TREE_CODE (TREE_TYPE (low1)) == ENUMERAL_TYPE
	      && known_eq (TYPE_PRECISION (TREE_TYPE (low1)),
			   GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (low1))))))
      && operand_equal_p (low1, high1, 0))
    {
      if (tree_int_cst_equal (low1, TYPE_MAX_VALUE (TREE_TYPE (low1)))
	  && merge_ranges (pin_p, plow, phigh, in0_p, low0, high0,
			   !in1_p, NULL_TREE, range_predecessor (low1)))
	return true;
      /* Similarly for the second range != low1 where low1 is the type minimum
	 of the type, try first merging with > low1 range.  */
      if (tree_int_cst_equal (low1, TYPE_MIN_VALUE (TREE_TYPE (low1)))
	  && merge_ranges (pin_p, plow, phigh, in0_p, low0, high0,
			   !in1_p, range_successor (low1), NULL_TREE))
	return true;
    }

  /* 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 (maybe_ne (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 (maybe_ne (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,
						       build_int_cst (TREE_TYPE (high1), 1),
						       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 (location_t loc, 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 (!HONOR_SIGNED_ZEROS (element_mode (type))
      && (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_loc (loc, arg1_type, arg1);
	return fold_convert_loc (loc, type, negate_expr (tem));
      case NE_EXPR:
      case LTGT_EXPR:
	return fold_convert_loc (loc, 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)))
	  break;
	tem = fold_build1_loc (loc, ABS_EXPR, TREE_TYPE (arg1), arg1);
	return fold_convert_loc (loc, type, tem);
      case UNLE_EXPR:
      case UNLT_EXPR:
	if (flag_trapping_math)
	  break;
	/* FALLTHRU */
      case LE_EXPR:
      case LT_EXPR:
	if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
	  break;
	if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg1))
	    && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1)))
	  {
	    /* A <= 0 ? A : -A for A INT_MIN is valid, but -abs(INT_MIN)
	       is not, invokes UB both in abs and in the negation of it.
	       So, use ABSU_EXPR instead.  */
	    tree utype = unsigned_type_for (TREE_TYPE (arg1));
	    tem = fold_build1_loc (loc, ABSU_EXPR, utype, arg1);
	    tem = negate_expr (tem);
	    return fold_convert_loc (loc, type, tem);
	  }
	else
	  {
	    tem = fold_build1_loc (loc, ABS_EXPR, TREE_TYPE (arg1), arg1);
	    return negate_expr (fold_convert_loc (loc, 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 (!HONOR_SIGNED_ZEROS (element_mode (type))
      && integer_zerop (arg01) && integer_zerop (arg2))
    {
      if (comp_code == NE_EXPR)
	return fold_convert_loc (loc, type, arg1);
      else if (comp_code == EQ_EXPR)
	return build_zero_cst (type);
    }

  /* 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 (!HONOR_SIGNED_ZEROS (element_mode (type))
      && operand_equal_for_comparison_p (arg01, arg2)
      /* Avoid these transformations if the COND_EXPR may be used
	 as an lvalue in the C++ front-end.  PR c++/19199.  */
      && (in_gimple_form
	  || VECTOR_TYPE_P (type)
	  || (! lang_GNU_CXX ()
	      && 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);

      switch (comp_code)
	{
	case EQ_EXPR:
	  return fold_convert_loc (loc, type, arg2);
	case NE_EXPR:
	  return fold_convert_loc (loc, 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 (arg1))
	    {
	      comp_op0 = fold_convert_loc (loc, comp_type, comp_op0);
	      comp_op1 = fold_convert_loc (loc, comp_type, comp_op1);
	      tem = (comp_code == LE_EXPR || comp_code == UNLE_EXPR)
		    ? fold_build2_loc (loc, MIN_EXPR, comp_type, comp_op0, comp_op1)
		    : fold_build2_loc (loc, MIN_EXPR, comp_type,
				   comp_op1, comp_op0);
	      return fold_convert_loc (loc, type, tem);
	    }
	  break;
	case GE_EXPR:
	case GT_EXPR:
	case UNGE_EXPR:
	case UNGT_EXPR:
	  if (!HONOR_NANS (arg1))
	    {
	      comp_op0 = fold_convert_loc (loc, comp_type, comp_op0);
	      comp_op1 = fold_convert_loc (loc, comp_type, comp_op1);
	      tem = (comp_code == GE_EXPR || comp_code == UNGE_EXPR)
		    ? fold_build2_loc (loc, MAX_EXPR, comp_type, comp_op0, comp_op1)
		    : fold_build2_loc (loc, MAX_EXPR, comp_type,
				   comp_op1, comp_op0);
	      return fold_convert_loc (loc, type, tem);
	    }
	  break;
	case UNEQ_EXPR:
	  if (!HONOR_NANS (arg1))
	    return fold_convert_loc (loc, type, arg2);
	  break;
	case LTGT_EXPR:
	  if (!HONOR_NANS (arg1))
	    return fold_convert_loc (loc, type, arg1);
	  break;
	default:
	  gcc_assert (TREE_CODE_CLASS (comp_code) == tcc_comparison);
	  break;
	}
    }

  return NULL_TREE;
}



#ifndef LOGICAL_OP_NON_SHORT_CIRCUIT
#define LOGICAL_OP_NON_SHORT_CIRCUIT \
  (BRANCH_COST (optimize_function_for_speed_p (cfun), \
		false) >= 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 (location_t loc, 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 tem, lhs, rhs;
  const char * const warnmsg = G_("assuming signed overflow does not occur "
				  "when simplifying range test");

  if (!INTEGRAL_TYPE_P (type))
    return 0;

  lhs = make_range (op0, &in0_p, &low0, &high0, &strict_overflow_p);
  /* If op0 is known true or false and this is a short-circuiting
     operation we must not merge with op1 since that makes side-effects
     unconditional.  So special-case this.  */
  if (!lhs
      && ((code == TRUTH_ORIF_EXPR && in0_p)
	  || (code == TRUTH_ANDIF_EXPR && !in0_p)))
    return op0;
  rhs = make_range (op1, &in1_p, &low1, &high1, &strict_overflow_p);

  /* 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)
      && (tem = (build_range_check (loc, type,
				    lhs != 0 ? lhs
				    : rhs != 0 ? rhs : integer_zero_node,
				    in_p, low, high))) != 0)
    {
      if (strict_overflow_p)
	fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_COMPARISON);
      return or_op ? invert_truthvalue_loc (loc, 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.  */
  bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
  if (param_logical_op_non_short_circuit != -1)
    logical_op_non_short_circuit
      = param_logical_op_non_short_circuit;
  if (logical_op_non_short_circuit
      && !sanitize_coverage_p ()
      && 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_loc (loc, code == TRUTH_ANDIF_EXPR
			   ? TRUTH_AND_EXPR : TRUTH_OR_EXPR,
			   type, op0, op1);

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

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

  return 0;
}

/* Subroutine for fold_truth_andor_1: 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 (SCALAR_INT_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 = build_int_cst (TREE_TYPE (c),
			wi::extract_uhwi (wi::to_wide (c), p - 1, 1));

  /* 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 (signed_type_for (type), temp);

  temp = const_binop (LSHIFT_EXPR, temp, size_int (modesize - 1));
  temp = const_binop (RSHIFT_EXPR, temp, size_int (modesize - p - 1));
  if (mask != 0)
    temp = const_binop (BIT_AND_EXPR, temp,
			fold_convert (TREE_TYPE (c), mask));
  /* 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));
}

/* For an expression that has the form
     (A && B) || ~B
   or
     (A || B) && ~B,
   we can drop one of the inner expressions and simplify to
     A || ~B
   or
     A && ~B
   LOC is the location of the resulting expression.  OP is the inner 
   logical operation; the left-hand side in the examples above, while CMPOP
   is the right-hand side.  RHS_ONLY is used to prevent us from accidentally
   removing a condition that guards another, as in
     (A != NULL && A->...) || A == NULL
   which we must not transform.  If RHS_ONLY is true, only eliminate the
   right-most operand of the inner logical operation.  */

static tree
merge_truthop_with_opposite_arm (location_t loc, tree op, tree cmpop,
				 bool rhs_only)
{
  tree type = TREE_TYPE (cmpop);
  enum tree_code code = TREE_CODE (cmpop);
  enum tree_code truthop_code = TREE_CODE (op);
  tree lhs = TREE_OPERAND (op, 0);
  tree rhs = TREE_OPERAND (op, 1);
  tree orig_lhs = lhs, orig_rhs = rhs;
  enum tree_code rhs_code = TREE_CODE (rhs);
  enum tree_code lhs_code = TREE_CODE (lhs);
  enum tree_code inv_code;

  if (TREE_SIDE_EFFECTS (op) || TREE_SIDE_EFFECTS (cmpop))
    return NULL_TREE;

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

  if (rhs_code == truthop_code)
    {
      tree newrhs = merge_truthop_with_opposite_arm (loc, rhs, cmpop, rhs_only);
      if (newrhs != NULL_TREE)
	{
	  rhs = newrhs;
	  rhs_code = TREE_CODE (rhs);
	}
    }
  if (lhs_code == truthop_code && !rhs_only)
    {
      tree newlhs = merge_truthop_with_opposite_arm (loc, lhs, cmpop, false);
      if (newlhs != NULL_TREE)
	{
	  lhs = newlhs;
	  lhs_code = TREE_CODE (lhs);
	}
    }

  inv_code = invert_tree_comparison (code, HONOR_NANS (type));
  if (inv_code == rhs_code
      && operand_equal_p (TREE_OPERAND (rhs, 0), TREE_OPERAND (cmpop, 0), 0)
      && operand_equal_p (TREE_OPERAND (rhs, 1), TREE_OPERAND (cmpop, 1), 0))
    return lhs;
  if (!rhs_only && inv_code == lhs_code
      && operand_equal_p (TREE_OPERAND (lhs, 0), TREE_OPERAND (cmpop, 0), 0)
      && operand_equal_p (TREE_OPERAND (lhs, 1), TREE_OPERAND (cmpop, 1), 0))
    return rhs;
  if (rhs != orig_rhs || lhs != orig_lhs)
    return fold_build2_loc (loc, truthop_code, TREE_TYPE (cmpop),
			    lhs, rhs);
  return NULL_TREE;
}

/* 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_truth_andor_1 (location_t loc, 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;
  int ll_reversep, lr_reversep, rl_reversep, rr_reversep;
  machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
  scalar_int_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;
  HOST_WIDE_INT first_bit, end_bit;
  int volatilep;

  /* 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))
    {
      if (operand_equal_p (ll_arg, rl_arg, 0)
          && operand_equal_p (lr_arg, rr_arg, 0))
	{
          result = combine_comparisons (loc, 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 (loc, 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.  */

  if (BRANCH_COST (optimize_function_for_speed_p (cfun),
		   false) >= 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)
	  && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)))
	return build2_loc (loc, 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)
	  && INTEGRAL_TYPE_P (TREE_TYPE (ll_arg)))
	return build2_loc (loc, EQ_EXPR, truth_type,
			   build2 (BIT_IOR_EXPR, TREE_TYPE (ll_arg),
				   ll_arg, rl_arg),
			   build_int_cst (TREE_TYPE (ll_arg), 0));
    }

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

  ll_reversep = lr_reversep = rl_reversep = rr_reversep = 0;
  volatilep = 0;
  ll_inner = decode_field_reference (loc, &ll_arg,
				     &ll_bitsize, &ll_bitpos, &ll_mode,
				     &ll_unsignedp, &ll_reversep, &volatilep,
				     &ll_mask, &ll_and_mask);
  lr_inner = decode_field_reference (loc, &lr_arg,
				     &lr_bitsize, &lr_bitpos, &lr_mode,
				     &lr_unsignedp, &lr_reversep, &volatilep,
				     &lr_mask, &lr_and_mask);
  rl_inner = decode_field_reference (loc, &rl_arg,
				     &rl_bitsize, &rl_bitpos, &rl_mode,
				     &rl_unsignedp, &rl_reversep, &volatilep,
				     &rl_mask, &rl_and_mask);
  rr_inner = decode_field_reference (loc, &rr_arg,
				     &rr_bitsize, &rr_bitpos, &rr_mode,
				     &rr_unsignedp, &rr_reversep, &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_reversep != rl_reversep
      || 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;
      lr_reversep = ll_reversep;
    }
  else if (lr_reversep != rr_reversep
	   || 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;
    }

  /* 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);
  if (!get_best_mode (end_bit - first_bit, first_bit, 0, 0,
		      TYPE_ALIGN (TREE_TYPE (ll_inner)), BITS_PER_WORD,
		      volatilep, &lnmode))
    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 (ll_reversep ? !BYTES_BIG_ENDIAN : 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_loc (loc, lntype, ll_mask),
			 size_int (xll_bitpos));
  rl_mask = const_binop (LSHIFT_EXPR, fold_convert_loc (loc, lntype, rl_mask),
			 size_int (xrl_bitpos));

  if (l_const)
    {
      l_const = fold_convert_loc (loc, 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));
      if (! integer_zerop (const_binop (BIT_AND_EXPR, l_const,
					fold_build1_loc (loc, BIT_NOT_EXPR,
						     lntype, ll_mask))))
	{
	  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_loc (loc, 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));
      if (! integer_zerop (const_binop (BIT_AND_EXPR, r_const,
					fold_build1_loc (loc, BIT_NOT_EXPR,
						     lntype, rl_mask))))
	{
	  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, signedness or storage order
     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
	  || ll_reversep != lr_reversep
	  /* 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);
      if (!get_best_mode (end_bit - first_bit, first_bit, 0, 0,
			  TYPE_ALIGN (TREE_TYPE (lr_inner)), BITS_PER_WORD,
			  volatilep, &rnmode))
	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 (lr_reversep ? !BYTES_BIG_ENDIAN : 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_loc (loc,
							    rntype, lr_mask),
			     size_int (xlr_bitpos));
      rr_mask = const_binop (LSHIFT_EXPR, fold_convert_loc (loc,
							    rntype, rr_mask),
			     size_int (xrr_bitpos));

      /* 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);
      lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask);
      if (lnbitsize == rnbitsize
	  && xll_bitpos == xlr_bitpos
	  && lnbitpos >= 0
	  && rnbitpos >= 0)
	{
	  lhs = make_bit_field_ref (loc, ll_inner, ll_arg,
				    lntype, lnbitsize, lnbitpos,
				    ll_unsignedp || rl_unsignedp, ll_reversep);
	  if (! all_ones_mask_p (ll_mask, lnbitsize))
	    lhs = build2 (BIT_AND_EXPR, lntype, lhs, ll_mask);

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

	  return build2_loc (loc, 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))
	  && ll_bitpos >= 0
	  && rl_bitpos >= 0
	  && lr_bitpos >= 0
	  && rr_bitpos >= 0)
	{
	  tree type;

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

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

	  /* Convert to the smaller type before masking out unwanted bits.  */
	  type = lntype;
	  if (lntype != rntype)
	    {
	      if (lnbitsize > rnbitsize)
		{
		  lhs = fold_convert_loc (loc, rntype, lhs);
		  ll_mask = fold_convert_loc (loc, rntype, ll_mask);
		  type = rntype;
		}
	      else if (lnbitsize < rnbitsize)
		{
		  rhs = fold_convert_loc (loc, lntype, rhs);
		  lr_mask = fold_convert_loc (loc, 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_loc (loc, 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);
  if (! integer_zerop (result)
      && simple_cst_equal (const_binop (BIT_AND_EXPR, result, l_const),
			   const_binop (BIT_AND_EXPR, result, r_const)) != 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);
	}
    }

  if (lnbitpos < 0)
    return 0;

  /* 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 (loc, ll_inner, ll_arg,
			       lntype, lnbitsize, lnbitpos,
			       ll_unsignedp || rl_unsignedp, ll_reversep);

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

  return build2_loc (loc, wanted_code, truth_type, result,
		     const_binop (BIT_IOR_EXPR, l_const, r_const));
}

/* 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.

   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 (SCALAR_INT_TYPE_MODE (wide_type))
		    > GET_MODE_SIZE (SCALAR_INT_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
	  || wi::multiple_of_p (wi::to_wide (t), wi::to_wide (c),
				TYPE_SIGN (type)))
	{
	  tree tem = const_binop (code, fold_convert (ctype, t),
				  fold_convert (ctype, c));
	  /* If the multiplication overflowed, we lost information on it.
	     See PR68142 and PR69845.  */
	  if (TREE_OVERFLOW (tem))
	    return NULL_TREE;
	  return tem;
	}
      break;

    CASE_CONVERT: case NON_LVALUE_EXPR:
      if (!INTEGRAL_TYPE_P (TREE_TYPE (op0)))
	break;
      /* If op0 is an expression ...  */
      if ((COMPARISON_CLASS_P (op0)
	   || UNARY_CLASS_P (op0)
	   || BINARY_CLASS_P (op0)
	   || VL_EXP_CLASS_P (op0)
	   || EXPRESSION_CLASS_P (op0))
	  /* ... and has wrapping overflow, and its type is smaller
	     than ctype, then we cannot pass through as widening.  */
	  && ((TYPE_OVERFLOW_WRAPS (TREE_TYPE (op0))
	       && (TYPE_PRECISION (ctype)
	           > TYPE_PRECISION (TREE_TYPE (op0))))
	      /* ... or this is a truncation (t is narrower than op0),
		 then we cannot pass through this narrowing.  */
	      || (TYPE_PRECISION (type)
		  < TYPE_PRECISION (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))))
	      /* ... or has undefined overflow while the converted to
		 type has not, we cannot do the operation in the inner type
		 as that would introduce undefined overflow.  */
	      || (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0))
		  && !TYPE_OVERFLOW_UNDEFINED (type))))
	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_OVERFLOW (t2)
	  && (t1 = extract_muldiv (op0, t2, code,
				   code == MULT_EXPR ? ctype : NULL_TREE,
				   strict_overflow_p)) != 0)
	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 = (*signed_type_for) (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;
        }
      /* If the constant is negative, we cannot simplify this.  */
      if (tree_int_cst_sgn (c) == -1)
        break;
      /* FALLTHROUGH */
    case NEGATE_EXPR:
      /* For division and modulus, type can't be unsigned, as e.g.
	 (-(x / 2U)) / 2U isn't equal to -((x / 2U) / 2U) for x >= 2.
	 For signed types, even with wrapping overflow, this is fine.  */
      if (code != MULT_EXPR && TYPE_UNSIGNED (type))
	break;
      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.  */
	  && wi::gtu_p (TYPE_PRECISION (TREE_TYPE (size_one_node)),
			wi::to_wide (op1))
	  && (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
	  && TYPE_OVERFLOW_WRAPS (ctype)
	  && (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 OP1 was not easily negatable, the constant may be OP0.  */
	  if (TREE_CODE (op0) == INTEGER_CST)
	    {
	      std::swap (op0, op1);
	      std::swap (t1, t2);
	    }
	}

      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
	  || wi::multiple_of_p (wi::to_wide (op1), wi::to_wide (c),
				TYPE_SIGN (type)))
	{
	  op1 = const_binop (code, fold_convert (ctype, op1),
			     fold_convert (ctype, c));
	  /* 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, we cannot widen the operation since it
	 will change the result if the original computation overflowed.  */
      if (TYPE_UNSIGNED (ctype) && ctype != type)
	break;

      /* 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
	 and overflow is defined.  With undefined overflow
	 op0 * c might overflow, while (op0 + orig_op1) * c doesn't.
	 But fold_plusminus_mult_expr would factor back any power-of-two
	 value so do not distribute in the first place in this case.  */
      if (code == MULT_EXPR
	  && TYPE_OVERFLOW_WRAPS (ctype)
	  && !(tree_fits_shwi_p (c) && pow2p_hwi (absu_hwi (tree_to_shwi (c)))))
	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)
	  /* If the multiplication can overflow we cannot optimize this.  */
	  && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t))
	  && TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
	  && wi::multiple_of_p (wi::to_wide (op1), wi::to_wide (c),
				TYPE_SIGN (type)))
	{
	  *strict_overflow_p = true;
	  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
	  && TYPE_OVERFLOW_WRAPS (ctype)
	  && (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
	       && TYPE_OVERFLOW_WRAPS (ctype)
	       && (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)
	{
	  bool overflow_p = false;
	  wi::overflow_type overflow_mul;
	  signop sign = TYPE_SIGN (ctype);
	  unsigned prec = TYPE_PRECISION (ctype);
	  wide_int mul = wi::mul (wi::to_wide (op1, prec),
				  wi::to_wide (c, prec),
				  sign, &overflow_mul);
	  overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1);
	  if (overflow_mul
	      && ((sign == UNSIGNED && tcode != MULT_EXPR) || sign == SIGNED))
	    overflow_p = true;
	  if (!overflow_p)
	    return fold_build2 (tcode, ctype, fold_convert (ctype, op0),
				wide_int_to_tree (ctype, mul));
	}

      /* 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, we cannot do this since it will change
	 the result if the original computation overflowed.  */
      if (TYPE_OVERFLOW_UNDEFINED (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
		  && code != MULT_EXPR)))
	{
	  if (wi::multiple_of_p (wi::to_wide (op1), wi::to_wide (c),
				 TYPE_SIGN (type)))
	    {
	      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)));
	    }
	  else if (wi::multiple_of_p (wi::to_wide (c), wi::to_wide (op1),
				      TYPE_SIGN (type)))
	    {
	      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)));
	    }
	}
      break;

    default:
      break;
    }

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

tree
constant_boolean_node (bool 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 if (TREE_CODE (type) == VECTOR_TYPE)
    return build_vector_from_val (type,
				  build_int_cst (TREE_TYPE (type),
						 value ? -1 : 0));
  else
    return fold_convert (type, value ? integer_one_node : integer_zero_node);
}


/* 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 (location_t loc,
				     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;
  enum tree_code cond_code = COND_EXPR;

  /* Do not move possibly trapping operations into the conditional as this
     pessimizes code and causes gimplification issues when applied late.  */
  if (operation_could_trap_p (code, FLOAT_TYPE_P (type),
			      ANY_INTEGRAL_TYPE_P (type)
			      && TYPE_OVERFLOW_TRAPS (type), op1))
    return NULL_TREE;

  if (TREE_CODE (cond) == COND_EXPR
      || TREE_CODE (cond) == VEC_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 if (!(TREE_CODE (type) != VECTOR_TYPE
	     && TREE_CODE (TREE_TYPE (cond)) == VECTOR_TYPE))
    {
      tree testtype = TREE_TYPE (cond);
      test = cond;
      true_value = constant_boolean_node (true, testtype);
      false_value = constant_boolean_node (false, testtype);
    }
  else
    /* Detect the case of mixing vector and scalar types - bail out.  */
    return NULL_TREE;

  if (TREE_CODE (TREE_TYPE (test)) == VECTOR_TYPE)
    cond_code = VEC_COND_EXPR;

  /* This transformation is only worthwhile if we don't have to wrap ARG
     in a SAVE_EXPR and the operation can be simplified without recursing
     on at least one of the branches once its pushed inside the COND_EXPR.  */
  if (!TREE_CONSTANT (arg)
      && (TREE_SIDE_EFFECTS (arg)
	  || TREE_CODE (arg) == COND_EXPR || TREE_CODE (arg) == VEC_COND_EXPR
	  || TREE_CONSTANT (true_value) || TREE_CONSTANT (false_value)))
    return NULL_TREE;

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

  /* Check that we have simplified at least one of the branches.  */
  if (!TREE_CONSTANT (arg) && !TREE_CONSTANT (lhs) && !TREE_CONSTANT (rhs))
    return NULL_TREE;

  return fold_build3_loc (loc, cond_code, type, test, lhs, rhs);
}

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

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

   If ARG is NULL, check for any value of type TYPE.

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

bool
fold_real_zero_addition_p (const_tree type, const_tree arg,
                           const_tree zero_arg, int negate)
{
  if (!real_zerop (zero_arg))
    return false;

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

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

  /* There is no case that is safe for all rounding modes.  */
  if (HONOR_SIGN_DEPENDENT_ROUNDING (type))
    return false;

  /* In a vector or complex, we would need to check the sign of all zeros.  */
  if (TREE_CODE (zero_arg) == VECTOR_CST)
    zero_arg = uniform_vector_p (zero_arg);
  if (!zero_arg || TREE_CODE (zero_arg) != REAL_CST)
    return false;

  /* Treat x + -0 as x - 0 and x - -0 as x + 0.  */
  if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (zero_arg)))
    negate = !negate;

  /* The mode has signed zeros, and we have to honor their sign.
     In this situation, there are only two cases we can return true for.
     (i) X - 0 is the same as X with default rounding.
     (ii) X + 0 is X when X can't possibly be -0.0.  */
  return negate || (arg && !tree_expr_maybe_real_minus_zero_p (arg));
}

/* Subroutine of match.pd 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.  ARG01 and ARG1 must be a INTEGER_CST.  */

enum tree_code
fold_div_compare (enum tree_code code, tree c1, tree c2, tree *lo,
		  tree *hi, bool *neg_overflow)
{
  tree prod, tmp, type = TREE_TYPE (c1);
  signop sign = TYPE_SIGN (type);
  wi::overflow_type overflow;

  /* We have to do this the hard way to detect unsigned overflow.
     prod = int_const_binop (MULT_EXPR, c1, c2);  */
  wide_int val = wi::mul (wi::to_wide (c1), wi::to_wide (c2), sign, &overflow);
  prod = force_fit_type (type, val, -1, overflow);
  *neg_overflow = false;

  if (sign == UNSIGNED)
    {
      tmp = int_const_binop (MINUS_EXPR, c1, build_int_cst (type, 1));
      *lo = prod;

      /* Likewise *hi = int_const_binop (PLUS_EXPR, prod, tmp).  */
      val = wi::add (wi::to_wide (prod), wi::to_wide (tmp), sign, &overflow);
      *hi = force_fit_type (type, val, -1, overflow | TREE_OVERFLOW (prod));
    }
  else if (tree_int_cst_sgn (c1) >= 0)
    {
      tmp = int_const_binop (MINUS_EXPR, c1, build_int_cst (type, 1));
      switch (tree_int_cst_sgn (c2))
	{
	case -1:
	  *neg_overflow = true;
	  *lo = int_const_binop (MINUS_EXPR, prod, tmp);
	  *hi = prod;
	  break;

	case 0:
	  *lo = fold_negate_const (tmp, type);
	  *hi = tmp;
	  break;

	case 1:
	  *hi = int_const_binop (PLUS_EXPR, prod, tmp);
	  *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, c1, build_int_cst (type, 1));
      switch (tree_int_cst_sgn (c2))
	{
	case -1:
	  *hi = int_const_binop (MINUS_EXPR, prod, tmp);
	  *lo = prod;
	  break;

	case 0:
	  *hi = fold_negate_const (tmp, type);
	  *lo = tmp;
	  break;

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

	default:
	  gcc_unreachable ();
	}
    }

  if (code != EQ_EXPR && code != NE_EXPR)
    return code;

  if (TREE_OVERFLOW (*lo)
      || operand_equal_p (*lo, TYPE_MIN_VALUE (type), 0))
    *lo = NULL_TREE;
  if (TREE_OVERFLOW (*hi)
      || operand_equal_p (*hi, TYPE_MAX_VALUE (type), 0))
    *hi = NULL_TREE;

  return code;
}


/* 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 (location_t loc,
				     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_has_mode_precision_p (TREE_TYPE (arg00)))
	{
	  tree stype = signed_type_for (TREE_TYPE (arg00));
	  return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
			      result_type,
			      fold_convert_loc (loc, 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 (location_t loc, 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));
      scalar_int_mode operand_mode = SCALAR_INT_TYPE_MODE (type);
      int ops_unsigned;
      tree signed_type, unsigned_type, intermediate_type;
      tree tem, one;

      /* First, see if we can fold the single bit test into a sign-bit
	 test.  */
      tem = fold_single_bit_test_into_sign_test (loc, 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
	  && bitnum < TYPE_PRECISION (type)
	  && wi::ltu_p (wi::to_wide (TREE_OPERAND (inner, 1)),
			TYPE_PRECISION (type) - bitnum))
	{
	  bitnum += tree_to_uhwi (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.  */
      ops_unsigned = (load_extend_op (operand_mode) == SIGN_EXTEND
		      && !flag_syntax_only) ? 0 : 1;

      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_loc (loc, intermediate_type, inner);

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

      one = build_int_cst (intermediate_type, 1);

      if (code == EQ_EXPR)
	inner = fold_build2_loc (loc, BIT_XOR_EXPR, intermediate_type, inner, one);

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

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

      return inner;
    }
  return NULL_TREE;
}

/* Test whether it is preferable to swap two operands, ARG0 and
   ARG1, for example because ARG0 is an integer constant and ARG1
   isn't.  */

bool
tree_swap_operands_p (const_tree arg0, const_tree arg1)
{
  if (CONSTANT_CLASS_P (arg1))
    return 0;
  if (CONSTANT_CLASS_P (arg0))
    return 1;

  STRIP_NOPS (arg0);
  STRIP_NOPS (arg1);

  if (TREE_CONSTANT (arg1))
    return 0;
  if (TREE_CONSTANT (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;

  /* Put SSA_NAMEs last.  */
  if (TREE_CODE (arg1) == SSA_NAME)
    return 0;
  if (TREE_CODE (arg0) == SSA_NAME)
    return 1;

  /* Put variables last.  */
  if (DECL_P (arg1))
    return 0;
  if (DECL_P (arg0))
    return 1;

  return 0;
}


/* 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 (location_t loc, 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;

  if (POINTER_TYPE_P (typea))
    {
      /* Convert the pointer types into integer before taking the difference.  */
      tree ta = fold_convert_loc (loc, ssizetype, a);
      tree ta1 = fold_convert_loc (loc, ssizetype, a1);
      diff = fold_binary_loc (loc, MINUS_EXPR, ssizetype, ta1, ta);
    }
  else
    diff = fold_binary_loc (loc, MINUS_EXPR, typea, a1, a);

  if (!diff || !integer_onep (diff))
   return NULL_TREE;

  return fold_build2_loc (loc, 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 (location_t loc, 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 if (TREE_CODE (arg0) == INTEGER_CST)
    {
      arg00 = build_one_cst (type);
      arg01 = arg0;
    }
  else
    {
      /* We cannot generate constant 1 for fract.  */
      if (ALL_FRACT_MODE_P (TYPE_MODE (type)))
	return NULL_TREE;
      arg00 = arg0;
      arg01 = build_one_cst (type);
    }
  if (TREE_CODE (arg1) == MULT_EXPR)
    {
      arg10 = TREE_OPERAND (arg1, 0);
      arg11 = TREE_OPERAND (arg1, 1);
    }
  else if (TREE_CODE (arg1) == INTEGER_CST)
    {
      arg10 = build_one_cst (type);
      /* As we canonicalize A - 2 to A + -2 get rid of that sign for
	 the purpose of this canonicalization.  */
      if (wi::neg_p (wi::to_wide (arg1), TYPE_SIGN (TREE_TYPE (arg1)))
	  && negate_expr_p (arg1)
	  && code == PLUS_EXPR)
	{
	  arg11 = negate_expr (arg1);
	  code = MINUS_EXPR;
	}
      else
	arg11 = arg1;
    }
  else
    {
      /* We cannot generate constant 1 for fract.  */
      if (ALL_FRACT_MODE_P (TYPE_MODE (type)))
	return NULL_TREE;
      arg10 = arg1;
      arg11 = build_one_cst (type);
    }
  same = NULL_TREE;

  /* Prefer factoring a common non-constant.  */
  if (operand_equal_p (arg00, arg10, 0))
    same = arg00, alt0 = arg01, alt1 = arg11;
  else if (operand_equal_p (arg01, arg11, 0))
    same = arg01, alt0 = arg00, alt1 = arg10;
  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 (tree_fits_shwi_p (arg01) && tree_fits_shwi_p (arg11))
    {
      HOST_WIDE_INT int01 = tree_to_shwi (arg01);
      HOST_WIDE_INT int11 = tree_to_shwi (arg11);
      HOST_WIDE_INT tmp;
      bool swap = false;
      tree maybe_same;

      /* Move min of absolute values to int11.  */
      if (absu_hwi (int01) < absu_hwi (int11))
        {
	  tmp = int01, int01 = int11, int11 = tmp;
	  alt0 = arg00, arg00 = arg10, arg10 = alt0;
	  maybe_same = arg01;
	  swap = true;
	}
      else
	maybe_same = arg11;

      const unsigned HOST_WIDE_INT factor = absu_hwi (int11);
      if (factor > 1
	  && pow2p_hwi (factor)
	  && (int01 & (factor - 1)) == 0
	  /* The remainder should not be a constant, otherwise we
	     end up folding i * 4 + 2 to (i * 2 + 1) * 2 which has
	     increased the number of multiplications necessary.  */
	  && TREE_CODE (arg10) != INTEGER_CST)
        {
	  alt0 = fold_build2_loc (loc, 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 NULL_TREE;

  if (! ANY_INTEGRAL_TYPE_P (type)
      || TYPE_OVERFLOW_WRAPS (type)
      /* We are neither factoring zero nor minus one.  */
      || TREE_CODE (same) == INTEGER_CST)
    return fold_build2_loc (loc, MULT_EXPR, type,
			fold_build2_loc (loc, code, type,
				     fold_convert_loc (loc, type, alt0),
				     fold_convert_loc (loc, type, alt1)),
			fold_convert_loc (loc, type, same));

  /* Same may be zero and thus the operation 'code' may overflow.  Likewise
     same may be minus one and thus the multiplication may overflow.  Perform
     the sum operation in an unsigned type.  */
  tree utype = unsigned_type_for (type);
  tree tem = fold_build2_loc (loc, code, utype,
			      fold_convert_loc (loc, utype, alt0),
			      fold_convert_loc (loc, utype, alt1));
  /* If the sum evaluated to a constant that is not -INF the multiplication
     cannot overflow.  */
  if (TREE_CODE (tem) == INTEGER_CST
      && (wi::to_wide (tem)
	  != wi::min_value (TYPE_PRECISION (utype), SIGNED)))
    return fold_build2_loc (loc, MULT_EXPR, type,
			    fold_convert (type, tem), same);

  /* Do not resort to unsigned multiplication because
     we lose the no-overflow property of the expression.  */
  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 (const_tree expr, unsigned char *ptr, int len, int off)
{
  tree type = TREE_TYPE (expr);
  int total_bytes = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));
  int byte, offset, word, words;
  unsigned char value;

  if ((off == -1 && total_bytes > len) || off >= total_bytes)
    return 0;
  if (off == -1)
    off = 0;

  if (ptr == NULL)
    /* Dry run.  */
    return MIN (len, total_bytes - off);

  words = total_bytes / UNITS_PER_WORD;

  for (byte = 0; byte < total_bytes; byte++)
    {
      int bitpos = byte * BITS_PER_UNIT;
      /* Extend EXPR according to TYPE_SIGN if the precision isn't a whole
	 number of bytes.  */
      value = wi::extract_uhwi (wi::to_widest (expr), bitpos, 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;
      if (offset >= off && offset - off < len)
	ptr[offset - off] = value;
    }
  return MIN (len, total_bytes - off);
}


/* Subroutine of native_encode_expr.  Encode the FIXED_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_fixed (const_tree expr, unsigned char *ptr, int len, int off)
{
  tree type = TREE_TYPE (expr);
  scalar_mode mode = SCALAR_TYPE_MODE (type);
  int total_bytes = GET_MODE_SIZE (mode);
  FIXED_VALUE_TYPE value;
  tree i_value, i_type;

  if (total_bytes * BITS_PER_UNIT > HOST_BITS_PER_DOUBLE_INT)
    return 0;

  i_type = lang_hooks.types.type_for_size (GET_MODE_BITSIZE (mode), 1);

  if (NULL_TREE == i_type || TYPE_PRECISION (i_type) != total_bytes)
    return 0;
  
  value = TREE_FIXED_CST (expr);
  i_value = double_int_to_tree (i_type, value.data);

  return native_encode_int (i_value, ptr, len, off);
}


/* 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 (const_tree expr, unsigned char *ptr, int len, int off)
{
  tree type = TREE_TYPE (expr);
  int total_bytes = GET_MODE_SIZE (SCALAR_FLOAT_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 ((off == -1 && total_bytes > len) || off >= total_bytes)
    return 0;
  if (off == -1)
    off = 0;

  if (ptr == NULL)
    /* Dry run.  */
    return MIN (len, total_bytes - off);

  words = (32 / BITS_PER_UNIT) / 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 = byte;
	  if (BYTES_BIG_ENDIAN)
	    {
	      /* Reverse bytes within each long, or within the entire float
		 if it's smaller than a long (for HFmode).  */
	      offset = MIN (3, total_bytes - 1) - offset;
	      gcc_assert (offset >= 0);
	    }
	}
      offset = offset + ((bitpos / BITS_PER_UNIT) & ~3);
      if (offset >= off
	  && offset - off < len)
	ptr[offset - off] = value;
    }
  return MIN (len, total_bytes - off);
}

/* 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 (const_tree expr, unsigned char *ptr, int len, int off)
{
  int rsize, isize;
  tree part;

  part = TREE_REALPART (expr);
  rsize = native_encode_expr (part, ptr, len, off);
  if (off == -1 && rsize == 0)
    return 0;
  part = TREE_IMAGPART (expr);
  if (off != -1)
    off = MAX (0, off - GET_MODE_SIZE (SCALAR_TYPE_MODE (TREE_TYPE (part))));
  isize = native_encode_expr (part, ptr ? ptr + rsize : NULL,
			      len - rsize, off);
  if (off == -1 && isize != rsize)
    return 0;
  return rsize + isize;
}

/* Like native_encode_vector, but only encode the first COUNT elements.
   The other arguments are as for native_encode_vector.  */

static int
native_encode_vector_part (const_tree expr, unsigned char *ptr, int len,
			   int off, unsigned HOST_WIDE_INT count)
{
  tree itype = TREE_TYPE (TREE_TYPE (expr));
  if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (expr))
      && TYPE_PRECISION (itype) <= BITS_PER_UNIT)
    {
      /* This is the only case in which elements can be smaller than a byte.
	 Element 0 is always in the lsb of the containing byte.  */
      unsigned int elt_bits = TYPE_PRECISION (itype);
      int total_bytes = CEIL (elt_bits * count, BITS_PER_UNIT);
      if ((off == -1 && total_bytes > len) || off >= total_bytes)
	return 0;

      if (off == -1)
	off = 0;

      /* Zero the buffer and then set bits later where necessary.  */
      int extract_bytes = MIN (len, total_bytes - off);
      if (ptr)
	memset (ptr, 0, extract_bytes);

      unsigned int elts_per_byte = BITS_PER_UNIT / elt_bits;
      unsigned int first_elt = off * elts_per_byte;
      unsigned int extract_elts = extract_bytes * elts_per_byte;
      for (unsigned int i = 0; i < extract_elts; ++i)
	{
	  tree elt = VECTOR_CST_ELT (expr, first_elt + i);
	  if (TREE_CODE (elt) != INTEGER_CST)
	    return 0;

	  if (ptr && wi::extract_uhwi (wi::to_wide (elt), 0, 1))
	    {
	      unsigned int bit = i * elt_bits;
	      ptr[bit / BITS_PER_UNIT] |= 1 << (bit % BITS_PER_UNIT);
	    }
	}
      return extract_bytes;
    }

  int offset = 0;
  int size = GET_MODE_SIZE (SCALAR_TYPE_MODE (itype));
  for (unsigned HOST_WIDE_INT i = 0; i < count; i++)
    {
      if (off >= size)
	{
	  off -= size;
	  continue;
	}
      tree elem = VECTOR_CST_ELT (expr, i);
      int res = native_encode_expr (elem, ptr ? ptr + offset : NULL,
				    len - offset, off);
      if ((off == -1 && res != size) || res == 0)
	return 0;
      offset += res;
      if (offset >= len)
	return (off == -1 && i < count - 1) ? 0 : offset;
      if (off != -1)
	off = 0;
    }
  return offset;
}

/* 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 (const_tree expr, unsigned char *ptr, int len, int off)
{
  unsigned HOST_WIDE_INT count;
  if (!VECTOR_CST_NELTS (expr).is_constant (&count))
    return 0;
  return native_encode_vector_part (expr, ptr, len, off, count);
}


/* Subroutine of native_encode_expr.  Encode the STRING_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_string (const_tree expr, unsigned char *ptr, int len, int off)
{
  tree type = TREE_TYPE (expr);

  /* Wide-char strings are encoded in target byte-order so native
     encoding them is trivial.  */
  if (BITS_PER_UNIT != CHAR_BIT
      || TREE_CODE (type) != ARRAY_TYPE
      || TREE_CODE (TREE_TYPE (type)) != INTEGER_TYPE
      || !tree_fits_shwi_p (TYPE_SIZE_UNIT (type)))
    return 0;

  HOST_WIDE_INT total_bytes = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
  if ((off == -1 && total_bytes > len) || off >= total_bytes)
    return 0;
  if (off == -1)
    off = 0;
  len = MIN (total_bytes - off, len);
  if (ptr == NULL)
    /* Dry run.  */;
  else
    {
      int written = 0;
      if (off < TREE_STRING_LENGTH (expr))
	{
	  written = MIN (len, TREE_STRING_LENGTH (expr) - off);
	  memcpy (ptr, TREE_STRING_POINTER (expr) + off, written);
	}
      memset (ptr + written, 0, len - written);
    }
  return len;
}


/* Subroutine of fold_view_convert_expr.  Encode the INTEGER_CST, REAL_CST,
   FIXED_CST, COMPLEX_CST, STRING_CST, or VECTOR_CST specified by EXPR into
   the buffer PTR of size LEN bytes.  If PTR is NULL, don't actually store
   anything, just do a dry run.  Fail either if OFF is -1 and LEN isn't
   sufficient to encode the entire EXPR, or if OFF is out of bounds.
   Otherwise, start at byte offset OFF and encode at most LEN bytes.
   Return the number of bytes placed in the buffer, or zero upon failure.  */

int
native_encode_expr (const_tree expr, unsigned char *ptr, int len, int off)
{
  /* We don't support starting at negative offset and -1 is special.  */
  if (off < -1)
    return 0;

  switch (TREE_CODE (expr))
    {
    case INTEGER_CST:
      return native_encode_int (expr, ptr, len, off);

    case REAL_CST:
      return native_encode_real (expr, ptr, len, off);

    case FIXED_CST:
      return native_encode_fixed (expr, ptr, len, off);

    case COMPLEX_CST:
      return native_encode_complex (expr, ptr, len, off);

    case VECTOR_CST:
      return native_encode_vector (expr, ptr, len, off);

    case STRING_CST:
      return native_encode_string (expr, ptr, len, off);

    default:
      return 0;
    }
}

/* Try to find a type whose byte size is smaller or equal to LEN bytes larger
   or equal to FIELDSIZE bytes, with underlying mode precision/size multiple
   of BITS_PER_UNIT.  As native_{interpret,encode}_int works in term of
   machine modes, we can't just use build_nonstandard_integer_type.  */

tree
find_bitfield_repr_type (int fieldsize, int len)
{
  machine_mode mode;
  for (int pass = 0; pass < 2; pass++)
    {
      enum mode_class mclass = pass ? MODE_PARTIAL_INT : MODE_INT;
      FOR_EACH_MODE_IN_CLASS (mode, mclass)
	if (known_ge (GET_MODE_SIZE (mode), fieldsize)
	    && known_eq (GET_MODE_PRECISION (mode),
			 GET_MODE_BITSIZE (mode))
	    && known_le (GET_MODE_SIZE (mode), len))
	  {
	    tree ret = lang_hooks.types.type_for_mode (mode, 1);
	    if (ret && TYPE_MODE (ret) == mode)
	      return ret;
	  }
    }

  for (int i = 0; i < NUM_INT_N_ENTS; i ++)
    if (int_n_enabled_p[i]
	&& int_n_data[i].bitsize >= (unsigned) (BITS_PER_UNIT * fieldsize)
	&& int_n_trees[i].unsigned_type)
      {
	tree ret = int_n_trees[i].unsigned_type;
	mode = TYPE_MODE (ret);
	if (known_ge (GET_MODE_SIZE (mode), fieldsize)
	    && known_eq (GET_MODE_PRECISION (mode),
			 GET_MODE_BITSIZE (mode))
	    && known_le (GET_MODE_SIZE (mode), len))
	  return ret;
      }

  return NULL_TREE;
}

/* Similar to native_encode_expr, but also handle CONSTRUCTORs, VCEs,
   NON_LVALUE_EXPRs and nops.  If MASK is non-NULL (then PTR has
   to be non-NULL and OFF zero), then in addition to filling the
   bytes pointed by PTR with the value also clear any bits pointed
   by MASK that are known to be initialized, keep them as is for
   e.g. uninitialized padding bits or uninitialized fields.  */

int
native_encode_initializer (tree init, unsigned char *ptr, int len,
			   int off, unsigned char *mask)
{
  int r;

  /* We don't support starting at negative offset and -1 is special.  */
  if (off < -1 || init == NULL_TREE)
    return 0;

  gcc_assert (mask == NULL || (off == 0 && ptr));

  STRIP_NOPS (init);
  switch (TREE_CODE (init))
    {
    case VIEW_CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      return native_encode_initializer (TREE_OPERAND (init, 0), ptr, len, off,
					mask);
    default:
      r = native_encode_expr (init, ptr, len, off);
      if (mask)
	memset (mask, 0, r);
      return r;
    case CONSTRUCTOR:
      tree type = TREE_TYPE (init);
      HOST_WIDE_INT total_bytes = int_size_in_bytes (type);
      if (total_bytes < 0)
	return 0;
      if ((off == -1 && total_bytes > len) || off >= total_bytes)
	return 0;
      int o = off == -1 ? 0 : off;
      if (TREE_CODE (type) == ARRAY_TYPE)
	{
	  tree min_index;
	  unsigned HOST_WIDE_INT cnt;
	  HOST_WIDE_INT curpos = 0, fieldsize, valueinit = -1;
	  constructor_elt *ce;

	  if (!TYPE_DOMAIN (type)
	      || TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) != INTEGER_CST)
	    return 0;

	  fieldsize = int_size_in_bytes (TREE_TYPE (type));
	  if (fieldsize <= 0)
	    return 0;

	  min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
	  if (ptr)
	    memset (ptr, '\0', MIN (total_bytes - off, len));

	  for (cnt = 0; ; cnt++)
	    {
	      tree val = NULL_TREE, index = NULL_TREE;
	      HOST_WIDE_INT pos = curpos, count = 0;
	      bool full = false;
	      if (vec_safe_iterate (CONSTRUCTOR_ELTS (init), cnt, &ce))
		{
		  val = ce->value;
		  index = ce->index;
		}
	      else if (mask == NULL
		       || CONSTRUCTOR_NO_CLEARING (init)
		       || curpos >= total_bytes)
		break;
	      else
		pos = total_bytes;

	      if (index && TREE_CODE (index) == RANGE_EXPR)
		{
		  if (TREE_CODE (TREE_OPERAND (index, 0)) != INTEGER_CST
		      || TREE_CODE (TREE_OPERAND (index, 1)) != INTEGER_CST)
		    return 0;
		  offset_int wpos
		    = wi::sext (wi::to_offset (TREE_OPERAND (index, 0))
				- wi::to_offset (min_index),
				TYPE_PRECISION (sizetype));
		  wpos *= fieldsize;
		  if (!wi::fits_shwi_p (pos))
		    return 0;
		  pos = wpos.to_shwi ();
		  offset_int wcount
		    = wi::sext (wi::to_offset (TREE_OPERAND (index, 1))
				- wi::to_offset (TREE_OPERAND (index, 0)),
				TYPE_PRECISION (sizetype));
		  if (!wi::fits_shwi_p (wcount))
		    return 0;
		  count = wcount.to_shwi ();
		}
	      else if (index)
		{
		  if (TREE_CODE (index) != INTEGER_CST)
		    return 0;
		  offset_int wpos
		    = wi::sext (wi::to_offset (index)
				- wi::to_offset (min_index),
				TYPE_PRECISION (sizetype));
		  wpos *= fieldsize;
		  if (!wi::fits_shwi_p (wpos))
		    return 0;
		  pos = wpos.to_shwi ();
		}

	      if (mask && !CONSTRUCTOR_NO_CLEARING (init) && curpos != pos)
		{
		  if (valueinit == -1)
		    {
		      tree zero = build_zero_cst (TREE_TYPE (type));
		      r = native_encode_initializer (zero, ptr + curpos,
						     fieldsize, 0,
						     mask + curpos);
		      if (TREE_CODE (zero) == CONSTRUCTOR)
			ggc_free (zero);
		      if (!r)
			return 0;
		      valueinit = curpos;
		      curpos += fieldsize;
		    }
		  while (curpos != pos)
		    {
		      memcpy (ptr + curpos, ptr + valueinit, fieldsize);
		      memcpy (mask + curpos, mask + valueinit, fieldsize);
		      curpos += fieldsize;
		    }
		}

	      curpos = pos;
	      if (val)
		do
		  {
		    if (off == -1
			|| (curpos >= off
			    && (curpos + fieldsize
				<= (HOST_WIDE_INT) off + len)))
		      {
			if (full)
			  {
			    if (ptr)
			      memcpy (ptr + (curpos - o), ptr + (pos - o),
				      fieldsize);
			    if (mask)
			      memcpy (mask + curpos, mask + pos, fieldsize);
			  }
			else if (!native_encode_initializer (val,
							     ptr
							     ? ptr + curpos - o
							     : NULL,
							     fieldsize,
							     off == -1 ? -1
								       : 0,
							     mask
							     ? mask + curpos
							     : NULL))
			  return 0;
			else
			  {
			    full = true;
			    pos = curpos;
			  }
		      }
		    else if (curpos + fieldsize > off
			     && curpos < (HOST_WIDE_INT) off + len)
		      {
			/* Partial overlap.  */
			unsigned char *p = NULL;
			int no = 0;
			int l;
			gcc_assert (mask == NULL);
			if (curpos >= off)
			  {
			    if (ptr)
			      p = ptr + curpos - off;
			    l = MIN ((HOST_WIDE_INT) off + len - curpos,
				     fieldsize);
			  }
			else
			  {
			    p = ptr;
			    no = off - curpos;
			    l = len;
			  }
			if (!native_encode_initializer (val, p, l, no, NULL))
			  return 0;
		      }
		    curpos += fieldsize;
		  }
		while (count-- != 0);
	    }
	  return MIN (total_bytes - off, len);
	}
      else if (TREE_CODE (type) == RECORD_TYPE
	       || TREE_CODE (type) == UNION_TYPE)
	{
	  unsigned HOST_WIDE_INT cnt;
	  constructor_elt *ce;
	  tree fld_base = TYPE_FIELDS (type);
	  tree to_free = NULL_TREE;

	  gcc_assert (TREE_CODE (type) == RECORD_TYPE || mask == NULL);
	  if (ptr != NULL)
	    memset (ptr, '\0', MIN (total_bytes - o, len));
	  for (cnt = 0; ; cnt++)
	    {
	      tree val = NULL_TREE, field = NULL_TREE;
	      HOST_WIDE_INT pos = 0, fieldsize;
	      unsigned HOST_WIDE_INT bpos = 0, epos = 0;

	      if (to_free)
		{
		  ggc_free (to_free);
		  to_free = NULL_TREE;
		}

	      if (vec_safe_iterate (CONSTRUCTOR_ELTS (init), cnt, &ce))
		{
		  val = ce->value;
		  field = ce->index;
		  if (field == NULL_TREE)
		    return 0;

		  pos = int_byte_position (field);
		  if (off != -1 && (HOST_WIDE_INT) off + len <= pos)
		    continue;
		}
	      else if (mask == NULL
		       || CONSTRUCTOR_NO_CLEARING (init))
		break;
	      else
		pos = total_bytes;

	      if (mask && !CONSTRUCTOR_NO_CLEARING (init))
		{
		  tree fld;
		  for (fld = fld_base; fld; fld = DECL_CHAIN (fld))
		    {
		      if (TREE_CODE (fld) != FIELD_DECL)
			continue;
		      if (fld == field)
			break;
		      if (DECL_PADDING_P (fld))
			continue;
		      if (DECL_SIZE_UNIT (fld) == NULL_TREE
			  || !tree_fits_shwi_p (DECL_SIZE_UNIT (fld)))
			return 0;
		      if (integer_zerop (DECL_SIZE_UNIT (fld)))
			continue;
		      break;
		    }
		  if (fld == NULL_TREE)
		    {
		      if (ce == NULL)
			break;
		      return 0;
		    }
		  fld_base = DECL_CHAIN (fld);
		  if (fld != field)
		    {
		      cnt--;
		      field = fld;
		      pos = int_byte_position (field);
		      val = build_zero_cst (TREE_TYPE (fld));
		      if (TREE_CODE (val) == CONSTRUCTOR)
			to_free = val;
		    }
		}

	      if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
		  && TYPE_DOMAIN (TREE_TYPE (field))
		  && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field))))
		{
		  if (mask || off != -1)
		    return 0;
		  if (val == NULL_TREE)
		    continue;
		  if (TREE_CODE (TREE_TYPE (val)) != ARRAY_TYPE)
		    return 0;
		  fieldsize = int_size_in_bytes (TREE_TYPE (val));
		  if (fieldsize < 0
		      || (int) fieldsize != fieldsize
		      || (pos + fieldsize) > INT_MAX)
		    return 0;
		  if (pos + fieldsize > total_bytes)
		    {
		      if (ptr != NULL && total_bytes < len)
			memset (ptr + total_bytes, '\0',
				MIN (pos + fieldsize, len) - total_bytes);
		      total_bytes = pos + fieldsize;
		    }
		}
	      else
		{
		  if (DECL_SIZE_UNIT (field) == NULL_TREE
		      || !tree_fits_shwi_p (DECL_SIZE_UNIT (field)))
		    return 0;
		  fieldsize = tree_to_shwi (DECL_SIZE_UNIT (field));
		}
	      if (fieldsize == 0)
		continue;

	      if (DECL_BIT_FIELD (field))
		{
		  if (!tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (field)))
		    return 0;
		  fieldsize = TYPE_PRECISION (TREE_TYPE (field));
		  bpos = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
		  if (bpos % BITS_PER_UNIT)
		    bpos %= BITS_PER_UNIT;
		  else
		    bpos = 0;
		  fieldsize += bpos;
		  epos = fieldsize % BITS_PER_UNIT;
		  fieldsize += BITS_PER_UNIT - 1;
		  fieldsize /= BITS_PER_UNIT;
		}

	      if (off != -1 && pos + fieldsize <= off)
		continue;

	      if (val == NULL_TREE)
		continue;

	      if (DECL_BIT_FIELD (field))
		{
		  /* FIXME: Handle PDP endian.  */
		  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
		    return 0;

		  if (TREE_CODE (val) != INTEGER_CST)
		    return 0;

		  tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
		  tree repr_type = NULL_TREE;
		  HOST_WIDE_INT rpos = 0;
		  if (repr && INTEGRAL_TYPE_P (TREE_TYPE (repr)))
		    {
		      rpos = int_byte_position (repr);
		      repr_type = TREE_TYPE (repr);
		    }
		  else
		    {
		      repr_type = find_bitfield_repr_type (fieldsize, len);
		      if (repr_type == NULL_TREE)
			return 0;
		      HOST_WIDE_INT repr_size = int_size_in_bytes (repr_type);
		      gcc_assert (repr_size > 0 && repr_size <= len);
		      if (pos + repr_size <= o + len)
			rpos = pos;
		      else
			{
			  rpos = o + len - repr_size;
			  gcc_assert (rpos <= pos);
			}
		    }

		  if (rpos > pos)
		    return 0;
		  wide_int w = wi::to_wide (val, TYPE_PRECISION (repr_type));
		  int diff = (TYPE_PRECISION (repr_type)
			      - TYPE_PRECISION (TREE_TYPE (field)));
		  HOST_WIDE_INT bitoff = (pos - rpos) * BITS_PER_UNIT + bpos;
		  if (!BYTES_BIG_ENDIAN)
		    w = wi::lshift (w, bitoff);
		  else
		    w = wi::lshift (w, diff - bitoff);
		  val = wide_int_to_tree (repr_type, w);

		  unsigned char buf[MAX_BITSIZE_MODE_ANY_INT
				    / BITS_PER_UNIT + 1];
		  int l = native_encode_int (val, buf, sizeof buf, 0);
		  if (l * BITS_PER_UNIT != TYPE_PRECISION (repr_type))
		    return 0;

		  if (ptr == NULL)
		    continue;

		  /* If the bitfield does not start at byte boundary, handle
		     the partial byte at the start.  */
		  if (bpos
		      && (off == -1 || (pos >= off && len >= 1)))
		    {
		      if (!BYTES_BIG_ENDIAN)
			{
			  int msk = (1 << bpos) - 1;
			  buf[pos - rpos] &= ~msk;
			  buf[pos - rpos] |= ptr[pos - o] & msk;
			  if (mask)
			    {
			      if (fieldsize > 1 || epos == 0)
				mask[pos] &= msk;
			      else
				mask[pos] &= (msk | ~((1 << epos) - 1));
			    }
			}
		      else
			{
			  int msk = (1 << (BITS_PER_UNIT - bpos)) - 1;
			  buf[pos - rpos] &= msk;
			  buf[pos - rpos] |= ptr[pos - o] & ~msk;
			  if (mask)
			    {
			      if (fieldsize > 1 || epos == 0)
				mask[pos] &= ~msk;
			      else
				mask[pos] &= (~msk
					      | ((1 << (BITS_PER_UNIT - epos))
						 - 1));
			    }
			}
		    }
		  /* If the bitfield does not end at byte boundary, handle
		     the partial byte at the end.  */
		  if (epos
		      && (off == -1
			  || pos + fieldsize <= (HOST_WIDE_INT) off + len))
		    {
		      if (!BYTES_BIG_ENDIAN)
			{
			  int msk = (1 << epos) - 1;
			  buf[pos - rpos + fieldsize - 1] &= msk;
			  buf[pos - rpos + fieldsize - 1]
			    |= ptr[pos + fieldsize - 1 - o] & ~msk;
			  if (mask && (fieldsize > 1 || bpos == 0))
			    mask[pos + fieldsize - 1] &= ~msk;
			}
		       else
			{
			  int msk = (1 << (BITS_PER_UNIT - epos)) - 1;
			  buf[pos - rpos + fieldsize - 1] &= ~msk;
			  buf[pos - rpos + fieldsize - 1]
			    |= ptr[pos + fieldsize - 1 - o] & msk;
			  if (mask && (fieldsize > 1 || bpos == 0))
			    mask[pos + fieldsize - 1] &= msk;
			}
		    }
		  if (off == -1
		      || (pos >= off
			  && (pos + fieldsize <= (HOST_WIDE_INT) off + len)))
		    {
		      memcpy (ptr + pos - o, buf + (pos - rpos), fieldsize);
		      if (mask && (fieldsize > (bpos != 0) + (epos != 0)))
			memset (mask + pos + (bpos != 0), 0,
				fieldsize - (bpos != 0) - (epos != 0));
		    }
		  else
		    {
		      /* Partial overlap.  */
		      HOST_WIDE_INT fsz = fieldsize;
		      gcc_assert (mask == NULL);
		      if (pos < off)
			{
			  fsz -= (off - pos);
			  pos = off;
			}
		      if (pos + fsz > (HOST_WIDE_INT) off + len)
			fsz = (HOST_WIDE_INT) off + len - pos;
		      memcpy (ptr + pos - off, buf + (pos - rpos), fsz);
		    }
		  continue;
		}

	      if (off == -1
		  || (pos >= off
		      && (pos + fieldsize <= (HOST_WIDE_INT) off + len)))
		{
		  int fldsize = fieldsize;
		  if (off == -1)
		    {
		      tree fld = DECL_CHAIN (field);
		      while (fld)
			{
			  if (TREE_CODE (fld) == FIELD_DECL)
			    break;
			  fld = DECL_CHAIN (fld);
			}
		      if (fld == NULL_TREE)
			fldsize = len - pos;
		    }
		  r = native_encode_initializer (val, ptr ? ptr + pos - o
							  : NULL,
						 fldsize,
						 off == -1 ? -1 : 0,
						 mask ? mask + pos : NULL);
		  if (!r)
		    return 0;
		  if (off == -1
		      && fldsize != fieldsize
		      && r > fieldsize
		      && pos + r > total_bytes)
		    total_bytes = pos + r;
		}
	      else
		{
		  /* Partial overlap.  */
		  unsigned char *p = NULL;
		  int no = 0;
		  int l;
		  gcc_assert (mask == NULL);
		  if (pos >= off)
		    {
		      if (ptr)
			p = ptr + pos - off;
		      l = MIN ((HOST_WIDE_INT) off + len - pos,
				fieldsize);
		    }
		  else
		    {
		      p = ptr;
		      no = off - pos;
		      l = len;
		    }
		  if (!native_encode_initializer (val, p, l, no, NULL))
		    return 0;
		}
	    }
	  return MIN (total_bytes - off, len);
	}
      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, const unsigned char *ptr, int len)
{
  int total_bytes = GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (type));

  if (total_bytes > len
      || total_bytes * BITS_PER_UNIT > HOST_BITS_PER_DOUBLE_INT)
    return NULL_TREE;

  wide_int result = wi::from_buffer (ptr, total_bytes);

  return wide_int_to_tree (type, result);
}


/* Subroutine of native_interpret_expr.  Interpret the contents of
   the buffer PTR of length LEN as a FIXED_CST of type TYPE.
   If the buffer cannot be interpreted, return NULL_TREE.  */

static tree
native_interpret_fixed (tree type, const unsigned char *ptr, int len)
{
  scalar_mode mode = SCALAR_TYPE_MODE (type);
  int total_bytes = GET_MODE_SIZE (mode);
  double_int result;
  FIXED_VALUE_TYPE fixed_value;

  if (total_bytes > len
      || total_bytes * BITS_PER_UNIT > HOST_BITS_PER_DOUBLE_INT)
    return NULL_TREE;

  result = double_int::from_buffer (ptr, total_bytes);
  fixed_value = fixed_from_double_int (result, mode);

  return build_fixed (type, fixed_value);
}


/* 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, const unsigned char *ptr, int len)
{
  scalar_float_mode mode = SCALAR_FLOAT_TYPE_MODE (type);
  int total_bytes = GET_MODE_SIZE (mode);
  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];

  if (total_bytes > len || total_bytes > 24)
    return NULL_TREE;
  int words = (32 / BITS_PER_UNIT) / UNITS_PER_WORD;

  memset (tmp, 0, sizeof (tmp));
  for (int bitpos = 0; bitpos < total_bytes * BITS_PER_UNIT;
       bitpos += BITS_PER_UNIT)
    {
      /* Both OFFSET and BYTE index within a long;
	 bitpos indexes the whole float.  */
      int offset, byte = (bitpos / BITS_PER_UNIT) & 3;
      if (UNITS_PER_WORD < 4)
	{
	  int 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 = byte;
	  if (BYTES_BIG_ENDIAN)
	    {
	      /* Reverse bytes within each long, or within the entire float
		 if it's smaller than a long (for HFmode).  */
	      offset = MIN (3, total_bytes - 1) - offset;
	      gcc_assert (offset >= 0);
	    }
	}
      value = ptr[offset + ((bitpos / BITS_PER_UNIT) & ~3)];

      tmp[bitpos / 32] |= (unsigned long)value << (bitpos & 31);
    }

  real_from_target (&r, tmp, mode);
  tree ret = build_real (type, r);
  if (MODE_COMPOSITE_P (mode))
    {
      /* For floating point values in composite modes, punt if this folding
	 doesn't preserve bit representation.  As the mode doesn't have fixed
	 precision while GCC pretends it does, there could be valid values that
	 GCC can't really represent accurately.  See PR95450.  */
      unsigned char buf[24];
      if (native_encode_expr (ret, buf, total_bytes, 0) != total_bytes
	  || memcmp (ptr, buf, total_bytes) != 0)
	ret = NULL_TREE;
    }
  return ret;
}


/* 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, const unsigned char *ptr, int len)
{
  tree etype, rpart, ipart;
  int size;

  etype = TREE_TYPE (type);
  size = GET_MODE_SIZE (SCALAR_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);
}

/* Read a vector of type TYPE from the target memory image given by BYTES,
   which contains LEN bytes.  The vector is known to be encodable using
   NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each.

   Return the vector on success, otherwise return null.  */

static tree
native_interpret_vector_part (tree type, const unsigned char *bytes,
			      unsigned int len, unsigned int npatterns,
			      unsigned int nelts_per_pattern)
{
  tree elt_type = TREE_TYPE (type);
  if (VECTOR_BOOLEAN_TYPE_P (type)
      && TYPE_PRECISION (elt_type) <= BITS_PER_UNIT)
    {
      /* This is the only case in which elements can be smaller than a byte.
	 Element 0 is always in the lsb of the containing byte.  */
      unsigned int elt_bits = TYPE_PRECISION (elt_type);
      if (elt_bits * npatterns * nelts_per_pattern > len * BITS_PER_UNIT)
	return NULL_TREE;

      tree_vector_builder builder (type, npatterns, nelts_per_pattern);
      for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
	{
	  unsigned int bit_index = i * elt_bits;
	  unsigned int byte_index = bit_index / BITS_PER_UNIT;
	  unsigned int lsb = bit_index % BITS_PER_UNIT;
	  builder.quick_push (bytes[byte_index] & (1 << lsb)
			      ? build_all_ones_cst (elt_type)
			      : build_zero_cst (elt_type));
	}
      return builder.build ();
    }

  unsigned int elt_bytes = tree_to_uhwi (TYPE_SIZE_UNIT (elt_type));
  if (elt_bytes * npatterns * nelts_per_pattern > len)
    return NULL_TREE;

  tree_vector_builder builder (type, npatterns, nelts_per_pattern);
  for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
    {
      tree elt = native_interpret_expr (elt_type, bytes, elt_bytes);
      if (!elt)
	return NULL_TREE;
      builder.quick_push (elt);
      bytes += elt_bytes;
    }
  return builder.build ();
}

/* 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, const unsigned char *ptr, unsigned int len)
{
  tree etype;
  unsigned int size;
  unsigned HOST_WIDE_INT count;

  etype = TREE_TYPE (type);
  size = GET_MODE_SIZE (SCALAR_TYPE_MODE (etype));
  if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&count)
      || size * count > len)
    return NULL_TREE;

  return native_interpret_vector_part (type, ptr, len, count, 1);
}


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

tree
native_interpret_expr (tree type, const unsigned char *ptr, int len)
{
  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case POINTER_TYPE:
    case REFERENCE_TYPE:
      return native_interpret_int (type, ptr, len);

    case REAL_TYPE:
      return native_interpret_real (type, ptr, len);

    case FIXED_POINT_TYPE:
      return native_interpret_fixed (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;
    }
}

/* Returns true if we can interpret the contents of a native encoding
   as TYPE.  */

bool
can_native_interpret_type_p (tree type)
{
  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
    case POINTER_TYPE:
    case REFERENCE_TYPE:
    case FIXED_POINT_TYPE:
    case REAL_TYPE:
    case COMPLEX_TYPE:
    case VECTOR_TYPE:
      return true;
    default:
      return false;
    }
}

/* Attempt to interpret aggregate of TYPE from bytes encoded in target
   byte order at PTR + OFF with LEN bytes.  Does not handle unions.  */

tree
native_interpret_aggregate (tree type, const unsigned char *ptr, int off,
			    int len)
{
  vec<constructor_elt, va_gc> *elts = NULL;
  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      HOST_WIDE_INT eltsz = int_size_in_bytes (TREE_TYPE (type));
      if (eltsz < 0 || eltsz > len || TYPE_DOMAIN (type) == NULL_TREE)
	return NULL_TREE;

      HOST_WIDE_INT cnt = 0;
      if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
	{
	  if (!tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
	    return NULL_TREE;
	  cnt = tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1;
	}
      if (eltsz == 0)
	cnt = 0;
      HOST_WIDE_INT pos = 0;
      for (HOST_WIDE_INT i = 0; i < cnt; i++, pos += eltsz)
	{
	  tree v = NULL_TREE;
	  if (pos >= len || pos + eltsz > len)
	    return NULL_TREE;
	  if (can_native_interpret_type_p (TREE_TYPE (type)))
	    {
	      v = native_interpret_expr (TREE_TYPE (type),
					 ptr + off + pos, eltsz);
	      if (v == NULL_TREE)
		return NULL_TREE;
	    }
	  else if (TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
		   || TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
	    v = native_interpret_aggregate (TREE_TYPE (type), ptr, off + pos,
					    eltsz);
	  if (v == NULL_TREE)
	    return NULL_TREE;
	  CONSTRUCTOR_APPEND_ELT (elts, size_int (i), v);
	}
      return build_constructor (type, elts);
    }
  if (TREE_CODE (type) != RECORD_TYPE)
    return NULL_TREE;
  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    {
      if (TREE_CODE (field) != FIELD_DECL || DECL_PADDING_P (field))
	continue;
      tree fld = field;
      HOST_WIDE_INT bitoff = 0, pos = 0, sz = 0;
      int diff = 0;
      tree v = NULL_TREE;
      if (DECL_BIT_FIELD (field))
	{
	  fld = DECL_BIT_FIELD_REPRESENTATIVE (field);
	  if (fld && INTEGRAL_TYPE_P (TREE_TYPE (fld)))
	    {
	      poly_int64 bitoffset;
	      poly_uint64 field_offset, fld_offset;
	      if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
		  && poly_int_tree_p (DECL_FIELD_OFFSET (fld), &fld_offset))
		bitoffset = (field_offset - fld_offset) * BITS_PER_UNIT;
	      else
		bitoffset = 0;
	      bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
			    - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (fld)));
	      diff = (TYPE_PRECISION (TREE_TYPE (fld))
		      - TYPE_PRECISION (TREE_TYPE (field)));
	      if (!bitoffset.is_constant (&bitoff)
		  || bitoff < 0
		  || bitoff > diff)
		return NULL_TREE;
	    }
	  else
	    {
	      if (!tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (field)))
		return NULL_TREE;
	      int fieldsize = TYPE_PRECISION (TREE_TYPE (field));
	      int bpos = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
	      bpos %= BITS_PER_UNIT;
	      fieldsize += bpos;
	      fieldsize += BITS_PER_UNIT - 1;
	      fieldsize /= BITS_PER_UNIT;
	      tree repr_type = find_bitfield_repr_type (fieldsize, len);
	      if (repr_type == NULL_TREE)
		return NULL_TREE;
	      sz = int_size_in_bytes (repr_type);
	      if (sz < 0 || sz > len)
		return NULL_TREE;
	      pos = int_byte_position (field);
	      if (pos < 0 || pos > len || pos + fieldsize > len)
		return NULL_TREE;
	      HOST_WIDE_INT rpos;
	      if (pos + sz <= len)
		rpos = pos;
	      else
		{
		  rpos = len - sz;
		  gcc_assert (rpos <= pos);
		}
	      bitoff = (HOST_WIDE_INT) (pos - rpos) * BITS_PER_UNIT + bpos;
	      pos = rpos;
	      diff = (TYPE_PRECISION (repr_type)
		      - TYPE_PRECISION (TREE_TYPE (field)));
	      v = native_interpret_expr (repr_type, ptr + off + pos, sz);
	      if (v == NULL_TREE)
		return NULL_TREE;
	      fld = NULL_TREE;
	    }
	}

      if (fld)
	{
	  sz = int_size_in_bytes (TREE_TYPE (fld));
	  if (sz < 0 || sz > len)
	    return NULL_TREE;
	  tree byte_pos = byte_position (fld);
	  if (!tree_fits_shwi_p (byte_pos))
	    return NULL_TREE;
	  pos = tree_to_shwi (byte_pos);
	  if (pos < 0 || pos > len || pos + sz > len)
	    return NULL_TREE;
	}
      if (fld == NULL_TREE)
	/* Already handled above.  */;
      else if (can_native_interpret_type_p (TREE_TYPE (fld)))
	{
	  v = native_interpret_expr (TREE_TYPE (fld),
				     ptr + off + pos, sz);
	  if (v == NULL_TREE)
	    return NULL_TREE;
	}
      else if (TREE_CODE (TREE_TYPE (fld)) == RECORD_TYPE
	       || TREE_CODE (TREE_TYPE (fld)) == ARRAY_TYPE)
	v = native_interpret_aggregate (TREE_TYPE (fld), ptr, off + pos, sz);
      if (v == NULL_TREE)
	return NULL_TREE;
      if (fld != field)
	{
	  if (TREE_CODE (v) != INTEGER_CST)
	    return NULL_TREE;

	  /* FIXME: Figure out how to handle PDP endian bitfields.  */
	  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
	    return NULL_TREE;
	  if (!BYTES_BIG_ENDIAN)
	    v = wide_int_to_tree (TREE_TYPE (field),
				  wi::lrshift (wi::to_wide (v), bitoff));
	  else
	    v = wide_int_to_tree (TREE_TYPE (field),
				  wi::lrshift (wi::to_wide (v),
					       diff - bitoff));
	}
      CONSTRUCTOR_APPEND_ELT (elts, field, v);
    }
  return build_constructor (type, elts);
}

/* Routines for manipulation of native_encode_expr encoded data if the encoded
   or extracted constant positions and/or sizes aren't byte aligned.  */

/* Shift left the bytes in PTR of SZ elements by AMNT bits, carrying over the
   bits between adjacent elements.  AMNT should be within
   [0, BITS_PER_UNIT).
   Example, AMNT = 2:
   00011111|11100000 << 2 = 01111111|10000000
   PTR[1]  | PTR[0]         PTR[1]  | PTR[0].  */

void
shift_bytes_in_array_left (unsigned char *ptr, unsigned int sz,
			   unsigned int amnt)
{
  if (amnt == 0)
    return;

  unsigned char carry_over = 0U;
  unsigned char carry_mask = (~0U) << (unsigned char) (BITS_PER_UNIT - amnt);
  unsigned char clear_mask = (~0U) << amnt;

  for (unsigned int i = 0; i < sz; i++)
    {
      unsigned prev_carry_over = carry_over;
      carry_over = (ptr[i] & carry_mask) >> (BITS_PER_UNIT - amnt);

      ptr[i] <<= amnt;
      if (i != 0)
	{
	  ptr[i] &= clear_mask;
	  ptr[i] |= prev_carry_over;
	}
    }
}

/* Like shift_bytes_in_array_left but for big-endian.
   Shift right the bytes in PTR of SZ elements by AMNT bits, carrying over the
   bits between adjacent elements.  AMNT should be within
   [0, BITS_PER_UNIT).
   Example, AMNT = 2:
   00011111|11100000 >> 2 = 00000111|11111000
   PTR[0]  | PTR[1]         PTR[0]  | PTR[1].  */

void
shift_bytes_in_array_right (unsigned char *ptr, unsigned int sz,
			    unsigned int amnt)
{
  if (amnt == 0)
    return;

  unsigned char carry_over = 0U;
  unsigned char carry_mask = ~(~0U << amnt);

  for (unsigned int i = 0; i < sz; i++)
    {
      unsigned prev_carry_over = carry_over;
      carry_over = ptr[i] & carry_mask;

      carry_over <<= (unsigned char) BITS_PER_UNIT - amnt;
      ptr[i] >>= amnt;
      ptr[i] |= prev_carry_over;
    }
}

/* Try to view-convert VECTOR_CST EXPR to VECTOR_TYPE TYPE by operating
   directly on the VECTOR_CST encoding, in a way that works for variable-
   length vectors.  Return the resulting VECTOR_CST on success or null
   on failure.  */

static tree
fold_view_convert_vector_encoding (tree type, tree expr)
{
  tree expr_type = TREE_TYPE (expr);
  poly_uint64 type_bits, expr_bits;
  if (!poly_int_tree_p (TYPE_SIZE (type), &type_bits)
      || !poly_int_tree_p (TYPE_SIZE (expr_type), &expr_bits))
    return NULL_TREE;

  poly_uint64 type_units = TYPE_VECTOR_SUBPARTS (type);
  poly_uint64 expr_units = TYPE_VECTOR_SUBPARTS (expr_type);
  unsigned int type_elt_bits = vector_element_size (type_bits, type_units);
  unsigned int expr_elt_bits = vector_element_size (expr_bits, expr_units);

  /* We can only preserve the semantics of a stepped pattern if the new
     vector element is an integer of the same size.  */
  if (VECTOR_CST_STEPPED_P (expr)
      && (!INTEGRAL_TYPE_P (type) || type_elt_bits != expr_elt_bits))
    return NULL_TREE;

  /* The number of bits needed to encode one element from every pattern
     of the original vector.  */
  unsigned int expr_sequence_bits
    = VECTOR_CST_NPATTERNS (expr) * expr_elt_bits;

  /* The number of bits needed to encode one element from every pattern
     of the result.  */
  unsigned int type_sequence_bits
    = least_common_multiple (expr_sequence_bits, type_elt_bits);

  /* Don't try to read more bytes than are available, which can happen
     for constant-sized vectors if TYPE has larger elements than EXPR_TYPE.
     The general VIEW_CONVERT handling can cope with that case, so there's
     no point complicating things here.  */
  unsigned int nelts_per_pattern = VECTOR_CST_NELTS_PER_PATTERN (expr);
  unsigned int buffer_bytes = CEIL (nelts_per_pattern * type_sequence_bits,
				    BITS_PER_UNIT);
  unsigned int buffer_bits = buffer_bytes * BITS_PER_UNIT;
  if (known_gt (buffer_bits, expr_bits))
    return NULL_TREE;

  /* Get enough bytes of EXPR to form the new encoding.  */
  auto_vec<unsigned char, 128> buffer (buffer_bytes);
  buffer.quick_grow (buffer_bytes);
  if (native_encode_vector_part (expr, buffer.address (), buffer_bytes, 0,
				 buffer_bits / expr_elt_bits)
      != (int) buffer_bytes)
    return NULL_TREE;

  /* Reencode the bytes as TYPE.  */
  unsigned int type_npatterns = type_sequence_bits / type_elt_bits;
  return native_interpret_vector_part (type, &buffer[0], buffer.length (),
				       type_npatterns, nelts_per_pattern);
}

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

  if (VECTOR_TYPE_P (type) && TREE_CODE (expr) == VECTOR_CST)
    if (tree res = fold_view_convert_vector_encoding (type, expr))
      return res;

  len = native_encode_expr (expr, buffer, sizeof (buffer));
  if (len == 0)
    return NULL_TREE;

  return native_interpret_expr (type, buffer, len);
}

/* 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_loc (location_t loc, 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);

  if (TREE_CODE (t) == INDIRECT_REF)
    {
      t = TREE_OPERAND (t, 0);

      if (TREE_TYPE (t) != ptrtype)
	t = build1_loc (loc, NOP_EXPR, ptrtype, t);
    }
  else if (TREE_CODE (t) == MEM_REF
	   && integer_zerop (TREE_OPERAND (t, 1)))
    {
      t = TREE_OPERAND (t, 0);

      if (TREE_TYPE (t) != ptrtype)
	t = fold_convert_loc (loc, ptrtype, t);
    }
  else if (TREE_CODE (t) == MEM_REF
	   && TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
    return fold_binary (POINTER_PLUS_EXPR, ptrtype,
			TREE_OPERAND (t, 0),
			convert_to_ptrofftype (TREE_OPERAND (t, 1)));
  else if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
    {
      t = build_fold_addr_expr_loc (loc, TREE_OPERAND (t, 0));

      if (TREE_TYPE (t) != ptrtype)
	t = fold_convert_loc (loc, ptrtype, t);
    }
  else
    t = build1_loc (loc, ADDR_EXPR, ptrtype, t);

  return t;
}

/* Build an expression for the address of T.  */

tree
build_fold_addr_expr_loc (location_t loc, tree t)
{
  tree ptrtype = build_pointer_type (TREE_TYPE (t));

  return build_fold_addr_expr_with_type_loc (loc, t, ptrtype);
}

/* 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_loc (location_t loc, 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 (CONVERT_EXPR_CODE_P (code)
	  || code == FLOAT_EXPR || code == ABS_EXPR || code == NEGATE_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 (CONSTANT_CLASS_P (arg0))
	{
	  tree tem = const_unop (code, type, arg0);
	  if (tem)
	    {
	      if (TREE_TYPE (tem) != type)
		tem = fold_convert_loc (loc, type, tem);
	      return tem;
	    }
	}
    }

  tem = generic_simplify (loc, code, type, op0);
  if (tem)
    return tem;

  if (TREE_CODE_CLASS (code) == tcc_unary)
    {
      if (TREE_CODE (arg0) == COMPOUND_EXPR)
	return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
		       fold_build1_loc (loc, code, type,
				    fold_convert_loc (loc, TREE_TYPE (op0),
						      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_loc (loc, code, type,
				 fold_convert_loc (loc,
						   TREE_TYPE (op0), arg01));
	  if (! VOID_TYPE_P (TREE_TYPE (arg02)))
	    arg02 = fold_build1_loc (loc, code, type,
				 fold_convert_loc (loc,
						   TREE_TYPE (op0), arg02));
	  tem = fold_build3_loc (loc, 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 ((CONVERT_EXPR_CODE_P (code)
	       || 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_loc (loc, 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;
	}
   }

  switch (code)
    {
    case NON_LVALUE_EXPR:
      if (!maybe_lvalue_p (op0))
	return fold_convert_loc (loc, type, op0);
      return NULL_TREE;

    CASE_CONVERT:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
      if (COMPARISON_CLASS_P (op0))
	{
	  /* If we have (type) (a CMP b) and type is an integral type, return
	     new expression involving the new type.  Canonicalize
	     (type) (a CMP b) to (a CMP b) ? (type) true : (type) false for
	     non-integral type.
	     Do not fold the result as that would not simplify further, also
	     folding again results in recursions.  */
	  if (TREE_CODE (type) == BOOLEAN_TYPE)
	    return build2_loc (loc, TREE_CODE (op0), type,
			       TREE_OPERAND (op0, 0),
			       TREE_OPERAND (op0, 1));
	  else if (!INTEGRAL_TYPE_P (type) && !VOID_TYPE_P (type)
		   && TREE_CODE (type) != VECTOR_TYPE)
	    return build3_loc (loc, COND_EXPR, type, op0,
			       constant_boolean_node (true, type),
			       constant_boolean_node (false, type));
	}

      /* 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)))
        {
	  poly_int64 bitsize, bitpos;
	  tree offset;
	  machine_mode mode;
	  int unsignedp, reversep, volatilep;
	  tree base
	    = get_inner_reference (TREE_OPERAND (op0, 0), &bitsize, &bitpos,
				   &offset, &mode, &unsignedp, &reversep,
				   &volatilep);
	  /* 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 and the pointer type is unqualified.  */
	  if (!offset
	      && known_eq (bitpos, 0)
	      && (TYPE_MAIN_VARIANT (TREE_TYPE (type))
		  == TYPE_MAIN_VARIANT (TREE_TYPE (base)))
	      && TYPE_QUALS (type) == TYPE_UNQUALIFIED)
	    return fold_convert_loc (loc, type,
				     build_fold_addr_expr_loc (loc, 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_loc (loc, code, type, TREE_OPERAND (op0, 1));
	  /* First do the assignment, then return converted constant.  */
	  tem = build2_loc (loc, 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.
	 ??? We don't do it for BOOLEAN_TYPE or ENUMERAL_TYPE because they
	 very likely don't have maximal range for their precision and this
	 transformation effectively doesn't preserve non-maximal ranges.  */
      if (TREE_CODE (type) == INTEGER_TYPE
	  && TREE_CODE (op0) == BIT_AND_EXPR
	  && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
	{
	  tree and_expr = op0;
	  tree and0 = TREE_OPERAND (and_expr, 0);
	  tree and1 = TREE_OPERAND (and_expr, 1);
	  int change = 0;

	  if (TYPE_UNSIGNED (TREE_TYPE (and_expr))
	      || (TYPE_PRECISION (type)
		  <= TYPE_PRECISION (TREE_TYPE (and_expr))))
	    change = 1;
	  else if (TYPE_PRECISION (TREE_TYPE (and1))
		   <= HOST_BITS_PER_WIDE_INT
		   && tree_fits_uhwi_p (and1))
	    {
	      unsigned HOST_WIDE_INT cst;

	      cst = tree_to_uhwi (and1);
	      cst &= HOST_WIDE_INT_M1U
		     << (TYPE_PRECISION (TREE_TYPE (and1)) - 1);
	      change = (cst == 0);
	      if (change
		  && !flag_syntax_only
		  && (load_extend_op (TYPE_MODE (TREE_TYPE (and0)))
		      == ZERO_EXTEND))
		{
		  tree uns = unsigned_type_for (TREE_TYPE (and0));
		  and0 = fold_convert_loc (loc, uns, and0);
		  and1 = fold_convert_loc (loc, uns, and1);
		}
	    }
	  if (change)
	    {
	      tem = force_fit_type (type, wi::to_widest (and1), 0,
				    TREE_OVERFLOW (and1));
	      return fold_build2_loc (loc, BIT_AND_EXPR, type,
				      fold_convert_loc (loc, type, and0), tem);
	    }
	}

      /* Convert (T1)(X p+ Y) into ((T1)X p+ Y), for pointer type, when the new
	 cast (T1)X will fold away.  We assume that this happens when X itself
	 is a cast.  */
      if (POINTER_TYPE_P (type)
	  && TREE_CODE (arg0) == POINTER_PLUS_EXPR
	  && CONVERT_EXPR_P (TREE_OPERAND (arg0, 0)))
	{
	  tree arg00 = TREE_OPERAND (arg0, 0);
	  tree arg01 = TREE_OPERAND (arg0, 1);

	  /* If -fsanitize=alignment, avoid this optimization in GENERIC
	     when the pointed type needs higher alignment than
	     the p+ first operand's pointed type.  */
	  if (!in_gimple_form
	      && sanitize_flags_p (SANITIZE_ALIGNMENT)
	      && (min_align_of_type (TREE_TYPE (type))
		  > min_align_of_type (TREE_TYPE (TREE_TYPE (arg00)))))
	    return NULL_TREE;

	  arg00 = fold_convert_loc (loc, type, arg00);
	  return fold_build_pointer_plus_loc (loc, arg00, arg01);
	}

      /* Convert (T1)(~(T2)X) into ~(T1)X if T1 and T2 are integral types
	 of the same precision, and X is an 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))
	  && CONVERT_EXPR_P (TREE_OPERAND (op0, 0))
	  && 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_loc (loc, BIT_NOT_EXPR, type,
				fold_convert_loc (loc, type, tem));
	}

      /* Convert (T1)(X * Y) into (T1)X * (T1)Y if T1 is narrower than the
	 type of X and Y (integer types only).  */
      if (INTEGRAL_TYPE_P (type)
	  && TREE_CODE (op0) == MULT_EXPR
	  && INTEGRAL_TYPE_P (TREE_TYPE (op0))
	  && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (op0)))
	{
	  /* Be careful not to introduce new overflows.  */
	  tree mult_type;
          if (TYPE_OVERFLOW_WRAPS (type))
	    mult_type = type;
	  else
	    mult_type = unsigned_type_for (type);

	  if (TYPE_PRECISION (mult_type) < TYPE_PRECISION (TREE_TYPE (op0)))
	    {
	      tem = fold_build2_loc (loc, MULT_EXPR, mult_type,
				 fold_convert_loc (loc, mult_type,
						   TREE_OPERAND (op0, 0)),
				 fold_convert_loc (loc, mult_type,
						   TREE_OPERAND (op0, 1)));
	      return fold_convert_loc (loc, type, tem);
	    }
	}

      return NULL_TREE;

    case VIEW_CONVERT_EXPR:
      if (TREE_CODE (op0) == MEM_REF)
        {
	  if (TYPE_ALIGN (TREE_TYPE (op0)) != TYPE_ALIGN (type))
	    type = build_aligned_type (type, TYPE_ALIGN (TREE_TYPE (op0)));
	  tem = fold_build2_loc (loc, MEM_REF, type,
				 TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
	  REF_REVERSE_STORAGE_ORDER (tem) = REF_REVERSE_STORAGE_ORDER (op0);
	  return tem;
	}

      return NULL_TREE;

    case NEGATE_EXPR:
      tem = fold_negate_expr (loc, arg0);
      if (tem)
	return fold_convert_loc (loc, type, tem);
      return NULL_TREE;

    case ABS_EXPR:
      /* Convert fabs((double)float) into (double)fabsf(float).  */
      if (TREE_CODE (arg0) == NOP_EXPR
	  && TREE_CODE (type) == REAL_TYPE)
	{
	  tree targ0 = strip_float_extensions (arg0);
	  if (targ0 != arg0)
	    return fold_convert_loc (loc, type,
				     fold_build1_loc (loc, ABS_EXPR,
						  TREE_TYPE (targ0),
						  targ0));
	}
      return NULL_TREE;

    case BIT_NOT_EXPR:
      /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify.  */
      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,
				    fold_convert_loc (loc, type,
						      TREE_OPERAND (arg0, 0)))))
	return fold_build2_loc (loc, BIT_XOR_EXPR, type, tem,
				fold_convert_loc (loc, type,
						  TREE_OPERAND (arg0, 1)));
      else if (TREE_CODE (arg0) == BIT_XOR_EXPR
	       && (tem = fold_unary_loc (loc, BIT_NOT_EXPR, type,
			       	     fold_convert_loc (loc, type,
						       TREE_OPERAND (arg0, 1)))))
	return fold_build2_loc (loc, BIT_XOR_EXPR, type,
			    fold_convert_loc (loc, type,
					      TREE_OPERAND (arg0, 0)), tem);

      return NULL_TREE;

    case TRUTH_NOT_EXPR:
      /* 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 (loc, arg0);
      if (!tem)
	return NULL_TREE;
      return fold_convert_loc (loc, type, tem);

    case INDIRECT_REF:
      /* Fold *&X to X if X is an lvalue.  */
      if (TREE_CODE (op0) == ADDR_EXPR)
	{
	  tree op00 = TREE_OPERAND (op0, 0);
	  if ((VAR_P (op00)
	       || TREE_CODE (op00) == PARM_DECL
	       || TREE_CODE (op00) == RESULT_DECL)
	      && !TREE_READONLY (op00))
	    return op00;
	}
      return NULL_TREE;

    default:
      return NULL_TREE;
    } /* switch (code) */
}


/* If the operation was a conversion do _not_ mark a resulting constant
   with TREE_OVERFLOW if the original constant was not.  These conversions
   have implementation defined behavior and retaining the TREE_OVERFLOW
   flag here would confuse later passes such as VRP.  */
tree
fold_unary_ignore_overflow_loc (location_t loc, enum tree_code code,
				tree type, tree op0)
{
  tree res = fold_unary_loc (loc, code, type, op0);
  if (res
      && TREE_CODE (res) == INTEGER_CST
      && TREE_CODE (op0) == INTEGER_CST
      && CONVERT_EXPR_CODE_P (code))
    TREE_OVERFLOW (res) = TREE_OVERFLOW (op0);

  return res;
}

/* Fold a binary bitwise/truth expression of code CODE and type TYPE with
   operands OP0 and OP1.  LOC is the location of the resulting expression.
   ARG0 and ARG1 are the NOP_STRIPed results of OP0 and OP1.
   Return the folded expression if folding is successful.  Otherwise,
   return NULL_TREE.  */
static tree
fold_truth_andor (location_t loc, enum tree_code code, tree type,
		  tree arg0, tree arg1, tree op0, tree op1)
{
  tree tem;

  /* 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_loc (loc, TREE_CODE (arg0), type, a00,
			    fold_build2_loc (loc, code, type, a01, a11));
      else if (commutative && operand_equal_p (a00, a11, 0))
	return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
			    fold_build2_loc (loc, code, type, a01, a10));
      else if (commutative && operand_equal_p (a01, a10, 0))
	return fold_build2_loc (loc, TREE_CODE (arg0), type, a01,
			    fold_build2_loc (loc, 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_loc (loc, TREE_CODE (arg0), type,
			    fold_build2_loc (loc, code, type, a00, a10),
			    a01);
    }

  /* See if we can build a range comparison.  */
  if ((tem = fold_range_test (loc, code, type, op0, op1)) != 0)
    return tem;

  if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg0) == TRUTH_ORIF_EXPR)
      || (code == TRUTH_ORIF_EXPR && TREE_CODE (arg0) == TRUTH_ANDIF_EXPR))
    {
      tem = merge_truthop_with_opposite_arm (loc, arg0, arg1, true);
      if (tem)
	return fold_build2_loc (loc, code, type, tem, arg1);
    }

  if ((code == TRUTH_ANDIF_EXPR && TREE_CODE (arg1) == TRUTH_ORIF_EXPR)
      || (code == TRUTH_ORIF_EXPR && TREE_CODE (arg1) == TRUTH_ANDIF_EXPR))
    {
      tem = merge_truthop_with_opposite_arm (loc, arg1, arg0, false);
      if (tem)
	return fold_build2_loc (loc, code, type, arg0, 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
      && (tem = fold_truth_andor_1 (loc, code, type,
				    TREE_OPERAND (arg0, 1), arg1)) != 0)
    return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem);

  if ((tem = fold_truth_andor_1 (loc, code, type, arg0, arg1)) != 0)
    return tem;

  bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
  if (param_logical_op_non_short_circuit != -1)
    logical_op_non_short_circuit
      = param_logical_op_non_short_circuit;
  if (logical_op_non_short_circuit
      && !sanitize_coverage_p ()
      && (code == TRUTH_AND_EXPR
          || code == TRUTH_ANDIF_EXPR
          || code == TRUTH_OR_EXPR
          || code == TRUTH_ORIF_EXPR))
    {
      enum tree_code ncode, icode;

      ncode = (code == TRUTH_ANDIF_EXPR || code == TRUTH_AND_EXPR)
	      ? TRUTH_AND_EXPR : TRUTH_OR_EXPR;
      icode = ncode == TRUTH_AND_EXPR ? TRUTH_ANDIF_EXPR : TRUTH_ORIF_EXPR;

      /* Transform ((A AND-IF B) AND[-IF] C) into (A AND-IF (B AND C)),
	 or ((A OR-IF B) OR[-IF] C) into (A OR-IF (B OR C))
	 We don't want to pack more than two leafs to a non-IF AND/OR
	 expression.
	 If tree-code of left-hand operand isn't an AND/OR-IF code and not
	 equal to IF-CODE, then we don't want to add right-hand operand.
	 If the inner right-hand side of left-hand operand has
	 side-effects, or isn't simple, then we can't add to it,
	 as otherwise we might destroy if-sequence.  */
      if (TREE_CODE (arg0) == icode
	  && simple_operand_p_2 (arg1)
	  /* Needed for sequence points to handle trappings, and
	     side-effects.  */
	  && simple_operand_p_2 (TREE_OPERAND (arg0, 1)))
	{
	  tem = fold_build2_loc (loc, ncode, type, TREE_OPERAND (arg0, 1),
				 arg1);
	  return fold_build2_loc (loc, icode, type, TREE_OPERAND (arg0, 0),
				  tem);
	}
	/* Same as above but for (A AND[-IF] (B AND-IF C)) -> ((A AND B) AND-IF C),
	   or (A OR[-IF] (B OR-IF C) -> ((A OR B) OR-IF C).  */
      else if (TREE_CODE (arg1) == icode
	  && simple_operand_p_2 (arg0)
	  /* Needed for sequence points to handle trappings, and
	     side-effects.  */
	  && simple_operand_p_2 (TREE_OPERAND (arg1, 0)))
	{
	  tem = fold_build2_loc (loc, ncode, type, 
				 arg0, TREE_OPERAND (arg1, 0));
	  return fold_build2_loc (loc, icode, type, tem,
				  TREE_OPERAND (arg1, 1));
	}
      /* Transform (A AND-IF B) into (A AND B), or (A OR-IF B)
	 into (A OR B).
	 For sequence point consistancy, we need to check for trapping,
	 and side-effects.  */
      else if (code == icode && simple_operand_p_2 (arg0)
               && simple_operand_p_2 (arg1))
	return fold_build2_loc (loc, ncode, type, arg0, arg1);
    }

  return NULL_TREE;
}

/* Helper that tries to canonicalize the comparison ARG0 CODE ARG1
   by changing CODE to reduce the magnitude of constants involved in
   ARG0 of the comparison.
   Returns a canonicalized comparison tree if a simplification was
   possible, otherwise returns NULL_TREE.
   Set *STRICT_OVERFLOW_P to true if the canonicalization is only
   valid if signed overflow is undefined.  */

static tree
maybe_canonicalize_comparison_1 (location_t loc, enum tree_code code, tree type,
				 tree arg0, tree arg1,
				 bool *strict_overflow_p)
{
  enum tree_code code0 = TREE_CODE (arg0);
  tree t, cst0 = NULL_TREE;
  int sgn0;

  /* Match A +- CST code arg1.  We can change this only if overflow
     is undefined.  */
  if (!((ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
	 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0)))
	/* In principle pointers also have undefined overflow behavior,
	   but that causes problems elsewhere.  */
	&& !POINTER_TYPE_P (TREE_TYPE (arg0))
	&& (code0 == MINUS_EXPR
	    || code0 == PLUS_EXPR)
	&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST))
    return NULL_TREE;

  /* Identify the constant in arg0 and its sign.  */
  cst0 = TREE_OPERAND (arg0, 1);
  sgn0 = tree_int_cst_sgn (cst0);

  /* Overflowed constants and zero will cause problems.  */
  if (integer_zerop (cst0)
      || TREE_OVERFLOW (cst0))
    return NULL_TREE;

  /* See if we can reduce the magnitude of the constant in
     arg0 by changing the comparison code.  */
  /* A - CST < arg1  ->  A - CST-1 <= arg1.  */
  if (code == LT_EXPR
      && code0 == ((sgn0 == -1) ? PLUS_EXPR : MINUS_EXPR))
    code = LE_EXPR;
  /* A + CST > arg1  ->  A + CST-1 >= arg1.  */
  else if (code == GT_EXPR
	   && code0 == ((sgn0 == -1) ? MINUS_EXPR : PLUS_EXPR))
    code = GE_EXPR;
  /* A + CST <= arg1  ->  A + CST-1 < arg1.  */
  else if (code == LE_EXPR
	   && code0 == ((sgn0 == -1) ? MINUS_EXPR : PLUS_EXPR))
    code = LT_EXPR;
  /* A - CST >= arg1  ->  A - CST-1 > arg1.  */
  else if (code == GE_EXPR
	   && code0 == ((sgn0 == -1) ? PLUS_EXPR : MINUS_EXPR))
    code = GT_EXPR;
  else
    return NULL_TREE;
  *strict_overflow_p = true;

  /* Now build the constant reduced in magnitude.  But not if that
     would produce one outside of its types range.  */
  if (INTEGRAL_TYPE_P (TREE_TYPE (cst0))
      && ((sgn0 == 1
	   && TYPE_MIN_VALUE (TREE_TYPE (cst0))
	   && tree_int_cst_equal (cst0, TYPE_MIN_VALUE (TREE_TYPE (cst0))))
	  || (sgn0 == -1
	      && TYPE_MAX_VALUE (TREE_TYPE (cst0))
	      && tree_int_cst_equal (cst0, TYPE_MAX_VALUE (TREE_TYPE (cst0))))))
    return NULL_TREE;

  t = int_const_binop (sgn0 == -1 ? PLUS_EXPR : MINUS_EXPR,
		       cst0, build_int_cst (TREE_TYPE (cst0), 1));
  t = fold_build2_loc (loc, code0, TREE_TYPE (arg0), TREE_OPERAND (arg0, 0), t);
  t = fold_convert (TREE_TYPE (arg1), t);

  return fold_build2_loc (loc, code, type, t, arg1);
}

/* Canonicalize the comparison ARG0 CODE ARG1 with type TYPE with undefined
   overflow further.  Try to decrease the magnitude of constants involved
   by changing LE_EXPR and GE_EXPR to LT_EXPR and GT_EXPR or vice versa
   and put sole constants at the second argument position.
   Returns the canonicalized tree if changed, otherwise NULL_TREE.  */

static tree
maybe_canonicalize_comparison (location_t loc, enum tree_code code, tree type,
			       tree arg0, tree arg1)
{
  tree t;
  bool strict_overflow_p;
  const char * const warnmsg = G_("assuming signed overflow does not occur "
				  "when reducing constant in comparison");

  /* Try canonicalization by simplifying arg0.  */
  strict_overflow_p = false;
  t = maybe_canonicalize_comparison_1 (loc, code, type, arg0, arg1,
				       &strict_overflow_p);
  if (t)
    {
      if (strict_overflow_p)
	fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_MAGNITUDE);
      return t;
    }

  /* Try canonicalization by simplifying arg1 using the swapped
     comparison.  */
  code = swap_tree_comparison (code);
  strict_overflow_p = false;
  t = maybe_canonicalize_comparison_1 (loc, code, type, arg1, arg0,
				       &strict_overflow_p);
  if (t && strict_overflow_p)
    fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_MAGNITUDE);
  return t;
}

/* Return whether BASE + OFFSET + BITPOS may wrap around the address
   space.  This is used to avoid issuing overflow warnings for
   expressions like &p->x which cannot wrap.  */

static bool
pointer_may_wrap_p (tree base, tree offset, poly_int64 bitpos)
{
  if (!POINTER_TYPE_P (TREE_TYPE (base)))
    return true;

  if (maybe_lt (bitpos, 0))
    return true;

  poly_wide_int wi_offset;
  int precision = TYPE_PRECISION (TREE_TYPE (base));
  if (offset == NULL_TREE)
    wi_offset = wi::zero (precision);
  else if (!poly_int_tree_p (offset) || TREE_OVERFLOW (offset))
    return true;
  else
    wi_offset = wi::to_poly_wide (offset);

  wi::overflow_type overflow;
  poly_wide_int units = wi::shwi (bits_to_bytes_round_down (bitpos),
				  precision);
  poly_wide_int total = wi::add (wi_offset, units, UNSIGNED, &overflow);
  if (overflow)
    return true;

  poly_uint64 total_hwi, size;
  if (!total.to_uhwi (&total_hwi)
      || !poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (base))),
			   &size)
      || known_eq (size, 0U))
    return true;

  if (known_le (total_hwi, size))
    return false;

  /* We can do slightly better for SIZE if we have an ADDR_EXPR of an
     array.  */
  if (TREE_CODE (base) == ADDR_EXPR
      && poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (base, 0))),
			  &size)
      && maybe_ne (size, 0U)
      && known_le (total_hwi, size))
    return false;

  return true;
}

/* Return a positive integer when the symbol DECL is known to have
   a nonzero address, zero when it's known not to (e.g., it's a weak
   symbol), and a negative integer when the symbol is not yet in the
   symbol table and so whether or not its address is zero is unknown.
   For function local objects always return positive integer.  */
static int
maybe_nonzero_address (tree decl)
{
  if (DECL_P (decl) && decl_in_symtab_p (decl))
    if (struct symtab_node *symbol = symtab_node::get_create (decl))
      return symbol->nonzero_address ();

  /* Function local objects are never NULL.  */
  if (DECL_P (decl)
      && (DECL_CONTEXT (decl)
      && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL
      && auto_var_in_fn_p (decl, DECL_CONTEXT (decl))))
    return 1;

  return -1;
}

/* 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 (location_t loc, enum tree_code code, tree type,
		 tree op0, tree op1)
{
  const bool equality_code = (code == EQ_EXPR || code == NE_EXPR);
  tree arg0, arg1, tem;

  arg0 = op0;
  arg1 = op1;

  STRIP_SIGN_NOPS (arg0);
  STRIP_SIGN_NOPS (arg1);

  /* For comparisons of pointers we can decompose it to a compile time
     comparison of the base objects and the offsets into the object.
     This requires at least one operand being an ADDR_EXPR or a
     POINTER_PLUS_EXPR to do more than the operand_equal_p test below.  */
  if (POINTER_TYPE_P (TREE_TYPE (arg0))
      && (TREE_CODE (arg0) == ADDR_EXPR
	  || TREE_CODE (arg1) == ADDR_EXPR
	  || TREE_CODE (arg0) == POINTER_PLUS_EXPR
	  || TREE_CODE (arg1) == POINTER_PLUS_EXPR))
    {
      tree base0, base1, offset0 = NULL_TREE, offset1 = NULL_TREE;
      poly_int64 bitsize, bitpos0 = 0, bitpos1 = 0;
      machine_mode mode;
      int volatilep, reversep, unsignedp;
      bool indirect_base0 = false, indirect_base1 = false;

      /* Get base and offset for the access.  Strip ADDR_EXPR for
	 get_inner_reference, but put it back by stripping INDIRECT_REF
	 off the base object if possible.  indirect_baseN will be true
	 if baseN is not an address but refers to the object itself.  */
      base0 = arg0;
      if (TREE_CODE (arg0) == ADDR_EXPR)
	{
	  base0
	    = get_inner_reference (TREE_OPERAND (arg0, 0),
				   &bitsize, &bitpos0, &offset0, &mode,
				   &unsignedp, &reversep, &volatilep);
	  if (TREE_CODE (base0) == INDIRECT_REF)
	    base0 = TREE_OPERAND (base0, 0);
	  else
	    indirect_base0 = true;
	}
      else if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
	{
	  base0 = TREE_OPERAND (arg0, 0);
	  STRIP_SIGN_NOPS (base0);
	  if (TREE_CODE (base0) == ADDR_EXPR)
	    {
	      base0
		= get_inner_reference (TREE_OPERAND (base0, 0),
				       &bitsize, &bitpos0, &offset0, &mode,
				       &unsignedp, &reversep, &volatilep);
	      if (TREE_CODE (base0) == INDIRECT_REF)
		base0 = TREE_OPERAND (base0, 0);
	      else
		indirect_base0 = true;
	    }
	  if (offset0 == NULL_TREE || integer_zerop (offset0))
	    offset0 = TREE_OPERAND (arg0, 1);
	  else
	    offset0 = size_binop (PLUS_EXPR, offset0,
				  TREE_OPERAND (arg0, 1));
	  if (poly_int_tree_p (offset0))
	    {
	      poly_offset_int tem = wi::sext (wi::to_poly_offset (offset0),
					      TYPE_PRECISION (sizetype));
	      tem <<= LOG2_BITS_PER_UNIT;
	      tem += bitpos0;
	      if (tem.to_shwi (&bitpos0))
		offset0 = NULL_TREE;
	    }
	}

      base1 = arg1;
      if (TREE_CODE (arg1) == ADDR_EXPR)
	{
	  base1
	    = get_inner_reference (TREE_OPERAND (arg1, 0),
				   &bitsize, &bitpos1, &offset1, &mode,
				   &unsignedp, &reversep, &volatilep);
	  if (TREE_CODE (base1) == INDIRECT_REF)
	    base1 = TREE_OPERAND (base1, 0);
	  else
	    indirect_base1 = true;
	}
      else if (TREE_CODE (arg1) == POINTER_PLUS_EXPR)
	{
	  base1 = TREE_OPERAND (arg1, 0);
	  STRIP_SIGN_NOPS (base1);
	  if (TREE_CODE (base1) == ADDR_EXPR)
	    {
	      base1
		= get_inner_reference (TREE_OPERAND (base1, 0),
				       &bitsize, &bitpos1, &offset1, &mode,
				       &unsignedp, &reversep, &volatilep);
	      if (TREE_CODE (base1) == INDIRECT_REF)
		base1 = TREE_OPERAND (base1, 0);
	      else
		indirect_base1 = true;
	    }
	  if (offset1 == NULL_TREE || integer_zerop (offset1))
	    offset1 = TREE_OPERAND (arg1, 1);
	  else
	    offset1 = size_binop (PLUS_EXPR, offset1,
				  TREE_OPERAND (arg1, 1));
	  if (poly_int_tree_p (offset1))
	    {
	      poly_offset_int tem = wi::sext (wi::to_poly_offset (offset1),
					      TYPE_PRECISION (sizetype));
	      tem <<= LOG2_BITS_PER_UNIT;
	      tem += bitpos1;
	      if (tem.to_shwi (&bitpos1))
		offset1 = NULL_TREE;
	    }
	}

      /* If we have equivalent bases we might be able to simplify.  */
      if (indirect_base0 == indirect_base1
	  && operand_equal_p (base0, base1,
			      indirect_base0 ? OEP_ADDRESS_OF : 0))
	{
	  /* We can fold this expression to a constant if the non-constant
	     offset parts are equal.  */
	  if ((offset0 == offset1
	       || (offset0 && offset1
		   && operand_equal_p (offset0, offset1, 0)))
	      && (equality_code
		  || (indirect_base0
		      && (DECL_P (base0) || CONSTANT_CLASS_P (base0)))
		  || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))))
	    {
	      if (!equality_code
		  && maybe_ne (bitpos0, bitpos1)
		  && (pointer_may_wrap_p (base0, offset0, bitpos0)
		      || pointer_may_wrap_p (base1, offset1, bitpos1)))
		fold_overflow_warning (("assuming pointer wraparound does not "
					"occur when comparing P +- C1 with "
					"P +- C2"),
				       WARN_STRICT_OVERFLOW_CONDITIONAL);

	      switch (code)
		{
		case EQ_EXPR:
		  if (known_eq (bitpos0, bitpos1))
		    return constant_boolean_node (true, type);
		  if (known_ne (bitpos0, bitpos1))
		    return constant_boolean_node (false, type);
		  break;
		case NE_EXPR:
		  if (known_ne (bitpos0, bitpos1))
		    return constant_boolean_node (true, type);
		  if (known_eq (bitpos0, bitpos1))
		    return constant_boolean_node (false, type);
		  break;
		case LT_EXPR:
		  if (known_lt (bitpos0, bitpos1))
		    return constant_boolean_node (true, type);
		  if (known_ge (bitpos0, bitpos1))
		    return constant_boolean_node (false, type);
		  break;
		case LE_EXPR:
		  if (known_le (bitpos0, bitpos1))
		    return constant_boolean_node (true, type);
		  if (known_gt (bitpos0, bitpos1))
		    return constant_boolean_node (false, type);
		  break;
		case GE_EXPR:
		  if (known_ge (bitpos0, bitpos1))
		    return constant_boolean_node (true, type);
		  if (known_lt (bitpos0, bitpos1))
		    return constant_boolean_node (false, type);
		  break;
		case GT_EXPR:
		  if (known_gt (bitpos0, bitpos1))
		    return constant_boolean_node (true, type);
		  if (known_le (bitpos0, bitpos1))
		    return constant_boolean_node (false, type);
		  break;
		default:;
		}
	    }
	  /* We can simplify the comparison to a comparison of the variable
	     offset parts if the constant offset parts are equal.
	     Be careful to use signed sizetype here because otherwise we
	     mess with array offsets in the wrong way.  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.  */
	  else if (known_eq (bitpos0, bitpos1)
		   && (equality_code
		       || (indirect_base0
			   && (DECL_P (base0) || CONSTANT_CLASS_P (base0)))
		       || TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))))
	    {
	      /* By converting to signed sizetype 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
	         sizetype.  */
	      if (offset0 == NULL_TREE)
		offset0 = build_int_cst (ssizetype, 0);
	      else
		offset0 = fold_convert_loc (loc, ssizetype, offset0);
	      if (offset1 == NULL_TREE)
		offset1 = build_int_cst (ssizetype, 0);
	      else
		offset1 = fold_convert_loc (loc, ssizetype, offset1);

	      if (!equality_code
		  && (pointer_may_wrap_p (base0, offset0, bitpos0)
		      || pointer_may_wrap_p (base1, offset1, bitpos1)))
		fold_overflow_warning (("assuming pointer wraparound does not "
					"occur when comparing P +- C1 with "
					"P +- C2"),
				       WARN_STRICT_OVERFLOW_COMPARISON);

	      return fold_build2_loc (loc, code, type, offset0, offset1);
	    }
	}
      /* For equal offsets we can simplify to a comparison of the
	 base addresses.  */
      else if (known_eq (bitpos0, bitpos1)
	       && (indirect_base0
		   ? base0 != TREE_OPERAND (arg0, 0) : base0 != arg0)
	       && (indirect_base1
		   ? base1 != TREE_OPERAND (arg1, 0) : base1 != arg1)
	       && ((offset0 == offset1)
		   || (offset0 && offset1
		       && operand_equal_p (offset0, offset1, 0))))
	{
	  if (indirect_base0)
	    base0 = build_fold_addr_expr_loc (loc, base0);
	  if (indirect_base1)
	    base1 = build_fold_addr_expr_loc (loc, base1);
	  return fold_build2_loc (loc, code, type, base0, base1);
	}
      /* Comparison between an ordinary (non-weak) symbol and a null
	 pointer can be eliminated since such symbols must have a non
	 null address.  In C, relational expressions between pointers
	 to objects and null pointers are undefined.  The results
	 below follow the C++ rules with the additional property that
	 every object pointer compares greater than a null pointer.
      */
      else if (((DECL_P (base0)
		 && maybe_nonzero_address (base0) > 0
		 /* Avoid folding references to struct members at offset 0 to
		    prevent tests like '&ptr->firstmember == 0' from getting
		    eliminated.  When ptr is null, although the -> expression
		    is strictly speaking invalid, GCC retains it as a matter
		    of QoI.  See PR c/44555. */
		 && (offset0 == NULL_TREE && known_ne (bitpos0, 0)))
		|| CONSTANT_CLASS_P (base0))
	       && indirect_base0
	       /* The caller guarantees that when one of the arguments is
		  constant (i.e., null in this case) it is second.  */
	       && integer_zerop (arg1))
	{
	  switch (code)
	    {
	    case EQ_EXPR:
	    case LE_EXPR:
	    case LT_EXPR:
	      return constant_boolean_node (false, type);
	    case GE_EXPR:
	    case GT_EXPR:
	    case NE_EXPR:
	      return constant_boolean_node (true, type);
	    default:
	      gcc_unreachable ();
	    }
	}
    }

  /* Transform comparisons of the form X +- C1 CMP Y +- C2 to
     X CMP Y +- C2 +- C1 for signed X, Y.  This is valid if
     the resulting offset is smaller in absolute value than the
     original one and has the same sign.  */
  if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
      && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
      && (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
      && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
	  && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)))
      && (TREE_CODE (arg1) == PLUS_EXPR || TREE_CODE (arg1) == MINUS_EXPR)
      && (TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
	  && !TREE_OVERFLOW (TREE_OPERAND (arg1, 1))))
    {
      tree const1 = TREE_OPERAND (arg0, 1);
      tree const2 = TREE_OPERAND (arg1, 1);
      tree variable1 = TREE_OPERAND (arg0, 0);
      tree variable2 = TREE_OPERAND (arg1, 0);
      tree cst;
      const char * const warnmsg = G_("assuming signed overflow does not "
				      "occur when combining constants around "
				      "a comparison");

      /* Put the constant on the side where it doesn't overflow and is
	 of lower absolute value and of same sign than before.  */
      cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1)
			     ? MINUS_EXPR : PLUS_EXPR,
			     const2, const1);
      if (!TREE_OVERFLOW (cst)
	  && tree_int_cst_compare (const2, cst) == tree_int_cst_sgn (const2)
	  && tree_int_cst_sgn (cst) == tree_int_cst_sgn (const2))
	{
	  fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_COMPARISON);
	  return fold_build2_loc (loc, code, type,
				  variable1,
				  fold_build2_loc (loc, TREE_CODE (arg1),
						   TREE_TYPE (arg1),
						   variable2, cst));
	}

      cst = int_const_binop (TREE_CODE (arg0) == TREE_CODE (arg1)
			     ? MINUS_EXPR : PLUS_EXPR,
			     const1, const2);
      if (!TREE_OVERFLOW (cst)
	  && tree_int_cst_compare (const1, cst) == tree_int_cst_sgn (const1)
	  && tree_int_cst_sgn (cst) == tree_int_cst_sgn (const1))
	{
	  fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_COMPARISON);
	  return fold_build2_loc (loc, code, type,
				  fold_build2_loc (loc, TREE_CODE (arg0),
						   TREE_TYPE (arg0),
						   variable1, cst),
				  variable2);
	}
    }

  tem = maybe_canonicalize_comparison (loc, code, type, arg0, arg1);
  if (tem)
    return tem;

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

      if (twoval_comparison_p (arg0, &cval1, &cval2)
	  /* 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_loc (loc, code, type,
			       eval_subst (loc, arg0, cval1, maxval,
					   cval2, minval),
			       arg1);
	  tree equal_result
		= fold_build2_loc (loc, code, type,
			       eval_subst (loc, arg0, cval1, maxval,
					   cval2, maxval),
			       arg1);
	  tree low_result
		= fold_build2_loc (loc, code, type,
			       eval_subst (loc, 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_loc (loc, 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_loc (loc, type, integer_one_node, arg0);
		}

	      return fold_build2_loc (loc, code, type, cval1, cval2);
	    }
	}
    }

  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 (location_t loc, 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_loc (loc, REALPART_EXPR, itype, expr);
      ipart = fold_build1_loc (loc, IMAGPART_EXPR, itype, expr);
    }

  rpart = save_expr (rpart);
  ipart = save_expr (ipart);
  tem = fold_build2_loc (loc, PLUS_EXPR, itype,
		     fold_build2_loc (loc, MULT_EXPR, itype, rpart, rpart),
		     fold_build2_loc (loc, MULT_EXPR, itype, ipart, ipart));
  return fold_build2_loc (loc, COMPLEX_EXPR, type, tem,
			  build_zero_cst (itype));
}


/* Helper function for fold_vec_perm.  Store elements of VECTOR_CST or
   CONSTRUCTOR ARG into array ELTS, which has NELTS elements, and return
   true if successful.  */

static bool
vec_cst_ctor_to_array (tree arg, unsigned int nelts, tree *elts)
{
  unsigned HOST_WIDE_INT i, nunits;

  if (TREE_CODE (arg) == VECTOR_CST
      && VECTOR_CST_NELTS (arg).is_constant (&nunits))
    {
      for (i = 0; i < nunits; ++i)
	elts[i] = VECTOR_CST_ELT (arg, i);
    }
  else if (TREE_CODE (arg) == CONSTRUCTOR)
    {
      constructor_elt *elt;

      FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (arg), i, elt)
	if (i >= nelts || TREE_CODE (TREE_TYPE (elt->value)) == VECTOR_TYPE)
	  return false;
	else
	  elts[i] = elt->value;
    }
  else
    return false;
  for (; i < nelts; i++)
    elts[i]
      = fold_convert (TREE_TYPE (TREE_TYPE (arg)), integer_zero_node);
  return true;
}

/* Attempt to fold vector permutation of ARG0 and ARG1 vectors using SEL
   selector.  Return the folded VECTOR_CST or CONSTRUCTOR if successful,
   NULL_TREE otherwise.  */

tree
fold_vec_perm (tree type, tree arg0, tree arg1, const vec_perm_indices &sel)
{
  unsigned int i;
  unsigned HOST_WIDE_INT nelts;
  bool need_ctor = false;

  if (!sel.length ().is_constant (&nelts))
    return NULL_TREE;
  gcc_assert (known_eq (TYPE_VECTOR_SUBPARTS (type), nelts)
	      && known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)), nelts)
	      && known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)), nelts));
  if (TREE_TYPE (TREE_TYPE (arg0)) != TREE_TYPE (type)
      || TREE_TYPE (TREE_TYPE (arg1)) != TREE_TYPE (type))
    return NULL_TREE;

  tree *in_elts = XALLOCAVEC (tree, nelts * 2);
  if (!vec_cst_ctor_to_array (arg0, nelts, in_elts)
      || !vec_cst_ctor_to_array (arg1, nelts, in_elts + nelts))
    return NULL_TREE;

  tree_vector_builder out_elts (type, nelts, 1);
  for (i = 0; i < nelts; i++)
    {
      HOST_WIDE_INT index;
      if (!sel[i].is_constant (&index))
	return NULL_TREE;
      if (!CONSTANT_CLASS_P (in_elts[index]))
	need_ctor = true;
      out_elts.quick_push (unshare_expr (in_elts[index]));
    }

  if (need_ctor)
    {
      vec<constructor_elt, va_gc> *v;
      vec_alloc (v, nelts);
      for (i = 0; i < nelts; i++)
	CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, out_elts[i]);
      return build_constructor (type, v);
    }
  else
    return out_elts.build ();
}

/* Try to fold a pointer difference of type TYPE two address expressions of
   array references AREF0 and AREF1 using location LOC.  Return a
   simplified expression for the difference or NULL_TREE.  */

static tree
fold_addr_of_array_ref_difference (location_t loc, tree type,
				   tree aref0, tree aref1,
				   bool use_pointer_diff)
{
  tree base0 = TREE_OPERAND (aref0, 0);
  tree base1 = TREE_OPERAND (aref1, 0);
  tree base_offset = build_int_cst (type, 0);

  /* If the bases are array references as well, recurse.  If the bases
     are pointer indirections compute the difference of the pointers.
     If the bases are equal, we are set.  */
  if ((TREE_CODE (base0) == ARRAY_REF
       && TREE_CODE (base1) == ARRAY_REF
       && (base_offset
	   = fold_addr_of_array_ref_difference (loc, type, base0, base1,
						use_pointer_diff)))
      || (INDIRECT_REF_P (base0)
	  && INDIRECT_REF_P (base1)
	  && (base_offset
	        = use_pointer_diff
		  ? fold_binary_loc (loc, POINTER_DIFF_EXPR, type,
				     TREE_OPERAND (base0, 0),
				     TREE_OPERAND (base1, 0))
		  : fold_binary_loc (loc, MINUS_EXPR, type,
				     fold_convert (type,
						   TREE_OPERAND (base0, 0)),
				     fold_convert (type,
						   TREE_OPERAND (base1, 0)))))
      || operand_equal_p (base0, base1, OEP_ADDRESS_OF))
    {
      tree op0 = fold_convert_loc (loc, type, TREE_OPERAND (aref0, 1));
      tree op1 = fold_convert_loc (loc, type, TREE_OPERAND (aref1, 1));
      tree esz = fold_convert_loc (loc, type, array_ref_element_size (aref0));
      tree diff = fold_build2_loc (loc, MINUS_EXPR, type, op0, op1);
      return fold_build2_loc (loc, PLUS_EXPR, type,
			      base_offset,
			      fold_build2_loc (loc, MULT_EXPR, type,
					       diff, esz));
    }
  return NULL_TREE;
}

/* If the real or vector real constant CST of type TYPE has an exact
   inverse, return it, else return NULL.  */

tree
exact_inverse (tree type, tree cst)
{
  REAL_VALUE_TYPE r;
  tree unit_type;
  machine_mode mode;

  switch (TREE_CODE (cst))
    {
    case REAL_CST:
      r = TREE_REAL_CST (cst);

      if (exact_real_inverse (TYPE_MODE (type), &r))
	return build_real (type, r);

      return NULL_TREE;

    case VECTOR_CST:
      {
	unit_type = TREE_TYPE (type);
	mode = TYPE_MODE (unit_type);

	tree_vector_builder elts;
	if (!elts.new_unary_operation (type, cst, false))
	  return NULL_TREE;
	unsigned int count = elts.encoded_nelts ();
	for (unsigned int i = 0; i < count; ++i)
	  {
	    r = TREE_REAL_CST (VECTOR_CST_ELT (cst, i));
	    if (!exact_real_inverse (mode, &r))
	      return NULL_TREE;
	    elts.quick_push (build_real (unit_type, r));
	  }

	return elts.build ();
      }

    default:
      return NULL_TREE;
    }
}

/*  Mask out the tz least significant bits of X of type TYPE where
    tz is the number of trailing zeroes in Y.  */
static wide_int
mask_with_tz (tree type, const wide_int &x, const wide_int &y)
{
  int tz = wi::ctz (y);
  if (tz > 0)
    return wi::mask (tz, true, TYPE_PRECISION (type)) & x;
  return x;
}

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

static bool
tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
{
  tree type = TREE_TYPE (t);
  enum tree_code code;

  /* Doing something useful for floating point would need more work.  */
  if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
    return false;

  code = TREE_CODE (t);
  switch (TREE_CODE_CLASS (code))
    {
    case tcc_unary:
      return tree_unary_nonzero_warnv_p (code, type, TREE_OPERAND (t, 0),
					      strict_overflow_p);
    case tcc_binary:
    case tcc_comparison:
      return tree_binary_nonzero_warnv_p (code, type,
					       TREE_OPERAND (t, 0),
					       TREE_OPERAND (t, 1),
					       strict_overflow_p);
    case tcc_constant:
    case tcc_declaration:
    case tcc_reference:
      return tree_single_nonzero_warnv_p (t, strict_overflow_p);

    default:
      break;
    }

  switch (code)
    {
    case TRUTH_NOT_EXPR:
      return tree_unary_nonzero_warnv_p (code, type, TREE_OPERAND (t, 0),
					      strict_overflow_p);

    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
      return tree_binary_nonzero_warnv_p (code, type,
					       TREE_OPERAND (t, 0),
					       TREE_OPERAND (t, 1),
					       strict_overflow_p);

    case COND_EXPR:
    case CONSTRUCTOR:
    case OBJ_TYPE_REF:
    case ASSERT_EXPR:
    case ADDR_EXPR:
    case WITH_SIZE_EXPR:
    case SSA_NAME:
      return tree_single_nonzero_warnv_p (t, strict_overflow_p);

    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:
      return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
					strict_overflow_p);

    case CALL_EXPR:
      {
	tree fndecl = get_callee_fndecl (t);
	if (!fndecl) return false;
	if (flag_delete_null_pointer_checks && !flag_check_new
	    && DECL_IS_OPERATOR_NEW_P (fndecl)
	    && !TREE_NOTHROW (fndecl))
	  return true;
	if (flag_delete_null_pointer_checks
	    && lookup_attribute ("returns_nonnull",
		 TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
	  return true;
	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;
}

/* Return true if T is known not to be equal to an integer W.  */

bool
expr_not_equal_to (tree t, const wide_int &w)
{
  value_range vr;
  switch (TREE_CODE (t))
    {
    case INTEGER_CST:
      return wi::to_wide (t) != w;

    case SSA_NAME:
      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
	return false;

      if (cfun)
	get_range_query (cfun)->range_of_expr (vr, t);
      else
	get_global_range_query ()->range_of_expr (vr, t);

      if (!vr.undefined_p ()
	  && !vr.contains_p (wide_int_to_tree (TREE_TYPE (t), w)))
	return true;
      /* If T has some known zero bits and W has any of those bits set,
	 then T is known not to be equal to W.  */
      if (wi::ne_p (wi::zext (wi::bit_and_not (w, get_nonzero_bits (t)),
			      TYPE_PRECISION (TREE_TYPE (t))), 0))
	return true;
      return false;

    default:
      return false;
    }
}

/* Fold a binary expression of code CODE and type TYPE with operands
   OP0 and OP1.  LOC is the location of the resulting expression.
   Return the folded expression if folding is successful.  Otherwise,
   return NULL_TREE.  */

tree
fold_binary_loc (location_t loc, 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;
  unsigned int prec;

  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.  MIN_EXPR/MAX_EXPR also need signedness of arguments
     preserved.

     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 || code == MIN_EXPR || code == MAX_EXPR)
    {
      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 (CONSTANT_CLASS_P (arg0) && CONSTANT_CLASS_P (arg1))
    {
      tem = const_binop (code, type, arg0, arg1);
      if (tem != NULL_TREE)
	{
	  if (TREE_TYPE (tem) != type)
	    tem = fold_convert_loc (loc, 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))
    return fold_build2_loc (loc, code, type, op1, op0);

  /* Likewise if this is a comparison, and ARG0 is a constant, move it
     to ARG1 to reduce the number of tests below.  */
  if (kind == tcc_comparison
      && tree_swap_operands_p (arg0, arg1))
    return fold_build2_loc (loc, swap_tree_comparison (code), type, op1, op0);

  tem = generic_simplify (loc, code, type, op0, op1);
  if (tem)
    return tem;

  /* 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)
      && !VECTOR_TYPE_P (TREE_TYPE (arg0))
      && ((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_loc (loc, code == BIT_AND_EXPR ? TRUTH_AND_EXPR
			 : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
			 : TRUTH_XOR_EXPR,
			 boolean_type_node,
			 fold_convert_loc (loc, boolean_type_node, arg0),
			 fold_convert_loc (loc, boolean_type_node, arg1));

      if (code == EQ_EXPR)
	tem = invert_truthvalue_loc (loc, tem);

      return fold_convert_loc (loc, type, tem);
    }

  if (TREE_CODE_CLASS (code) == tcc_binary
      || TREE_CODE_CLASS (code) == tcc_comparison)
    {
      if (TREE_CODE (arg0) == COMPOUND_EXPR)
	{
	  tem = fold_build2_loc (loc, code, type,
			     fold_convert_loc (loc, TREE_TYPE (op0),
					       TREE_OPERAND (arg0, 1)), op1);
	  return build2_loc (loc, COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
			     tem);
	}
      if (TREE_CODE (arg1) == COMPOUND_EXPR)
	{
	  tem = fold_build2_loc (loc, code, type, op0,
			     fold_convert_loc (loc, TREE_TYPE (op1),
					       TREE_OPERAND (arg1, 1)));
	  return build2_loc (loc, COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
			     tem);
	}

      if (TREE_CODE (arg0) == COND_EXPR
	  || TREE_CODE (arg0) == VEC_COND_EXPR
	  || COMPARISON_CLASS_P (arg0))
	{
	  tem = fold_binary_op_with_conditional_arg (loc, code, type, op0, op1,
						     arg0, arg1,
						     /*cond_first_p=*/1);
	  if (tem != NULL_TREE)
	    return tem;
	}

      if (TREE_CODE (arg1) == COND_EXPR
	  || TREE_CODE (arg1) == VEC_COND_EXPR
	  || COMPARISON_CLASS_P (arg1))
	{
	  tem = fold_binary_op_with_conditional_arg (loc, code, type, op0, op1,
						     arg1, arg0,
					             /*cond_first_p=*/0);
	  if (tem != NULL_TREE)
	    return tem;
	}
    }

  switch (code)
    {
    case MEM_REF:
      /* MEM[&MEM[p, CST1], CST2] -> MEM[p, CST1 + CST2].  */
      if (TREE_CODE (arg0) == ADDR_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == MEM_REF)
	{
	  tree iref = TREE_OPERAND (arg0, 0);
	  return fold_build2 (MEM_REF, type,
			      TREE_OPERAND (iref, 0),
			      int_const_binop (PLUS_EXPR, arg1,
					       TREE_OPERAND (iref, 1)));
	}

      /* MEM[&a.b, CST2] -> MEM[&a, offsetof (a, b) + CST2].  */
      if (TREE_CODE (arg0) == ADDR_EXPR
	  && handled_component_p (TREE_OPERAND (arg0, 0)))
	{
	  tree base;
	  poly_int64 coffset;
	  base = get_addr_base_and_unit_offset (TREE_OPERAND (arg0, 0),
						&coffset);
	  if (!base)
	    return NULL_TREE;
	  return fold_build2 (MEM_REF, type,
			      build1 (ADDR_EXPR, TREE_TYPE (arg0), base),
			      int_const_binop (PLUS_EXPR, arg1,
					       size_int (coffset)));
	}

      return NULL_TREE;

    case POINTER_PLUS_EXPR:
      /* INT +p INT -> (PTR)(INT + INT).  Stripping types allows for this. */
      if (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
	   && INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
        return fold_convert_loc (loc, type,
				 fold_build2_loc (loc, PLUS_EXPR, sizetype,
					      fold_convert_loc (loc, sizetype,
								arg1),
					      fold_convert_loc (loc, sizetype,
								arg0)));

      return NULL_TREE;

    case PLUS_EXPR:
      if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type))
	{
	  /* X + (X / CST) * -CST is X % CST.  */
	  if (TREE_CODE (arg1) == MULT_EXPR
	      && TREE_CODE (TREE_OPERAND (arg1, 0)) == TRUNC_DIV_EXPR
	      && operand_equal_p (arg0,
				  TREE_OPERAND (TREE_OPERAND (arg1, 0), 0), 0))
	    {
	      tree cst0 = TREE_OPERAND (TREE_OPERAND (arg1, 0), 1);
	      tree cst1 = TREE_OPERAND (arg1, 1);
	      tree sum = fold_binary_loc (loc, PLUS_EXPR, TREE_TYPE (cst1),
				      cst1, cst0);
	      if (sum && integer_zerop (sum))
		return fold_convert_loc (loc, type,
					 fold_build2_loc (loc, TRUNC_MOD_EXPR,
						      TREE_TYPE (arg0), arg0,
						      cst0));
	    }
	}

      /* Handle (A1 * C1) + (A2 * C2) with A1, A2 or C1, C2 being the same or
	 one.  Make sure the type is not saturating and has the signedness of
	 the stripped operands, as fold_plusminus_mult_expr will re-associate.
	 ??? The latter condition should use TYPE_OVERFLOW_* flags instead.  */
      if ((TREE_CODE (arg0) == MULT_EXPR
	   || TREE_CODE (arg1) == MULT_EXPR)
	  && !TYPE_SATURATING (type)
	  && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (TREE_TYPE (arg0))
	  && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (TREE_TYPE (arg1))
	  && (!FLOAT_TYPE_P (type) || flag_associative_math))
        {
	  tree tem = fold_plusminus_mult_expr (loc, code, type, arg0, arg1);
	  if (tem)
	    return tem;
	}

      if (! FLOAT_TYPE_P (type))
	{
	  /* Reassociate (plus (plus (mult) (foo)) (mult)) as
	     (plus (plus (mult) (mult)) (foo)) so that we can
	     take advantage of the factoring cases below.  */
	  if (ANY_INTEGRAL_TYPE_P (type)
	      && TYPE_OVERFLOW_WRAPS (type)
	      && (((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_loc (loc, pcode, type,
				    fold_build2_loc (loc, PLUS_EXPR, type,
						 fold_convert_loc (loc, type,
								   parg0),
						 fold_convert_loc (loc, type,
								   marg)),
				    fold_convert_loc (loc, type, parg1));
	      if (TREE_CODE (parg0) != MULT_EXPR
		  && TREE_CODE (parg1) == MULT_EXPR)
		return
		  fold_build2_loc (loc, PLUS_EXPR, type,
			       fold_convert_loc (loc, type, parg0),
			       fold_build2_loc (loc, pcode, type,
					    fold_convert_loc (loc, type, marg),
					    fold_convert_loc (loc, type,
							      parg1)));
	    }
	}
      else
	{
	  /* Fold __complex__ ( x, 0 ) + __complex__ ( 0, y )
	     to __complex__ ( x, y ).  This is not the same for SNaNs or
	     if signed zeros are involved.  */
	  if (!HONOR_SNANS (element_mode (arg0))
              && !HONOR_SIGNED_ZEROS (element_mode (arg0))
	      && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0)))
	    {
	      tree rtype = TREE_TYPE (TREE_TYPE (arg0));
	      tree arg0r = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0);
	      tree arg0i = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
	      bool arg0rz = false, arg0iz = false;
	      if ((arg0r && (arg0rz = real_zerop (arg0r)))
		  || (arg0i && (arg0iz = real_zerop (arg0i))))
		{
		  tree arg1r = fold_unary_loc (loc, REALPART_EXPR, rtype, arg1);
		  tree arg1i = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg1);
		  if (arg0rz && arg1i && real_zerop (arg1i))
		    {
		      tree rp = arg1r ? arg1r
				  : build1 (REALPART_EXPR, rtype, arg1);
		      tree ip = arg0i ? arg0i
				  : build1 (IMAGPART_EXPR, rtype, arg0);
		      return fold_build2_loc (loc, COMPLEX_EXPR, type, rp, ip);
		    }
		  else if (arg0iz && arg1r && real_zerop (arg1r))
		    {
		      tree rp = arg0r ? arg0r
				  : build1 (REALPART_EXPR, rtype, arg0);
		      tree ip = arg1i ? arg1i
				  : build1 (IMAGPART_EXPR, rtype, arg1);
		      return fold_build2_loc (loc, COMPLEX_EXPR, type, rp, ip);
		    }
		}
	    }

          /* Convert a + (b*c + d*e) into (a + b*c) + d*e.
             We associate floats only if the user has specified
             -fassociative-math.  */
          if (flag_associative_math
              && 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_loc (loc, PLUS_EXPR, type, arg0, tree10);
                  return fold_build2_loc (loc, PLUS_EXPR, type, tree0, tree11);
                }
            }
          /* Convert (b*c + d*e) + a into b*c + (d*e +a).
             We associate floats only if the user has specified
             -fassociative-math.  */
          if (flag_associative_math
              && 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_loc (loc, PLUS_EXPR, type, tree01, arg1);
                  return fold_build2_loc (loc, 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.
	 Similarly for (A << B) | (A >> (-B & C3)) where C3 is Z-1,
	 though in this case CODE must be | and not + or ^, otherwise
	 it doesn't return A when B is 0.  */
      {
	enum tree_code code0, code1;
	tree rtype;
	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)
	    && (rtype = TREE_TYPE (TREE_OPERAND (arg0, 0)),
	        TYPE_UNSIGNED (rtype))
	    /* Only create rotates in complete modes.  Other cases are not
	       expanded properly.  */
	    && (element_precision (rtype)
		== GET_MODE_UNIT_PRECISION (TYPE_MODE (rtype))))
	  {
	    tree tree01, tree11;
	    tree orig_tree01, orig_tree11;
	    enum tree_code code01, code11;

	    tree01 = orig_tree01 = TREE_OPERAND (arg0, 1);
	    tree11 = orig_tree11 = TREE_OPERAND (arg1, 1);
	    STRIP_NOPS (tree01);
	    STRIP_NOPS (tree11);
	    code01 = TREE_CODE (tree01);
	    code11 = TREE_CODE (tree11);
	    if (code11 != MINUS_EXPR
		&& (code01 == MINUS_EXPR || code01 == BIT_AND_EXPR))
	      {
		std::swap (code0, code1);
		std::swap (code01, code11);
		std::swap (tree01, tree11);
		std::swap (orig_tree01, orig_tree11);
	      }
	    if (code01 == INTEGER_CST
		&& code11 == INTEGER_CST
		&& (wi::to_widest (tree01) + wi::to_widest (tree11)
		    == element_precision (rtype)))
	      {
		tem = build2_loc (loc, LROTATE_EXPR,
				  rtype, TREE_OPERAND (arg0, 0),
				  code0 == LSHIFT_EXPR
				  ? orig_tree01 : orig_tree11);
		return fold_convert_loc (loc, type, tem);
	      }
	    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
		    && compare_tree_int (tree110,
					 element_precision (rtype)) == 0
		    && operand_equal_p (tree01, tree111, 0))
		  {
		    tem = build2_loc (loc, (code0 == LSHIFT_EXPR
					    ? LROTATE_EXPR : RROTATE_EXPR),
				      rtype, TREE_OPERAND (arg0, 0),
				      orig_tree01);
		    return fold_convert_loc (loc, type, tem);
		  }
	      }
	    else if (code == BIT_IOR_EXPR
		     && code11 == BIT_AND_EXPR
		     && pow2p_hwi (element_precision (rtype)))
	      {
		tree tree110, tree111;
		tree110 = TREE_OPERAND (tree11, 0);
		tree111 = TREE_OPERAND (tree11, 1);
		STRIP_NOPS (tree110);
		STRIP_NOPS (tree111);
		if (TREE_CODE (tree110) == NEGATE_EXPR
		    && TREE_CODE (tree111) == INTEGER_CST
		    && compare_tree_int (tree111,
					 element_precision (rtype) - 1) == 0
		    && operand_equal_p (tree01, TREE_OPERAND (tree110, 0), 0))
		  {
		    tem = build2_loc (loc, (code0 == LSHIFT_EXPR
					    ? LROTATE_EXPR : RROTATE_EXPR),
				      rtype, TREE_OPERAND (arg0, 0),
				      orig_tree01);
		    return fold_convert_loc (loc, type, tem);
		  }
	      }
	  }
      }

    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
	 -fassociative-math.
	 And, we need to make sure type is not saturating.  */

      if ((! FLOAT_TYPE_P (type) || flag_associative_math)
	  && !TYPE_SATURATING (type))
	{
	  tree var0, minus_var0, con0, minus_con0, lit0, minus_lit0;
	  tree var1, minus_var1, con1, minus_con1, lit1, minus_lit1;
	  tree atype = type;
	  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, type, code,
			     &minus_var0, &con0, &minus_con0,
			     &lit0, &minus_lit0, 0);
	  var1 = split_tree (arg1, type, code,
			     &minus_var1, &con1, &minus_con1,
			     &lit1, &minus_lit1, code == MINUS_EXPR);

	  /* Recombine MINUS_EXPR operands by using PLUS_EXPR.  */
	  if (code == MINUS_EXPR)
	    code = PLUS_EXPR;

	  /* With undefined overflow prefer doing association in a type
	     which wraps on overflow, if that is one of the operand types.  */
	  if ((POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
	      && !TYPE_OVERFLOW_WRAPS (type))
	    {
	      if (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
		  && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
		atype = TREE_TYPE (arg0);
	      else if (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
		       && TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg1)))
		atype = TREE_TYPE (arg1);
	      gcc_assert (TYPE_PRECISION (atype) == TYPE_PRECISION (type));
	    }

	  /* With undefined overflow we can only associate constants with one
	     variable, and constants whose association doesn't overflow.  */
	  if ((POINTER_TYPE_P (atype) || INTEGRAL_TYPE_P (atype))
	      && !TYPE_OVERFLOW_WRAPS (atype))
	    {
	      if ((var0 && var1) || (minus_var0 && minus_var1))
		{
		  /* ???  If split_tree would handle NEGATE_EXPR we could
		     simply reject these cases and the allowed cases would
		     be the var0/minus_var1 ones.  */
		  tree tmp0 = var0 ? var0 : minus_var0;
		  tree tmp1 = var1 ? var1 : minus_var1;
		  bool one_neg = false;

		  if (TREE_CODE (tmp0) == NEGATE_EXPR)
		    {
		      tmp0 = TREE_OPERAND (tmp0, 0);
		      one_neg = !one_neg;
		    }
		  if (CONVERT_EXPR_P (tmp0)
		      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp0, 0)))
		      && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (tmp0, 0)))
			  <= TYPE_PRECISION (atype)))
		    tmp0 = TREE_OPERAND (tmp0, 0);
		  if (TREE_CODE (tmp1) == NEGATE_EXPR)
		    {
		      tmp1 = TREE_OPERAND (tmp1, 0);
		      one_neg = !one_neg;
		    }
		  if (CONVERT_EXPR_P (tmp1)
		      && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (tmp1, 0)))
		      && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (tmp1, 0)))
			  <= TYPE_PRECISION (atype)))
		    tmp1 = TREE_OPERAND (tmp1, 0);
		  /* The only case we can still associate with two variables
		     is if they cancel out.  */
		  if (!one_neg
		      || !operand_equal_p (tmp0, tmp1, 0))
		    ok = false;
		}
	      else if ((var0 && minus_var1
			&& ! operand_equal_p (var0, minus_var1, 0))
		       || (minus_var0 && var1
			   && ! operand_equal_p (minus_var0, var1, 0)))
		ok = false;
	    }

	  /* Only do something if we found more than two objects.  Otherwise,
	     nothing has changed and we risk infinite recursion.  */
	  if (ok
	      && ((var0 != 0) + (var1 != 0)
		  + (minus_var0 != 0) + (minus_var1 != 0)
		  + (con0 != 0) + (con1 != 0)
		  + (minus_con0 != 0) + (minus_con1 != 0)
		  + (lit0 != 0) + (lit1 != 0)
		  + (minus_lit0 != 0) + (minus_lit1 != 0)) > 2)
	    {
	      var0 = associate_trees (loc, var0, var1, code, atype);
	      minus_var0 = associate_trees (loc, minus_var0, minus_var1,
					    code, atype);
	      con0 = associate_trees (loc, con0, con1, code, atype);
	      minus_con0 = associate_trees (loc, minus_con0, minus_con1,
					    code, atype);
	      lit0 = associate_trees (loc, lit0, lit1, code, atype);
	      minus_lit0 = associate_trees (loc, minus_lit0, minus_lit1,
					    code, atype);

	      if (minus_var0 && var0)
		{
		  var0 = associate_trees (loc, var0, minus_var0,
					  MINUS_EXPR, atype);
		  minus_var0 = 0;
		}
	      if (minus_con0 && con0)
		{
		  con0 = associate_trees (loc, con0, minus_con0,
					  MINUS_EXPR, atype);
		  minus_con0 = 0;
		}

	      /* 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)
		      /* But avoid ending up with only negated parts.  */
		      && (var0 || con0))
		    {
		      minus_lit0 = associate_trees (loc, minus_lit0, lit0,
						    MINUS_EXPR, atype);
		      lit0 = 0;
		    }
		  else
		    {
		      lit0 = associate_trees (loc, lit0, minus_lit0,
					      MINUS_EXPR, atype);
		      minus_lit0 = 0;
		    }
		}

	      /* Don't introduce overflows through reassociation.  */
	      if ((lit0 && TREE_OVERFLOW_P (lit0))
		  || (minus_lit0 && TREE_OVERFLOW_P (minus_lit0)))
		return NULL_TREE;

	      /* Eliminate lit0 and minus_lit0 to con0 and minus_con0. */
	      con0 = associate_trees (loc, con0, lit0, code, atype);
	      lit0 = 0;
	      minus_con0 = associate_trees (loc, minus_con0, minus_lit0,
					    code, atype);
	      minus_lit0 = 0;

	      /* Eliminate minus_con0.  */
	      if (minus_con0)
		{
		  if (con0)
		    con0 = associate_trees (loc, con0, minus_con0,
					    MINUS_EXPR, atype);
		  else if (var0)
		    var0 = associate_trees (loc, var0, minus_con0,
					    MINUS_EXPR, atype);
		  else
		    gcc_unreachable ();
		  minus_con0 = 0;
		}

	      /* Eliminate minus_var0.  */
	      if (minus_var0)
		{
		  if (con0)
		    con0 = associate_trees (loc, con0, minus_var0,
					    MINUS_EXPR, atype);
		  else
		    gcc_unreachable ();
		  minus_var0 = 0;
		}

	      return
		fold_convert_loc (loc, type, associate_trees (loc, var0, con0,
							      code, atype));
	    }
	}

      return NULL_TREE;

    case POINTER_DIFF_EXPR:
    case MINUS_EXPR:
      /* 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 tem = fold_addr_of_array_ref_difference (loc, type,
							TREE_OPERAND (arg0, 0),
							TREE_OPERAND (arg1, 0),
							code
							== POINTER_DIFF_EXPR);
	  if (tem)
	    return tem;
	}

      /* Further transformations are not for pointers.  */
      if (code == POINTER_DIFF_EXPR)
	return NULL_TREE;

      /* (-A) - B -> (-B) - A  where B is easily negated and we can swap.  */
      if (TREE_CODE (arg0) == NEGATE_EXPR
	  && negate_expr_p (op1)
	  /* If arg0 is e.g. unsigned int and type is int, then this could
	     introduce UB, because if A is INT_MIN at runtime, the original
	     expression can be well defined while the latter is not.
	     See PR83269.  */
	  && !(ANY_INTEGRAL_TYPE_P (type)
	       && TYPE_OVERFLOW_UNDEFINED (type)
	       && ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
	       && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))))
	return fold_build2_loc (loc, MINUS_EXPR, type, negate_expr (op1),
			        fold_convert_loc (loc, type,
						  TREE_OPERAND (arg0, 0)));

      /* Fold __complex__ ( x, 0 ) - __complex__ ( 0, y ) to
	 __complex__ ( x, -y ).  This is not the same for SNaNs or if
	 signed zeros are involved.  */
      if (!HONOR_SNANS (element_mode (arg0))
	  && !HONOR_SIGNED_ZEROS (element_mode (arg0))
	  && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0)))
        {
	  tree rtype = TREE_TYPE (TREE_TYPE (arg0));
	  tree arg0r = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0);
	  tree arg0i = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
	  bool arg0rz = false, arg0iz = false;
	  if ((arg0r && (arg0rz = real_zerop (arg0r)))
	      || (arg0i && (arg0iz = real_zerop (arg0i))))
	    {
	      tree arg1r = fold_unary_loc (loc, REALPART_EXPR, rtype, arg1);
	      tree arg1i = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg1);
	      if (arg0rz && arg1i && real_zerop (arg1i))
	        {
		  tree rp = fold_build1_loc (loc, NEGATE_EXPR, rtype,
					 arg1r ? arg1r
					 : build1 (REALPART_EXPR, rtype, arg1));
		  tree ip = arg0i ? arg0i
		    : build1 (IMAGPART_EXPR, rtype, arg0);
		  return fold_build2_loc (loc, COMPLEX_EXPR, type, rp, ip);
		}
	      else if (arg0iz && arg1r && real_zerop (arg1r))
	        {
		  tree rp = arg0r ? arg0r
		    : build1 (REALPART_EXPR, rtype, arg0);
		  tree ip = fold_build1_loc (loc, NEGATE_EXPR, rtype,
					 arg1i ? arg1i
					 : build1 (IMAGPART_EXPR, rtype, arg1));
		  return fold_build2_loc (loc, COMPLEX_EXPR, type, rp, ip);
		}
	    }
	}

      /* A - B -> A + (-B) if B is easily negatable.  */
      if (negate_expr_p (op1)
	  && ! TYPE_OVERFLOW_SANITIZED (type)
	  && ((FLOAT_TYPE_P (type)
               /* Avoid this transformation if B is a positive REAL_CST.  */
	       && (TREE_CODE (op1) != REAL_CST
		   || REAL_VALUE_NEGATIVE (TREE_REAL_CST (op1))))
	      || INTEGRAL_TYPE_P (type)))
	return fold_build2_loc (loc, PLUS_EXPR, type,
				fold_convert_loc (loc, type, arg0),
				negate_expr (op1));

      /* Handle (A1 * C1) - (A2 * C2) with A1, A2 or C1, C2 being the same or
	 one.  Make sure the type is not saturating and has the signedness of
	 the stripped operands, as fold_plusminus_mult_expr will re-associate.
	 ??? The latter condition should use TYPE_OVERFLOW_* flags instead.  */
      if ((TREE_CODE (arg0) == MULT_EXPR
	   || TREE_CODE (arg1) == MULT_EXPR)
	  && !TYPE_SATURATING (type)
	  && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (TREE_TYPE (arg0))
	  && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (TREE_TYPE (arg1))
	  && (!FLOAT_TYPE_P (type) || flag_associative_math))
        {
	  tree tem = fold_plusminus_mult_expr (loc, code, type, arg0, arg1);
	  if (tem)
	    return tem;
	}

      goto associate;

    case MULT_EXPR:
      if (! FLOAT_TYPE_P (type))
	{
	  /* Transform x * -C into -x * C if x is easily negatable.  */
	  if (TREE_CODE (op1) == INTEGER_CST
	      && tree_int_cst_sgn (op1) == -1
	      && negate_expr_p (op0)
	      && negate_expr_p (op1)
	      && (tem = negate_expr (op1)) != op1
	      && ! TREE_OVERFLOW (tem))
	    return fold_build2_loc (loc, MULT_EXPR, type,
				    fold_convert_loc (loc, type,
						      negate_expr (op0)), tem);

	  strict_overflow_p = false;
	  if (TREE_CODE (arg1) == INTEGER_CST
	      && (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
					&strict_overflow_p)) != 0)
	    {
	      if (strict_overflow_p)
		fold_overflow_warning (("assuming signed overflow does not "
					"occur when simplifying "
					"multiplication"),
				       WARN_STRICT_OVERFLOW_MISC);
	      return fold_convert_loc (loc, 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 (loc, type, arg1);
	  if (TREE_CODE (arg1) == CONJ_EXPR
	      && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
	    return fold_mult_zconjz (loc, type, arg0);
	}
      else
	{
	  /* Fold z * +-I to __complex__ (-+__imag z, +-__real z).
	     This is not the same for NaNs or if signed zeros are
	     involved.  */
	  if (!HONOR_NANS (arg0)
              && !HONOR_SIGNED_ZEROS (element_mode (arg0))
	      && COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0))
	      && TREE_CODE (arg1) == COMPLEX_CST
	      && real_zerop (TREE_REALPART (arg1)))
	    {
	      tree rtype = TREE_TYPE (TREE_TYPE (arg0));
	      if (real_onep (TREE_IMAGPART (arg1)))
		return
		  fold_build2_loc (loc, COMPLEX_EXPR, type,
			       negate_expr (fold_build1_loc (loc, IMAGPART_EXPR,
							     rtype, arg0)),
			       fold_build1_loc (loc, REALPART_EXPR, rtype, arg0));
	      else if (real_minus_onep (TREE_IMAGPART (arg1)))
		return
		  fold_build2_loc (loc, COMPLEX_EXPR, type,
			       fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0),
			       negate_expr (fold_build1_loc (loc, REALPART_EXPR,
							     rtype, arg0)));
	    }

	  /* 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 (loc, 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 (loc, type, arg0);
	}
      goto associate;

    case BIT_IOR_EXPR:
      /* Canonicalize (X & C1) | C2.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
	{
	  int width = TYPE_PRECISION (type), w;
	  wide_int c1 = wi::to_wide (TREE_OPERAND (arg0, 1));
	  wide_int c2 = wi::to_wide (arg1);

	  /* If (C1&C2) == C1, then (X&C1)|C2 becomes (X,C2).  */
	  if ((c1 & c2) == c1)
	    return omit_one_operand_loc (loc, type, arg1,
					 TREE_OPERAND (arg0, 0));

	  wide_int msk = wi::mask (width, false,
				   TYPE_PRECISION (TREE_TYPE (arg1)));

	  /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2.  */
	  if (wi::bit_and_not (msk, c1 | c2) == 0)
	    {
	      tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
	      return fold_build2_loc (loc, BIT_IOR_EXPR, type, tem, arg1);
	    }

	  /* Minimize the number of bits set in C1, i.e. C1 := C1 & ~C2,
	     unless (C1 & ~C2) | (C2 & C3) for some C3 is a mask of some
	     mode which allows further optimizations.  */
	  c1 &= msk;
	  c2 &= msk;
	  wide_int c3 = wi::bit_and_not (c1, c2);
	  for (w = BITS_PER_UNIT; w <= width; w <<= 1)
	    {
	      wide_int mask = wi::mask (w, false,
					TYPE_PRECISION (type));
	      if (((c1 | c2) & mask) == mask
		  && wi::bit_and_not (c1, mask) == 0)
		{
		  c3 = mask;
		  break;
		}
	    }

	  if (c3 != c1)
	    {
	      tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
	      tem = fold_build2_loc (loc, BIT_AND_EXPR, type, tem,
				     wide_int_to_tree (type, c3));
	      return fold_build2_loc (loc, BIT_IOR_EXPR, type, tem, arg1);
	    }
	}

      /* 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:
      /* Fold (X & 1) ^ 1 as (X & 1) == 0.  */
      if (TREE_CODE (arg0) == BIT_AND_EXPR
	  && INTEGRAL_TYPE_P (type)
	  && integer_onep (TREE_OPERAND (arg0, 1))
	  && integer_onep (arg1))
	return fold_build2_loc (loc, EQ_EXPR, type, arg0,
				build_zero_cst (TREE_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:
      /* Fold (X ^ 1) & 1 as (X & 1) == 0.  */
      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && INTEGRAL_TYPE_P (type)
	  && integer_onep (TREE_OPERAND (arg0, 1))
	  && integer_onep (arg1))
	{
	  tree tem2;
	  tem = TREE_OPERAND (arg0, 0);
	  tem2 = fold_convert_loc (loc, TREE_TYPE (tem), arg1);
	  tem2 = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (tem),
				  tem, tem2);
	  return fold_build2_loc (loc, EQ_EXPR, type, tem2,
				  build_zero_cst (TREE_TYPE (tem)));
	}
      /* Fold ~X & 1 as (X & 1) == 0.  */
      if (TREE_CODE (arg0) == BIT_NOT_EXPR
	  && INTEGRAL_TYPE_P (type)
	  && integer_onep (arg1))
	{
	  tree tem2;
	  tem = TREE_OPERAND (arg0, 0);
	  tem2 = fold_convert_loc (loc, TREE_TYPE (tem), arg1);
	  tem2 = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (tem),
				  tem, tem2);
	  return fold_build2_loc (loc, EQ_EXPR, type, tem2,
				  build_zero_cst (TREE_TYPE (tem)));
	}
      /* Fold !X & 1 as X == 0.  */
      if (TREE_CODE (arg0) == TRUTH_NOT_EXPR
	  && integer_onep (arg1))
	{
	  tem = TREE_OPERAND (arg0, 0);
	  return fold_build2_loc (loc, EQ_EXPR, type, tem,
				  build_zero_cst (TREE_TYPE (tem)));
	}

      /* Fold (X * Y) & -(1 << CST) to X * Y if Y is a constant
         multiple of 1 << CST.  */
      if (TREE_CODE (arg1) == INTEGER_CST)
	{
	  wi::tree_to_wide_ref cst1 = wi::to_wide (arg1);
	  wide_int ncst1 = -cst1;
	  if ((cst1 & ncst1) == ncst1
	      && multiple_of_p (type, arg0,
				wide_int_to_tree (TREE_TYPE (arg1), ncst1)))
	    return fold_convert_loc (loc, type, arg0);
	}

      /* Fold (X * CST1) & CST2 to zero if we can, or drop known zero
         bits from CST2.  */
      if (TREE_CODE (arg1) == INTEGER_CST
	  && TREE_CODE (arg0) == MULT_EXPR
	  && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
	{
	  wi::tree_to_wide_ref warg1 = wi::to_wide (arg1);
	  wide_int masked
	    = mask_with_tz (type, warg1, wi::to_wide (TREE_OPERAND (arg0, 1)));

	  if (masked == 0)
	    return omit_two_operands_loc (loc, type, build_zero_cst (type),
	                                  arg0, arg1);
	  else if (masked != warg1)
	    {
	      /* Avoid the transform if arg1 is a mask of some
	         mode which allows further optimizations.  */
	      int pop = wi::popcount (warg1);
	      if (!(pop >= BITS_PER_UNIT
		    && pow2p_hwi (pop)
		    && wi::mask (pop, false, warg1.get_precision ()) == warg1))
		return fold_build2_loc (loc, code, type, op0,
					wide_int_to_tree (type, masked));
	    }
	}

      /* 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))))
	{
	  prec = element_precision (TREE_TYPE (TREE_OPERAND (arg0, 0)));

	  wide_int mask = wide_int::from (wi::to_wide (arg1), prec, UNSIGNED);
	  if (mask == -1)
	    return
	      fold_convert_loc (loc, type, TREE_OPERAND (arg0, 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;

      /* (-A) / (-B) -> A / B  */
      if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
	return fold_build2_loc (loc, RDIV_EXPR, type,
			    TREE_OPERAND (arg0, 0),
			    negate_expr (arg1));
      if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
	return fold_build2_loc (loc, RDIV_EXPR, type,
			    negate_expr (arg0),
			    TREE_OPERAND (arg1, 0));
      return NULL_TREE;

    case TRUNC_DIV_EXPR:
      /* Fall through */
      
    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 (op0, &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);
	      tree pow2 = build_int_cst (TREE_TYPE (sh_cnt),
					 wi::exact_log2 (wi::to_wide (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_loc (loc, PLUS_EXPR, TREE_TYPE (sh_cnt),
					sh_cnt, pow2);
	      return fold_build2_loc (loc, RSHIFT_EXPR, type,
				      fold_convert_loc (loc, type, arg0), sh_cnt);
	    }
	}

      /* Fall through */

    case ROUND_DIV_EXPR:
    case CEIL_DIV_EXPR:
    case EXACT_DIV_EXPR:
      if (integer_zerop (arg1))
	return NULL_TREE;

      /* Convert -A / -B to A / B when the type is signed and overflow is
	 undefined.  */
      if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
	  && TREE_CODE (op0) == NEGATE_EXPR
	  && negate_expr_p (op1))
	{
	  if (ANY_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_loc (loc, code, type,
				  fold_convert_loc (loc, type,
						    TREE_OPERAND (arg0, 0)),
				  negate_expr (op1));
	}
      if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
	  && TREE_CODE (arg1) == NEGATE_EXPR
	  && negate_expr_p (op0))
	{
	  if (ANY_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_loc (loc, code, type,
				  negate_expr (op0),
				  fold_convert_loc (loc, type,
						    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_loc (loc, EXACT_DIV_EXPR, type,
				fold_convert (type, arg0),
				fold_convert (type, arg1));

      strict_overflow_p = false;
      if (TREE_CODE (arg1) == INTEGER_CST
	  && (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
				    &strict_overflow_p)) != 0)
	{
	  if (strict_overflow_p)
	    fold_overflow_warning (("assuming signed overflow does not occur "
				    "when simplifying division"),
				   WARN_STRICT_OVERFLOW_MISC);
	  return fold_convert_loc (loc, type, tem);
	}

      return NULL_TREE;

    case CEIL_MOD_EXPR:
    case FLOOR_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case TRUNC_MOD_EXPR:
      strict_overflow_p = false;
      if (TREE_CODE (arg1) == INTEGER_CST
	  && (tem = extract_muldiv (op0, arg1, code, NULL_TREE,
				    &strict_overflow_p)) != 0)
	{
	  if (strict_overflow_p)
	    fold_overflow_warning (("assuming signed overflow does not occur "
				    "when simplifying modulus"),
				   WARN_STRICT_OVERFLOW_MISC);
	  return fold_convert_loc (loc, type, tem);
	}

      return NULL_TREE;

    case LROTATE_EXPR:
    case RROTATE_EXPR:
    case RSHIFT_EXPR:
    case LSHIFT_EXPR:
      /* 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;

      prec = element_precision (type);

      /* 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)
	{
	  tree arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
	  tree arg01 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
	  return fold_build2_loc (loc, TREE_CODE (arg0), type,
				  fold_build2_loc (loc, code, type,
						   arg00, arg1),
				  fold_build2_loc (loc, code, type,
						   arg01, arg1));
	}

      /* Two consecutive rotates adding up to the some integer
	 multiple of the precision of the type 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
	  && wi::umod_trunc (wi::to_wide (arg1)
			     + wi::to_wide (TREE_OPERAND (arg0, 1)),
			     prec) == 0)
	return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));

      return NULL_TREE;

    case MIN_EXPR:
    case MAX_EXPR:
      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_loc (loc, type, arg0);
      /* FALLTHRU */
    case TRUTH_AND_EXPR:
      /* If either arg is constant true, drop it.  */
      if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
	return non_lvalue_loc (loc, fold_convert_loc (loc, 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_loc (loc, fold_convert_loc (loc, 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_loc (loc, 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_loc (loc, 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_loc (loc, 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_loc (loc, 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 (loc, arg0, arg1);
	  if (tem && !operand_equal_p (tem, arg0, 0))
	    return fold_build2_loc (loc, code, type, tem, arg1);

	  tem = fold_to_nonsharp_ineq_using_bound (loc, arg1, arg0);
	  if (tem && !operand_equal_p (tem, arg1, 0))
	    return fold_build2_loc (loc, code, type, arg0, tem);
	}

      if ((tem = fold_truth_andor (loc, code, type, arg0, arg1, op0, op1))
          != NULL_TREE)
        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_loc (loc, type, arg0);
      /* FALLTHRU */
    case TRUTH_OR_EXPR:
      /* If either arg is constant zero, drop it.  */
      if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
	return non_lvalue_loc (loc, fold_convert_loc (loc, 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_loc (loc, fold_convert_loc (loc, 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_loc (loc, 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_loc (loc, 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_loc (loc, 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_loc (loc, type, integer_one_node, arg0);

      /* (X && !Y) || (!X && Y) is X ^ Y */
      if (TREE_CODE (arg0) == TRUTH_AND_EXPR
	  && TREE_CODE (arg1) == TRUTH_AND_EXPR)
        {
	  tree a0, a1, l0, l1, n0, n1;

	  a0 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 0));
	  a1 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 1));

	  l0 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
	  l1 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
	  
	  n0 = fold_build1_loc (loc, TRUTH_NOT_EXPR, type, l0);
	  n1 = fold_build1_loc (loc, TRUTH_NOT_EXPR, type, l1);
	  
	  if ((operand_equal_p (n0, a0, 0)
	       && operand_equal_p (n1, a1, 0))
	      || (operand_equal_p (n0, a1, 0)
		  && operand_equal_p (n1, a0, 0)))
	    return fold_build2_loc (loc, TRUTH_XOR_EXPR, type, l0, n1);
	}

      if ((tem = fold_truth_andor (loc, code, type, arg0, arg1, op0, op1))
          != NULL_TREE)
        return tem;

      return NULL_TREE;

    case TRUTH_XOR_EXPR:
      /* If the second arg is constant zero, drop it.  */
      if (integer_zerop (arg1))
	return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));
      /* If the second arg is constant true, this is a logical inversion.  */
      if (integer_onep (arg1))
	{
	  tem = invert_truthvalue_loc (loc, arg0);
	  return non_lvalue_loc (loc, fold_convert_loc (loc, type, tem));
	}
      /* Identical arguments cancel to zero.  */
      if (operand_equal_p (arg0, arg1, 0))
	return omit_one_operand_loc (loc, 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_loc (loc, 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_loc (loc, type, integer_one_node, arg0);

      return NULL_TREE;

    case EQ_EXPR:
    case NE_EXPR:
      STRIP_NOPS (arg0);
      STRIP_NOPS (arg1);

      tem = fold_comparison (loc, code, type, op0, op1);
      if (tem != NULL_TREE)
	return tem;

      /* bool_var != 1 becomes !bool_var. */
      if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_onep (arg1)
          && code == NE_EXPR)
        return fold_convert_loc (loc, type,
				 fold_build1_loc (loc, TRUTH_NOT_EXPR,
						  TREE_TYPE (arg0), arg0));

      /* bool_var == 0 becomes !bool_var. */
      if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE && integer_zerop (arg1)
          && code == EQ_EXPR)
        return fold_convert_loc (loc, type,
				 fold_build1_loc (loc, TRUTH_NOT_EXPR,
						  TREE_TYPE (arg0), arg0));

      /* !exp != 0 becomes !exp */
      if (TREE_CODE (arg0) == TRUTH_NOT_EXPR && integer_zerop (arg1)
	  && code == NE_EXPR)
        return non_lvalue_loc (loc, fold_convert_loc (loc, type, arg0));

      /* 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)))
	    {
	      tree tem = fold_build2_loc (loc, RSHIFT_EXPR, TREE_TYPE (arg00),
					  arg01, TREE_OPERAND (arg00, 1));
	      tem = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), tem,
				     build_one_cst (TREE_TYPE (arg0)));
	      return fold_build2_loc (loc, code, type,
				      fold_convert_loc (loc, TREE_TYPE (arg1),
							tem), arg1);
	    }
	  else if (TREE_CODE (arg01) == LSHIFT_EXPR
		   && integer_onep (TREE_OPERAND (arg01, 0)))
	    {
	      tree tem = fold_build2_loc (loc, RSHIFT_EXPR, TREE_TYPE (arg01),
					  arg00, TREE_OPERAND (arg01, 1));
	      tem = fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0), tem,
				     build_one_cst (TREE_TYPE (arg0)));
	      return fold_build2_loc (loc, code, type,
				      fold_convert_loc (loc, TREE_TYPE (arg1),
							tem), 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
	  && integer_pow2p (TREE_OPERAND (arg0, 1))
	  && integer_zerop (arg1))
	{
	  tree arg00 = TREE_OPERAND (arg0, 0);
	  STRIP_NOPS (arg00);
	  if (TREE_CODE (arg00) == RSHIFT_EXPR
	      && TREE_CODE (TREE_OPERAND (arg00, 1)) == INTEGER_CST)
	    {
	      tree itype = TREE_TYPE (arg00);
	      tree arg001 = TREE_OPERAND (arg00, 1);
	      prec = TYPE_PRECISION (itype);

	      /* Check for a valid shift count.  */
	      if (wi::ltu_p (wi::to_wide (arg001), prec))
		{
		  tree arg01 = TREE_OPERAND (arg0, 1);
		  tree arg000 = TREE_OPERAND (arg00, 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_loc (loc, LSHIFT_EXPR, itype,
					     arg01, arg001);
		      tem = fold_build2_loc (loc, BIT_AND_EXPR, itype,
					     arg000, tem);
		      return fold_build2_loc (loc, code, type, tem,
				fold_convert_loc (loc, itype, 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_loc (loc, 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_loc (loc, type,
					 code == EQ_EXPR ? integer_one_node
							 : integer_zero_node,
					 arg000);
		}
	    }
	}

      /* If this is a comparison of a field, we may be able to simplify it.  */
      if ((TREE_CODE (arg0) == COMPONENT_REF
	   || 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 (loc, 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);

	  if (fndecl
	      && fndecl_built_in_p (fndecl, BUILT_IN_STRLEN)
	      && call_expr_nargs (arg0) == 1
	      && (TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (arg0, 0)))
		  == POINTER_TYPE))
	    {
	      tree ptrtype
		= build_pointer_type (build_qualified_type (char_type_node,
							    TYPE_QUAL_CONST));
	      tree ptr = fold_convert_loc (loc, ptrtype,
					   CALL_EXPR_ARG (arg0, 0));
	      tree iref = build_fold_indirect_ref_loc (loc, ptr);
	      return fold_build2_loc (loc, 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 (wi::to_wide (arg01) == element_precision (itype) - 1)
	    {
	      if (TYPE_UNSIGNED (itype))
		{
		  itype = signed_type_for (itype);
		  arg00 = fold_convert_loc (loc, itype, arg00);
		}
	      return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
				  type, arg00, build_zero_cst (itype));
	    }
	}

      /* 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_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg0),
				 TREE_OPERAND (TREE_OPERAND (arg0, 0), 0),
				 TREE_OPERAND (arg0, 1));
	  return fold_build2_loc (loc, code == EQ_EXPR ? NE_EXPR : EQ_EXPR,
				  type, tem,
				  fold_convert_loc (loc, TREE_TYPE (arg0),
						    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_loc (loc, 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_loc (loc, BIT_AND_EXPR, TREE_TYPE (arg000),
			     arg000, TREE_OPERAND (arg0, 1));
	  return fold_build2_loc (loc, 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_loc (loc, type, res, arg0);
	}

      if (TREE_CODE (arg0) == BIT_XOR_EXPR
	  && TREE_CODE (arg1) == BIT_XOR_EXPR)
	{
	  tree arg00 = TREE_OPERAND (arg0, 0);
	  tree arg01 = TREE_OPERAND (arg0, 1);
	  tree arg10 = TREE_OPERAND (arg1, 0);
	  tree arg11 = TREE_OPERAND (arg1, 1);
	  tree itype = TREE_TYPE (arg0);

	  /* Optimize (X ^ Z) op (Y ^ Z) as X op Y, and symmetries.
	     operand_equal_p guarantees no side-effects so we don't need
	     to use omit_one_operand on Z.  */
	  if (operand_equal_p (arg01, arg11, 0))
	    return fold_build2_loc (loc, code, type, arg00,
				    fold_convert_loc (loc, TREE_TYPE (arg00),
						      arg10));
	  if (operand_equal_p (arg01, arg10, 0))
	    return fold_build2_loc (loc, code, type, arg00,
				    fold_convert_loc (loc, TREE_TYPE (arg00),
						      arg11));
	  if (operand_equal_p (arg00, arg11, 0))
	    return fold_build2_loc (loc, code, type, arg01,
				    fold_convert_loc (loc, TREE_TYPE (arg01),
						      arg10));
	  if (operand_equal_p (arg00, arg10, 0))
	    return fold_build2_loc (loc, code, type, arg01,
				    fold_convert_loc (loc, TREE_TYPE (arg01),
						      arg11));

	  /* Optimize (X ^ C1) op (Y ^ C2) as (X ^ (C1 ^ C2)) op Y.  */
	  if (TREE_CODE (arg01) == INTEGER_CST
	      && TREE_CODE (arg11) == INTEGER_CST)
	    {
	      tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg01,
				     fold_convert_loc (loc, itype, arg11));
	      tem = fold_build2_loc (loc, BIT_XOR_EXPR, itype, arg00, tem);
	      return fold_build2_loc (loc, code, type, tem,
				      fold_convert_loc (loc, itype, arg10));
	    }
	}

      /* Attempt to simplify equality/inequality comparisons of complex
	 values.  Only lower the comparison if the result is known or
	 can be simplified to a single scalar comparison.  */
      if ((TREE_CODE (arg0) == COMPLEX_EXPR
	   || TREE_CODE (arg0) == COMPLEX_CST)
	  && (TREE_CODE (arg1) == COMPLEX_EXPR
	      || TREE_CODE (arg1) == COMPLEX_CST))
	{
	  tree real0, imag0, real1, imag1;
	  tree rcond, icond;

	  if (TREE_CODE (arg0) == COMPLEX_EXPR)
	    {
	      real0 = TREE_OPERAND (arg0, 0);
	      imag0 = TREE_OPERAND (arg0, 1);
	    }
	  else
	    {
	      real0 = TREE_REALPART (arg0);
	      imag0 = TREE_IMAGPART (arg0);
	    }

	  if (TREE_CODE (arg1) == COMPLEX_EXPR)
	    {
	      real1 = TREE_OPERAND (arg1, 0);
	      imag1 = TREE_OPERAND (arg1, 1);
	    }
	  else
	    {
	      real1 = TREE_REALPART (arg1);
	      imag1 = TREE_IMAGPART (arg1);
	    }

	  rcond = fold_binary_loc (loc, code, type, real0, real1);
	  if (rcond && TREE_CODE (rcond) == INTEGER_CST)
	    {
	      if (integer_zerop (rcond))
		{
		  if (code == EQ_EXPR)
		    return omit_two_operands_loc (loc, type, boolean_false_node,
					      imag0, imag1);
		  return fold_build2_loc (loc, NE_EXPR, type, imag0, imag1);
		}
	      else
		{
		  if (code == NE_EXPR)
		    return omit_two_operands_loc (loc, type, boolean_true_node,
					      imag0, imag1);
		  return fold_build2_loc (loc, EQ_EXPR, type, imag0, imag1);
		}
	    }

	  icond = fold_binary_loc (loc, code, type, imag0, imag1);
	  if (icond && TREE_CODE (icond) == INTEGER_CST)
	    {
	      if (integer_zerop (icond))
		{
		  if (code == EQ_EXPR)
		    return omit_two_operands_loc (loc, type, boolean_false_node,
					      real0, real1);
		  return fold_build2_loc (loc, NE_EXPR, type, real0, real1);
		}
	      else
		{
		  if (code == NE_EXPR)
		    return omit_two_operands_loc (loc, type, boolean_true_node,
					      real0, real1);
		  return fold_build2_loc (loc, EQ_EXPR, type, real0, real1);
		}
	    }
	}

      return NULL_TREE;

    case LT_EXPR:
    case GT_EXPR:
    case LE_EXPR:
    case GE_EXPR:
      tem = fold_comparison (loc, 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 (arg0))
	{
	  tree arg01 = TREE_OPERAND (arg0, 1);
	  enum tree_code code0 = TREE_CODE (arg0);
	  int is_positive = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg01)) ? -1 : 1;

	  /* (X - c) > X becomes false.  */
	  if (code == GT_EXPR
	      && ((code0 == MINUS_EXPR && is_positive >= 0)
		  || (code0 == PLUS_EXPR && is_positive <= 0)))
	    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)))
	    return constant_boolean_node (0, type);

	  /* Convert (X - c) <= X to true.  */
	  if (!HONOR_NANS (arg1)
	      && code == LE_EXPR
	      && ((code0 == MINUS_EXPR && is_positive >= 0)
		  || (code0 == PLUS_EXPR && is_positive <= 0)))
	    return constant_boolean_node (1, type);

	  /* Convert (X + c) >= X to true.  */
	  if (!HONOR_NANS (arg1)
	      && code == GE_EXPR
	      && ((code0 == PLUS_EXPR && is_positive >= 0)
		  || (code0 == MINUS_EXPR && is_positive <= 0)))
	    return constant_boolean_node (1, type);
	}

      /* 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)
	  && (tem = negate_expr (arg1)) != 0
	  && TREE_CODE (tem) == INTEGER_CST
	  && !TREE_OVERFLOW (tem))
	return fold_build2_loc (loc, 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 (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_loc (loc, type,
				       constant_boolean_node (true, type),
				       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_loc (loc, type,
				       constant_boolean_node (false, type),
				       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_loc (loc, code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
			   build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
				   TREE_OPERAND (arg1, 1)),
			   build_zero_cst (TREE_TYPE (arg0)));

      /* Similarly for X < (cast) (1 << Y).  But cast can't be narrowing,
	 otherwise Y might be >= # of bits in X's type and thus e.g.
	 (unsigned char) (1 << Y) for Y 15 might be 0.
	 If the cast is widening, then 1 << Y should have unsigned type,
	 otherwise if Y is number of bits in the signed shift type minus 1,
	 we can't optimize this.  E.g. (unsigned long long) (1 << Y) for Y
	 31 might be 0xffffffff80000000.  */
      if ((code == LT_EXPR || code == GE_EXPR)
	  && TYPE_UNSIGNED (TREE_TYPE (arg0))
	  && CONVERT_EXPR_P (arg1)
	  && TREE_CODE (TREE_OPERAND (arg1, 0)) == LSHIFT_EXPR
	  && (element_precision (TREE_TYPE (arg1))
	      >= element_precision (TREE_TYPE (TREE_OPERAND (arg1, 0))))
	  && (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg1, 0)))
	      || (element_precision (TREE_TYPE (arg1))
		  == element_precision (TREE_TYPE (TREE_OPERAND (arg1, 0)))))
	  && integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
	{
	  tem = build2 (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
			TREE_OPERAND (TREE_OPERAND (arg1, 0), 1));
	  return build2_loc (loc, code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
			     fold_convert_loc (loc, TREE_TYPE (arg0), tem),
			     build_zero_cst (TREE_TYPE (arg0)));
	}

      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:
      /* 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_loc (loc, code, type,
			      fold_convert_loc (loc, newtype, targ0),
			      fold_convert_loc (loc, 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_loc (loc, NOP_EXPR, type, arg1)
				 : fold_convert_loc (loc, type, arg1);
      return tem;

    case ASSERT_EXPR:
      /* An ASSERT_EXPR should never be passed to fold_binary.  */
      gcc_unreachable ();

    default:
      return NULL_TREE;
    } /* switch (code) */
}

/* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
   ((A & N) + B) & M -> (A + B) & M
   Similarly if (N & M) == 0,
   ((A | N) + B) & M -> (A + B) & M
   and for - instead of + (or unary - instead of +)
   and/or ^ instead of |.
   If B is constant and (B & M) == 0, fold into A & M.

   This function is a helper for match.pd patterns.  Return non-NULL
   type in which the simplified operation should be performed only
   if any optimization is possible.

   ARG1 is M above, ARG00 is left operand of +/-, if CODE00 is BIT_*_EXPR,
   then ARG00{0,1} are operands of that bitop, otherwise CODE00 is ERROR_MARK.
   Similarly for ARG01, CODE01 and ARG01{0,1}, just for the right operand of
   +/-.  */
tree
fold_bit_and_mask (tree type, tree arg1, enum tree_code code,
		   tree arg00, enum tree_code code00, tree arg000, tree arg001,
		   tree arg01, enum tree_code code01, tree arg010, tree arg011,
		   tree *pmop)
{
  gcc_assert (TREE_CODE (arg1) == INTEGER_CST);
  gcc_assert (code == PLUS_EXPR || code == MINUS_EXPR || code == NEGATE_EXPR);
  wi::tree_to_wide_ref cst1 = wi::to_wide (arg1);
  if (~cst1 == 0
      || (cst1 & (cst1 + 1)) != 0
      || !INTEGRAL_TYPE_P (type)
      || (!TYPE_OVERFLOW_WRAPS (type)
	  && TREE_CODE (type) != INTEGER_TYPE)
      || (wi::max_value (type) & cst1) != cst1)
    return NULL_TREE;

  enum tree_code codes[2] = { code00, code01 };
  tree arg0xx[4] = { arg000, arg001, arg010, arg011 };
  int which = 0;
  wide_int cst0;

  /* Now we know that arg0 is (C + D) or (C - D) or -C and
     arg1 (M) is == (1LL << cst) - 1.
     Store C into PMOP[0] and D into PMOP[1].  */
  pmop[0] = arg00;
  pmop[1] = arg01;
  which = code != NEGATE_EXPR;

  for (; which >= 0; which--)
    switch (codes[which])
      {
      case BIT_AND_EXPR:
      case BIT_IOR_EXPR:
      case BIT_XOR_EXPR:
	gcc_assert (TREE_CODE (arg0xx[2 * which + 1]) == INTEGER_CST);
	cst0 = wi::to_wide (arg0xx[2 * which + 1]) & cst1;
	if (codes[which] == BIT_AND_EXPR)
	  {
	    if (cst0 != cst1)
	      break;
	  }
	else if (cst0 != 0)
	  break;
	/* If C or D is of the form (A & N) where
	   (N & M) == M, or of the form (A | N) or
	   (A ^ N) where (N & M) == 0, replace it with A.  */
	pmop[which] = arg0xx[2 * which];
	break;
      case ERROR_MARK:
	if (TREE_CODE (pmop[which]) != INTEGER_CST)
	  break;
	/* If C or D is a N where (N & M) == 0, it can be
	   omitted (replaced with 0).  */
	if ((code == PLUS_EXPR
	     || (code == MINUS_EXPR && which == 0))
	    && (cst1 & wi::to_wide (pmop[which])) == 0)
	  pmop[which] = build_int_cst (type, 0);
	/* Similarly, with C - N where (-N & M) == 0.  */
	if (code == MINUS_EXPR
	    && which == 1
	    && (cst1 & -wi::to_wide (pmop[which])) == 0)
	  pmop[which] = build_int_cst (type, 0);
	break;
      default:
	gcc_unreachable ();
      }

  /* Only build anything new if we optimized one or both arguments above.  */
  if (pmop[0] == arg00 && pmop[1] == arg01)
    return NULL_TREE;

  if (TYPE_OVERFLOW_WRAPS (type))
    return type;
  else
    return unsigned_type_for (type);
}

/* Used by contains_label_[p1].  */

struct contains_label_data
{
  hash_set<tree> *pset;
  bool inside_switch_p;
};

/* Callback for walk_tree, looking for LABEL_EXPR.  Return *TP if it is
   a LABEL_EXPR or CASE_LABEL_EXPR not inside of another SWITCH_EXPR; otherwise
   return NULL_TREE.  Do not check the subtrees of GOTO_EXPR.  */

static tree
contains_label_1 (tree *tp, int *walk_subtrees, void *data)
{
  contains_label_data *d = (contains_label_data *) data;
  switch (TREE_CODE (*tp))
    {
    case LABEL_EXPR:
      return *tp;

    case CASE_LABEL_EXPR:
      if (!d->inside_switch_p)
	return *tp;
      return NULL_TREE;

    case SWITCH_EXPR:
      if (!d->inside_switch_p)
	{
	  if (walk_tree (&SWITCH_COND (*tp), contains_label_1, data, d->pset))
	    return *tp;
	  d->inside_switch_p = true;
	  if (walk_tree (&SWITCH_BODY (*tp), contains_label_1, data, d->pset))
	    return *tp;
	  d->inside_switch_p = false;
	  *walk_subtrees = 0;
	}
      return NULL_TREE;

    case GOTO_EXPR:
      *walk_subtrees = 0;
      return NULL_TREE;

    default:
      return NULL_TREE;
    }
}

/* Return whether the sub-tree ST contains a label which is accessible from
   outside the sub-tree.  */

static bool
contains_label_p (tree st)
{
  hash_set<tree> pset;
  contains_label_data data = { &pset, false };
  return walk_tree (&st, contains_label_1, &data, &pset) != 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_loc (location_t loc, enum tree_code code, tree type,
		  tree op0, tree op1, tree op2)
{
  tree tem;
  tree arg0 = NULL_TREE, arg1 = NULL_TREE, arg2 = NULL_TREE;
  enum tree_code_class kind = TREE_CODE_CLASS (code);

  gcc_assert (IS_EXPR_CODE_CLASS (kind)
	      && TREE_CODE_LENGTH (code) == 3);

  /* If this is a commutative operation, and OP0 is a constant, move it
     to OP1 to reduce the number of tests below.  */
  if (commutative_ternary_tree_code (code)
      && tree_swap_operands_p (op0, op1))
    return fold_build3_loc (loc, code, type, op1, op0, op2);

  tem = generic_simplify (loc, code, type, op0, op1, op2);
  if (tem)
    return tem;

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

  if (op2)
    {
      arg2 = op2;
      STRIP_NOPS (arg2);
    }

  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:
    case VEC_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 protected_set_expr_location_unshare (tem, loc);
	  return NULL_TREE;
	}
      else if (TREE_CODE (arg0) == VECTOR_CST)
	{
	  unsigned HOST_WIDE_INT nelts;
	  if ((TREE_CODE (arg1) == VECTOR_CST
	       || TREE_CODE (arg1) == CONSTRUCTOR)
	      && (TREE_CODE (arg2) == VECTOR_CST
		  || TREE_CODE (arg2) == CONSTRUCTOR)
	      && TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts))
	    {
	      vec_perm_builder sel (nelts, nelts, 1);
	      for (unsigned int i = 0; i < nelts; i++)
		{
		  tree val = VECTOR_CST_ELT (arg0, i);
		  if (integer_all_onesp (val))
		    sel.quick_push (i);
		  else if (integer_zerop (val))
		    sel.quick_push (nelts + i);
		  else /* Currently unreachable.  */
		    return NULL_TREE;
		}
	      vec_perm_indices indices (sel, 2, nelts);
	      tree t = fold_vec_perm (type, arg1, arg2, indices);
	      if (t != NULL_TREE)
		return t;
	    }
	}

      /* 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), op1)
	  && !HONOR_SIGNED_ZEROS (element_mode (op1)))
	{
	  tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2);
	  if (tem)
	    return tem;
	}

      if (COMPARISON_CLASS_P (arg0)
	  && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op2)
	  && !HONOR_SIGNED_ZEROS (element_mode (op2)))
	{
	  location_t loc0 = expr_location_or (arg0, loc);
	  tem = fold_invert_truthvalue (loc0, arg0);
	  if (tem && COMPARISON_CLASS_P (tem))
	    {
	      tem = fold_cond_expr_with_comparison (loc, 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))
	{
	  location_t loc0 = expr_location_or (arg0, loc);
	  /* 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_invert_truthvalue (loc0, arg0);
	  if (tem)
	    return fold_build3_loc (loc, code, type, tem, op2, op1);
	}

      /* Convert A ? 1 : 0 to simply A.  */
      if ((code == VEC_COND_EXPR ? integer_all_onesp (op1)
				 : (integer_onep (op1)
				    && !VECTOR_TYPE_P (type)))
	  && 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 protected_set_expr_location_unshare (arg0, loc);

      /* 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)
	  && code == COND_EXPR
	  && integer_onep (op2)
	  && !VECTOR_TYPE_P (type)
	  && truth_value_p (TREE_CODE (arg0)))
	return fold_convert_loc (loc, type,
				 invert_truthvalue_loc (loc, 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 looks through both zero and sign extensions,
	     but for this optimization only sign extensions are
	     usable.  */
	  tree tem2 = TREE_OPERAND (arg0, 0);
	  while (tem != tem2)
	    {
	      if (TREE_CODE (tem2) != NOP_EXPR
		  || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (tem2, 0))))
		{
		  tem = NULL_TREE;
		  break;
		}
	      tem2 = TREE_OPERAND (tem2, 0);
	    }
	  /* 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 (tem
	      && TYPE_PRECISION (TREE_TYPE (tem))
		 < TYPE_PRECISION (TREE_TYPE (arg1))
	      && TYPE_PRECISION (TREE_TYPE (tem))
		 < TYPE_PRECISION (type))
	    {
	      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);

	      wide_int mask = wi::shifted_mask
		(inner_width, outer_width - inner_width, false,
		 TYPE_PRECISION (TREE_TYPE (arg1)));

	      wide_int common = mask & wi::to_wide (arg1);
	      if (common == mask)
		{
		  tem_type = signed_type_for (TREE_TYPE (tem));
		  tem = fold_convert_loc (loc, tem_type, tem);
		}
	      else if (common == 0)
		{
		  tem_type = unsigned_type_for (TREE_TYPE (tem));
		  tem = fold_convert_loc (loc, tem_type, tem);
		}
	      else
		tem = NULL;
	    }

	  if (tem)
	    return
	      fold_convert_loc (loc, type,
				fold_build2_loc (loc, BIT_AND_EXPR,
					     TREE_TYPE (tem), tem,
					     fold_convert_loc (loc,
							       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_fits_uhwi_p (TREE_OPERAND (tem, 1))
              && (unsigned HOST_WIDE_INT) tree_log2 (arg1)
		 == tree_to_uhwi (TREE_OPERAND (tem, 1)))
	    return fold_build2_loc (loc, BIT_AND_EXPR, type,
				    fold_convert_loc (loc, type,
						      TREE_OPERAND (tem, 0)),
				    op1);
	}

      /* 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)
	  /* operand_equal_p compares just value, not precision, so e.g.
	     arg1 could be 8-bit -128 and be power of two, but BIT_AND_EXPR
	     second operand 32-bit -128, which is not a power of two (or vice
	     versa.  */
	  && integer_pow2p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)))
	return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));

      /* Disable the transformations below for vectors, since
	 fold_binary_op_with_conditional_arg may undo them immediately,
	 yielding an infinite loop.  */
      if (code == VEC_COND_EXPR)
	return NULL_TREE;

      /* 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))
	  && (code == VEC_COND_EXPR || !VECTOR_TYPE_P (type)))
	return fold_build2_loc (loc, code == VEC_COND_EXPR ? BIT_AND_EXPR
							   : TRUTH_ANDIF_EXPR,
				type, fold_convert_loc (loc, type, arg0), op1);

      /* Convert A ? B : 1 into !A || B if A and B are truth values.  */
      if (code == VEC_COND_EXPR ? integer_all_onesp (op2) : integer_onep (op2)
	  && truth_value_p (TREE_CODE (arg0))
	  && truth_value_p (TREE_CODE (arg1))
	  && (code == VEC_COND_EXPR || !VECTOR_TYPE_P (type)))
	{
	  location_t loc0 = expr_location_or (arg0, loc);
	  /* Only perform transformation if ARG0 is easily inverted.  */
	  tem = fold_invert_truthvalue (loc0, arg0);
	  if (tem)
	    return fold_build2_loc (loc, code == VEC_COND_EXPR
					 ? BIT_IOR_EXPR
					 : TRUTH_ORIF_EXPR,
				    type, fold_convert_loc (loc, type, tem),
				    op1);
	}

      /* 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))
	  && (code == VEC_COND_EXPR || !VECTOR_TYPE_P (type)))
	{
	  location_t loc0 = expr_location_or (arg0, loc);
	  /* Only perform transformation if ARG0 is easily inverted.  */
	  tem = fold_invert_truthvalue (loc0, arg0);
	  if (tem)
	    return fold_build2_loc (loc, code == VEC_COND_EXPR
					 ? BIT_AND_EXPR : TRUTH_ANDIF_EXPR,
				    type, fold_convert_loc (loc, type, tem),
				    op2);
	}

      /* Convert A ? 1 : B into A || B if A and B are truth values.  */
      if (code == VEC_COND_EXPR ? integer_all_onesp (arg1) : integer_onep (arg1)
	  && truth_value_p (TREE_CODE (arg0))
	  && truth_value_p (TREE_CODE (op2))
	  && (code == VEC_COND_EXPR || !VECTOR_TYPE_P (type)))
	return fold_build2_loc (loc, code == VEC_COND_EXPR
				     ? BIT_IOR_EXPR : TRUTH_ORIF_EXPR,
				type, fold_convert_loc (loc, type, arg0), op2);

      return NULL_TREE;

    case CALL_EXPR:
      /* CALL_EXPRs used to be ternary exprs.  Catch any mistaken uses
	 of fold_ternary on them.  */
      gcc_unreachable ();

    case BIT_FIELD_REF:
      if (TREE_CODE (arg0) == VECTOR_CST
	  && (type == TREE_TYPE (TREE_TYPE (arg0))
	      || (VECTOR_TYPE_P (type)
		  && TREE_TYPE (type) == TREE_TYPE (TREE_TYPE (arg0))))
	  && tree_fits_uhwi_p (op1)
	  && tree_fits_uhwi_p (op2))
	{
	  tree eltype = TREE_TYPE (TREE_TYPE (arg0));
	  unsigned HOST_WIDE_INT width
	    = (TREE_CODE (eltype) == BOOLEAN_TYPE
	       ? TYPE_PRECISION (eltype) : tree_to_uhwi (TYPE_SIZE (eltype)));
	  unsigned HOST_WIDE_INT n = tree_to_uhwi (arg1);
	  unsigned HOST_WIDE_INT idx = tree_to_uhwi (op2);

	  if (n != 0
	      && (idx % width) == 0
	      && (n % width) == 0
	      && known_le ((idx + n) / width,
			   TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0))))
	    {
	      idx = idx / width;
	      n = n / width;

	      if (TREE_CODE (arg0) == VECTOR_CST)
		{
		  if (n == 1)
		    {
		      tem = VECTOR_CST_ELT (arg0, idx);
		      if (VECTOR_TYPE_P (type))
			tem = fold_build1 (VIEW_CONVERT_EXPR, type, tem);
		      return tem;
		    }

		  tree_vector_builder vals (type, n, 1);
		  for (unsigned i = 0; i < n; ++i)
		    vals.quick_push (VECTOR_CST_ELT (arg0, idx + i));
		  return vals.build ();
		}
	    }
	}

      /* On constants we can use native encode/interpret to constant
         fold (nearly) all BIT_FIELD_REFs.  */
      if (CONSTANT_CLASS_P (arg0)
	  && can_native_interpret_type_p (type)
	  && BITS_PER_UNIT == 8
	  && tree_fits_uhwi_p (op1)
	  && tree_fits_uhwi_p (op2))
	{
	  unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
	  unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (op1);
	  /* Limit us to a reasonable amount of work.  To relax the
	     other limitations we need bit-shifting of the buffer
	     and rounding up the size.  */
	  if (bitpos % BITS_PER_UNIT == 0
	      && bitsize % BITS_PER_UNIT == 0
	      && bitsize <= MAX_BITSIZE_MODE_ANY_MODE)
	    {
	      unsigned char b[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
	      unsigned HOST_WIDE_INT len
		= native_encode_expr (arg0, b, bitsize / BITS_PER_UNIT,
				      bitpos / BITS_PER_UNIT);
	      if (len > 0
		  && len * BITS_PER_UNIT >= bitsize)
		{
		  tree v = native_interpret_expr (type, b,
						  bitsize / BITS_PER_UNIT);
		  if (v)
		    return v;
		}
	    }
	}

      return NULL_TREE;

    case VEC_PERM_EXPR:
      /* Perform constant folding of BIT_INSERT_EXPR.  */
      if (TREE_CODE (arg2) == VECTOR_CST
	  && TREE_CODE (op0) == VECTOR_CST
	  && TREE_CODE (op1) == VECTOR_CST)
	{
	  /* Build a vector of integers from the tree mask.  */
	  vec_perm_builder builder;
	  if (!tree_to_vec_perm_builder (&builder, arg2))
	    return NULL_TREE;

	  /* Create a vec_perm_indices for the integer vector.  */
	  poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type);
	  bool single_arg = (op0 == op1);
	  vec_perm_indices sel (builder, single_arg ? 1 : 2, nelts);
	  return fold_vec_perm (type, op0, op1, sel);
	}
      return NULL_TREE;

    case BIT_INSERT_EXPR:
      /* Perform (partial) constant folding of BIT_INSERT_EXPR.  */
      if (TREE_CODE (arg0) == INTEGER_CST
	  && TREE_CODE (arg1) == INTEGER_CST)
	{
	  unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
	  unsigned bitsize = TYPE_PRECISION (TREE_TYPE (arg1));
	  wide_int tem = (wi::to_wide (arg0)
			  & wi::shifted_mask (bitpos, bitsize, true,
					      TYPE_PRECISION (type)));
	  wide_int tem2
	    = wi::lshift (wi::zext (wi::to_wide (arg1, TYPE_PRECISION (type)),
				    bitsize), bitpos);
	  return wide_int_to_tree (type, wi::bit_or (tem, tem2));
	}
      else if (TREE_CODE (arg0) == VECTOR_CST
	       && CONSTANT_CLASS_P (arg1)
	       && types_compatible_p (TREE_TYPE (TREE_TYPE (arg0)),
				      TREE_TYPE (arg1)))
	{
	  unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
	  unsigned HOST_WIDE_INT elsize
	    = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (arg1)));
	  if (bitpos % elsize == 0)
	    {
	      unsigned k = bitpos / elsize;
	      unsigned HOST_WIDE_INT nelts;
	      if (operand_equal_p (VECTOR_CST_ELT (arg0, k), arg1, 0))
		return arg0;
	      else if (VECTOR_CST_NELTS (arg0).is_constant (&nelts))
		{
		  tree_vector_builder elts (type, nelts, 1);
		  elts.quick_grow (nelts);
		  for (unsigned HOST_WIDE_INT i = 0; i < nelts; ++i)
		    elts[i] = (i == k ? arg1 : VECTOR_CST_ELT (arg0, i));
		  return elts.build ();
		}
	    }
	}
      return NULL_TREE;

    default:
      return NULL_TREE;
    } /* switch (code) */
}

/* Gets the element ACCESS_INDEX from CTOR, which must be a CONSTRUCTOR
   of an array (or vector).  *CTOR_IDX if non-NULL is updated with the
   constructor element index of the value returned.  If the element is
   not found NULL_TREE is returned and *CTOR_IDX is updated to
   the index of the element after the ACCESS_INDEX position (which
   may be outside of the CTOR array).  */

tree
get_array_ctor_element_at_index (tree ctor, offset_int access_index,
				 unsigned *ctor_idx)
{
  tree index_type = NULL_TREE;
  signop index_sgn = UNSIGNED;
  offset_int low_bound = 0;

  if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
    {
      tree domain_type = TYPE_DOMAIN (TREE_TYPE (ctor));
      if (domain_type && TYPE_MIN_VALUE (domain_type))
	{
	  /* Static constructors for variably sized objects makes no sense.  */
	  gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
	  index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type));
	  /* ???  When it is obvious that the range is signed, treat it so.  */
	  if (TYPE_UNSIGNED (index_type)
	      && TYPE_MAX_VALUE (domain_type)
	      && tree_int_cst_lt (TYPE_MAX_VALUE (domain_type),
				  TYPE_MIN_VALUE (domain_type)))
	    {
	      index_sgn = SIGNED;
	      low_bound
		= offset_int::from (wi::to_wide (TYPE_MIN_VALUE (domain_type)),
				    SIGNED);
	    }
	  else
	    {
	      index_sgn = TYPE_SIGN (index_type);
	      low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
	    }
	}
    }

  if (index_type)
    access_index = wi::ext (access_index, TYPE_PRECISION (index_type),
			    index_sgn);

  offset_int index = low_bound;
  if (index_type)
    index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);

  offset_int max_index = index;
  unsigned cnt;
  tree cfield, cval;
  bool first_p = true;

  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
    {
      /* Array constructor might explicitly set index, or specify a range,
	 or leave index NULL meaning that it is next index after previous
	 one.  */
      if (cfield)
	{
	  if (TREE_CODE (cfield) == INTEGER_CST)
	    max_index = index
	      = offset_int::from (wi::to_wide (cfield), index_sgn);
	  else
	    {
	      gcc_assert (TREE_CODE (cfield) == RANGE_EXPR);
	      index = offset_int::from (wi::to_wide (TREE_OPERAND (cfield, 0)),
					index_sgn);
	      max_index
	        = offset_int::from (wi::to_wide (TREE_OPERAND (cfield, 1)),
				    index_sgn);
	      gcc_checking_assert (wi::le_p (index, max_index, index_sgn));
	    }
	}
      else if (!first_p)
	{
	  index = max_index + 1;
	  if (index_type)
	    index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);
	  gcc_checking_assert (wi::gt_p (index, max_index, index_sgn));
	  max_index = index;
	}
      else
	first_p = false;

      /* Do we have match?  */
      if (wi::cmp (access_index, index, index_sgn) >= 0)
	{
	  if (wi::cmp (access_index, max_index, index_sgn) <= 0)
	    {
	      if (ctor_idx)
		*ctor_idx = cnt;
	      return cval;
	    }
	}
      else if (in_gimple_form)
	/* We're past the element we search for.  Note during parsing
	   the elements might not be sorted.
	   ???  We should use a binary search and a flag on the
	   CONSTRUCTOR as to whether elements are sorted in declaration
	   order.  */
	break;
    }
  if (ctor_idx)
    *ctor_idx = cnt;
  return NULL_TREE;
}

/* 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;
  location_t loc = EXPR_LOCATION (expr);

  /* Return right away if a constant.  */
  if (kind == tcc_constant)
    return t;

  /* CALL_EXPR-like objects with variable numbers of operands are
     treated specially.  */
  if (kind == tcc_vl_exp)
    {
      if (code == CALL_EXPR)
	{
	  tem = fold_call_expr (loc, expr, false);
	  return tem ? tem : expr;
	}
      return expr;
    }

  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_loc (loc, code, type, op0);
	  return tem ? tem : expr;
	case 2:
	  op0 = TREE_OPERAND (t, 0);
	  op1 = TREE_OPERAND (t, 1);
	  tem = fold_binary_loc (loc, 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_loc (loc, code, type, op0, op1, op2);
	  return tem ? tem : expr;
	default:
	  break;
	}
    }

  switch (code)
    {
    case ARRAY_REF:
      {
	tree op0 = TREE_OPERAND (t, 0);
	tree op1 = TREE_OPERAND (t, 1);

	if (TREE_CODE (op1) == INTEGER_CST
	    && TREE_CODE (op0) == CONSTRUCTOR
	    && ! type_contains_placeholder_p (TREE_TYPE (op0)))
	  {
	    tree val = get_array_ctor_element_at_index (op0,
							wi::to_offset (op1));
	    if (val)
	      return val;
	  }

	return t;
      }

      /* Return a VECTOR_CST if possible.  */
    case CONSTRUCTOR:
      {
	tree type = TREE_TYPE (t);
	if (TREE_CODE (type) != VECTOR_TYPE)
	  return t;

	unsigned i;
	tree val;
	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
	  if (! CONSTANT_CLASS_P (val))
	    return t;

	return build_vector_from_ctor (type, CONSTRUCTOR_ELTS (t));
      }

    case CONST_DECL:
      return fold (DECL_INITIAL (t));

    default:
      return t;
    } /* switch (code) */
}

#ifdef ENABLE_FOLD_CHECKING
#undef fold

static void fold_checksum_tree (const_tree, struct md5_ctx *,
				hash_table<nofree_ptr_hash<const tree_node> > *);
static void fold_check_failed (const_tree, const_tree);
void print_fold_checksum (const_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];
  hash_table<nofree_ptr_hash<const tree_node> > ht (32);

  md5_init_ctx (&ctx);
  fold_checksum_tree (expr, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_before);
  ht.empty ();

  ret = fold_1 (expr);

  md5_init_ctx (&ctx);
  fold_checksum_tree (expr, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_after);

  if (memcmp (checksum_before, checksum_after, 16))
    fold_check_failed (expr, ret);

  return ret;
}

void
print_fold_checksum (const_tree expr)
{
  struct md5_ctx ctx;
  unsigned char checksum[16], cnt;
  hash_table<nofree_ptr_hash<const tree_node> > ht (32);

  md5_init_ctx (&ctx);
  fold_checksum_tree (expr, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum);
  for (cnt = 0; cnt < 16; ++cnt)
    fprintf (stderr, "%02x", checksum[cnt]);
  putc ('\n', stderr);
}

static void
fold_check_failed (const_tree expr ATTRIBUTE_UNUSED, const_tree ret ATTRIBUTE_UNUSED)
{
  internal_error ("fold check: original tree changed by fold");
}

static void
fold_checksum_tree (const_tree expr, struct md5_ctx *ctx,
		    hash_table<nofree_ptr_hash <const tree_node> > *ht)
{
  const tree_node **slot;
  enum tree_code code;
  union tree_node *buf;
  int i, len;

 recursive_label:
  if (expr == NULL)
    return;
  slot = ht->find_slot (expr, INSERT);
  if (*slot != NULL)
    return;
  *slot = expr;
  code = TREE_CODE (expr);
  if (TREE_CODE_CLASS (code) == tcc_declaration
      && HAS_DECL_ASSEMBLER_NAME_P (expr))
    {
      /* Allow DECL_ASSEMBLER_NAME and symtab_node to be modified.  */
      size_t sz = tree_size (expr);
      buf = XALLOCAVAR (union tree_node, sz);
      memcpy ((char *) buf, expr, sz);
      SET_DECL_ASSEMBLER_NAME ((tree) buf, NULL);
      buf->decl_with_vis.symtab_node = NULL;
      buf->base.nowarning_flag = 0;
      expr = (tree) buf;
    }
  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)
	       || TYPE_NEXT_VARIANT (expr)
	       || TYPE_ALIAS_SET_KNOWN_P (expr)))
    {
      /* Allow these fields to be modified.  */
      tree tmp;
      size_t sz = tree_size (expr);
      buf = XALLOCAVAR (union tree_node, sz);
      memcpy ((char *) buf, expr, sz);
      expr = tmp = (tree) buf;
      TYPE_CONTAINS_PLACEHOLDER_INTERNAL (tmp) = 0;
      TYPE_POINTER_TO (tmp) = NULL;
      TYPE_REFERENCE_TO (tmp) = NULL;
      TYPE_NEXT_VARIANT (tmp) = NULL;
      TYPE_ALIAS_SET (tmp) = -1;
      if (TYPE_CACHED_VALUES_P (tmp))
	{
	  TYPE_CACHED_VALUES_P (tmp) = 0;
	  TYPE_CACHED_VALUES (tmp) = NULL;
	}
    }
  else if (TREE_NO_WARNING (expr) && (DECL_P (expr) || EXPR_P (expr)))
    {
      /* Allow TREE_NO_WARNING to be set.  Perhaps we shouldn't allow that
	 and change builtins.c etc. instead - see PR89543.  */
      size_t sz = tree_size (expr);
      buf = XALLOCAVAR (union tree_node, sz);
      memcpy ((char *) buf, expr, sz);
      buf->base.nowarning_flag = 0;
      expr = (tree) buf;
    }
  md5_process_bytes (expr, tree_size (expr), ctx);
  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
    fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
  if (TREE_CODE_CLASS (code) != tcc_type
      && TREE_CODE_CLASS (code) != tcc_declaration
      && code != TREE_LIST
      && code != SSA_NAME
      && CODE_CONTAINS_STRUCT (code, TS_COMMON))
    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:
	  len = vector_cst_encoded_nelts (expr);
	  for (i = 0; i < len; ++i)
	    fold_checksum_tree (VECTOR_CST_ENCODED_ELT (expr, i), 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:
    case tcc_vl_exp:
      len = TREE_OPERAND_LENGTH (expr);
      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_NON_COMMON))
	{
	  if (TREE_CODE (expr) == FUNCTION_DECL)
	    {
	      fold_checksum_tree (DECL_VINDEX (expr), ctx, ht);
	      fold_checksum_tree (DECL_ARGUMENTS (expr), ctx, ht);
	    }
	  fold_checksum_tree (DECL_RESULT_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;
    }
}

/* Helper function for outputting the checksum of a tree T.  When
   debugging with gdb, you can "define mynext" to be "next" followed
   by "call debug_fold_checksum (op0)", then just trace down till the
   outputs differ.  */

DEBUG_FUNCTION void
debug_fold_checksum (const_tree t)
{
  int i;
  unsigned char checksum[16];
  struct md5_ctx ctx;
  hash_table<nofree_ptr_hash<const tree_node> > ht (32);

  md5_init_ctx (&ctx);
  fold_checksum_tree (t, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum);
  ht.empty ();

  for (i = 0; i < 16; i++)
    fprintf (stderr, "%d ", checksum[i]);

  fprintf (stderr, "\n");
}

#endif

/* Fold a unary tree expression with code CODE of type TYPE with an
   operand OP0.  LOC is the location of the resulting expression.
   Return a folded expression if successful.  Otherwise, return a tree
   expression with code CODE of type TYPE with an operand OP0.  */

tree
fold_build1_loc (location_t loc,
		 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;
  hash_table<nofree_ptr_hash<const tree_node> > ht (32);

  md5_init_ctx (&ctx);
  fold_checksum_tree (op0, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_before);
  ht.empty ();
#endif

  tem = fold_unary_loc (loc, code, type, op0);
  if (!tem)
    tem = build1_loc (loc, 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);

  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.  LOC is the location of the resulting
   expression.  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_loc (location_t loc,
		      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;
  hash_table<nofree_ptr_hash<const tree_node> > ht (32);

  md5_init_ctx (&ctx);
  fold_checksum_tree (op0, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_before_op0);
  ht.empty ();

  md5_init_ctx (&ctx);
  fold_checksum_tree (op1, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_before_op1);
  ht.empty ();
#endif

  tem = fold_binary_loc (loc, code, type, op0, op1);
  if (!tem)
    tem = build2_loc (loc, 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);
  ht.empty ();

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

  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_loc (location_t loc, 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;
  hash_table<nofree_ptr_hash<const tree_node> > ht (32);

  md5_init_ctx (&ctx);
  fold_checksum_tree (op0, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_before_op0);
  ht.empty ();

  md5_init_ctx (&ctx);
  fold_checksum_tree (op1, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_before_op1);
  ht.empty ();

  md5_init_ctx (&ctx);
  fold_checksum_tree (op2, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_before_op2);
  ht.empty ();
#endif

  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
  tem = fold_ternary_loc (loc, code, type, op0, op1, op2);
  if (!tem)
    tem = build3_loc (loc, 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);
  ht.empty ();

  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);
  ht.empty ();

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

  if (memcmp (checksum_before_op2, checksum_after_op2, 16))
    fold_check_failed (op2, tem);
#endif
  return tem;
}

/* Fold a CALL_EXPR expression of type TYPE with operands FN and NARGS
   arguments in ARGARRAY, and a null static chain.
   Return a folded expression if successful.  Otherwise, return a CALL_EXPR
   of type TYPE from the given operands as constructed by build_call_array.  */

tree
fold_build_call_array_loc (location_t loc, tree type, tree fn,
			   int nargs, tree *argarray)
{
  tree tem;
#ifdef ENABLE_FOLD_CHECKING
  unsigned char checksum_before_fn[16],
                checksum_before_arglist[16],
		checksum_after_fn[16],
		checksum_after_arglist[16];
  struct md5_ctx ctx;
  hash_table<nofree_ptr_hash<const tree_node> > ht (32);
  int i;

  md5_init_ctx (&ctx);
  fold_checksum_tree (fn, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_before_fn);
  ht.empty ();

  md5_init_ctx (&ctx);
  for (i = 0; i < nargs; i++)
    fold_checksum_tree (argarray[i], &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_before_arglist);
  ht.empty ();
#endif

  tem = fold_builtin_call_array (loc, type, fn, nargs, argarray);
  if (!tem)
    tem = build_call_array_loc (loc, type, fn, nargs, argarray);

#ifdef ENABLE_FOLD_CHECKING
  md5_init_ctx (&ctx);
  fold_checksum_tree (fn, &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_after_fn);
  ht.empty ();

  if (memcmp (checksum_before_fn, checksum_after_fn, 16))
    fold_check_failed (fn, tem);

  md5_init_ctx (&ctx);
  for (i = 0; i < nargs; i++)
    fold_checksum_tree (argarray[i], &ctx, &ht);
  md5_finish_ctx (&ctx, checksum_after_arglist);

  if (memcmp (checksum_before_arglist, checksum_after_arglist, 16))
    fold_check_failed (NULL_TREE, 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_loc (location_t loc, enum tree_code code,
			     tree type, tree op)
{
  tree result;
  START_FOLD_INIT;

  result = fold_build1_loc (loc, code, type, op);

  END_FOLD_INIT;
  return result;
}

tree
fold_build2_initializer_loc (location_t loc, enum tree_code code,
			     tree type, tree op0, tree op1)
{
  tree result;
  START_FOLD_INIT;

  result = fold_build2_loc (loc, code, type, op0, op1);

  END_FOLD_INIT;
  return result;
}

tree
fold_build_call_array_initializer_loc (location_t loc, tree type, tree fn,
				       int nargs, tree *argarray)
{
  tree result;
  START_FOLD_INIT;

  result = fold_build_call_array_loc (loc, type, fn, nargs, argarray);

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

int
multiple_of_p (tree type, const_tree top, const_tree bottom)
{
  gimple *stmt;
  tree t1, op1, op2;

  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;
      return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom)
	      || multiple_of_p (type, TREE_OPERAND (top, 0), bottom));

    case MULT_EXPR:
      if (TREE_CODE (bottom) == INTEGER_CST)
	{
	  op1 = TREE_OPERAND (top, 0);
	  op2 = TREE_OPERAND (top, 1);
	  if (TREE_CODE (op1) == INTEGER_CST)
	    std::swap (op1, op2);
	  if (TREE_CODE (op2) == INTEGER_CST)
	    {
	      if (multiple_of_p (type, op2, bottom))
		return 1;
	      /* Handle multiple_of_p ((x * 2 + 2) * 4, 8).  */
	      if (multiple_of_p (type, bottom, op2))
		{
		  widest_int w = wi::sdiv_trunc (wi::to_widest (bottom),
						 wi::to_widest (op2));
		  if (wi::fits_to_tree_p (w, TREE_TYPE (bottom)))
		    {
		      op2 = wide_int_to_tree (TREE_TYPE (bottom), w);
		      return multiple_of_p (type, op1, op2);
		    }
		}
	      return multiple_of_p (type, op1, bottom);
	    }
	}
      return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom)
	      || multiple_of_p (type, TREE_OPERAND (top, 0), bottom));

    case MINUS_EXPR:
      /* It is impossible to prove if op0 - op1 is multiple of bottom
	 precisely, so be conservative here checking if both op0 and op1
	 are multiple of bottom.  Note we check the second operand first
	 since it's usually simpler.  */
      return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom)
	      && multiple_of_p (type, TREE_OPERAND (top, 0), bottom));

    case PLUS_EXPR:
      /* The same as MINUS_EXPR, but handle cases like op0 + 0xfffffffd
	 as op0 - 3 if the expression has unsigned type.  For example,
	 (X / 3) + 0xfffffffd is multiple of 3, but 0xfffffffd is not.  */
      op1 = TREE_OPERAND (top, 1);
      if (TYPE_UNSIGNED (type)
	  && TREE_CODE (op1) == INTEGER_CST && tree_int_cst_sign_bit (op1))
	op1 = fold_build1 (NEGATE_EXPR, type, op1);
      return (multiple_of_p (type, op1, bottom)
	      && multiple_of_p (type, TREE_OPERAND (top, 0), bottom));

    case LSHIFT_EXPR:
      if (TREE_CODE (TREE_OPERAND (top, 1)) == INTEGER_CST)
	{
	  op1 = TREE_OPERAND (top, 1);
	  /* const_binop may not detect overflow correctly,
	     so check for it explicitly here.  */
	  if (wi::gtu_p (TYPE_PRECISION (TREE_TYPE (size_one_node)),
			 wi::to_wide (op1))
	      && (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 COND_EXPR:
      return (multiple_of_p (type, TREE_OPERAND (top, 1), bottom)
	      && multiple_of_p (type, TREE_OPERAND (top, 2), bottom));

    case INTEGER_CST:
      if (TREE_CODE (bottom) != INTEGER_CST
	  || integer_zerop (bottom)
	  || (TYPE_UNSIGNED (type)
	      && (tree_int_cst_sgn (top) < 0
		  || tree_int_cst_sgn (bottom) < 0)))
	return 0;
      return wi::multiple_of_p (wi::to_widest (top), wi::to_widest (bottom),
				SIGNED);

    case SSA_NAME:
      if (TREE_CODE (bottom) == INTEGER_CST
	  && (stmt = SSA_NAME_DEF_STMT (top)) != NULL
	  && gimple_code (stmt) == GIMPLE_ASSIGN)
	{
	  enum tree_code code = gimple_assign_rhs_code (stmt);

	  /* Check for special cases to see if top is defined as multiple
	     of bottom:

	       top = (X & ~(bottom - 1) ; bottom is power of 2

	     or

	       Y = X % bottom
	       top = X - Y.  */
	  if (code == BIT_AND_EXPR
	      && (op2 = gimple_assign_rhs2 (stmt)) != NULL_TREE
	      && TREE_CODE (op2) == INTEGER_CST
	      && integer_pow2p (bottom)
	      && wi::multiple_of_p (wi::to_widest (op2),
				    wi::to_widest (bottom), UNSIGNED))
	    return 1;

	  op1 = gimple_assign_rhs1 (stmt);
	  if (code == MINUS_EXPR
	      && (op2 = gimple_assign_rhs2 (stmt)) != NULL_TREE
	      && TREE_CODE (op2) == SSA_NAME
	      && (stmt = SSA_NAME_DEF_STMT (op2)) != NULL
	      && gimple_code (stmt) == GIMPLE_ASSIGN
	      && (code = gimple_assign_rhs_code (stmt)) == TRUNC_MOD_EXPR
	      && operand_equal_p (op1, gimple_assign_rhs1 (stmt), 0)
	      && operand_equal_p (bottom, gimple_assign_rhs2 (stmt), 0))
	    return 1;
	}

      /* fall through */

    default:
      if (POLY_INT_CST_P (top) && poly_int_tree_p (bottom))
	return multiple_p (wi::to_poly_widest (top),
			   wi::to_poly_widest (bottom));

      return 0;
    }
}

/* Return true if expression X cannot be (or contain) a NaN or infinity.
   This function returns true for integer expressions, and returns
   false if uncertain.  */

bool
tree_expr_finite_p (const_tree x)
{
  machine_mode mode = element_mode (x);
  if (!HONOR_NANS (mode) && !HONOR_INFINITIES (mode))
    return true;
  switch (TREE_CODE (x))
    {
    case REAL_CST:
      return real_isfinite (TREE_REAL_CST_PTR (x));
    case COMPLEX_CST:
      return tree_expr_finite_p (TREE_REALPART (x))
	     && tree_expr_finite_p (TREE_IMAGPART (x));
    case FLOAT_EXPR:
      return true;
    case ABS_EXPR:
    case CONVERT_EXPR:
    case NON_LVALUE_EXPR:
    case NEGATE_EXPR:
    case SAVE_EXPR:
      return tree_expr_finite_p (TREE_OPERAND (x, 0));
    case MIN_EXPR:
    case MAX_EXPR:
      return tree_expr_finite_p (TREE_OPERAND (x, 0))
	     && tree_expr_finite_p (TREE_OPERAND (x, 1));
    case COND_EXPR:
      return tree_expr_finite_p (TREE_OPERAND (x, 1))
	     && tree_expr_finite_p (TREE_OPERAND (x, 2));
    case CALL_EXPR:
      switch (get_call_combined_fn (x))
	{
	CASE_CFN_FABS:
	  return tree_expr_finite_p (CALL_EXPR_ARG (x, 0));
	CASE_CFN_FMAX:
	CASE_CFN_FMIN:
	  return tree_expr_finite_p (CALL_EXPR_ARG (x, 0))
		 && tree_expr_finite_p (CALL_EXPR_ARG (x, 1));
	default:
	  return false;
	}

    default:
      return false;
    }
}

/* Return true if expression X evaluates to an infinity.
   This function returns false for integer expressions.  */

bool
tree_expr_infinite_p (const_tree x)
{
  if (!HONOR_INFINITIES (x))
    return false;
  switch (TREE_CODE (x))
    {
    case REAL_CST:
      return real_isinf (TREE_REAL_CST_PTR (x));
    case ABS_EXPR:
    case NEGATE_EXPR:
    case NON_LVALUE_EXPR:
    case SAVE_EXPR:
      return tree_expr_infinite_p (TREE_OPERAND (x, 0));
    case COND_EXPR:
      return tree_expr_infinite_p (TREE_OPERAND (x, 1))
	     && tree_expr_infinite_p (TREE_OPERAND (x, 2));
    default:
      return false;
    }
}

/* Return true if expression X could evaluate to an infinity.
   This function returns false for integer expressions, and returns
   true if uncertain.  */

bool
tree_expr_maybe_infinite_p (const_tree x)
{
  if (!HONOR_INFINITIES (x))
    return false;
  switch (TREE_CODE (x))
    {
    case REAL_CST:
      return real_isinf (TREE_REAL_CST_PTR (x));
    case FLOAT_EXPR:
      return false;
    case ABS_EXPR:
    case NEGATE_EXPR:
      return tree_expr_maybe_infinite_p (TREE_OPERAND (x, 0));
    case COND_EXPR:
      return tree_expr_maybe_infinite_p (TREE_OPERAND (x, 1))
	     || tree_expr_maybe_infinite_p (TREE_OPERAND (x, 2));
    default:
      return true;
    }
}

/* Return true if expression X evaluates to a signaling NaN.
   This function returns false for integer expressions.  */

bool
tree_expr_signaling_nan_p (const_tree x)
{
  if (!HONOR_SNANS (x))
    return false;
  switch (TREE_CODE (x))
    {
    case REAL_CST:
      return real_issignaling_nan (TREE_REAL_CST_PTR (x));
    case NON_LVALUE_EXPR:
    case SAVE_EXPR:
      return tree_expr_signaling_nan_p (TREE_OPERAND (x, 0));
    case COND_EXPR:
      return tree_expr_signaling_nan_p (TREE_OPERAND (x, 1))
	     && tree_expr_signaling_nan_p (TREE_OPERAND (x, 2));
    default:
      return false;
    }
}

/* Return true if expression X could evaluate to a signaling NaN.
   This function returns false for integer expressions, and returns
   true if uncertain.  */

bool
tree_expr_maybe_signaling_nan_p (const_tree x)
{
  if (!HONOR_SNANS (x))
    return false;
  switch (TREE_CODE (x))
    {
    case REAL_CST:
      return real_issignaling_nan (TREE_REAL_CST_PTR (x));
    case FLOAT_EXPR:
      return false;
    case ABS_EXPR:
    case CONVERT_EXPR:
    case NEGATE_EXPR:
    case NON_LVALUE_EXPR:
    case SAVE_EXPR:
      return tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 0));
    case MIN_EXPR:
    case MAX_EXPR:
      return tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 0))
	     || tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 1));
    case COND_EXPR:
      return tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 1))
	     || tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 2));
    case CALL_EXPR:
      switch (get_call_combined_fn (x))
	{
	CASE_CFN_FABS:
	  return tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 0));
	CASE_CFN_FMAX:
	CASE_CFN_FMIN:
	  return tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 0))
		 || tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 1));
	default:
	  return true;
	}
    default:
      return true;
    }
}

/* Return true if expression X evaluates to a NaN.
   This function returns false for integer expressions.  */

bool
tree_expr_nan_p (const_tree x)
{
  if (!HONOR_NANS (x))
    return false;
  switch (TREE_CODE (x))
    {
    case REAL_CST:
      return real_isnan (TREE_REAL_CST_PTR (x));
    case NON_LVALUE_EXPR:
    case SAVE_EXPR:
      return tree_expr_nan_p (TREE_OPERAND (x, 0));
    case COND_EXPR:
      return tree_expr_nan_p (TREE_OPERAND (x, 1))
	     && tree_expr_nan_p (TREE_OPERAND (x, 2));
    default:
      return false;
    }
}

/* Return true if expression X could evaluate to a NaN.
   This function returns false for integer expressions, and returns
   true if uncertain.  */

bool
tree_expr_maybe_nan_p (const_tree x)
{
  if (!HONOR_NANS (x))
    return false;
  switch (TREE_CODE (x))
    {
    case REAL_CST:
      return real_isnan (TREE_REAL_CST_PTR (x));
    case FLOAT_EXPR:
      return false;
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
      return !tree_expr_finite_p (TREE_OPERAND (x, 0))
	     || !tree_expr_finite_p (TREE_OPERAND (x, 1));
    case ABS_EXPR:
    case CONVERT_EXPR:
    case NEGATE_EXPR:
    case NON_LVALUE_EXPR:
    case SAVE_EXPR:
      return tree_expr_maybe_nan_p (TREE_OPERAND (x, 0));
    case MIN_EXPR:
    case MAX_EXPR:
      return tree_expr_maybe_nan_p (TREE_OPERAND (x, 0))
	     || tree_expr_maybe_nan_p (TREE_OPERAND (x, 1));
    case COND_EXPR:
      return tree_expr_maybe_nan_p (TREE_OPERAND (x, 1))
	     || tree_expr_maybe_nan_p (TREE_OPERAND (x, 2));
    case CALL_EXPR:
      switch (get_call_combined_fn (x))
	{
	CASE_CFN_FABS:
	  return tree_expr_maybe_nan_p (CALL_EXPR_ARG (x, 0));
	CASE_CFN_FMAX:
	CASE_CFN_FMIN:
	  return tree_expr_maybe_nan_p (CALL_EXPR_ARG (x, 0))
		 || tree_expr_maybe_nan_p (CALL_EXPR_ARG (x, 1));
	default:
	  return true;
	}
    default:
      return true;
    }
}

/* Return true if expression X could evaluate to -0.0.
   This function returns true if uncertain.  */

bool
tree_expr_maybe_real_minus_zero_p (const_tree x)
{
  if (!HONOR_SIGNED_ZEROS (x))
    return false;
  switch (TREE_CODE (x))
    {
    case REAL_CST:
      return REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (x));
    case INTEGER_CST:
    case FLOAT_EXPR:
    case ABS_EXPR:
      return false;
    case NON_LVALUE_EXPR:
    case SAVE_EXPR:
      return tree_expr_maybe_real_minus_zero_p (TREE_OPERAND (x, 0));
    case COND_EXPR:
      return tree_expr_maybe_real_minus_zero_p (TREE_OPERAND (x, 1))
	     || tree_expr_maybe_real_minus_zero_p (TREE_OPERAND (x, 2));
    case CALL_EXPR:
      switch (get_call_combined_fn (x))
	{
	CASE_CFN_FABS:
	  return false;
	default:
	  break;
	}
    default:
      break;
    }
  /* Ideally !(tree_expr_nonzero_p (X) || tree_expr_nonnegative_p (X))
   * but currently those predicates require tree and not const_tree.  */
  return true;
}

#define tree_expr_nonnegative_warnv_p(X, Y) \
  _Pragma ("GCC error \"Use RECURSE for recursive calls\"") 0

#define RECURSE(X) \
  ((tree_expr_nonnegative_warnv_p) (X, strict_overflow_p, depth + 1))

/* Return true if CODE or TYPE is known to be non-negative. */

static bool
tree_simple_nonnegative_warnv_p (enum tree_code code, tree type)
{
  if ((TYPE_PRECISION (type) != 1 || TYPE_UNSIGNED (type))
      && truth_value_p (code))
    /* 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;
  return false;
}

/* Return true if (CODE OP0) 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.  DEPTH is the current nesting depth of the query.  */

bool
tree_unary_nonnegative_warnv_p (enum tree_code code, tree type, tree op0,
				bool *strict_overflow_p, int depth)
{
  if (TYPE_UNSIGNED (type))
    return true;

  switch (code)
    {
    case ABS_EXPR:
      /* We can't return 1 if flag_wrapv is set because
	 ABS_EXPR<INT_MIN> = INT_MIN.  */
      if (!ANY_INTEGRAL_TYPE_P (type))
	return true;
      if (TYPE_OVERFLOW_UNDEFINED (type))
	{
	  *strict_overflow_p = true;
	  return true;
	}
      break;

    case NON_LVALUE_EXPR:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
      return RECURSE (op0);

    CASE_CONVERT:
      {
	tree inner_type = TREE_TYPE (op0);
	tree outer_type = type;

	if (TREE_CODE (outer_type) == REAL_TYPE)
	  {
	    if (TREE_CODE (inner_type) == REAL_TYPE)
	      return RECURSE (op0);
	    if (INTEGRAL_TYPE_P (inner_type))
	      {
		if (TYPE_UNSIGNED (inner_type))
		  return true;
		return RECURSE (op0);
	      }
	  }
	else if (INTEGRAL_TYPE_P (outer_type))
	  {
	    if (TREE_CODE (inner_type) == REAL_TYPE)
	      return RECURSE (op0);
	    if (INTEGRAL_TYPE_P (inner_type))
	      return TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type)
		      && TYPE_UNSIGNED (inner_type);
	  }
      }
      break;

    default:
      return tree_simple_nonnegative_warnv_p (code, type);
    }

  /* We don't know sign of `t', so be conservative and return false.  */
  return false;
}

/* Return true if (CODE OP0 OP1) 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.  DEPTH is the current nesting depth of the query.  */

bool
tree_binary_nonnegative_warnv_p (enum tree_code code, tree type, tree op0,
				 tree op1, bool *strict_overflow_p,
				 int depth)
{
  if (TYPE_UNSIGNED (type))
    return true;

  switch (code)
    {
    case POINTER_PLUS_EXPR:
    case PLUS_EXPR:
      if (FLOAT_TYPE_P (type))
	return RECURSE (op0) && RECURSE (op1);

      /* 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 (type) == INTEGER_TYPE
	  && TREE_CODE (op0) == NOP_EXPR
	  && TREE_CODE (op1) == NOP_EXPR)
	{
	  tree inner1 = TREE_TYPE (TREE_OPERAND (op0, 0));
	  tree inner2 = TREE_TYPE (TREE_OPERAND (op1, 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 (type);
	    }
	}
      break;

    case MULT_EXPR:
      if (FLOAT_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
	{
	  /* x * x is always non-negative for floating point x
	     or without overflow.  */
	  if (operand_equal_p (op0, op1, 0)
	      || (RECURSE (op0) && RECURSE (op1)))
	    {
	      if (ANY_INTEGRAL_TYPE_P (type)
		  && TYPE_OVERFLOW_UNDEFINED (type))
		*strict_overflow_p = true;
	      return true;
	    }
	}

      /* 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 (type) == INTEGER_TYPE
	  && (TREE_CODE (op0) == NOP_EXPR || TREE_CODE (op0) == INTEGER_CST)
	  && (TREE_CODE (op1) == NOP_EXPR || TREE_CODE (op1) == INTEGER_CST))
	{
	  tree inner0 = (TREE_CODE (op0) == NOP_EXPR)
	    ? TREE_TYPE (TREE_OPERAND (op0, 0))
	    : TREE_TYPE (op0);
	  tree inner1 = (TREE_CODE (op1) == NOP_EXPR)
	    ? TREE_TYPE (TREE_OPERAND (op1, 0))
	    : TREE_TYPE (op1);

	  bool unsigned0 = TYPE_UNSIGNED (inner0);
	  bool unsigned1 = TYPE_UNSIGNED (inner1);

	  if (TREE_CODE (op0) == INTEGER_CST)
	    unsigned0 = unsigned0 || tree_int_cst_sgn (op0) >= 0;

	  if (TREE_CODE (op1) == INTEGER_CST)
	    unsigned1 = unsigned1 || tree_int_cst_sgn (op1) >= 0;

	  if (TREE_CODE (inner0) == INTEGER_TYPE && unsigned0
	      && TREE_CODE (inner1) == INTEGER_TYPE && unsigned1)
	    {
	      unsigned int precision0 = (TREE_CODE (op0) == INTEGER_CST)
		? tree_int_cst_min_precision (op0, UNSIGNED)
		: TYPE_PRECISION (inner0);

	      unsigned int precision1 = (TREE_CODE (op1) == INTEGER_CST)
		? tree_int_cst_min_precision (op1, UNSIGNED)
		: TYPE_PRECISION (inner1);

	      return precision0 + precision1 < TYPE_PRECISION (type);
	    }
	}
      return false;

    case BIT_AND_EXPR:
      return RECURSE (op0) || RECURSE (op1);

    case MAX_EXPR:
      /* Usually RECURSE (op0) || RECURSE (op1) but NaNs complicate
	 things.  */
      if (tree_expr_maybe_nan_p (op0) || tree_expr_maybe_nan_p (op1))
	return RECURSE (op0) && RECURSE (op1);
      return RECURSE (op0) || RECURSE (op1);

    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 RECURSE (op0) && RECURSE (op1);

    case TRUNC_MOD_EXPR:
      return RECURSE (op0);

    case FLOOR_MOD_EXPR:
      return RECURSE (op1);

    case CEIL_MOD_EXPR:
    case ROUND_MOD_EXPR:
    default:
      return tree_simple_nonnegative_warnv_p (code, type);
    }

  /* We don't know sign of `t', so be conservative and return false.  */
  return false;
}

/* 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.  DEPTH is the current nesting depth of the query.  */

bool
tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p, int depth)
{
  if (TYPE_UNSIGNED (TREE_TYPE (t)))
    return true;

  switch (TREE_CODE (t))
    {
    case INTEGER_CST:
      return tree_int_cst_sgn (t) >= 0;

    case REAL_CST:
      return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));

    case FIXED_CST:
      return ! FIXED_VALUE_NEGATIVE (TREE_FIXED_CST (t));

    case COND_EXPR:
      return RECURSE (TREE_OPERAND (t, 1)) && RECURSE (TREE_OPERAND (t, 2));

    case SSA_NAME:
      /* Limit the depth of recursion to avoid quadratic behavior.
	 This is expected to catch almost all occurrences in practice.
	 If this code misses important cases that unbounded recursion
	 would not, passes that need this information could be revised
	 to provide it through dataflow propagation.  */
      return (!name_registered_for_update_p (t)
	      && depth < param_max_ssa_name_query_depth
	      && gimple_stmt_nonnegative_warnv_p (SSA_NAME_DEF_STMT (t),
						  strict_overflow_p, depth));

    default:
      return tree_simple_nonnegative_warnv_p (TREE_CODE (t), TREE_TYPE (t));
    }
}

/* 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.  DEPTH is the current nesting depth of the query.  */

bool
tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
			       bool *strict_overflow_p, int depth)
{
  switch (fn)
    {
    CASE_CFN_ACOS:
    CASE_CFN_ACOSH:
    CASE_CFN_CABS:
    CASE_CFN_COSH:
    CASE_CFN_ERFC:
    CASE_CFN_EXP:
    CASE_CFN_EXP10:
    CASE_CFN_EXP2:
    CASE_CFN_FABS:
    CASE_CFN_FDIM:
    CASE_CFN_HYPOT:
    CASE_CFN_POW10:
    CASE_CFN_FFS:
    CASE_CFN_PARITY:
    CASE_CFN_POPCOUNT:
    CASE_CFN_CLZ:
    CASE_CFN_CLRSB:
    case CFN_BUILT_IN_BSWAP16:
    case CFN_BUILT_IN_BSWAP32:
    case CFN_BUILT_IN_BSWAP64:
    case CFN_BUILT_IN_BSWAP128:
      /* Always true.  */
      return true;

    CASE_CFN_SQRT:
    CASE_CFN_SQRT_FN:
      /* sqrt(-0.0) is -0.0.  */
      if (!HONOR_SIGNED_ZEROS (element_mode (type)))
	return true;
      return RECURSE (arg0);

    CASE_CFN_ASINH:
    CASE_CFN_ATAN:
    CASE_CFN_ATANH:
    CASE_CFN_CBRT:
    CASE_CFN_CEIL:
    CASE_CFN_CEIL_FN:
    CASE_CFN_ERF:
    CASE_CFN_EXPM1:
    CASE_CFN_FLOOR:
    CASE_CFN_FLOOR_FN:
    CASE_CFN_FMOD:
    CASE_CFN_FREXP:
    CASE_CFN_ICEIL:
    CASE_CFN_IFLOOR:
    CASE_CFN_IRINT:
    CASE_CFN_IROUND:
    CASE_CFN_LCEIL:
    CASE_CFN_LDEXP:
    CASE_CFN_LFLOOR:
    CASE_CFN_LLCEIL:
    CASE_CFN_LLFLOOR:
    CASE_CFN_LLRINT:
    CASE_CFN_LLROUND:
    CASE_CFN_LRINT:
    CASE_CFN_LROUND:
    CASE_CFN_MODF:
    CASE_CFN_NEARBYINT:
    CASE_CFN_NEARBYINT_FN:
    CASE_CFN_RINT:
    CASE_CFN_RINT_FN:
    CASE_CFN_ROUND:
    CASE_CFN_ROUND_FN:
    CASE_CFN_ROUNDEVEN:
    CASE_CFN_ROUNDEVEN_FN:
    CASE_CFN_SCALB:
    CASE_CFN_SCALBLN:
    CASE_CFN_SCALBN:
    CASE_CFN_SIGNBIT:
    CASE_CFN_SIGNIFICAND:
    CASE_CFN_SINH:
    CASE_CFN_TANH:
    CASE_CFN_TRUNC:
    CASE_CFN_TRUNC_FN:
      /* True if the 1st argument is nonnegative.  */
      return RECURSE (arg0);

    CASE_CFN_FMAX:
    CASE_CFN_FMAX_FN:
      /* Usually RECURSE (arg0) || RECURSE (arg1) but NaNs complicate
	 things.  In the presence of sNaNs, we're only guaranteed to be
	 non-negative if both operands are non-negative.  In the presence
	 of qNaNs, we're non-negative if either operand is non-negative
	 and can't be a qNaN, or if both operands are non-negative.  */
      if (tree_expr_maybe_signaling_nan_p (arg0) ||
	  tree_expr_maybe_signaling_nan_p (arg1))
        return RECURSE (arg0) && RECURSE (arg1);
      return RECURSE (arg0) ? (!tree_expr_maybe_nan_p (arg0)
			       || RECURSE (arg1))
			    : (RECURSE (arg1)
			       && !tree_expr_maybe_nan_p (arg1));

    CASE_CFN_FMIN:
    CASE_CFN_FMIN_FN:
      /* True if the 1st AND 2nd arguments are nonnegative.  */
      return RECURSE (arg0) && RECURSE (arg1);

    CASE_CFN_COPYSIGN:
    CASE_CFN_COPYSIGN_FN:
      /* True if the 2nd argument is nonnegative.  */
      return RECURSE (arg1);

    CASE_CFN_POWI:
      /* True if the 1st argument is nonnegative or the second
	 argument is an even integer.  */
      if (TREE_CODE (arg1) == INTEGER_CST
	  && (TREE_INT_CST_LOW (arg1) & 1) == 0)
	return true;
      return RECURSE (arg0);

    CASE_CFN_POW:
      /* True if the 1st argument is nonnegative or the second
	 argument is an even integer valued real.  */
      if (TREE_CODE (arg1) == REAL_CST)
	{
	  REAL_VALUE_TYPE c;
	  HOST_WIDE_INT n;

	  c = TREE_REAL_CST (arg1);
	  n = real_to_integer (&c);
	  if ((n & 1) == 0)
	    {
	      REAL_VALUE_TYPE cint;
	      real_from_integer (&cint, VOIDmode, n, SIGNED);
	      if (real_identical (&c, &cint))
		return true;
	    }
	}
      return RECURSE (arg0);

    default:
      break;
    }
  return tree_simple_nonnegative_warnv_p (CALL_EXPR, type);
}

/* 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.  DEPTH is the current nesting depth of the query.  */

static bool
tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p, int depth)
{
  enum tree_code code = TREE_CODE (t);
  if (TYPE_UNSIGNED (TREE_TYPE (t)))
    return true;

  switch (code)
    {
    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 RECURSE (t);

	/* 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 RECURSE (TREE_OPERAND (t, 1));

	return false;
      }

    case CALL_EXPR:
      {
	tree arg0 = call_expr_nargs (t) > 0 ?  CALL_EXPR_ARG (t, 0) : NULL_TREE;
	tree arg1 = call_expr_nargs (t) > 1 ?  CALL_EXPR_ARG (t, 1) : NULL_TREE;

	return tree_call_nonnegative_warnv_p (TREE_TYPE (t),
					      get_call_combined_fn (t),
					      arg0,
					      arg1,
					      strict_overflow_p, depth);
      }
    case COMPOUND_EXPR:
    case MODIFY_EXPR:
      return RECURSE (TREE_OPERAND (t, 1));

    case BIND_EXPR:
      return RECURSE (expr_last (TREE_OPERAND (t, 1)));

    case SAVE_EXPR:
      return RECURSE (TREE_OPERAND (t, 0));

    default:
      return tree_simple_nonnegative_warnv_p (TREE_CODE (t), TREE_TYPE (t));
    }
}

#undef RECURSE
#undef tree_expr_nonnegative_warnv_p

/* 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.  DEPTH is the current nesting depth of the query.  */

bool
tree_expr_nonnegative_warnv_p (tree t, bool *strict_overflow_p, int depth)
{
  enum tree_code code;
  if (t == error_mark_node)
    return false;

  code = TREE_CODE (t);
  switch (TREE_CODE_CLASS (code))
    {
    case tcc_binary:
    case tcc_comparison:
      return tree_binary_nonnegative_warnv_p (TREE_CODE (t),
					      TREE_TYPE (t),
					      TREE_OPERAND (t, 0),
					      TREE_OPERAND (t, 1),
					      strict_overflow_p, depth);

    case tcc_unary:
      return tree_unary_nonnegative_warnv_p (TREE_CODE (t),
					     TREE_TYPE (t),
					     TREE_OPERAND (t, 0),
					     strict_overflow_p, depth);

    case tcc_constant:
    case tcc_declaration:
    case tcc_reference:
      return tree_single_nonnegative_warnv_p (t, strict_overflow_p, depth);

    default:
      break;
    }

  switch (code)
    {
    case TRUTH_AND_EXPR:
    case TRUTH_OR_EXPR:
    case TRUTH_XOR_EXPR:
      return tree_binary_nonnegative_warnv_p (TREE_CODE (t),
					      TREE_TYPE (t),
					      TREE_OPERAND (t, 0),
					      TREE_OPERAND (t, 1),
					      strict_overflow_p, depth);
    case TRUTH_NOT_EXPR:
      return tree_unary_nonnegative_warnv_p (TREE_CODE (t),
					     TREE_TYPE (t),
					     TREE_OPERAND (t, 0),
					     strict_overflow_p, depth);

    case COND_EXPR:
    case CONSTRUCTOR:
    case OBJ_TYPE_REF:
    case ASSERT_EXPR:
    case ADDR_EXPR:
    case WITH_SIZE_EXPR:
    case SSA_NAME:
      return tree_single_nonnegative_warnv_p (t, strict_overflow_p, depth);

    default:
      return tree_invalid_nonnegative_warnv_p (t, strict_overflow_p, depth);
    }
}

/* Return true if `t' is known to be non-negative.  Handle warnings
   about undefined signed overflow.  */

bool
tree_expr_nonnegative_p (tree t)
{
  bool ret, 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 (CODE OP0) 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_unary_nonzero_warnv_p (enum tree_code code, tree type, tree op0,
				 bool *strict_overflow_p)
{
  switch (code)
    {
    case ABS_EXPR:
      return tree_expr_nonzero_warnv_p (op0,
					strict_overflow_p);

    case NOP_EXPR:
      {
	tree inner_type = TREE_TYPE (op0);
	tree outer_type = type;

	return (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
		&& tree_expr_nonzero_warnv_p (op0,
					      strict_overflow_p));
      }
      break;

    case NON_LVALUE_EXPR:
      return tree_expr_nonzero_warnv_p (op0,
					strict_overflow_p);

    default:
      break;
  }

  return false;
}

/* Return true when (CODE OP0 OP1) 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_binary_nonzero_warnv_p (enum tree_code code,
			     tree type,
			     tree op0,
			     tree op1, bool *strict_overflow_p)
{
  bool sub_strict_overflow_p;
  switch (code)
    {
    case POINTER_PLUS_EXPR:
    case PLUS_EXPR:
      if (ANY_INTEGRAL_TYPE_P (type) && 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 (op0,
					      &sub_strict_overflow_p)
	      || !tree_expr_nonnegative_warnv_p (op1,
						 &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 (op0,
					     strict_overflow_p)
		  || tree_expr_nonzero_warnv_p (op1,
						strict_overflow_p));
	}
      break;

    case MULT_EXPR:
      if (TYPE_OVERFLOW_UNDEFINED (type))
	{
	  if (tree_expr_nonzero_warnv_p (op0,
					 strict_overflow_p)
	      && tree_expr_nonzero_warnv_p (op1,
					    strict_overflow_p))
	    {
	      *strict_overflow_p = true;
	      return true;
	    }
	}
      break;

    case MIN_EXPR:
      sub_strict_overflow_p = false;
      if (tree_expr_nonzero_warnv_p (op0,
				     &sub_strict_overflow_p)
	  && tree_expr_nonzero_warnv_p (op1,
					&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 (op0,
				     &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 (op1,
					 strict_overflow_p))
	    return true;

	  /* MAX where operand 0 is positive is positive.  */
	  return tree_expr_nonnegative_warnv_p (op0,
					       strict_overflow_p);
	}
      /* MAX where operand 1 is positive is positive.  */
      else if (tree_expr_nonzero_warnv_p (op1,
					  &sub_strict_overflow_p)
	       && tree_expr_nonnegative_warnv_p (op1,
						 &sub_strict_overflow_p))
	{
	  if (sub_strict_overflow_p)
	    *strict_overflow_p = true;
	  return true;
	}
      break;

    case BIT_IOR_EXPR:
      return (tree_expr_nonzero_warnv_p (op1,
					 strict_overflow_p)
	      || tree_expr_nonzero_warnv_p (op0,
					    strict_overflow_p));

    default:
      break;
  }

  return false;
}

/* 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_single_nonzero_warnv_p (tree t, bool *strict_overflow_p)
{
  bool sub_strict_overflow_p;
  switch (TREE_CODE (t))
    {
    case INTEGER_CST:
      return !integer_zerop (t);

    case ADDR_EXPR:
      {
	tree base = TREE_OPERAND (t, 0);

	if (!DECL_P (base))
	  base = get_base_address (base);

	if (base && TREE_CODE (base) == TARGET_EXPR)
	  base = TARGET_EXPR_SLOT (base);

	if (!base)
	  return false;

	/* For objects in symbol table check if we know they are non-zero.
	   Don't do anything for variables and functions before symtab is built;
	   it is quite possible that they will be declared weak later.  */
	int nonzero_addr = maybe_nonzero_address (base);
	if (nonzero_addr >= 0)
	  return nonzero_addr;

	/* 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 SSA_NAME:
      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
	break;
      return expr_not_equal_to (t, wi::zero (TYPE_PRECISION (TREE_TYPE (t))));

    default:
      break;
    }
  return false;
}

#define integer_valued_real_p(X) \
  _Pragma ("GCC error \"Use RECURSE for recursive calls\"") 0

#define RECURSE(X) \
  ((integer_valued_real_p) (X, depth + 1))

/* Return true if the floating point result of (CODE OP0) has an
   integer value.  We also allow +Inf, -Inf and NaN to be considered
   integer values. Return false for signaling NaN.

   DEPTH is the current nesting depth of the query.  */

bool
integer_valued_real_unary_p (tree_code code, tree op0, int depth)
{
  switch (code)
    {
    case FLOAT_EXPR:
      return true;

    case ABS_EXPR:
      return RECURSE (op0);

    CASE_CONVERT:
      {
	tree type = TREE_TYPE (op0);
	if (TREE_CODE (type) == INTEGER_TYPE)
	  return true;
	if (TREE_CODE (type) == REAL_TYPE)
	  return RECURSE (op0);
	break;
      }

    default:
      break;
    }
  return false;
}

/* Return true if the floating point result of (CODE OP0 OP1) has an
   integer value.  We also allow +Inf, -Inf and NaN to be considered
   integer values. Return false for signaling NaN.

   DEPTH is the current nesting depth of the query.  */

bool
integer_valued_real_binary_p (tree_code code, tree op0, tree op1, int depth)
{
  switch (code)
    {
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case MIN_EXPR:
    case MAX_EXPR:
      return RECURSE (op0) && RECURSE (op1);

    default:
      break;
    }
  return false;
}

/* Return true if the floating point result of calling FNDECL with arguments
   ARG0 and ARG1 has an integer value.  We also allow +Inf, -Inf and NaN to be
   considered integer values. Return false for signaling NaN.  If FNDECL
   takes fewer than 2 arguments, the remaining ARGn are null.

   DEPTH is the current nesting depth of the query.  */

bool
integer_valued_real_call_p (combined_fn fn, tree arg0, tree arg1, int depth)
{
  switch (fn)
    {
    CASE_CFN_CEIL:
    CASE_CFN_CEIL_FN:
    CASE_CFN_FLOOR:
    CASE_CFN_FLOOR_FN:
    CASE_CFN_NEARBYINT:
    CASE_CFN_NEARBYINT_FN:
    CASE_CFN_RINT:
    CASE_CFN_RINT_FN:
    CASE_CFN_ROUND:
    CASE_CFN_ROUND_FN:
    CASE_CFN_ROUNDEVEN:
    CASE_CFN_ROUNDEVEN_FN:
    CASE_CFN_TRUNC:
    CASE_CFN_TRUNC_FN:
      return true;

    CASE_CFN_FMIN:
    CASE_CFN_FMIN_FN:
    CASE_CFN_FMAX:
    CASE_CFN_FMAX_FN:
      return RECURSE (arg0) && RECURSE (arg1);

    default:
      break;
    }
  return false;
}

/* Return true if the floating point expression T (a GIMPLE_SINGLE_RHS)
   has an integer value.  We also allow +Inf, -Inf and NaN to be
   considered integer values. Return false for signaling NaN.

   DEPTH is the current nesting depth of the query.  */

bool
integer_valued_real_single_p (tree t, int depth)
{
  switch (TREE_CODE (t))
    {
    case REAL_CST:
      return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));

    case COND_EXPR:
      return RECURSE (TREE_OPERAND (t, 1)) && RECURSE (TREE_OPERAND (t, 2));

    case SSA_NAME:
      /* Limit the depth of recursion to avoid quadratic behavior.
	 This is expected to catch almost all occurrences in practice.
	 If this code misses important cases that unbounded recursion
	 would not, passes that need this information could be revised
	 to provide it through dataflow propagation.  */
      return (!name_registered_for_update_p (t)
	      && depth < param_max_ssa_name_query_depth
	      && gimple_stmt_integer_valued_real_p (SSA_NAME_DEF_STMT (t),
						    depth));

    default:
      break;
    }
  return false;
}

/* Return true if the floating point expression T (a GIMPLE_INVALID_RHS)
   has an integer value.  We also allow +Inf, -Inf and NaN to be
   considered integer values. Return false for signaling NaN.

   DEPTH is the current nesting depth of the query.  */

static bool
integer_valued_real_invalid_p (tree t, int depth)
{
  switch (TREE_CODE (t))
    {
    case COMPOUND_EXPR:
    case MODIFY_EXPR:
    case BIND_EXPR:
      return RECURSE (TREE_OPERAND (t, 1));

    case SAVE_EXPR:
      return RECURSE (TREE_OPERAND (t, 0));

    default:
      break;
    }
  return false;
}

#undef RECURSE
#undef integer_valued_real_p

/* Return true if the floating point expression T has an integer value.
   We also allow +Inf, -Inf and NaN to be considered integer values.
   Return false for signaling NaN.

   DEPTH is the current nesting depth of the query.  */

bool
integer_valued_real_p (tree t, int depth)
{
  if (t == error_mark_node)
    return false;

  STRIP_ANY_LOCATION_WRAPPER (t);

  tree_code code = TREE_CODE (t);
  switch (TREE_CODE_CLASS (code))
    {
    case tcc_binary:
    case tcc_comparison:
      return integer_valued_real_binary_p (code, TREE_OPERAND (t, 0),
					   TREE_OPERAND (t, 1), depth);

    case tcc_unary:
      return integer_valued_real_unary_p (code, TREE_OPERAND (t, 0), depth);

    case tcc_constant:
    case tcc_declaration:
    case tcc_reference:
      return integer_valued_real_single_p (t, depth);

    default:
      break;
    }

  switch (code)
    {
    case COND_EXPR:
    case SSA_NAME:
      return integer_valued_real_single_p (t, depth);

    case CALL_EXPR:
      {
	tree arg0 = (call_expr_nargs (t) > 0
		     ? CALL_EXPR_ARG (t, 0)
		     : NULL_TREE);
	tree arg1 = (call_expr_nargs (t) > 1
		     ? CALL_EXPR_ARG (t, 1)
		     : NULL_TREE);
	return integer_valued_real_call_p (get_call_combined_fn (t),
					   arg0, arg1, depth);
      }

    default:
      return integer_valued_real_invalid_p (t, depth);
    }
}

/* 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)
    {
      tree exp1 = TREE_OPERAND (exp, 0);
      tree index;
      tree string;
      location_t loc = EXPR_LOCATION (exp);

      if (TREE_CODE (exp) == INDIRECT_REF)
	string = string_constant (exp1, &index, NULL, NULL);
      else
	{
	  tree low_bound = array_ref_low_bound (exp);
	  index = fold_convert_loc (loc, 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).  Oops!)  */
	  if (! integer_zerop (low_bound))
	    index = size_diffop_loc (loc, index,
				 fold_convert_loc (loc, sizetype, low_bound));

	  string = exp1;
	}

      scalar_int_mode char_mode;
      if (string
	  && TYPE_MODE (TREE_TYPE (exp)) == TYPE_MODE (TREE_TYPE (TREE_TYPE (string)))
	  && TREE_CODE (string) == STRING_CST
	  && tree_fits_uhwi_p (index)
	  && compare_tree_int (index, TREE_STRING_LENGTH (string)) < 0
	  && is_int_mode (TYPE_MODE (TREE_TYPE (TREE_TYPE (string))),
			  &char_mode)
	  && GET_MODE_SIZE (char_mode) == 1)
	return build_int_cst_type (TREE_TYPE (exp),
				   (TREE_STRING_POINTER (string)
				    [TREE_INT_CST_LOW (index)]));
    }
  return NULL;
}

/* Folds a read from vector element at IDX of vector ARG.  */

tree
fold_read_from_vector (tree arg, poly_uint64 idx)
{
  unsigned HOST_WIDE_INT i;
  if (known_lt (idx, TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)))
      && known_ge (idx, 0u)
      && idx.is_constant (&i))
    {
      if (TREE_CODE (arg) == VECTOR_CST)
	return VECTOR_CST_ELT (arg, i);
      else if (TREE_CODE (arg) == CONSTRUCTOR)
	{
	  if (CONSTRUCTOR_NELTS (arg)
	      && VECTOR_TYPE_P (TREE_TYPE (CONSTRUCTOR_ELT (arg, 0)->value)))
	    return NULL_TREE;
	  if (i >= CONSTRUCTOR_NELTS (arg))
	    return build_zero_cst (TREE_TYPE (TREE_TYPE (arg)));
	  return CONSTRUCTOR_ELT (arg, i)->value;
	}
    }
  return NULL_TREE;
}

/* Return the tree for neg (ARG0) when ARG0 is known to be either
   an integer constant, real, or fixed-point 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 REAL_CST:
      t = build_real (type, real_value_negate (&TREE_REAL_CST (arg0)));
      break;

    case FIXED_CST:
      {
        FIXED_VALUE_TYPE f;
        bool overflow_p = fixed_arithmetic (&f, NEGATE_EXPR,
					    &(TREE_FIXED_CST (arg0)), NULL,
					    TYPE_SATURATING (type));
	t = build_fixed (type, f);
	/* Propagate overflow flags.  */
	if (overflow_p | TREE_OVERFLOW (arg0))
	  TREE_OVERFLOW (t) = 1;
	break;
      }

    default:
      if (poly_int_tree_p (arg0))
	{
	  wi::overflow_type overflow;
	  poly_wide_int res = wi::neg (wi::to_poly_wide (arg0), &overflow);
	  t = force_fit_type (type, res, 1,
			      (overflow && ! TYPE_UNSIGNED (type))
			      || TREE_OVERFLOW (arg0));
	  break;
	}

      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 or non-negative, then the absolute value
	   is the same as the ordinary value.  */
	wide_int val = wi::to_wide (arg0);
	wi::overflow_type overflow = wi::OVF_NONE;
	if (!wi::neg_p (val, TYPE_SIGN (TREE_TYPE (arg0))))
	  ;

	/* If the value is negative, then the absolute value is
	   its negation.  */
	else
	  val = wi::neg (val, &overflow);

	/* Force to the destination type, set TREE_OVERFLOW for signed
	   TYPE only.  */
	t = force_fit_type (type, val, 1, overflow | TREE_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 (const_tree arg0, tree type)
{
  gcc_assert (TREE_CODE (arg0) == INTEGER_CST);

  return force_fit_type (type, ~wi::to_wide (arg0), 0, TREE_OVERFLOW (arg0));
}

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

  if (TREE_CODE (op0) == FIXED_CST && TREE_CODE (op1) == FIXED_CST)
    {
      const FIXED_VALUE_TYPE *c0 = TREE_FIXED_CST_PTR (op0);
      const FIXED_VALUE_TYPE *c1 = TREE_FIXED_CST_PTR (op1);
      return constant_boolean_node (fixed_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;
    }

  if (TREE_CODE (op0) == VECTOR_CST && TREE_CODE (op1) == VECTOR_CST)
    {
      if (!VECTOR_TYPE_P (type))
	{
	  /* Have vector comparison with scalar boolean result.  */
	  gcc_assert ((code == EQ_EXPR || code == NE_EXPR)
		      && known_eq (VECTOR_CST_NELTS (op0),
				   VECTOR_CST_NELTS (op1)));
	  unsigned HOST_WIDE_INT nunits;
	  if (!VECTOR_CST_NELTS (op0).is_constant (&nunits))
	    return NULL_TREE;
	  for (unsigned i = 0; i < nunits; i++)
	    {
	      tree elem0 = VECTOR_CST_ELT (op0, i);
	      tree elem1 = VECTOR_CST_ELT (op1, i);
	      tree tmp = fold_relational_const (EQ_EXPR, type, elem0, elem1);
	      if (tmp == NULL_TREE)
		return NULL_TREE;
	      if (integer_zerop (tmp))
		return constant_boolean_node (code == NE_EXPR, type);
	    }
	  return constant_boolean_node (code == EQ_EXPR, type);
	}
      tree_vector_builder elts;
      if (!elts.new_binary_operation (type, op0, op1, false))
	return NULL_TREE;
      unsigned int count = elts.encoded_nelts ();
      for (unsigned i = 0; i < count; i++)
	{
	  tree elem_type = TREE_TYPE (type);
	  tree elem0 = VECTOR_CST_ELT (op0, i);
	  tree elem1 = VECTOR_CST_ELT (op1, i);

	  tree tem = fold_relational_const (code, elem_type,
					    elem0, elem1);

	  if (tem == NULL_TREE)
	    return NULL_TREE;

	  elts.quick_push (build_int_cst (elem_type,
					  integer_zerop (tem) ? 0 : -1));
	}

      return elts.build ();
    }

  /* 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)
    {
      std::swap (op0, op1);
      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
	result = tree_int_cst_lt (op0, op1);
    }
  else
    return NULL_TREE;

  if (invert)
    result ^= 1;
  return constant_boolean_node (result, type);
}

/* If necessary, return a CLEANUP_POINT_EXPR for EXPR with the
   indicated TYPE.  If no CLEANUP_POINT_EXPR is necessary, return EXPR
   itself.  */

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_loc (EXPR_LOCATION (expr), CLEANUP_POINT_EXPR, type, expr);
}

/* 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 (location_t loc, tree type, tree op0)
{
  tree sub = op0;
  tree subtype;
  poly_uint64 const_op01;

  STRIP_NOPS (sub);
  subtype = TREE_TYPE (sub);
  if (!POINTER_TYPE_P (subtype)
      || TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (op0)))
    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)
	       && (!in_gimple_form
		   || TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST))
	{
	  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);
	  if (in_gimple_form
	      && TREE_CODE (min_val) != INTEGER_CST)
	    return NULL_TREE;
	  return build4_loc (loc, 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_loc (loc, REALPART_EXPR, type, op);
      /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
      else if (VECTOR_TYPE_P (optype)
	       && type == TREE_TYPE (optype))
	{
	  tree part_width = TYPE_SIZE (type);
	  tree index = bitsize_int (0);
	  return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width,
				  index);
	}
    }

  if (TREE_CODE (sub) == POINTER_PLUS_EXPR
      && poly_int_tree_p (TREE_OPERAND (sub, 1), &const_op01))
    {
      tree op00 = TREE_OPERAND (sub, 0);
      tree op01 = TREE_OPERAND (sub, 1);

      STRIP_NOPS (op00);
      if (TREE_CODE (op00) == ADDR_EXPR)
	{
	  tree op00type;
	  op00 = TREE_OPERAND (op00, 0);
	  op00type = TREE_TYPE (op00);

	  /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
	  if (VECTOR_TYPE_P (op00type)
	      && type == TREE_TYPE (op00type)
	      /* POINTER_PLUS_EXPR second operand is sizetype, unsigned,
		 but we want to treat offsets with MSB set as negative.
		 For the code below negative offsets are invalid and
		 TYPE_SIZE of the element is something unsigned, so
		 check whether op01 fits into poly_int64, which implies
		 it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and
		 then just use poly_uint64 because we want to treat the
		 value as unsigned.  */
	      && tree_fits_poly_int64_p (op01))
	    {
	      tree part_width = TYPE_SIZE (type);
	      poly_uint64 max_offset
		= (tree_to_uhwi (part_width) / BITS_PER_UNIT
		   * TYPE_VECTOR_SUBPARTS (op00type));
	      if (known_lt (const_op01, max_offset))
		{
		  tree index = bitsize_int (const_op01 * BITS_PER_UNIT);
		  return fold_build3_loc (loc,
					  BIT_FIELD_REF, type, op00,
					  part_width, index);
		}
	    }
	  /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
	  else if (TREE_CODE (op00type) == COMPLEX_TYPE
		   && type == TREE_TYPE (op00type))
	    {
	      if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)),
			    const_op01))
		return fold_build1_loc (loc, IMAGPART_EXPR, type, op00);
	    }
	  /* ((foo *)&fooarray)[1] => fooarray[1] */
	  else if (TREE_CODE (op00type) == ARRAY_TYPE
		   && type == TREE_TYPE (op00type))
	    {
	      tree type_domain = TYPE_DOMAIN (op00type);
	      tree min_val = size_zero_node;
	      if (type_domain && TYPE_MIN_VALUE (type_domain))
		min_val = TYPE_MIN_VALUE (type_domain);
	      poly_uint64 type_size, index;
	      if (poly_int_tree_p (min_val)
		  && poly_int_tree_p (TYPE_SIZE_UNIT (type), &type_size)
		  && multiple_p (const_op01, type_size, &index))
		{
		  poly_offset_int off = index + wi::to_poly_offset (min_val);
		  op01 = wide_int_to_tree (sizetype, off);
		  return build4_loc (loc, ARRAY_REF, type, op00, op01,
				     NULL_TREE, NULL_TREE);
		}
	    }
	}
    }

  /* *(foo *)fooarrptr => (*fooarrptr)[0] */
  if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
      && type == TREE_TYPE (TREE_TYPE (subtype))
      && (!in_gimple_form
	  || TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST))
    {
      tree type_domain;
      tree min_val = size_zero_node;
      sub = build_fold_indirect_ref_loc (loc, sub);
      type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
      if (type_domain && TYPE_MIN_VALUE (type_domain))
	min_val = TYPE_MIN_VALUE (type_domain);
      if (in_gimple_form
	  && TREE_CODE (min_val) != INTEGER_CST)
	return NULL_TREE;
      return build4_loc (loc, 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_loc (location_t loc, tree t)
{
  tree type = TREE_TYPE (TREE_TYPE (t));
  tree sub = fold_indirect_ref_1 (loc, type, t);

  if (sub)
    return sub;

  return build1_loc (loc, INDIRECT_REF, type, t);
}

/* Given an INDIRECT_REF T, return either T or a simplified version.  */

tree
fold_indirect_ref_loc (location_t loc, tree t)
{
  tree sub = fold_indirect_ref_1 (loc, 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. */

tree
round_up_loc (location_t loc, tree value, unsigned int divisor)
{
  tree div = NULL_TREE;

  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 (pow2_or_zerop (divisor))
    {
      if (TREE_CODE (value) == INTEGER_CST)
	{
	  wide_int val = wi::to_wide (value);
	  bool overflow_p;

	  if ((val & (divisor - 1)) == 0)
	    return value;

	  overflow_p = TREE_OVERFLOW (value);
	  val += divisor - 1;
	  val &= (int) -divisor;
	  if (val == 0)
	    overflow_p = true;

	  return force_fit_type (TREE_TYPE (value), val, -1, overflow_p);
	}
      else
	{
	  tree t;

	  t = build_int_cst (TREE_TYPE (value), divisor - 1);
	  value = size_binop_loc (loc, PLUS_EXPR, value, t);
	  t = build_int_cst (TREE_TYPE (value), - (int) divisor);
	  value = size_binop_loc (loc, BIT_AND_EXPR, value, t);
	}
    }
  else
    {
      if (!div)
	div = build_int_cst (TREE_TYPE (value), divisor);
      value = size_binop_loc (loc, CEIL_DIV_EXPR, value, div);
      value = size_binop_loc (loc, MULT_EXPR, value, div);
    }

  return value;
}

/* Likewise, but round down.  */

tree
round_down_loc (location_t loc, 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 (pow2_or_zerop (divisor))
    {
      tree t;

      t = build_int_cst (TREE_TYPE (value), -divisor);
      value = size_binop_loc (loc, BIT_AND_EXPR, value, t);
    }
  else
    {
      if (!div)
	div = build_int_cst (TREE_TYPE (value), divisor);
      value = size_binop_loc (loc, FLOOR_DIV_EXPR, value, div);
      value = size_binop_loc (loc, 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,
				  poly_int64_pod *pbitpos, tree *poffset)
{
  tree core;
  machine_mode mode;
  int unsignedp, reversep, volatilep;
  poly_int64 bitsize;
  location_t loc = EXPR_LOCATION (exp);

  if (TREE_CODE (exp) == ADDR_EXPR)
    {
      core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
				  poffset, &mode, &unsignedp, &reversep,
				  &volatilep);
      core = build_fold_addr_expr_loc (loc, core);
    }
  else if (TREE_CODE (exp) == POINTER_PLUS_EXPR)
    {
      core = TREE_OPERAND (exp, 0);
      STRIP_NOPS (core);
      *pbitpos = 0;
      *poffset = TREE_OPERAND (exp, 1);
      if (poly_int_tree_p (*poffset))
	{
	  poly_offset_int tem
	    = wi::sext (wi::to_poly_offset (*poffset),
			TYPE_PRECISION (TREE_TYPE (*poffset)));
	  tem <<= LOG2_BITS_PER_UNIT;
	  if (tem.to_shwi (pbitpos))
	    *poffset = NULL_TREE;
	}
    }
  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, poly_int64_pod *diff)
{
  tree core1, core2;
  poly_int64 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);

  poly_int64 bytepos1, bytepos2;
  if (!multiple_p (bitpos1, BITS_PER_UNIT, &bytepos1)
      || !multiple_p (bitpos2, BITS_PER_UNIT, &bytepos2)
      || !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 += bytepos1 - bytepos2;
  return true;
}

/* Return OFF converted to a pointer offset type suitable as offset for
   POINTER_PLUS_EXPR.  Use location LOC for this conversion.  */
tree
convert_to_ptrofftype_loc (location_t loc, tree off)
{
  if (ptrofftype_p (TREE_TYPE (off)))
    return off;
  return fold_convert_loc (loc, sizetype, off);
}

/* Build and fold a POINTER_PLUS_EXPR at LOC offsetting PTR by OFF.  */
tree
fold_build_pointer_plus_loc (location_t loc, tree ptr, tree off)
{
  return fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (ptr),
			  ptr, convert_to_ptrofftype_loc (loc, off));
}

/* Build and fold a POINTER_PLUS_EXPR at LOC offsetting PTR by OFF.  */
tree
fold_build_pointer_plus_hwi_loc (location_t loc, tree ptr, HOST_WIDE_INT off)
{
  return fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (ptr),
			  ptr, size_int (off));
}

/* Return a pointer to a NUL-terminated string containing the sequence
   of bytes corresponding to the representation of the object referred to
   by SRC (or a subsequence of such bytes within it if SRC is a reference
   to an initialized constant array plus some constant offset).
   Set *STRSIZE the number of bytes in the constant sequence including
   the terminating NUL byte.  *STRSIZE is equal to sizeof(A) - OFFSET
   where A is the array that stores the constant sequence that SRC points
   to and OFFSET is the byte offset of SRC from the beginning of A.  SRC
   need not point to a string or even an array of characters but may point
   to an object of any type.  */

const char *
getbyterep (tree src, unsigned HOST_WIDE_INT *strsize)
{
  /* The offset into the array A storing the string, and A's byte size.  */
  tree offset_node;
  tree mem_size;

  if (strsize)
    *strsize = 0;

  if (strsize)
    src = byte_representation (src, &offset_node, &mem_size, NULL);
  else
    src = string_constant (src, &offset_node, &mem_size, NULL);
  if (!src)
    return NULL;

  unsigned HOST_WIDE_INT offset = 0;
  if (offset_node != NULL_TREE)
    {
      if (!tree_fits_uhwi_p (offset_node))
	return NULL;
      else
	offset = tree_to_uhwi (offset_node);
    }

  if (!tree_fits_uhwi_p (mem_size))
    return NULL;

  /* ARRAY_SIZE is the byte size of the array the constant sequence
     is stored in and equal to sizeof A.  INIT_BYTES is the number
     of bytes in the constant sequence used to initialize the array,
     including any embedded NULs as well as the terminating NUL (for
     strings), but not including any trailing zeros/NULs past
     the terminating one appended implicitly to a string literal to
     zero out the remainder of the array it's stored in.  For example,
     given:
       const char a[7] = "abc\0d";
       n = strlen (a + 1);
     ARRAY_SIZE is 7, INIT_BYTES is 6, and OFFSET is 1.  For a valid
     (i.e., nul-terminated) string with no embedded nuls, INIT_BYTES
     is equal to strlen (A) + 1.  */
  const unsigned HOST_WIDE_INT array_size = tree_to_uhwi (mem_size);
  unsigned HOST_WIDE_INT init_bytes = TREE_STRING_LENGTH (src);
  const char *string = TREE_STRING_POINTER (src);

  /* Ideally this would turn into a gcc_checking_assert over time.  */
  if (init_bytes > array_size)
    init_bytes = array_size;

  if (init_bytes == 0 || offset >= array_size)
    return NULL;

  if (strsize)
    {
      /* Compute and store the number of characters from the beginning
	 of the substring at OFFSET to the end, including the terminating
	 nul.  Offsets past the initial length refer to null strings.  */
      if (offset < init_bytes)
	*strsize = init_bytes - offset;
      else
	*strsize = 1;
    }
  else
    {
      tree eltype = TREE_TYPE (TREE_TYPE (src));
      /* Support only properly NUL-terminated single byte strings.  */
      if (tree_to_uhwi (TYPE_SIZE_UNIT (eltype)) != 1)
	return NULL;
      if (string[init_bytes - 1] != '\0')
	return NULL;
    }

  return offset < init_bytes ? string + offset : "";
}

/* Return a pointer to a NUL-terminated string corresponding to
   the expression STR referencing a constant string, possibly
   involving a constant offset.  Return null if STR either doesn't
   reference a constant string or if it involves a nonconstant
   offset.  */

const char *
c_getstr (tree str)
{
  return getbyterep (str, NULL);
}

/* Given a tree T, compute which bits in T may be nonzero.  */

wide_int
tree_nonzero_bits (const_tree t)
{
  switch (TREE_CODE (t))
    {
    case INTEGER_CST:
      return wi::to_wide (t);
    case SSA_NAME:
      return get_nonzero_bits (t);
    case NON_LVALUE_EXPR:
    case SAVE_EXPR:
      return tree_nonzero_bits (TREE_OPERAND (t, 0));
    case BIT_AND_EXPR:
      return wi::bit_and (tree_nonzero_bits (TREE_OPERAND (t, 0)),
			  tree_nonzero_bits (TREE_OPERAND (t, 1)));
    case BIT_IOR_EXPR:
    case BIT_XOR_EXPR:
      return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 0)),
			 tree_nonzero_bits (TREE_OPERAND (t, 1)));
    case COND_EXPR:
      return wi::bit_or (tree_nonzero_bits (TREE_OPERAND (t, 1)),
			 tree_nonzero_bits (TREE_OPERAND (t, 2)));
    CASE_CONVERT:
      return wide_int::from (tree_nonzero_bits (TREE_OPERAND (t, 0)),
			     TYPE_PRECISION (TREE_TYPE (t)),
			     TYPE_SIGN (TREE_TYPE (TREE_OPERAND (t, 0))));
    case PLUS_EXPR:
      if (INTEGRAL_TYPE_P (TREE_TYPE (t)))
	{
	  wide_int nzbits1 = tree_nonzero_bits (TREE_OPERAND (t, 0));
	  wide_int nzbits2 = tree_nonzero_bits (TREE_OPERAND (t, 1));
	  if (wi::bit_and (nzbits1, nzbits2) == 0)
	    return wi::bit_or (nzbits1, nzbits2);
	}
      break;
    case LSHIFT_EXPR:
      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
	{
	  tree type = TREE_TYPE (t);
	  wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0));
	  wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1),
				       TYPE_PRECISION (type));
	  return wi::neg_p (arg1)
		 ? wi::rshift (nzbits, -arg1, TYPE_SIGN (type))
		 : wi::lshift (nzbits, arg1);
	}
      break;
    case RSHIFT_EXPR:
      if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST)
        {
	  tree type = TREE_TYPE (t);
	  wide_int nzbits = tree_nonzero_bits (TREE_OPERAND (t, 0));
	  wide_int arg1 = wi::to_wide (TREE_OPERAND (t, 1),
				       TYPE_PRECISION (type));
	  return wi::neg_p (arg1)
		 ? wi::lshift (nzbits, -arg1)
		 : wi::rshift (nzbits, arg1, TYPE_SIGN (type));
        }
      break;
    default:
      break;
    }

  return wi::shwi (-1, TYPE_PRECISION (TREE_TYPE (t)));
}

#if CHECKING_P

namespace selftest {

/* Helper functions for writing tests of folding trees.  */

/* Verify that the binary op (LHS CODE RHS) folds to CONSTANT.  */

static void
assert_binop_folds_to_const (tree lhs, enum tree_code code, tree rhs,
			     tree constant)
{
  ASSERT_EQ (constant, fold_build2 (code, TREE_TYPE (lhs), lhs, rhs));
}

/* Verify that the binary op (LHS CODE RHS) folds to an NON_LVALUE_EXPR
   wrapping WRAPPED_EXPR.  */

static void
assert_binop_folds_to_nonlvalue (tree lhs, enum tree_code code, tree rhs,
				 tree wrapped_expr)
{
  tree result = fold_build2 (code, TREE_TYPE (lhs), lhs, rhs);
  ASSERT_NE (wrapped_expr, result);
  ASSERT_EQ (NON_LVALUE_EXPR, TREE_CODE (result));
  ASSERT_EQ (wrapped_expr, TREE_OPERAND (result, 0));
}

/* Verify that various arithmetic binary operations are folded
   correctly.  */

static void
test_arithmetic_folding ()
{
  tree type = integer_type_node;
  tree x = create_tmp_var_raw (type, "x");
  tree zero = build_zero_cst (type);
  tree one = build_int_cst (type, 1);

  /* Addition.  */
  /* 1 <-- (0 + 1) */
  assert_binop_folds_to_const (zero, PLUS_EXPR, one,
			       one);
  assert_binop_folds_to_const (one, PLUS_EXPR, zero,
			       one);

  /* (nonlvalue)x <-- (x + 0) */
  assert_binop_folds_to_nonlvalue (x, PLUS_EXPR, zero,
				   x);

  /* Subtraction.  */
  /* 0 <-- (x - x) */
  assert_binop_folds_to_const (x, MINUS_EXPR, x,
			       zero);
  assert_binop_folds_to_nonlvalue (x, MINUS_EXPR, zero,
				   x);

  /* Multiplication.  */
  /* 0 <-- (x * 0) */
  assert_binop_folds_to_const (x, MULT_EXPR, zero,
			       zero);

  /* (nonlvalue)x <-- (x * 1) */
  assert_binop_folds_to_nonlvalue (x, MULT_EXPR, one,
				   x);
}

/* Verify that various binary operations on vectors are folded
   correctly.  */

static void
test_vector_folding ()
{
  tree inner_type = integer_type_node;
  tree type = build_vector_type (inner_type, 4);
  tree zero = build_zero_cst (type);
  tree one = build_one_cst (type);
  tree index = build_index_vector (type, 0, 1);

  /* Verify equality tests that return a scalar boolean result.  */
  tree res_type = boolean_type_node;
  ASSERT_FALSE (integer_nonzerop (fold_build2 (EQ_EXPR, res_type, zero, one)));
  ASSERT_TRUE (integer_nonzerop (fold_build2 (EQ_EXPR, res_type, zero, zero)));
  ASSERT_TRUE (integer_nonzerop (fold_build2 (NE_EXPR, res_type, zero, one)));
  ASSERT_FALSE (integer_nonzerop (fold_build2 (NE_EXPR, res_type, one, one)));
  ASSERT_TRUE (integer_nonzerop (fold_build2 (NE_EXPR, res_type, index, one)));
  ASSERT_FALSE (integer_nonzerop (fold_build2 (EQ_EXPR, res_type,
					       index, one)));
  ASSERT_FALSE (integer_nonzerop (fold_build2 (NE_EXPR, res_type,
					      index, index)));
  ASSERT_TRUE (integer_nonzerop (fold_build2 (EQ_EXPR, res_type,
					      index, index)));
}

/* Verify folding of VEC_DUPLICATE_EXPRs.  */

static void
test_vec_duplicate_folding ()
{
  scalar_int_mode int_mode = SCALAR_INT_TYPE_MODE (ssizetype);
  machine_mode vec_mode = targetm.vectorize.preferred_simd_mode (int_mode);
  /* This will be 1 if VEC_MODE isn't a vector mode.  */
  poly_uint64 nunits = GET_MODE_NUNITS (vec_mode);

  tree type = build_vector_type (ssizetype, nunits);
  tree dup5_expr = fold_unary (VEC_DUPLICATE_EXPR, type, ssize_int (5));
  tree dup5_cst = build_vector_from_val (type, ssize_int (5));
  ASSERT_TRUE (operand_equal_p (dup5_expr, dup5_cst, 0));
}

/* Run all of the selftests within this file.  */

void
fold_const_c_tests ()
{
  test_arithmetic_folding ();
  test_vector_folding ();
  test_vec_duplicate_folding ();
}

} // namespace selftest

#endif /* CHECKING_P */
