/* Statement simplification on GIMPLE.
   Copyright (C) 2010-2021 Free Software Foundation, Inc.
   Split out from tree-ssa-ccp.c.

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

#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 "ssa.h"
#include "cgraph.h"
#include "gimple-pretty-print.h"
#include "gimple-ssa-warn-access.h"
#include "gimple-ssa-warn-restrict.h"
#include "fold-const.h"
#include "stmt.h"
#include "expr.h"
#include "stor-layout.h"
#include "dumpfile.h"
#include "gimple-fold.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "tree-into-ssa.h"
#include "tree-dfa.h"
#include "tree-object-size.h"
#include "tree-ssa.h"
#include "tree-ssa-propagate.h"
#include "ipa-utils.h"
#include "tree-ssa-address.h"
#include "langhooks.h"
#include "gimplify-me.h"
#include "dbgcnt.h"
#include "builtins.h"
#include "tree-eh.h"
#include "gimple-match.h"
#include "gomp-constants.h"
#include "optabs-query.h"
#include "omp-general.h"
#include "tree-cfg.h"
#include "fold-const-call.h"
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
#include "diagnostic-core.h"
#include "intl.h"
#include "calls.h"
#include "tree-vector-builder.h"
#include "tree-ssa-strlen.h"
#include "varasm.h"
#include "memmodel.h"
#include "optabs.h"

enum strlen_range_kind {
  /* Compute the exact constant string length.  */
  SRK_STRLEN,
  /* Compute the maximum constant string length.  */
  SRK_STRLENMAX,
  /* Compute a range of string lengths bounded by object sizes.  When
     the length of a string cannot be determined, consider as the upper
     bound the size of the enclosing object the string may be a member
     or element of.  Also determine the size of the largest character
     array the string may refer to.  */
  SRK_LENRANGE,
  /* Determine the integer value of the argument (not string length).  */
  SRK_INT_VALUE
};

static bool
get_range_strlen (tree, bitmap *, strlen_range_kind, c_strlen_data *, unsigned);

/* Return true when DECL can be referenced from current unit.
   FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
   We can get declarations that are not possible to reference for various
   reasons:

     1) When analyzing C++ virtual tables.
	C++ virtual tables do have known constructors even
	when they are keyed to other compilation unit.
	Those tables can contain pointers to methods and vars
	in other units.  Those methods have both STATIC and EXTERNAL
	set.
     2) In WHOPR mode devirtualization might lead to reference
	to method that was partitioned elsehwere.
	In this case we have static VAR_DECL or FUNCTION_DECL
	that has no corresponding callgraph/varpool node
	declaring the body.  
     3) COMDAT functions referred by external vtables that
        we devirtualize only during final compilation stage.
        At this time we already decided that we will not output
        the function body and thus we can't reference the symbol
        directly.  */

static bool
can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
{
  varpool_node *vnode;
  struct cgraph_node *node;
  symtab_node *snode;

  if (DECL_ABSTRACT_P (decl))
    return false;

  /* We are concerned only about static/external vars and functions.  */
  if ((!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
      || !VAR_OR_FUNCTION_DECL_P (decl))
    return true;

  /* Static objects can be referred only if they are defined and not optimized
     out yet.  */
  if (!TREE_PUBLIC (decl))
    {
      if (DECL_EXTERNAL (decl))
	return false;
      /* Before we start optimizing unreachable code we can be sure all
	 static objects are defined.  */
      if (symtab->function_flags_ready)
	return true;
      snode = symtab_node::get (decl);
      if (!snode || !snode->definition)
	return false;
      node = dyn_cast <cgraph_node *> (snode);
      return !node || !node->inlined_to;
    }

  /* We will later output the initializer, so we can refer to it.
     So we are concerned only when DECL comes from initializer of
     external var or var that has been optimized out.  */
  if (!from_decl
      || !VAR_P (from_decl)
      || (!DECL_EXTERNAL (from_decl)
	  && (vnode = varpool_node::get (from_decl)) != NULL
	  && vnode->definition)
      || (flag_ltrans
	  && (vnode = varpool_node::get (from_decl)) != NULL
	  && vnode->in_other_partition))
    return true;
  /* We are folding reference from external vtable.  The vtable may reffer
     to a symbol keyed to other compilation unit.  The other compilation
     unit may be in separate DSO and the symbol may be hidden.  */
  if (DECL_VISIBILITY_SPECIFIED (decl)
      && DECL_EXTERNAL (decl)
      && DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT
      && (!(snode = symtab_node::get (decl)) || !snode->in_other_partition))
    return false;
  /* When function is public, we always can introduce new reference.
     Exception are the COMDAT functions where introducing a direct
     reference imply need to include function body in the curren tunit.  */
  if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
    return true;
  /* We have COMDAT.  We are going to check if we still have definition
     or if the definition is going to be output in other partition.
     Bypass this when gimplifying; all needed functions will be produced.

     As observed in PR20991 for already optimized out comdat virtual functions
     it may be tempting to not necessarily give up because the copy will be
     output elsewhere when corresponding vtable is output.  
     This is however not possible - ABI specify that COMDATs are output in
     units where they are used and when the other unit was compiled with LTO
     it is possible that vtable was kept public while the function itself
     was privatized. */
  if (!symtab->function_flags_ready)
    return true;

  snode = symtab_node::get (decl);
  if (!snode
      || ((!snode->definition || DECL_EXTERNAL (decl))
	  && (!snode->in_other_partition
	      || (!snode->forced_by_abi && !snode->force_output))))
    return false;
  node = dyn_cast <cgraph_node *> (snode);
  return !node || !node->inlined_to;
}

/* Create a temporary for TYPE for a statement STMT.  If the current function
   is in SSA form, a SSA name is created.  Otherwise a temporary register
   is made.  */

tree
create_tmp_reg_or_ssa_name (tree type, gimple *stmt)
{
  if (gimple_in_ssa_p (cfun))
    return make_ssa_name (type, stmt);
  else
    return create_tmp_reg (type);
}

/* CVAL is value taken from DECL_INITIAL of variable.  Try to transform it into
   acceptable form for is_gimple_min_invariant.
   FROM_DECL (if non-NULL) specify variable whose constructor contains CVAL.  */

tree
canonicalize_constructor_val (tree cval, tree from_decl)
{
  if (CONSTANT_CLASS_P (cval))
    return cval;

  tree orig_cval = cval;
  STRIP_NOPS (cval);
  if (TREE_CODE (cval) == POINTER_PLUS_EXPR
      && TREE_CODE (TREE_OPERAND (cval, 1)) == INTEGER_CST)
    {
      tree ptr = TREE_OPERAND (cval, 0);
      if (is_gimple_min_invariant (ptr))
	cval = build1_loc (EXPR_LOCATION (cval),
			   ADDR_EXPR, TREE_TYPE (ptr),
			   fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (ptr)),
					ptr,
					fold_convert (ptr_type_node,
						      TREE_OPERAND (cval, 1))));
    }
  if (TREE_CODE (cval) == ADDR_EXPR)
    {
      tree base = NULL_TREE;
      if (TREE_CODE (TREE_OPERAND (cval, 0)) == COMPOUND_LITERAL_EXPR)
	{
	  base = COMPOUND_LITERAL_EXPR_DECL (TREE_OPERAND (cval, 0));
	  if (base)
	    TREE_OPERAND (cval, 0) = base;
	}
      else
	base = get_base_address (TREE_OPERAND (cval, 0));
      if (!base)
	return NULL_TREE;

      if (VAR_OR_FUNCTION_DECL_P (base)
	  && !can_refer_decl_in_current_unit_p (base, from_decl))
	return NULL_TREE;
      if (TREE_TYPE (base) == error_mark_node)
	return NULL_TREE;
      if (VAR_P (base))
	/* ???  We should be able to assert that TREE_ADDRESSABLE is set,
	   but since the use can be in a debug stmt we can't.  */
	;
      else if (TREE_CODE (base) == FUNCTION_DECL)
	{
	  /* Make sure we create a cgraph node for functions we'll reference.
	     They can be non-existent if the reference comes from an entry
	     of an external vtable for example.  */
	  cgraph_node::get_create (base);
	}
      /* Fixup types in global initializers.  */
      if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
	cval = build_fold_addr_expr (TREE_OPERAND (cval, 0));

      if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
	cval = fold_convert (TREE_TYPE (orig_cval), cval);
      return cval;
    }
  /* In CONSTRUCTORs we may see unfolded constants like (int (*) ()) 0.  */
  if (TREE_CODE (cval) == INTEGER_CST)
    {
      if (TREE_OVERFLOW_P (cval))
	cval = drop_tree_overflow (cval);
      if (!useless_type_conversion_p (TREE_TYPE (orig_cval), TREE_TYPE (cval)))
	cval = fold_convert (TREE_TYPE (orig_cval), cval);
      return cval;
    }
  return orig_cval;
}

/* If SYM is a constant variable with known value, return the value.
   NULL_TREE is returned otherwise.  */

tree
get_symbol_constant_value (tree sym)
{
  tree val = ctor_for_folding (sym);
  if (val != error_mark_node)
    {
      if (val)
	{
	  val = canonicalize_constructor_val (unshare_expr (val), sym);
	  if (val && is_gimple_min_invariant (val))
	    return val;
	  else
	    return NULL_TREE;
	}
      /* Variables declared 'const' without an initializer
	 have zero as the initializer if they may not be
	 overridden at link or run time.  */
      if (!val
          && is_gimple_reg_type (TREE_TYPE (sym)))
	return build_zero_cst (TREE_TYPE (sym));
    }

  return NULL_TREE;
}



/* Subroutine of fold_stmt.  We perform constant folding of the
   memory reference tree EXPR.  */

static tree
maybe_fold_reference (tree expr)
{
  tree result = NULL_TREE;

  if ((TREE_CODE (expr) == VIEW_CONVERT_EXPR
       || TREE_CODE (expr) == REALPART_EXPR
       || TREE_CODE (expr) == IMAGPART_EXPR)
      && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
    result = fold_unary_loc (EXPR_LOCATION (expr),
			     TREE_CODE (expr),
			     TREE_TYPE (expr),
			     TREE_OPERAND (expr, 0));
  else if (TREE_CODE (expr) == BIT_FIELD_REF
	   && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
    result = fold_ternary_loc (EXPR_LOCATION (expr),
			       TREE_CODE (expr),
			       TREE_TYPE (expr),
			       TREE_OPERAND (expr, 0),
			       TREE_OPERAND (expr, 1),
			       TREE_OPERAND (expr, 2));
  else
    result = fold_const_aggregate_ref (expr);

  if (result && is_gimple_min_invariant (result))
    return result;

  return NULL_TREE;
}

/* Return true if EXPR is an acceptable right-hand-side for a
   GIMPLE assignment.  We validate the entire tree, not just
   the root node, thus catching expressions that embed complex
   operands that are not permitted in GIMPLE.  This function
   is needed because the folding routines in fold-const.c
   may return such expressions in some cases, e.g., an array
   access with an embedded index addition.  It may make more
   sense to have folding routines that are sensitive to the
   constraints on GIMPLE operands, rather than abandoning any
   any attempt to fold if the usual folding turns out to be too
   aggressive.  */

bool
valid_gimple_rhs_p (tree expr)
{
  enum tree_code code = TREE_CODE (expr);

  switch (TREE_CODE_CLASS (code))
    {
    case tcc_declaration:
      if (!is_gimple_variable (expr))
	return false;
      break;

    case tcc_constant:
      /* All constants are ok.  */
      break;

    case tcc_comparison:
      /* GENERIC allows comparisons with non-boolean types, reject
	 those for GIMPLE.  Let vector-typed comparisons pass - rules
	 for GENERIC and GIMPLE are the same here.  */
      if (!(INTEGRAL_TYPE_P (TREE_TYPE (expr))
	    && (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE
		|| TYPE_PRECISION (TREE_TYPE (expr)) == 1))
	  && ! VECTOR_TYPE_P (TREE_TYPE (expr)))
	return false;

      /* Fallthru.  */
    case tcc_binary:
      if (!is_gimple_val (TREE_OPERAND (expr, 0))
	  || !is_gimple_val (TREE_OPERAND (expr, 1)))
	return false;
      break;

    case tcc_unary:
      if (!is_gimple_val (TREE_OPERAND (expr, 0)))
	return false;
      break;

    case tcc_expression:
      switch (code)
	{
	case ADDR_EXPR:
	  {
	    tree t;
	    if (is_gimple_min_invariant (expr))
	      return true;
	    t = TREE_OPERAND (expr, 0);
	    while (handled_component_p (t))
	      {
		/* ??? More checks needed, see the GIMPLE verifier.  */
		if ((TREE_CODE (t) == ARRAY_REF
		     || TREE_CODE (t) == ARRAY_RANGE_REF)
		    && !is_gimple_val (TREE_OPERAND (t, 1)))
		  return false;
		t = TREE_OPERAND (t, 0);
	      }
	    if (!is_gimple_id (t))
	      return false;
	  }
	  break;

	default:
	  if (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS)
	    {
	      if ((code == COND_EXPR
		   ? !is_gimple_condexpr (TREE_OPERAND (expr, 0))
		   : !is_gimple_val (TREE_OPERAND (expr, 0)))
		  || !is_gimple_val (TREE_OPERAND (expr, 1))
		  || !is_gimple_val (TREE_OPERAND (expr, 2)))
		return false;
	      break;
	    }
	  return false;
	}
      break;

    case tcc_vl_exp:
      return false;

    case tcc_exceptional:
      if (code == CONSTRUCTOR)
	{
	  unsigned i;
	  tree elt;
	  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, elt)
	    if (!is_gimple_val (elt))
	      return false;
	  return true;
	}
      if (code != SSA_NAME)
	return false;
      break;

    case tcc_reference:
      if (code == BIT_FIELD_REF)
	return is_gimple_val (TREE_OPERAND (expr, 0));
      return false;

    default:
      return false;
    }

  return true;
}


/* Attempt to fold an assignment statement pointed-to by SI.  Returns a
   replacement rhs for the statement or NULL_TREE if no simplification
   could be made.  It is assumed that the operands have been previously
   folded.  */

static tree
fold_gimple_assign (gimple_stmt_iterator *si)
{
  gimple *stmt = gsi_stmt (*si);
  enum tree_code subcode = gimple_assign_rhs_code (stmt);
  location_t loc = gimple_location (stmt);

  tree result = NULL_TREE;

  switch (get_gimple_rhs_class (subcode))
    {
    case GIMPLE_SINGLE_RHS:
      {
        tree rhs = gimple_assign_rhs1 (stmt);

	if (TREE_CLOBBER_P (rhs))
	  return NULL_TREE;

	if (REFERENCE_CLASS_P (rhs))
	  return maybe_fold_reference (rhs);

	else if (TREE_CODE (rhs) == OBJ_TYPE_REF)
	  {
	    tree val = OBJ_TYPE_REF_EXPR (rhs);
	    if (is_gimple_min_invariant (val))
	      return val;
	    else if (flag_devirtualize && virtual_method_call_p (rhs))
	      {
		bool final;
		vec <cgraph_node *>targets
		  = possible_polymorphic_call_targets (rhs, stmt, &final);
		if (final && targets.length () <= 1 && dbg_cnt (devirt))
		  {
		    if (dump_enabled_p ())
		      {
			dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
					 "resolving virtual function address "
					 "reference to function %s\n",
					 targets.length () == 1
					 ? targets[0]->name ()
					 : "NULL");
		      }
		    if (targets.length () == 1)
		      {
			val = fold_convert (TREE_TYPE (val),
					    build_fold_addr_expr_loc
					      (loc, targets[0]->decl));
			STRIP_USELESS_TYPE_CONVERSION (val);
		      }
		    else
		      /* We cannot use __builtin_unreachable here because it
			 cannot have address taken.  */
		      val = build_int_cst (TREE_TYPE (val), 0);
		    return val;
		  }
	      }
	  }

	else if (TREE_CODE (rhs) == ADDR_EXPR)
	  {
	    tree ref = TREE_OPERAND (rhs, 0);
	    if (TREE_CODE (ref) == MEM_REF
		&& integer_zerop (TREE_OPERAND (ref, 1)))
	      {
		result = TREE_OPERAND (ref, 0);
		if (!useless_type_conversion_p (TREE_TYPE (rhs),
						TREE_TYPE (result)))
		  result = build1 (NOP_EXPR, TREE_TYPE (rhs), result);
		return result;
	      }
	  }

	else if (TREE_CODE (rhs) == CONSTRUCTOR
		 && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE)
	  {
	    /* Fold a constant vector CONSTRUCTOR to VECTOR_CST.  */
	    unsigned i;
	    tree val;

	    FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
	      if (! CONSTANT_CLASS_P (val))
		return NULL_TREE;

	    return build_vector_from_ctor (TREE_TYPE (rhs),
					   CONSTRUCTOR_ELTS (rhs));
	  }

	else if (DECL_P (rhs)
		 && is_gimple_reg_type (TREE_TYPE (rhs)))
	  return get_symbol_constant_value (rhs);
      }
      break;

    case GIMPLE_UNARY_RHS:
      break;

    case GIMPLE_BINARY_RHS:
      break;

    case GIMPLE_TERNARY_RHS:
      result = fold_ternary_loc (loc, subcode,
				 TREE_TYPE (gimple_assign_lhs (stmt)),
				 gimple_assign_rhs1 (stmt),
				 gimple_assign_rhs2 (stmt),
				 gimple_assign_rhs3 (stmt));

      if (result)
        {
          STRIP_USELESS_TYPE_CONVERSION (result);
          if (valid_gimple_rhs_p (result))
	    return result;
        }
      break;

    case GIMPLE_INVALID_RHS:
      gcc_unreachable ();
    }

  return NULL_TREE;
}


/* Replace a statement at *SI_P with a sequence of statements in STMTS,
   adjusting the replacement stmts location and virtual operands.
   If the statement has a lhs the last stmt in the sequence is expected
   to assign to that lhs.  */

static void
gsi_replace_with_seq_vops (gimple_stmt_iterator *si_p, gimple_seq stmts)
{
  gimple *stmt = gsi_stmt (*si_p);

  if (gimple_has_location (stmt))
    annotate_all_with_location (stmts, gimple_location (stmt));

  /* First iterate over the replacement statements backward, assigning
     virtual operands to their defining statements.  */
  gimple *laststore = NULL;
  for (gimple_stmt_iterator i = gsi_last (stmts);
       !gsi_end_p (i); gsi_prev (&i))
    {
      gimple *new_stmt = gsi_stmt (i);
      if ((gimple_assign_single_p (new_stmt)
	   && !is_gimple_reg (gimple_assign_lhs (new_stmt)))
	  || (is_gimple_call (new_stmt)
	      && (gimple_call_flags (new_stmt)
		  & (ECF_NOVOPS | ECF_PURE | ECF_CONST | ECF_NORETURN)) == 0))
	{
	  tree vdef;
	  if (!laststore)
	    vdef = gimple_vdef (stmt);
	  else
	    vdef = make_ssa_name (gimple_vop (cfun), new_stmt);
	  gimple_set_vdef (new_stmt, vdef);
	  if (vdef && TREE_CODE (vdef) == SSA_NAME)
	    SSA_NAME_DEF_STMT (vdef) = new_stmt;
	  laststore = new_stmt;
	}
    }

  /* Second iterate over the statements forward, assigning virtual
     operands to their uses.  */
  tree reaching_vuse = gimple_vuse (stmt);
  for (gimple_stmt_iterator i = gsi_start (stmts);
       !gsi_end_p (i); gsi_next (&i))
    {
      gimple *new_stmt = gsi_stmt (i);
      /* If the new statement possibly has a VUSE, update it with exact SSA
	 name we know will reach this one.  */
      if (gimple_has_mem_ops (new_stmt))
	gimple_set_vuse (new_stmt, reaching_vuse);
      gimple_set_modified (new_stmt, true);
      if (gimple_vdef (new_stmt))
	reaching_vuse = gimple_vdef (new_stmt);
    }

  /* If the new sequence does not do a store release the virtual
     definition of the original statement.  */
  if (reaching_vuse
      && reaching_vuse == gimple_vuse (stmt))
    {
      tree vdef = gimple_vdef (stmt);
      if (vdef
	  && TREE_CODE (vdef) == SSA_NAME)
	{
	  unlink_stmt_vdef (stmt);
	  release_ssa_name (vdef);
	}
    }

  /* Finally replace the original statement with the sequence.  */
  gsi_replace_with_seq (si_p, stmts, false);
}

/* Helper function for update_gimple_call and
   gimplify_and_update_call_from_tree.  A GIMPLE_CALL STMT is being replaced
   with GIMPLE_CALL NEW_STMT.  */

static void
finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple *new_stmt,
			   gimple *stmt)
{
  tree lhs = gimple_call_lhs (stmt);
  gimple_call_set_lhs (new_stmt, lhs);
  if (lhs && TREE_CODE (lhs) == SSA_NAME)
    SSA_NAME_DEF_STMT (lhs) = new_stmt;
  gimple_move_vops (new_stmt, stmt);
  gimple_set_location (new_stmt, gimple_location (stmt));
  if (gimple_block (new_stmt) == NULL_TREE)
    gimple_set_block (new_stmt, gimple_block (stmt));
  gsi_replace (si_p, new_stmt, false);
}

/* Update a GIMPLE_CALL statement at iterator *SI_P to call to FN
   with number of arguments NARGS, where the arguments in GIMPLE form
   follow NARGS argument.  */

bool
update_gimple_call (gimple_stmt_iterator *si_p, tree fn, int nargs, ...)
{
  va_list ap;
  gcall *new_stmt, *stmt = as_a <gcall *> (gsi_stmt (*si_p));

  gcc_assert (is_gimple_call (stmt));
  va_start (ap, nargs);
  new_stmt = gimple_build_call_valist (fn, nargs, ap);
  finish_update_gimple_call (si_p, new_stmt, stmt);
  va_end (ap);
  return true;
}

/* Return true if EXPR is a CALL_EXPR suitable for representation
   as a single GIMPLE_CALL statement.  If the arguments require
   further gimplification, return false.  */

static bool
valid_gimple_call_p (tree expr)
{
  unsigned i, nargs;

  if (TREE_CODE (expr) != CALL_EXPR)
    return false;

  nargs = call_expr_nargs (expr);
  for (i = 0; i < nargs; i++)
    {
      tree arg = CALL_EXPR_ARG (expr, i);
      if (is_gimple_reg_type (TREE_TYPE (arg)))
	{
	  if (!is_gimple_val (arg))
	    return false;
	}
      else
	if (!is_gimple_lvalue (arg))
	  return false;
    }

  return true;
}

/* Convert EXPR into a GIMPLE value suitable for substitution on the
   RHS of an assignment.  Insert the necessary statements before
   iterator *SI_P.  The statement at *SI_P, which must be a GIMPLE_CALL
   is replaced.  If the call is expected to produces a result, then it
   is replaced by an assignment of the new RHS to the result variable.
   If the result is to be ignored, then the call is replaced by a
   GIMPLE_NOP.  A proper VDEF chain is retained by making the first
   VUSE and the last VDEF of the whole sequence be the same as the replaced
   statement and using new SSA names for stores in between.  */

void
gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
{
  tree lhs;
  gimple *stmt, *new_stmt;
  gimple_stmt_iterator i;
  gimple_seq stmts = NULL;

  stmt = gsi_stmt (*si_p);

  gcc_assert (is_gimple_call (stmt));

  if (valid_gimple_call_p (expr))
    {
      /* The call has simplified to another call.  */
      tree fn = CALL_EXPR_FN (expr);
      unsigned i;
      unsigned nargs = call_expr_nargs (expr);
      vec<tree> args = vNULL;
      gcall *new_stmt;

      if (nargs > 0)
	{
	  args.create (nargs);
	  args.safe_grow_cleared (nargs, true);

	  for (i = 0; i < nargs; i++)
	    args[i] = CALL_EXPR_ARG (expr, i);
	}

      new_stmt = gimple_build_call_vec (fn, args);
      finish_update_gimple_call (si_p, new_stmt, stmt);
      args.release ();
      return;
    }

  lhs = gimple_call_lhs (stmt);
  if (lhs == NULL_TREE)
    {
      push_gimplify_context (gimple_in_ssa_p (cfun));
      gimplify_and_add (expr, &stmts);
      pop_gimplify_context (NULL);

      /* We can end up with folding a memcpy of an empty class assignment
	 which gets optimized away by C++ gimplification.  */
      if (gimple_seq_empty_p (stmts))
	{
	  if (gimple_in_ssa_p (cfun))
	    {
	      unlink_stmt_vdef (stmt);
	      release_defs (stmt);
	    }
	  gsi_replace (si_p, gimple_build_nop (), false);
	  return;
	}
    }
  else
    {
      tree tmp = force_gimple_operand (expr, &stmts, false, NULL_TREE);
      new_stmt = gimple_build_assign (lhs, tmp);
      i = gsi_last (stmts);
      gsi_insert_after_without_update (&i, new_stmt,
				       GSI_CONTINUE_LINKING);
    }

  gsi_replace_with_seq_vops (si_p, stmts);
}


/* Replace the call at *GSI with the gimple value VAL.  */

void
replace_call_with_value (gimple_stmt_iterator *gsi, tree val)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_call_lhs (stmt);
  gimple *repl;
  if (lhs)
    {
      if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (val)))
	val = fold_convert (TREE_TYPE (lhs), val);
      repl = gimple_build_assign (lhs, val);
    }
  else
    repl = gimple_build_nop ();
  tree vdef = gimple_vdef (stmt);
  if (vdef && TREE_CODE (vdef) == SSA_NAME)
    {
      unlink_stmt_vdef (stmt);
      release_ssa_name (vdef);
    }
  gsi_replace (gsi, repl, false);
}

/* Replace the call at *GSI with the new call REPL and fold that
   again.  */

static void
replace_call_with_call_and_fold (gimple_stmt_iterator *gsi, gimple *repl)
{
  gimple *stmt = gsi_stmt (*gsi);
  gimple_call_set_lhs (repl, gimple_call_lhs (stmt));
  gimple_set_location (repl, gimple_location (stmt));
  gimple_move_vops (repl, stmt);
  gsi_replace (gsi, repl, false);
  fold_stmt (gsi);
}

/* Return true if VAR is a VAR_DECL or a component thereof.  */

static bool
var_decl_component_p (tree var)
{
  tree inner = var;
  while (handled_component_p (inner))
    inner = TREE_OPERAND (inner, 0);
  return (DECL_P (inner)
	  || (TREE_CODE (inner) == MEM_REF
	      && TREE_CODE (TREE_OPERAND (inner, 0)) == ADDR_EXPR));
}

/* Return TRUE if the SIZE argument, representing the size of an
   object, is in a range of values of which exactly zero is valid.  */

static bool
size_must_be_zero_p (tree size)
{
  if (integer_zerop (size))
    return true;

  if (TREE_CODE (size) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (size)))
    return false;

  tree type = TREE_TYPE (size);
  int prec = TYPE_PRECISION (type);

  /* Compute the value of SSIZE_MAX, the largest positive value that
     can be stored in ssize_t, the signed counterpart of size_t.  */
  wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
  value_range valid_range (build_int_cst (type, 0),
			   wide_int_to_tree (type, ssize_max));
  value_range vr;
  if (cfun)
    get_range_query (cfun)->range_of_expr (vr, size);
  else
    get_global_range_query ()->range_of_expr (vr, size);
  if (vr.undefined_p ())
    vr.set_varying (TREE_TYPE (size));
  vr.intersect (&valid_range);
  return vr.zero_p ();
}

/* Fold function call to builtin mem{{,p}cpy,move}.  Try to detect and
   diagnose (otherwise undefined) overlapping copies without preventing
   folding.  When folded, GCC guarantees that overlapping memcpy has
   the same semantics as memmove.  Call to the library memcpy need not
   provide the same guarantee.  Return false if no simplification can
   be made.  */

static bool
gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
			       tree dest, tree src, enum built_in_function code)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_call_lhs (stmt);
  tree len = gimple_call_arg (stmt, 2);
  location_t loc = gimple_location (stmt);

  /* If the LEN parameter is a constant zero or in range where
     the only valid value is zero, return DEST.  */
  if (size_must_be_zero_p (len))
    {
      gimple *repl;
      if (gimple_call_lhs (stmt))
	repl = gimple_build_assign (gimple_call_lhs (stmt), dest);
      else
	repl = gimple_build_nop ();
      tree vdef = gimple_vdef (stmt);
      if (vdef && TREE_CODE (vdef) == SSA_NAME)
	{
	  unlink_stmt_vdef (stmt);
	  release_ssa_name (vdef);
	}
      gsi_replace (gsi, repl, false);
      return true;
    }

  /* If SRC and DEST are the same (and not volatile), return
     DEST{,+LEN,+LEN-1}.  */
  if (operand_equal_p (src, dest, 0))
    {
      /* Avoid diagnosing exact overlap in calls to __builtin_memcpy.
	 It's safe and may even be emitted by GCC itself (see bug
	 32667).  */
      unlink_stmt_vdef (stmt);
      if (gimple_vdef (stmt) && TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
	release_ssa_name (gimple_vdef (stmt));
      if (!lhs)
	{
	  gsi_replace (gsi, gimple_build_nop (), false);
	  return true;
	}
      goto done;
    }
  else
    {
      /* We cannot (easily) change the type of the copy if it is a storage
	 order barrier, i.e. is equivalent to a VIEW_CONVERT_EXPR that can
	 modify the storage order of objects (see storage_order_barrier_p).  */
      tree srctype
	= POINTER_TYPE_P (TREE_TYPE (src))
	  ? TREE_TYPE (TREE_TYPE (src)) : NULL_TREE;
      tree desttype
	= POINTER_TYPE_P (TREE_TYPE (dest))
	  ? TREE_TYPE (TREE_TYPE (dest)) : NULL_TREE;
      tree destvar, srcvar, srcoff;
      unsigned int src_align, dest_align;
      unsigned HOST_WIDE_INT tmp_len;
      const char *tmp_str;

      /* Build accesses at offset zero with a ref-all character type.  */
      tree off0
	= build_int_cst (build_pointer_type_for_mode (char_type_node,
						      ptr_mode, true), 0);

      /* If we can perform the copy efficiently with first doing all loads and
	 then all stores inline it that way.  Currently efficiently means that
	 we can load all the memory with a single set operation and that the
	 total size is less than MOVE_MAX * MOVE_RATIO.  */
      src_align = get_pointer_alignment (src);
      dest_align = get_pointer_alignment (dest);
      if (tree_fits_uhwi_p (len)
	  && (compare_tree_int
	      (len, (MOVE_MAX
		     * MOVE_RATIO (optimize_function_for_size_p (cfun))))
	      <= 0)
	  /* FIXME: Don't transform copies from strings with known length.
	     Until GCC 9 this prevented a case in gcc.dg/strlenopt-8.c
	     from being handled, and the case was XFAILed for that reason.
	     Now that it is handled and the XFAIL removed, as soon as other
	     strlenopt tests that rely on it for passing are adjusted, this
	     hack can be removed.  */
	  && !c_strlen (src, 1)
	  && !((tmp_str = getbyterep (src, &tmp_len)) != NULL
	       && memchr (tmp_str, 0, tmp_len) == NULL)
	  && !(srctype
	       && AGGREGATE_TYPE_P (srctype)
	       && TYPE_REVERSE_STORAGE_ORDER (srctype))
	  && !(desttype
	       && AGGREGATE_TYPE_P (desttype)
	       && TYPE_REVERSE_STORAGE_ORDER (desttype)))
	{
	  unsigned ilen = tree_to_uhwi (len);
	  if (pow2p_hwi (ilen))
	    {
	      /* Detect out-of-bounds accesses without issuing warnings.
		 Avoid folding out-of-bounds copies but to avoid false
		 positives for unreachable code defer warning until after
		 DCE has worked its magic.
		 -Wrestrict is still diagnosed.  */
	      if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
							 dest, src, len, len,
							 false, false))
		if (warning != OPT_Wrestrict)
		  return false;

	      scalar_int_mode mode;
	      if (int_mode_for_size (ilen * 8, 0).exists (&mode)
		  && GET_MODE_SIZE (mode) * BITS_PER_UNIT == ilen * 8
		  && have_insn_for (SET, mode)
		  /* If the destination pointer is not aligned we must be able
		     to emit an unaligned store.  */
		  && (dest_align >= GET_MODE_ALIGNMENT (mode)
		      || !targetm.slow_unaligned_access (mode, dest_align)
		      || (optab_handler (movmisalign_optab, mode)
			  != CODE_FOR_nothing)))
		{
		  tree type = build_nonstandard_integer_type (ilen * 8, 1);
		  tree srctype = type;
		  tree desttype = type;
		  if (src_align < GET_MODE_ALIGNMENT (mode))
		    srctype = build_aligned_type (type, src_align);
		  tree srcmem = fold_build2 (MEM_REF, srctype, src, off0);
		  tree tem = fold_const_aggregate_ref (srcmem);
		  if (tem)
		    srcmem = tem;
		  else if (src_align < GET_MODE_ALIGNMENT (mode)
			   && targetm.slow_unaligned_access (mode, src_align)
			   && (optab_handler (movmisalign_optab, mode)
			       == CODE_FOR_nothing))
		    srcmem = NULL_TREE;
		  if (srcmem)
		    {
		      gimple *new_stmt;
		      if (is_gimple_reg_type (TREE_TYPE (srcmem)))
			{
			  new_stmt = gimple_build_assign (NULL_TREE, srcmem);
			  srcmem
			    = create_tmp_reg_or_ssa_name (TREE_TYPE (srcmem),
							  new_stmt);
			  gimple_assign_set_lhs (new_stmt, srcmem);
			  gimple_set_vuse (new_stmt, gimple_vuse (stmt));
			  gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
			}
		      if (dest_align < GET_MODE_ALIGNMENT (mode))
			desttype = build_aligned_type (type, dest_align);
		      new_stmt
			= gimple_build_assign (fold_build2 (MEM_REF, desttype,
							    dest, off0),
					       srcmem);
		      gimple_move_vops (new_stmt, stmt);
		      if (!lhs)
			{
			  gsi_replace (gsi, new_stmt, false);
			  return true;
			}
		      gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
		      goto done;
		    }
		}
	    }
	}

      if (code == BUILT_IN_MEMMOVE)
	{
	  /* Both DEST and SRC must be pointer types.
	     ??? This is what old code did.  Is the testing for pointer types
	     really mandatory?

	     If either SRC is readonly or length is 1, we can use memcpy.  */
	  if (!dest_align || !src_align)
	    return false;
	  if (readonly_data_expr (src)
	      || (tree_fits_uhwi_p (len)
		  && (MIN (src_align, dest_align) / BITS_PER_UNIT
		      >= tree_to_uhwi (len))))
	    {
	      tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
	      if (!fn)
		return false;
	      gimple_call_set_fndecl (stmt, fn);
	      gimple_call_set_arg (stmt, 0, dest);
	      gimple_call_set_arg (stmt, 1, src);
	      fold_stmt (gsi);
	      return true;
	    }

	  /* If *src and *dest can't overlap, optimize into memcpy as well.  */
	  if (TREE_CODE (src) == ADDR_EXPR
	      && TREE_CODE (dest) == ADDR_EXPR)
	    {
	      tree src_base, dest_base, fn;
	      poly_int64 src_offset = 0, dest_offset = 0;
	      poly_uint64 maxsize;

	      srcvar = TREE_OPERAND (src, 0);
	      src_base = get_addr_base_and_unit_offset (srcvar, &src_offset);
	      if (src_base == NULL)
		src_base = srcvar;
	      destvar = TREE_OPERAND (dest, 0);
	      dest_base = get_addr_base_and_unit_offset (destvar,
							 &dest_offset);
	      if (dest_base == NULL)
		dest_base = destvar;
	      if (!poly_int_tree_p (len, &maxsize))
		maxsize = -1;
	      if (SSA_VAR_P (src_base)
		  && SSA_VAR_P (dest_base))
		{
		  if (operand_equal_p (src_base, dest_base, 0)
		      && ranges_maybe_overlap_p (src_offset, maxsize,
						 dest_offset, maxsize))
		    return false;
		}
	      else if (TREE_CODE (src_base) == MEM_REF
		       && TREE_CODE (dest_base) == MEM_REF)
		{
		  if (! operand_equal_p (TREE_OPERAND (src_base, 0),
					 TREE_OPERAND (dest_base, 0), 0))
		    return false;
		  poly_offset_int full_src_offset
		    = mem_ref_offset (src_base) + src_offset;
		  poly_offset_int full_dest_offset
		    = mem_ref_offset (dest_base) + dest_offset;
		  if (ranges_maybe_overlap_p (full_src_offset, maxsize,
					      full_dest_offset, maxsize))
		    return false;
		}
	      else
		return false;

	      fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
	      if (!fn)
		return false;
	      gimple_call_set_fndecl (stmt, fn);
	      gimple_call_set_arg (stmt, 0, dest);
	      gimple_call_set_arg (stmt, 1, src);
	      fold_stmt (gsi);
	      return true;
	    }

	  /* If the destination and source do not alias optimize into
	     memcpy as well.  */
	  if ((is_gimple_min_invariant (dest)
	       || TREE_CODE (dest) == SSA_NAME)
	      && (is_gimple_min_invariant (src)
		  || TREE_CODE (src) == SSA_NAME))
	    {
	      ao_ref destr, srcr;
	      ao_ref_init_from_ptr_and_size (&destr, dest, len);
	      ao_ref_init_from_ptr_and_size (&srcr, src, len);
	      if (!refs_may_alias_p_1 (&destr, &srcr, false))
		{
		  tree fn;
		  fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
		  if (!fn)
		    return false;
		  gimple_call_set_fndecl (stmt, fn);
		  gimple_call_set_arg (stmt, 0, dest);
		  gimple_call_set_arg (stmt, 1, src);
		  fold_stmt (gsi);
		  return true;
		}
	    }

	  return false;
	}

      if (!tree_fits_shwi_p (len))
	return false;
      if (!srctype
	  || (AGGREGATE_TYPE_P (srctype)
	      && TYPE_REVERSE_STORAGE_ORDER (srctype)))
	return false;
      if (!desttype
	  || (AGGREGATE_TYPE_P (desttype)
	      && TYPE_REVERSE_STORAGE_ORDER (desttype)))
	return false;
      /* In the following try to find a type that is most natural to be
	 used for the memcpy source and destination and that allows
	 the most optimization when memcpy is turned into a plain assignment
	 using that type.  In theory we could always use a char[len] type
	 but that only gains us that the destination and source possibly
	 no longer will have their address taken.  */
      if (TREE_CODE (srctype) == ARRAY_TYPE
	  && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
	srctype = TREE_TYPE (srctype);
      if (TREE_CODE (desttype) == ARRAY_TYPE
	  && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
	desttype = TREE_TYPE (desttype);
      if (TREE_ADDRESSABLE (srctype)
	  || TREE_ADDRESSABLE (desttype))
	return false;

      /* Make sure we are not copying using a floating-point mode or
         a type whose size possibly does not match its precision.  */
      if (FLOAT_MODE_P (TYPE_MODE (desttype))
	  || TREE_CODE (desttype) == BOOLEAN_TYPE
	  || TREE_CODE (desttype) == ENUMERAL_TYPE)
	desttype = bitwise_type_for_mode (TYPE_MODE (desttype));
      if (FLOAT_MODE_P (TYPE_MODE (srctype))
	  || TREE_CODE (srctype) == BOOLEAN_TYPE
	  || TREE_CODE (srctype) == ENUMERAL_TYPE)
	srctype = bitwise_type_for_mode (TYPE_MODE (srctype));
      if (!srctype)
	srctype = desttype;
      if (!desttype)
	desttype = srctype;
      if (!srctype)
	return false;

      src_align = get_pointer_alignment (src);
      dest_align = get_pointer_alignment (dest);

      /* Choose between src and destination type for the access based
         on alignment, whether the access constitutes a register access
	 and whether it may actually expose a declaration for SSA rewrite
	 or SRA decomposition.  Also try to expose a string constant, we
	 might be able to concatenate several of them later into a single
	 string store.  */
      destvar = NULL_TREE;
      srcvar = NULL_TREE;
      if (TREE_CODE (dest) == ADDR_EXPR
	  && var_decl_component_p (TREE_OPERAND (dest, 0))
	  && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len)
	  && dest_align >= TYPE_ALIGN (desttype)
	  && (is_gimple_reg_type (desttype)
	      || src_align >= TYPE_ALIGN (desttype)))
	destvar = fold_build2 (MEM_REF, desttype, dest, off0);
      else if (TREE_CODE (src) == ADDR_EXPR
	       && var_decl_component_p (TREE_OPERAND (src, 0))
	       && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
	       && src_align >= TYPE_ALIGN (srctype)
	       && (is_gimple_reg_type (srctype)
		   || dest_align >= TYPE_ALIGN (srctype)))
	srcvar = fold_build2 (MEM_REF, srctype, src, off0);
      /* FIXME: Don't transform copies from strings with known original length.
	 As soon as strlenopt tests that rely on it for passing are adjusted,
	 this hack can be removed.  */
      else if (gimple_call_alloca_for_var_p (stmt)
	       && (srcvar = string_constant (src, &srcoff, NULL, NULL))
	       && integer_zerop (srcoff)
	       && tree_int_cst_equal (TYPE_SIZE_UNIT (TREE_TYPE (srcvar)), len)
	       && dest_align >= TYPE_ALIGN (TREE_TYPE (srcvar)))
	srctype = TREE_TYPE (srcvar);
      else
	return false;

      /* Now that we chose an access type express the other side in
         terms of it if the target allows that with respect to alignment
	 constraints.  */
      if (srcvar == NULL_TREE)
	{
	  if (src_align >= TYPE_ALIGN (desttype))
	    srcvar = fold_build2 (MEM_REF, desttype, src, off0);
	  else
	    {
	      if (STRICT_ALIGNMENT)
		return false;
	      srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
					    src_align);
	      srcvar = fold_build2 (MEM_REF, srctype, src, off0);
	    }
	}
      else if (destvar == NULL_TREE)
	{
	  if (dest_align >= TYPE_ALIGN (srctype))
	    destvar = fold_build2 (MEM_REF, srctype, dest, off0);
	  else
	    {
	      if (STRICT_ALIGNMENT)
		return false;
	      desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype),
					     dest_align);
	      destvar = fold_build2 (MEM_REF, desttype, dest, off0);
	    }
	}

      /* Same as above, detect out-of-bounds accesses without issuing
	 warnings.  Avoid folding out-of-bounds copies but to avoid
	 false positives for unreachable code defer warning until
	 after DCE has worked its magic.
	 -Wrestrict is still diagnosed.  */
      if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
						 dest, src, len, len,
						 false, false))
	if (warning != OPT_Wrestrict)
	  return false;

      gimple *new_stmt;
      if (is_gimple_reg_type (TREE_TYPE (srcvar)))
	{
	  tree tem = fold_const_aggregate_ref (srcvar);
	  if (tem)
	    srcvar = tem;
	  if (! is_gimple_min_invariant (srcvar))
	    {
	      new_stmt = gimple_build_assign (NULL_TREE, srcvar);
	      srcvar = create_tmp_reg_or_ssa_name (TREE_TYPE (srcvar),
						   new_stmt);
	      gimple_assign_set_lhs (new_stmt, srcvar);
	      gimple_set_vuse (new_stmt, gimple_vuse (stmt));
	      gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
	    }
	  new_stmt = gimple_build_assign (destvar, srcvar);
	  goto set_vop_and_replace;
	}

      /* We get an aggregate copy.  If the source is a STRING_CST, then
	 directly use its type to perform the copy.  */
      if (TREE_CODE (srcvar) == STRING_CST)
	  desttype = srctype;

      /* Or else, use an unsigned char[] type to perform the copy in order
	 to preserve padding and to avoid any issues with TREE_ADDRESSABLE
	 types or float modes behavior on copying.  */
      else
	{
	  desttype = build_array_type_nelts (unsigned_char_type_node,
					     tree_to_uhwi (len));
	  srctype = desttype;
	  if (src_align > TYPE_ALIGN (srctype))
	    srctype = build_aligned_type (srctype, src_align);
	  srcvar = fold_build2 (MEM_REF, srctype, src, off0);
	}

      if (dest_align > TYPE_ALIGN (desttype))
	desttype = build_aligned_type (desttype, dest_align);
      destvar = fold_build2 (MEM_REF, desttype, dest, off0);
      new_stmt = gimple_build_assign (destvar, srcvar);

set_vop_and_replace:
      gimple_move_vops (new_stmt, stmt);
      if (!lhs)
	{
	  gsi_replace (gsi, new_stmt, false);
	  return true;
	}
      gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
    }

done:
  gimple_seq stmts = NULL;
  if (code == BUILT_IN_MEMCPY || code == BUILT_IN_MEMMOVE)
    len = NULL_TREE;
  else if (code == BUILT_IN_MEMPCPY)
    {
      len = gimple_convert_to_ptrofftype (&stmts, loc, len);
      dest = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
			   TREE_TYPE (dest), dest, len);
    }
  else
    gcc_unreachable ();

  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
  gimple *repl = gimple_build_assign (lhs, dest);
  gsi_replace (gsi, repl, false);
  return true;
}

/* Transform a call to built-in bcmp(a, b, len) at *GSI into one
   to built-in memcmp (a, b, len).  */

static bool
gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi)
{
  tree fn = builtin_decl_implicit (BUILT_IN_MEMCMP);

  if (!fn)
    return false;

  /* Transform bcmp (a, b, len) into memcmp (a, b, len).  */

  gimple *stmt = gsi_stmt (*gsi);
  tree a = gimple_call_arg (stmt, 0);
  tree b = gimple_call_arg (stmt, 1);
  tree len = gimple_call_arg (stmt, 2);

  gimple *repl = gimple_build_call (fn, 3, a, b, len);
  replace_call_with_call_and_fold (gsi, repl);

  return true;
}

/* Transform a call to built-in bcopy (src, dest, len) at *GSI into one
   to built-in memmove (dest, src, len).  */

static bool
gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi)
{
  tree fn = builtin_decl_implicit (BUILT_IN_MEMMOVE);

  if (!fn)
    return false;

  /* bcopy has been removed from POSIX in Issue 7 but Issue 6 specifies
     it's quivalent to memmove (not memcpy).  Transform bcopy (src, dest,
     len) into memmove (dest, src, len).  */

  gimple *stmt = gsi_stmt (*gsi);
  tree src = gimple_call_arg (stmt, 0);
  tree dest = gimple_call_arg (stmt, 1);
  tree len = gimple_call_arg (stmt, 2);

  gimple *repl = gimple_build_call (fn, 3, dest, src, len);
  gimple_call_set_fntype (as_a <gcall *> (stmt), TREE_TYPE (fn));
  replace_call_with_call_and_fold (gsi, repl);

  return true;
}

/* Transform a call to built-in bzero (dest, len) at *GSI into one
   to built-in memset (dest, 0, len).  */

static bool
gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi)
{
  tree fn = builtin_decl_implicit (BUILT_IN_MEMSET);

  if (!fn)
    return false;

  /* Transform bzero (dest, len) into memset (dest, 0, len).  */

  gimple *stmt = gsi_stmt (*gsi);
  tree dest = gimple_call_arg (stmt, 0);
  tree len = gimple_call_arg (stmt, 1);

  gimple_seq seq = NULL;
  gimple *repl = gimple_build_call (fn, 3, dest, integer_zero_node, len);
  gimple_seq_add_stmt_without_update (&seq, repl);
  gsi_replace_with_seq_vops (gsi, seq);
  fold_stmt (gsi);

  return true;
}

/* Fold function call to builtin memset or bzero at *GSI setting the
   memory of size LEN to VAL.  Return whether a simplification was made.  */

static bool
gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree etype;
  unsigned HOST_WIDE_INT length, cval;

  /* If the LEN parameter is zero, return DEST.  */
  if (integer_zerop (len))
    {
      replace_call_with_value (gsi, gimple_call_arg (stmt, 0));
      return true;
    }

  if (! tree_fits_uhwi_p (len))
    return false;

  if (TREE_CODE (c) != INTEGER_CST)
    return false;

  tree dest = gimple_call_arg (stmt, 0);
  tree var = dest;
  if (TREE_CODE (var) != ADDR_EXPR)
    return false;

  var = TREE_OPERAND (var, 0);
  if (TREE_THIS_VOLATILE (var))
    return false;

  etype = TREE_TYPE (var);
  if (TREE_CODE (etype) == ARRAY_TYPE)
    etype = TREE_TYPE (etype);

  if (!INTEGRAL_TYPE_P (etype)
      && !POINTER_TYPE_P (etype))
    return NULL_TREE;

  if (! var_decl_component_p (var))
    return NULL_TREE;

  length = tree_to_uhwi (len);
  if (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (etype)) != length
      || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (etype))
	  != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (etype)))
      || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
    return NULL_TREE;

  if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
    return NULL_TREE;

  if (!type_has_mode_precision_p (etype))
    etype = lang_hooks.types.type_for_mode (SCALAR_INT_TYPE_MODE (etype),
					    TYPE_UNSIGNED (etype));

  if (integer_zerop (c))
    cval = 0;
  else
    {
      if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
	return NULL_TREE;

      cval = TREE_INT_CST_LOW (c);
      cval &= 0xff;
      cval |= cval << 8;
      cval |= cval << 16;
      cval |= (cval << 31) << 1;
    }

  var = fold_build2 (MEM_REF, etype, dest, build_int_cst (ptr_type_node, 0));
  gimple *store = gimple_build_assign (var, build_int_cst_type (etype, cval));
  gimple_move_vops (store, stmt);
  gsi_insert_before (gsi, store, GSI_SAME_STMT);
  if (gimple_call_lhs (stmt))
    {
      gimple *asgn = gimple_build_assign (gimple_call_lhs (stmt), dest);
      gsi_replace (gsi, asgn, false);
    }
  else
    {
      gimple_stmt_iterator gsi2 = *gsi;
      gsi_prev (gsi);
      gsi_remove (&gsi2, true);
    }

  return true;
}

/* Helper of get_range_strlen for ARG that is not an SSA_NAME.  */

static bool
get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind,
		       c_strlen_data *pdata, unsigned eltsize)
{
  gcc_assert (TREE_CODE (arg) != SSA_NAME);

  /* The length computed by this invocation of the function.  */
  tree val = NULL_TREE;

  /* True if VAL is an optimistic (tight) bound determined from
     the size of the character array in which the string may be
     stored.  In that case, the computed VAL is used to set
     PDATA->MAXBOUND.  */
  bool tight_bound = false;

  /* We can end up with &(*iftmp_1)[0] here as well, so handle it.  */
  if (TREE_CODE (arg) == ADDR_EXPR
      && TREE_CODE (TREE_OPERAND (arg, 0)) == ARRAY_REF)
    {
      tree op = TREE_OPERAND (arg, 0);
      if (integer_zerop (TREE_OPERAND (op, 1)))
	{
	  tree aop0 = TREE_OPERAND (op, 0);
	  if (TREE_CODE (aop0) == INDIRECT_REF
	      && TREE_CODE (TREE_OPERAND (aop0, 0)) == SSA_NAME)
	    return get_range_strlen (TREE_OPERAND (aop0, 0), visited, rkind,
				     pdata, eltsize);
	}
      else if (TREE_CODE (TREE_OPERAND (op, 0)) == COMPONENT_REF
	       && rkind == SRK_LENRANGE)
	{
	  /* Fail if an array is the last member of a struct object
	     since it could be treated as a (fake) flexible array
	     member.  */
	  tree idx = TREE_OPERAND (op, 1);

	  arg = TREE_OPERAND (op, 0);
	  tree optype = TREE_TYPE (arg);
	  if (tree dom = TYPE_DOMAIN (optype))
	    if (tree bound = TYPE_MAX_VALUE (dom))
	      if (TREE_CODE (bound) == INTEGER_CST
		  && TREE_CODE (idx) == INTEGER_CST
		  && tree_int_cst_lt (bound, idx))
		return false;
	}
    }

  if (rkind == SRK_INT_VALUE)
    {
      /* We are computing the maximum value (not string length).  */
      val = arg;
      if (TREE_CODE (val) != INTEGER_CST
	  || tree_int_cst_sgn (val) < 0)
	return false;
    }
  else
    {
      c_strlen_data lendata = { };
      val = c_strlen (arg, 1, &lendata, eltsize);

      if (!val && lendata.decl)
	{
	  /* ARG refers to an unterminated const character array.
	     DATA.DECL with size DATA.LEN.  */
	  val = lendata.minlen;
	  pdata->decl = lendata.decl;
	}
    }

  /* Set if VAL represents the maximum length based on array size (set
     when exact length cannot be determined).  */
  bool maxbound = false;

  if (!val && rkind == SRK_LENRANGE)
    {
      if (TREE_CODE (arg) == ADDR_EXPR)
	return get_range_strlen (TREE_OPERAND (arg, 0), visited, rkind,
				 pdata, eltsize);

      if (TREE_CODE (arg) == ARRAY_REF)
	{
	  tree optype = TREE_TYPE (TREE_OPERAND (arg, 0));

	  /* Determine the "innermost" array type.  */
	  while (TREE_CODE (optype) == ARRAY_TYPE
		 && TREE_CODE (TREE_TYPE (optype)) == ARRAY_TYPE)
	    optype = TREE_TYPE (optype);

	  /* Avoid arrays of pointers.  */
	  tree eltype = TREE_TYPE (optype);
	  if (TREE_CODE (optype) != ARRAY_TYPE
	      || !INTEGRAL_TYPE_P (eltype))
	    return false;

	  /* Fail when the array bound is unknown or zero.  */
	  val = TYPE_SIZE_UNIT (optype);
	  if (!val
	      || TREE_CODE (val) != INTEGER_CST
	      || integer_zerop (val))
	    return false;

	  val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
			      integer_one_node);

	  /* Set the minimum size to zero since the string in
	     the array could have zero length.  */
	  pdata->minlen = ssize_int (0);

	  tight_bound = true;
	}
      else if (TREE_CODE (arg) == COMPONENT_REF
	       && (TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1)))
		   == ARRAY_TYPE))
	{
	  /* Use the type of the member array to determine the upper
	     bound on the length of the array.  This may be overly
	     optimistic if the array itself isn't NUL-terminated and
	     the caller relies on the subsequent member to contain
	     the NUL but that would only be considered valid if
	     the array were the last member of a struct.  */

	  tree fld = TREE_OPERAND (arg, 1);

	  tree optype = TREE_TYPE (fld);

	  /* Determine the "innermost" array type.  */
	  while (TREE_CODE (optype) == ARRAY_TYPE
		 && TREE_CODE (TREE_TYPE (optype)) == ARRAY_TYPE)
	    optype = TREE_TYPE (optype);

	  /* Fail when the array bound is unknown or zero.  */
	  val = TYPE_SIZE_UNIT (optype);
	  if (!val
	      || TREE_CODE (val) != INTEGER_CST
	      || integer_zerop (val))
	    return false;
	  val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
			     integer_one_node);

	  /* Set the minimum size to zero since the string in
	     the array could have zero length.  */
	  pdata->minlen = ssize_int (0);

	  /* The array size determined above is an optimistic bound
	     on the length.  If the array isn't nul-terminated the
	     length computed by the library function would be greater.
	     Even though using strlen to cross the subobject boundary
	     is undefined, avoid drawing conclusions from the member
	     type about the length here.  */
	  tight_bound = true;
	}
      else if (TREE_CODE (arg) == MEM_REF
	       && TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE
	       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == INTEGER_TYPE
	       && TREE_CODE (TREE_OPERAND (arg, 0)) == ADDR_EXPR)
	{
	  /* Handle a MEM_REF into a DECL accessing an array of integers,
	     being conservative about references to extern structures with
	     flexible array members that can be initialized to arbitrary
	     numbers of elements as an extension (static structs are okay).
	     FIXME: Make this less conservative -- see
	     component_ref_size in tree.c.  */
	  tree ref = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
	  if ((TREE_CODE (ref) == PARM_DECL || VAR_P (ref))
	      && (decl_binds_to_current_def_p (ref)
		  || !array_at_struct_end_p (arg)))
	    {
	      /* Fail if the offset is out of bounds.  Such accesses
		 should be diagnosed at some point.  */
	      val = DECL_SIZE_UNIT (ref);
	      if (!val
		  || TREE_CODE (val) != INTEGER_CST
		  || integer_zerop (val))
		return false;

	      poly_offset_int psiz = wi::to_offset (val);
	      poly_offset_int poff = mem_ref_offset (arg);
	      if (known_le (psiz, poff))
		return false;

	      pdata->minlen = ssize_int (0);

	      /* Subtract the offset and one for the terminating nul.  */
	      psiz -= poff;
	      psiz -= 1;
	      val = wide_int_to_tree (TREE_TYPE (val), psiz);
	      /* Since VAL reflects the size of a declared object
		 rather the type of the access it is not a tight bound.  */
	    }
	}
      else if (TREE_CODE (arg) == PARM_DECL || VAR_P (arg))
	{
	  /* Avoid handling pointers to arrays.  GCC might misuse
	     a pointer to an array of one bound to point to an array
	     object of a greater bound.  */
	  tree argtype = TREE_TYPE (arg);
	  if (TREE_CODE (argtype) == ARRAY_TYPE)
	    {
	      val = TYPE_SIZE_UNIT (argtype);
	      if (!val
		  || TREE_CODE (val) != INTEGER_CST
		  || integer_zerop (val))
		return false;
	      val = wide_int_to_tree (TREE_TYPE (val),
				      wi::sub (wi::to_wide (val), 1));

	      /* Set the minimum size to zero since the string in
		 the array could have zero length.  */
	      pdata->minlen = ssize_int (0);
	    }
	}
      maxbound = true;
    }

  if (!val)
    return false;

  /* Adjust the lower bound on the string length as necessary.  */
  if (!pdata->minlen
      || (rkind != SRK_STRLEN
	  && TREE_CODE (pdata->minlen) == INTEGER_CST
	  && TREE_CODE (val) == INTEGER_CST
	  && tree_int_cst_lt (val, pdata->minlen)))
    pdata->minlen = val;

  if (pdata->maxbound && TREE_CODE (pdata->maxbound) == INTEGER_CST)
    {
      /* Adjust the tighter (more optimistic) string length bound
	 if necessary and proceed to adjust the more conservative
	 bound.  */
      if (TREE_CODE (val) == INTEGER_CST)
	{
	  if (tree_int_cst_lt (pdata->maxbound, val))
	    pdata->maxbound = val;
	}
      else
	pdata->maxbound = val;
    }
  else if (pdata->maxbound || maxbound)
    /* Set PDATA->MAXBOUND only if it either isn't INTEGER_CST or
       if VAL corresponds to the maximum length determined based
       on the type of the object.  */
    pdata->maxbound = val;

  if (tight_bound)
    {
      /* VAL computed above represents an optimistically tight bound
	 on the length of the string based on the referenced object's
	 or subobject's type.  Determine the conservative upper bound
	 based on the enclosing object's size if possible.  */
      if (rkind == SRK_LENRANGE)
	{
	  poly_int64 offset;
	  tree base = get_addr_base_and_unit_offset (arg, &offset);
	  if (!base)
	    {
	      /* When the call above fails due to a non-constant offset
		 assume the offset is zero and use the size of the whole
		 enclosing object instead.  */
	      base = get_base_address (arg);
	      offset = 0;
	    }
	  /* If the base object is a pointer no upper bound on the length
	     can be determined.  Otherwise the maximum length is equal to
	     the size of the enclosing object minus the offset of
	     the referenced subobject minus 1 (for the terminating nul).  */
	  tree type = TREE_TYPE (base);
	  if (TREE_CODE (type) == POINTER_TYPE
	      || (TREE_CODE (base) != PARM_DECL && !VAR_P (base))
	      || !(val = DECL_SIZE_UNIT (base)))
	    val = build_all_ones_cst (size_type_node);
	  else
	    {
	      val = DECL_SIZE_UNIT (base);
	      val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,
				 size_int (offset + 1));
	    }
	}
      else
	return false;
    }

  if (pdata->maxlen)
    {
      /* Adjust the more conservative bound if possible/necessary
	 and fail otherwise.  */
      if (rkind != SRK_STRLEN)
	{
	  if (TREE_CODE (pdata->maxlen) != INTEGER_CST
	      || TREE_CODE (val) != INTEGER_CST)
	    return false;

	  if (tree_int_cst_lt (pdata->maxlen, val))
	    pdata->maxlen = val;
	  return true;
	}
      else if (simple_cst_equal (val, pdata->maxlen) != 1)
	{
	  /* Fail if the length of this ARG is different from that
	     previously determined from another ARG.  */
	  return false;
	}
    }

  pdata->maxlen = val;
  return rkind == SRK_LENRANGE || !integer_all_onesp (val);
}

/* For an ARG referencing one or more strings, try to obtain the range
   of their lengths, or the size of the largest array ARG referes to if
   the range of lengths cannot be determined, and store all in *PDATA.
   For an integer ARG (when RKIND == SRK_INT_VALUE), try to determine
   the maximum constant value.
   If ARG is an SSA_NAME, follow its use-def chains.  When RKIND ==
   SRK_STRLEN, then if PDATA->MAXLEN is not equal to the determined
   length or if we are unable to determine the length, return false.
   VISITED is a bitmap of visited variables.
   RKIND determines the kind of value or range to obtain (see
   strlen_range_kind).
   Set PDATA->DECL if ARG refers to an unterminated constant array.
   On input, set ELTSIZE to 1 for normal single byte character strings,
   and either 2 or 4 for wide characer strings (the size of wchar_t).
   Return true if *PDATA was successfully populated and false otherwise.  */

static bool
get_range_strlen (tree arg, bitmap *visited,
		  strlen_range_kind rkind,
		  c_strlen_data *pdata, unsigned eltsize)
{

  if (TREE_CODE (arg) != SSA_NAME)
    return get_range_strlen_tree (arg, visited, rkind, pdata, eltsize);

  /* If ARG is registered for SSA update we cannot look at its defining
     statement.  */
  if (name_registered_for_update_p (arg))
    return false;

  /* If we were already here, break the infinite cycle.  */
  if (!*visited)
    *visited = BITMAP_ALLOC (NULL);
  if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (arg)))
    return true;

  tree var = arg;
  gimple *def_stmt = SSA_NAME_DEF_STMT (var);

  switch (gimple_code (def_stmt))
    {
      case GIMPLE_ASSIGN:
	/* The RHS of the statement defining VAR must either have a
	   constant length or come from another SSA_NAME with a constant
	   length.  */
        if (gimple_assign_single_p (def_stmt)
            || gimple_assign_unary_nop_p (def_stmt))
          {
	    tree rhs = gimple_assign_rhs1 (def_stmt);
	    return get_range_strlen (rhs, visited, rkind, pdata, eltsize);
          }
	else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR)
	  {
	    tree ops[2] = { gimple_assign_rhs2 (def_stmt),
			    gimple_assign_rhs3 (def_stmt) };

	    for (unsigned int i = 0; i < 2; i++)
	      if (!get_range_strlen (ops[i], visited, rkind, pdata, eltsize))
		{
		  if (rkind != SRK_LENRANGE)
		    return false;
		  /* Set the upper bound to the maximum to prevent
		     it from being adjusted in the next iteration but
		     leave MINLEN and the more conservative MAXBOUND
		     determined so far alone (or leave them null if
		     they haven't been set yet).  That the MINLEN is
		     in fact zero can be determined from MAXLEN being
		     unbounded but the discovered minimum is used for
		     diagnostics.  */
		  pdata->maxlen = build_all_ones_cst (size_type_node);
		}
	    return true;
	  }
        return false;

      case GIMPLE_PHI:
	/* Unless RKIND == SRK_LENRANGE, all arguments of the PHI node
	   must have a constant length.  */
	for (unsigned i = 0; i < gimple_phi_num_args (def_stmt); i++)
          {
            tree arg = gimple_phi_arg (def_stmt, i)->def;

            /* If this PHI has itself as an argument, we cannot
               determine the string length of this argument.  However,
               if we can find a constant string length for the other
               PHI args then we can still be sure that this is a
               constant string length.  So be optimistic and just
               continue with the next argument.  */
            if (arg == gimple_phi_result (def_stmt))
              continue;

	    if (!get_range_strlen (arg, visited, rkind, pdata, eltsize))
	      {
		if (rkind != SRK_LENRANGE)
		  return false;
		/* Set the upper bound to the maximum to prevent
		   it from being adjusted in the next iteration but
		   leave MINLEN and the more conservative MAXBOUND
		   determined so far alone (or leave them null if
		   they haven't been set yet).  That the MINLEN is
		   in fact zero can be determined from MAXLEN being
		   unbounded but the discovered minimum is used for
		   diagnostics.  */
		pdata->maxlen = build_all_ones_cst (size_type_node);
	      }
          }
        return true;

      default:
        return false;
    }
}

/* Try to obtain the range of the lengths of the string(s) referenced
   by ARG, or the size of the largest array ARG refers to if the range
   of lengths cannot be determined, and store all in *PDATA which must
   be zero-initialized on input except PDATA->MAXBOUND may be set to
   a non-null tree node other than INTEGER_CST to request to have it
   set to the length of the longest string in a PHI.  ELTSIZE is
   the expected size of the string element in bytes: 1 for char and
   some power of 2 for wide characters.
   Return true if the range [PDATA->MINLEN, PDATA->MAXLEN] is suitable
   for optimization.  Returning false means that a nonzero PDATA->MINLEN
   doesn't reflect the true lower bound of the range when PDATA->MAXLEN
   is -1 (in that case, the actual range is indeterminate, i.e.,
   [0, PTRDIFF_MAX - 2].  */

bool
get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize)
{
  bitmap visited = NULL;
  tree maxbound = pdata->maxbound;

  if (!get_range_strlen (arg, &visited, SRK_LENRANGE, pdata, eltsize))
    {
      /* On failure extend the length range to an impossible maximum
	 (a valid MAXLEN must be less than PTRDIFF_MAX - 1).  Other
	 members can stay unchanged regardless.  */
      pdata->minlen = ssize_int (0);
      pdata->maxlen = build_all_ones_cst (size_type_node);
    }
  else if (!pdata->minlen)
    pdata->minlen = ssize_int (0);

  /* If it's unchanged from it initial non-null value, set the conservative
     MAXBOUND to SIZE_MAX.  Otherwise leave it null (if it is null).  */
  if (maxbound && pdata->maxbound == maxbound)
    pdata->maxbound = build_all_ones_cst (size_type_node);

  if (visited)
    BITMAP_FREE (visited);

  return !integer_all_onesp (pdata->maxlen);
}

/* Return the maximum value for ARG given RKIND (see strlen_range_kind).
   For ARG of pointer types, NONSTR indicates if the caller is prepared
   to handle unterminated strings.   For integer ARG and when RKIND ==
   SRK_INT_VALUE, NONSTR must be null.

   If an unterminated array is discovered and our caller handles
   unterminated arrays, then bubble up the offending DECL and
   return the maximum size.  Otherwise return NULL.  */

static tree
get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL)
{
  /* A non-null NONSTR is meaningless when determining the maximum
     value of an integer ARG.  */
  gcc_assert (rkind != SRK_INT_VALUE || nonstr == NULL);
  /* ARG must have an integral type when RKIND says so.  */
  gcc_assert (rkind != SRK_INT_VALUE || INTEGRAL_TYPE_P (TREE_TYPE (arg)));

  bitmap visited = NULL;

  /* Reset DATA.MAXLEN if the call fails or when DATA.MAXLEN
     is unbounded.  */
  c_strlen_data lendata = { };
  if (!get_range_strlen (arg, &visited, rkind, &lendata, /* eltsize = */1))
    lendata.maxlen = NULL_TREE;
  else if (lendata.maxlen && integer_all_onesp (lendata.maxlen))
    lendata.maxlen = NULL_TREE;

  if (visited)
    BITMAP_FREE (visited);

  if (nonstr)
    {
      /* For callers prepared to handle unterminated arrays set
	 *NONSTR to point to the declaration of the array and return
	 the maximum length/size. */
      *nonstr = lendata.decl;
      return lendata.maxlen;
    }

  /* Fail if the constant array isn't nul-terminated.  */
  return lendata.decl ? NULL_TREE : lendata.maxlen;
}


/* Fold function call to builtin strcpy with arguments DEST and SRC.
   If LEN is not NULL, it represents the length of the string to be
   copied.  Return NULL_TREE if no simplification can be made.  */

static bool
gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
			    tree dest, tree src)
{
  gimple *stmt = gsi_stmt (*gsi);
  location_t loc = gimple_location (stmt);
  tree fn;

  /* If SRC and DEST are the same (and not volatile), return DEST.  */
  if (operand_equal_p (src, dest, 0))
    {
      /* Issue -Wrestrict unless the pointers are null (those do
	 not point to objects and so do not indicate an overlap;
	 such calls could be the result of sanitization and jump
	 threading).  */
      if (!integer_zerop (dest) && !warning_suppressed_p (stmt, OPT_Wrestrict))
	{
	  tree func = gimple_call_fndecl (stmt);

	  warning_at (loc, OPT_Wrestrict,
		      "%qD source argument is the same as destination",
		      func);
	}

      replace_call_with_value (gsi, dest);
      return true;
    }

  if (optimize_function_for_size_p (cfun))
    return false;

  fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
  if (!fn)
    return false;

  /* Set to non-null if ARG refers to an unterminated array.  */
  tree nonstr = NULL;
  tree len = get_maxval_strlen (src, SRK_STRLEN, &nonstr);

  if (nonstr)
    {
      /* Avoid folding calls with unterminated arrays.  */
      if (!warning_suppressed_p (stmt, OPT_Wstringop_overread))
	warn_string_no_nul (loc, stmt, "strcpy", src, nonstr);
      suppress_warning (stmt, OPT_Wstringop_overread);
      return false;
    }

  if (!len)
    return false;

  len = fold_convert_loc (loc, size_type_node, len);
  len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
  len = force_gimple_operand_gsi (gsi, len, true,
				  NULL_TREE, true, GSI_SAME_STMT);
  gimple *repl = gimple_build_call (fn, 3, dest, src, len);
  replace_call_with_call_and_fold (gsi, repl);
  return true;
}

/* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
   If SLEN is not NULL, it represents the length of the source string.
   Return NULL_TREE if no simplification can be made.  */

static bool
gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
			     tree dest, tree src, tree len)
{
  gimple *stmt = gsi_stmt (*gsi);
  location_t loc = gimple_location (stmt);
  bool nonstring = get_attr_nonstring_decl (dest) != NULL_TREE;

  /* If the LEN parameter is zero, return DEST.  */
  if (integer_zerop (len))
    {
      /* Avoid warning if the destination refers to an array/pointer
	 decorate with attribute nonstring.  */
      if (!nonstring)
	{
	  tree fndecl = gimple_call_fndecl (stmt);

	  /* Warn about the lack of nul termination: the result is not
	     a (nul-terminated) string.  */
	  tree slen = get_maxval_strlen (src, SRK_STRLEN);
	  if (slen && !integer_zerop (slen))
	    warning_at (loc, OPT_Wstringop_truncation,
			"%qD destination unchanged after copying no bytes "
			"from a string of length %E",
			fndecl, slen);
	  else
	    warning_at (loc, OPT_Wstringop_truncation,
			"%qD destination unchanged after copying no bytes",
			fndecl);
	}

      replace_call_with_value (gsi, dest);
      return true;
    }

  /* We can't compare slen with len as constants below if len is not a
     constant.  */
  if (TREE_CODE (len) != INTEGER_CST)
    return false;

  /* Now, we must be passed a constant src ptr parameter.  */
  tree slen = get_maxval_strlen (src, SRK_STRLEN);
  if (!slen || TREE_CODE (slen) != INTEGER_CST)
    return false;

  /* The size of the source string including the terminating nul.  */
  tree ssize = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));

  /* We do not support simplification of this case, though we do
     support it when expanding trees into RTL.  */
  /* FIXME: generate a call to __builtin_memset.  */
  if (tree_int_cst_lt (ssize, len))
    return false;

  /* Diagnose truncation that leaves the copy unterminated.  */
  maybe_diag_stxncpy_trunc (*gsi, src, len);

  /* OK transform into builtin memcpy.  */
  tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
  if (!fn)
    return false;

  len = fold_convert_loc (loc, size_type_node, len);
  len = force_gimple_operand_gsi (gsi, len, true,
				  NULL_TREE, true, GSI_SAME_STMT);
  gimple *repl = gimple_build_call (fn, 3, dest, src, len);
  replace_call_with_call_and_fold (gsi, repl);

  return true;
}

/* Fold function call to builtin strchr or strrchr.
   If both arguments are constant, evaluate and fold the result,
   otherwise simplify str(r)chr (str, 0) into str + strlen (str).
   In general strlen is significantly faster than strchr
   due to being a simpler operation.  */
static bool
gimple_fold_builtin_strchr (gimple_stmt_iterator *gsi, bool is_strrchr)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree str = gimple_call_arg (stmt, 0);
  tree c = gimple_call_arg (stmt, 1);
  location_t loc = gimple_location (stmt);
  const char *p;
  char ch;

  if (!gimple_call_lhs (stmt))
    return false;

  /* Avoid folding if the first argument is not a nul-terminated array.
     Defer warning until later.  */
  if (!check_nul_terminated_array (NULL_TREE, str))
    return false;

  if ((p = c_getstr (str)) && target_char_cst_p (c, &ch))
    {
      const char *p1 = is_strrchr ? strrchr (p, ch) : strchr (p, ch);

      if (p1 == NULL)
	{
	  replace_call_with_value (gsi, integer_zero_node);
	  return true;
	}

      tree len = build_int_cst (size_type_node, p1 - p);
      gimple_seq stmts = NULL;
      gimple *new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
					      POINTER_PLUS_EXPR, str, len);
      gimple_seq_add_stmt_without_update (&stmts, new_stmt);
      gsi_replace_with_seq_vops (gsi, stmts);
      return true;
    }

  if (!integer_zerop (c))
    return false;

  /* Transform strrchr (s, 0) to strchr (s, 0) when optimizing for size.  */
  if (is_strrchr && optimize_function_for_size_p (cfun))
    {
      tree strchr_fn = builtin_decl_implicit (BUILT_IN_STRCHR);

      if (strchr_fn)
	{
	  gimple *repl = gimple_build_call (strchr_fn, 2, str, c);
	  replace_call_with_call_and_fold (gsi, repl);
	  return true;
	}

      return false;
    }

  tree len;
  tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);

  if (!strlen_fn)
    return false;

  /* Create newstr = strlen (str).  */
  gimple_seq stmts = NULL;
  gimple *new_stmt = gimple_build_call (strlen_fn, 1, str);
  gimple_set_location (new_stmt, loc);
  len = create_tmp_reg_or_ssa_name (size_type_node);
  gimple_call_set_lhs (new_stmt, len);
  gimple_seq_add_stmt_without_update (&stmts, new_stmt);

  /* Create (str p+ strlen (str)).  */
  new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
				  POINTER_PLUS_EXPR, str, len);
  gimple_seq_add_stmt_without_update (&stmts, new_stmt);
  gsi_replace_with_seq_vops (gsi, stmts);
  /* gsi now points at the assignment to the lhs, get a
     stmt iterator to the strlen.
     ???  We can't use gsi_for_stmt as that doesn't work when the
     CFG isn't built yet.  */
  gimple_stmt_iterator gsi2 = *gsi;
  gsi_prev (&gsi2);
  fold_stmt (&gsi2);
  return true;
}

/* Fold function call to builtin strstr.
   If both arguments are constant, evaluate and fold the result,
   additionally fold strstr (x, "") into x and strstr (x, "c")
   into strchr (x, 'c').  */
static bool
gimple_fold_builtin_strstr (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  if (!gimple_call_lhs (stmt))
    return false;

  tree haystack = gimple_call_arg (stmt, 0);
  tree needle = gimple_call_arg (stmt, 1);

  /* Avoid folding if either argument is not a nul-terminated array.
     Defer warning until later.  */
  if (!check_nul_terminated_array (NULL_TREE, haystack)
      || !check_nul_terminated_array (NULL_TREE, needle))
    return false;

  const char *q = c_getstr (needle);
  if (q == NULL)
    return false;

  if (const char *p = c_getstr (haystack))
    {
      const char *r = strstr (p, q);

      if (r == NULL)
	{
	  replace_call_with_value (gsi, integer_zero_node);
	  return true;
	}

      tree len = build_int_cst (size_type_node, r - p);
      gimple_seq stmts = NULL;
      gimple *new_stmt
	= gimple_build_assign (gimple_call_lhs (stmt), POINTER_PLUS_EXPR,
			       haystack, len);
      gimple_seq_add_stmt_without_update (&stmts, new_stmt);
      gsi_replace_with_seq_vops (gsi, stmts);
      return true;
    }

  /* For strstr (x, "") return x.  */
  if (q[0] == '\0')
    {
      replace_call_with_value (gsi, haystack);
      return true;
    }

  /* Transform strstr (x, "c") into strchr (x, 'c').  */
  if (q[1] == '\0')
    {
      tree strchr_fn = builtin_decl_implicit (BUILT_IN_STRCHR);
      if (strchr_fn)
	{
	  tree c = build_int_cst (integer_type_node, q[0]);
	  gimple *repl = gimple_build_call (strchr_fn, 2, haystack, c);
	  replace_call_with_call_and_fold (gsi, repl);
	  return true;
	}
    }

  return false;
}

/* Simplify a call to the strcat builtin.  DST and SRC are the arguments
   to the call.

   Return NULL_TREE if no simplification was possible, otherwise return the
   simplified form of the call as a tree.

   The simplified form may be a constant or other expression which
   computes the same value, but in a more efficient manner (including
   calls to other builtin functions).

   The call may contain arguments which need to be evaluated, but
   which are not useful to determine the result of the call.  In
   this case we return a chain of COMPOUND_EXPRs.  The LHS of each
   COMPOUND_EXPR will be an argument which must be evaluated.
   COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
   COMPOUND_EXPR in the chain will contain the tree for the simplified
   form of the builtin function call.  */

static bool
gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, tree dst, tree src)
{
  gimple *stmt = gsi_stmt (*gsi);
  location_t loc = gimple_location (stmt);

  const char *p = c_getstr (src);

  /* If the string length is zero, return the dst parameter.  */
  if (p && *p == '\0')
    {
      replace_call_with_value (gsi, dst);
      return true;
    }

  if (!optimize_bb_for_speed_p (gimple_bb (stmt)))
    return false;

  /* See if we can store by pieces into (dst + strlen(dst)).  */
  tree newdst;
  tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
  tree memcpy_fn = builtin_decl_implicit (BUILT_IN_MEMCPY);

  if (!strlen_fn || !memcpy_fn)
    return false;

  /* If the length of the source string isn't computable don't
     split strcat into strlen and memcpy.  */
  tree len = get_maxval_strlen (src, SRK_STRLEN);
  if (! len)
    return false;

  /* Create strlen (dst).  */
  gimple_seq stmts = NULL, stmts2;
  gimple *repl = gimple_build_call (strlen_fn, 1, dst);
  gimple_set_location (repl, loc);
  newdst = create_tmp_reg_or_ssa_name (size_type_node);
  gimple_call_set_lhs (repl, newdst);
  gimple_seq_add_stmt_without_update (&stmts, repl);

  /* Create (dst p+ strlen (dst)).  */
  newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
  newdst = force_gimple_operand (newdst, &stmts2, true, NULL_TREE);
  gimple_seq_add_seq_without_update (&stmts, stmts2);

  len = fold_convert_loc (loc, size_type_node, len);
  len = size_binop_loc (loc, PLUS_EXPR, len,
			build_int_cst (size_type_node, 1));
  len = force_gimple_operand (len, &stmts2, true, NULL_TREE);
  gimple_seq_add_seq_without_update (&stmts, stmts2);

  repl = gimple_build_call (memcpy_fn, 3, newdst, src, len);
  gimple_seq_add_stmt_without_update (&stmts, repl);
  if (gimple_call_lhs (stmt))
    {
      repl = gimple_build_assign (gimple_call_lhs (stmt), dst);
      gimple_seq_add_stmt_without_update (&stmts, repl);
      gsi_replace_with_seq_vops (gsi, stmts);
      /* gsi now points at the assignment to the lhs, get a
         stmt iterator to the memcpy call.
	 ???  We can't use gsi_for_stmt as that doesn't work when the
	 CFG isn't built yet.  */
      gimple_stmt_iterator gsi2 = *gsi;
      gsi_prev (&gsi2);
      fold_stmt (&gsi2);
    }
  else
    {
      gsi_replace_with_seq_vops (gsi, stmts);
      fold_stmt (gsi);
    }
  return true;
}

/* Fold a call to the __strcat_chk builtin FNDECL.  DEST, SRC, and SIZE
   are the arguments to the call.  */

static bool
gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree dest = gimple_call_arg (stmt, 0);
  tree src = gimple_call_arg (stmt, 1);
  tree size = gimple_call_arg (stmt, 2);
  tree fn;
  const char *p;


  p = c_getstr (src);
  /* If the SRC parameter is "", return DEST.  */
  if (p && *p == '\0')
    {
      replace_call_with_value (gsi, dest);
      return true;
    }

  if (! tree_fits_uhwi_p (size) || ! integer_all_onesp (size))
    return false;

  /* If __builtin_strcat_chk is used, assume strcat is available.  */
  fn = builtin_decl_explicit (BUILT_IN_STRCAT);
  if (!fn)
    return false;

  gimple *repl = gimple_build_call (fn, 2, dest, src);
  replace_call_with_call_and_fold (gsi, repl);
  return true;
}

/* Simplify a call to the strncat builtin.  */

static bool
gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree dst = gimple_call_arg (stmt, 0);
  tree src = gimple_call_arg (stmt, 1);
  tree len = gimple_call_arg (stmt, 2);

  const char *p = c_getstr (src);

  /* If the requested length is zero, or the src parameter string
     length is zero, return the dst parameter.  */
  if (integer_zerop (len) || (p && *p == '\0'))
    {
      replace_call_with_value (gsi, dst);
      return true;
    }

  if (TREE_CODE (len) != INTEGER_CST || !p)
    return false;

  unsigned srclen = strlen (p);

  int cmpsrc = compare_tree_int (len, srclen);

  /* Return early if the requested len is less than the string length.
     Warnings will be issued elsewhere later.  */
  if (cmpsrc < 0)
    return false;

  unsigned HOST_WIDE_INT dstsize;

  bool nowarn = warning_suppressed_p (stmt, OPT_Wstringop_overflow_);

  if (!nowarn && compute_builtin_object_size (dst, 1, &dstsize))
    {
      int cmpdst = compare_tree_int (len, dstsize);

      if (cmpdst >= 0)
	{
	  tree fndecl = gimple_call_fndecl (stmt);

	  /* Strncat copies (at most) LEN bytes and always appends
	     the terminating NUL so the specified bound should never
	     be equal to (or greater than) the size of the destination.
	     If it is, the copy could overflow.  */
	  location_t loc = gimple_location (stmt);
	  nowarn = warning_at (loc, OPT_Wstringop_overflow_,
			       cmpdst == 0
			       ? G_("%qD specified bound %E equals "
				    "destination size")
			       : G_("%qD specified bound %E exceeds "
				    "destination size %wu"),
			       fndecl, len, dstsize);
	  if (nowarn)
	    suppress_warning (stmt, OPT_Wstringop_overflow_);
	}
    }

  if (!nowarn && cmpsrc == 0)
    {
      tree fndecl = gimple_call_fndecl (stmt);
      location_t loc = gimple_location (stmt);

      /* To avoid possible overflow the specified bound should also
	 not be equal to the length of the source, even when the size
	 of the destination is unknown (it's not an uncommon mistake
	 to specify as the bound to strncpy the length of the source).  */
      if (warning_at (loc, OPT_Wstringop_overflow_,
		      "%qD specified bound %E equals source length",
		      fndecl, len))
	suppress_warning (stmt, OPT_Wstringop_overflow_);
    }

  tree fn = builtin_decl_implicit (BUILT_IN_STRCAT);

  /* If the replacement _DECL isn't initialized, don't do the
     transformation.  */
  if (!fn)
    return false;

  /* Otherwise, emit a call to strcat.  */
  gcall *repl = gimple_build_call (fn, 2, dst, src);
  replace_call_with_call_and_fold (gsi, repl);
  return true;
}

/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
   LEN, and SIZE.  */

static bool 
gimple_fold_builtin_strncat_chk (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree dest = gimple_call_arg (stmt, 0);
  tree src = gimple_call_arg (stmt, 1);
  tree len = gimple_call_arg (stmt, 2);
  tree size = gimple_call_arg (stmt, 3);
  tree fn;
  const char *p;

  p = c_getstr (src);
  /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
  if ((p && *p == '\0')
      || integer_zerop (len))
    {
      replace_call_with_value (gsi, dest);
      return true;
    }

  if (! tree_fits_uhwi_p (size))
    return false;

  if (! integer_all_onesp (size))
    {
      tree src_len = c_strlen (src, 1);
      if (src_len
	  && tree_fits_uhwi_p (src_len)
	  && tree_fits_uhwi_p (len)
	  && ! tree_int_cst_lt (len, src_len))
	{
	  /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
	  fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
	  if (!fn)
	    return false;

	  gimple *repl = gimple_build_call (fn, 3, dest, src, size);
	  replace_call_with_call_and_fold (gsi, repl);
	  return true;
	}
      return false;
    }

  /* If __builtin_strncat_chk is used, assume strncat is available.  */
  fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
  if (!fn)
    return false;

  gimple *repl = gimple_build_call (fn, 3, dest, src, len);
  replace_call_with_call_and_fold (gsi, repl);
  return true;
}

/* Build and append gimple statements to STMTS that would load a first
   character of a memory location identified by STR.  LOC is location
   of the statement.  */

static tree
gimple_load_first_char (location_t loc, tree str, gimple_seq *stmts)
{
  tree var;

  tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
  tree cst_uchar_ptr_node
    = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
  tree off0 = build_int_cst (cst_uchar_ptr_node, 0);

  tree temp = fold_build2_loc (loc, MEM_REF, cst_uchar_node, str, off0);
  gassign *stmt = gimple_build_assign (NULL_TREE, temp);
  var = create_tmp_reg_or_ssa_name (cst_uchar_node, stmt);

  gimple_assign_set_lhs (stmt, var);
  gimple_seq_add_stmt_without_update (stmts, stmt);

  return var;
}

/* Fold a call to the str{n}{case}cmp builtin pointed by GSI iterator.  */

static bool
gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree callee = gimple_call_fndecl (stmt);
  enum built_in_function fcode = DECL_FUNCTION_CODE (callee);

  tree type = integer_type_node;
  tree str1 = gimple_call_arg (stmt, 0);
  tree str2 = gimple_call_arg (stmt, 1);
  tree lhs = gimple_call_lhs (stmt);

  tree bound_node = NULL_TREE;
  unsigned HOST_WIDE_INT bound = HOST_WIDE_INT_M1U;

  /* Handle strncmp and strncasecmp functions.  */
  if (gimple_call_num_args (stmt) == 3)
    {
      bound_node = gimple_call_arg (stmt, 2);
      if (tree_fits_uhwi_p (bound_node))
	bound = tree_to_uhwi (bound_node);
    }

  /* If the BOUND parameter is zero, return zero.  */
  if (bound == 0)
    {
      replace_call_with_value (gsi, integer_zero_node);
      return true;
    }

  /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
  if (operand_equal_p (str1, str2, 0))
    {
      replace_call_with_value (gsi, integer_zero_node);
      return true;
    }

  /* Initially set to the number of characters, including the terminating
     nul if each array has one.   LENx == strnlen (Sx, LENx) implies that
     the array Sx is not terminated by a nul.
     For nul-terminated strings then adjusted to their length so that
     LENx == NULPOSx holds.  */
  unsigned HOST_WIDE_INT len1 = HOST_WIDE_INT_MAX, len2 = len1;
  const char *p1 = getbyterep (str1, &len1);
  const char *p2 = getbyterep (str2, &len2);

  /* The position of the terminating nul character if one exists, otherwise
     a value greater than LENx.  */
  unsigned HOST_WIDE_INT nulpos1 = HOST_WIDE_INT_MAX, nulpos2 = nulpos1;

  if (p1)
    {
      size_t n = strnlen (p1, len1);
      if (n < len1)
	len1 = nulpos1 = n;
    }

  if (p2)
    {
      size_t n = strnlen (p2, len2);
      if (n < len2)
	len2 = nulpos2 = n;
    }

  /* For known strings, return an immediate value.  */
  if (p1 && p2)
    {
      int r = 0;
      bool known_result = false;

      switch (fcode)
	{
	case BUILT_IN_STRCMP:
	case BUILT_IN_STRCMP_EQ:
	  if (len1 != nulpos1 || len2 != nulpos2)
	    break;

	  r = strcmp (p1, p2);
	  known_result = true;
	  break;

	case BUILT_IN_STRNCMP:
	case BUILT_IN_STRNCMP_EQ:
	  {
	    if (bound == HOST_WIDE_INT_M1U)
	      break;

	    /* Reduce the bound to be no more than the length
	       of the shorter of the two strings, or the sizes
	       of the unterminated arrays.  */
	    unsigned HOST_WIDE_INT n = bound;

	    if (len1 == nulpos1 && len1 < n)
	      n = len1 + 1;
	    if (len2 == nulpos2 && len2 < n)
	      n = len2 + 1;

	    if (MIN (nulpos1, nulpos2) + 1 < n)
	      break;

	    r = strncmp (p1, p2, n);
	    known_result = true;
	    break;
	  }
	/* Only handleable situation is where the string are equal (result 0),
	   which is already handled by operand_equal_p case.  */
	case BUILT_IN_STRCASECMP:
	  break;
	case BUILT_IN_STRNCASECMP:
	  {
	    if (bound == HOST_WIDE_INT_M1U)
	      break;
	    r = strncmp (p1, p2, bound);
	    if (r == 0)
	      known_result = true;
	    break;
	  }
	default:
	  gcc_unreachable ();
	}

      if (known_result)
	{
	  replace_call_with_value (gsi, build_cmp_result (type, r));
	  return true;
	}
    }

  bool nonzero_bound = (bound >= 1 && bound < HOST_WIDE_INT_M1U)
    || fcode == BUILT_IN_STRCMP
    || fcode == BUILT_IN_STRCMP_EQ
    || fcode == BUILT_IN_STRCASECMP;

  location_t loc = gimple_location (stmt);

  /* If the second arg is "", return *(const unsigned char*)arg1.  */
  if (p2 && *p2 == '\0' && nonzero_bound)
    {
      gimple_seq stmts = NULL;
      tree var = gimple_load_first_char (loc, str1, &stmts);
      if (lhs)
	{
	  stmt = gimple_build_assign (lhs, NOP_EXPR, var);
	  gimple_seq_add_stmt_without_update (&stmts, stmt);
	}

      gsi_replace_with_seq_vops (gsi, stmts);
      return true;
    }

  /* If the first arg is "", return -*(const unsigned char*)arg2.  */
  if (p1 && *p1 == '\0' && nonzero_bound)
    {
      gimple_seq stmts = NULL;
      tree var = gimple_load_first_char (loc, str2, &stmts);

      if (lhs)
	{
	  tree c = create_tmp_reg_or_ssa_name (integer_type_node);
	  stmt = gimple_build_assign (c, NOP_EXPR, var);
	  gimple_seq_add_stmt_without_update (&stmts, stmt);

	  stmt = gimple_build_assign (lhs, NEGATE_EXPR, c);
	  gimple_seq_add_stmt_without_update (&stmts, stmt);
	}

      gsi_replace_with_seq_vops (gsi, stmts);
      return true;
    }

  /* If BOUND is one, return an expression corresponding to
     (*(const unsigned char*)arg2 - *(const unsigned char*)arg1).  */
  if (fcode == BUILT_IN_STRNCMP && bound == 1)
    {
      gimple_seq stmts = NULL;
      tree temp1 = gimple_load_first_char (loc, str1, &stmts);
      tree temp2 = gimple_load_first_char (loc, str2, &stmts);

      if (lhs)
	{
	  tree c1 = create_tmp_reg_or_ssa_name (integer_type_node);
	  gassign *convert1 = gimple_build_assign (c1, NOP_EXPR, temp1);
	  gimple_seq_add_stmt_without_update (&stmts, convert1);

	  tree c2 = create_tmp_reg_or_ssa_name (integer_type_node);
	  gassign *convert2 = gimple_build_assign (c2, NOP_EXPR, temp2);
	  gimple_seq_add_stmt_without_update (&stmts, convert2);

	  stmt = gimple_build_assign (lhs, MINUS_EXPR, c1, c2);
	  gimple_seq_add_stmt_without_update (&stmts, stmt);
	}

      gsi_replace_with_seq_vops (gsi, stmts);
      return true;
    }

  /* If BOUND is greater than the length of one constant string,
     and the other argument is also a nul-terminated string, replace
     strncmp with strcmp.  */
  if (fcode == BUILT_IN_STRNCMP
      && bound > 0 && bound < HOST_WIDE_INT_M1U
      && ((p2 && len2 < bound && len2 == nulpos2)
	  || (p1 && len1 < bound && len1 == nulpos1)))
    {
      tree fn = builtin_decl_implicit (BUILT_IN_STRCMP);
      if (!fn)
        return false;
      gimple *repl = gimple_build_call (fn, 2, str1, str2);
      replace_call_with_call_and_fold (gsi, repl);
      return true;
    }

  return false;
}

/* Fold a call to the memchr pointed by GSI iterator.  */

static bool
gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_call_lhs (stmt);
  tree arg1 = gimple_call_arg (stmt, 0);
  tree arg2 = gimple_call_arg (stmt, 1);
  tree len = gimple_call_arg (stmt, 2);

  /* If the LEN parameter is zero, return zero.  */
  if (integer_zerop (len))
    {
      replace_call_with_value (gsi, build_int_cst (ptr_type_node, 0));
      return true;
    }

  char c;
  if (TREE_CODE (arg2) != INTEGER_CST
      || !tree_fits_uhwi_p (len)
      || !target_char_cst_p (arg2, &c))
    return false;

  unsigned HOST_WIDE_INT length = tree_to_uhwi (len);
  unsigned HOST_WIDE_INT string_length;
  const char *p1 = getbyterep (arg1, &string_length);

  if (p1)
    {
      const char *r = (const char *)memchr (p1, c, MIN (length, string_length));
      if (r == NULL)
	{
	  tree mem_size, offset_node;
	  byte_representation (arg1, &offset_node, &mem_size, NULL);
	  unsigned HOST_WIDE_INT offset = (offset_node == NULL_TREE)
					  ? 0 : tree_to_uhwi (offset_node);
	  /* MEM_SIZE is the size of the array the string literal
	     is stored in.  */
	  unsigned HOST_WIDE_INT string_size = tree_to_uhwi (mem_size) - offset;
	  gcc_checking_assert (string_length <= string_size);
	  if (length <= string_size)
	    {
	      replace_call_with_value (gsi, build_int_cst (ptr_type_node, 0));
	      return true;
	    }
	}
      else
	{
	  unsigned HOST_WIDE_INT offset = r - p1;
	  gimple_seq stmts = NULL;
	  if (lhs != NULL_TREE)
	    {
	      tree offset_cst = build_int_cst (sizetype, offset);
	      gassign *stmt = gimple_build_assign (lhs, POINTER_PLUS_EXPR,
						   arg1, offset_cst);
	      gimple_seq_add_stmt_without_update (&stmts, stmt);
	    }
	  else
	    gimple_seq_add_stmt_without_update (&stmts,
						gimple_build_nop ());

	  gsi_replace_with_seq_vops (gsi, stmts);
	  return true;
	}
    }

  return false;
}

/* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
   to the call.  IGNORE is true if the value returned
   by the builtin will be ignored.  UNLOCKED is true is true if this
   actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
   the known length of the string.  Return NULL_TREE if no simplification
   was possible.  */

static bool
gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
			   tree arg0, tree arg1,
			   bool unlocked)
{
  gimple *stmt = gsi_stmt (*gsi);

  /* If we're using an unlocked function, assume the other unlocked
     functions exist explicitly.  */
  tree const fn_fputc = (unlocked
			 ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
			 : builtin_decl_implicit (BUILT_IN_FPUTC));
  tree const fn_fwrite = (unlocked
			  ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
			  : builtin_decl_implicit (BUILT_IN_FWRITE));

  /* If the return value is used, don't do the transformation.  */
  if (gimple_call_lhs (stmt))
    return false;

  /* Get the length of the string passed to fputs.  If the length
     can't be determined, punt.  */
  tree len = get_maxval_strlen (arg0, SRK_STRLEN);
  if (!len
      || TREE_CODE (len) != INTEGER_CST)
    return false;

  switch (compare_tree_int (len, 1))
    {
    case -1: /* length is 0, delete the call entirely .  */
      replace_call_with_value (gsi, integer_zero_node);
      return true;

    case 0: /* length is 1, call fputc.  */
      {
	const char *p = c_getstr (arg0);
	if (p != NULL)
	  {
	    if (!fn_fputc)
	      return false;

	    gimple *repl = gimple_build_call (fn_fputc, 2,
					     build_int_cst
					     (integer_type_node, p[0]), arg1);
	    replace_call_with_call_and_fold (gsi, repl);
	    return true;
	  }
      }
      /* FALLTHROUGH */
    case 1: /* length is greater than 1, call fwrite.  */
      {
	/* If optimizing for size keep fputs.  */
	if (optimize_function_for_size_p (cfun))
	  return false;
	/* New argument list transforming fputs(string, stream) to
	   fwrite(string, 1, len, stream).  */
	if (!fn_fwrite)
	  return false;

	gimple *repl = gimple_build_call (fn_fwrite, 4, arg0,
					 size_one_node, len, arg1);
	replace_call_with_call_and_fold (gsi, repl);
	return true;
      }
    default:
      gcc_unreachable ();
    }
  return false;
}

/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
   DEST, SRC, LEN, and SIZE are the arguments to the call.
   IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
   code of the builtin.  If MAXLEN is not NULL, it is maximum length
   passed as third argument.  */

static bool
gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
				tree dest, tree src, tree len, tree size,
				enum built_in_function fcode)
{
  gimple *stmt = gsi_stmt (*gsi);
  location_t loc = gimple_location (stmt);
  bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
  tree fn;

  /* If SRC and DEST are the same (and not volatile), return DEST
     (resp. DEST+LEN for __mempcpy_chk).  */
  if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
    {
      if (fcode != BUILT_IN_MEMPCPY_CHK)
	{
	  replace_call_with_value (gsi, dest);
	  return true;
	}
      else
	{
	  gimple_seq stmts = NULL;
	  len = gimple_convert_to_ptrofftype (&stmts, loc, len);
	  tree temp = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
				    TREE_TYPE (dest), dest, len);
	  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
	  replace_call_with_value (gsi, temp);
	  return true;
	}
    }

  if (! tree_fits_uhwi_p (size))
    return false;

  tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
  if (! integer_all_onesp (size))
    {
      if (! tree_fits_uhwi_p (len))
	{
	  /* If LEN is not constant, try MAXLEN too.
	     For MAXLEN only allow optimizing into non-_ocs function
	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
	  if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
	    {
	      if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
		{
		  /* (void) __mempcpy_chk () can be optimized into
		     (void) __memcpy_chk ().  */
		  fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
		  if (!fn)
		    return false;

		  gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
		  replace_call_with_call_and_fold (gsi, repl);
		  return true;
		}
	      return false;
	    }
	}
      else
	maxlen = len;

      if (tree_int_cst_lt (size, maxlen))
	return false;
    }

  fn = NULL_TREE;
  /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
     mem{cpy,pcpy,move,set} is available.  */
  switch (fcode)
    {
    case BUILT_IN_MEMCPY_CHK:
      fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
      break;
    case BUILT_IN_MEMPCPY_CHK:
      fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
      break;
    case BUILT_IN_MEMMOVE_CHK:
      fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
      break;
    case BUILT_IN_MEMSET_CHK:
      fn = builtin_decl_explicit (BUILT_IN_MEMSET);
      break;
    default:
      break;
    }

  if (!fn)
    return false;

  gimple *repl = gimple_build_call (fn, 3, dest, src, len);
  replace_call_with_call_and_fold (gsi, repl);
  return true;
}

/* Fold a call to the __st[rp]cpy_chk builtin.
   DEST, SRC, and SIZE are the arguments to the call.
   IGNORE is true if return value can be ignored.  FCODE is the BUILT_IN_*
   code of the builtin.  If MAXLEN is not NULL, it is maximum length of
   strings passed as second argument.  */

static bool
gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
				tree dest,
				tree src, tree size,
				enum built_in_function fcode)
{
  gimple *stmt = gsi_stmt (*gsi);
  location_t loc = gimple_location (stmt);
  bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
  tree len, fn;

  /* If SRC and DEST are the same (and not volatile), return DEST.  */
  if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
    {
      /* Issue -Wrestrict unless the pointers are null (those do
	 not point to objects and so do not indicate an overlap;
	 such calls could be the result of sanitization and jump
	 threading).  */
      if (!integer_zerop (dest)
	  && !warning_suppressed_p (stmt, OPT_Wrestrict))
	{
	  tree func = gimple_call_fndecl (stmt);

	  warning_at (loc, OPT_Wrestrict,
		      "%qD source argument is the same as destination",
		      func);
	}

      replace_call_with_value (gsi, dest);
      return true;
    }

  if (! tree_fits_uhwi_p (size))
    return false;

  tree maxlen = get_maxval_strlen (src, SRK_STRLENMAX);
  if (! integer_all_onesp (size))
    {
      len = c_strlen (src, 1);
      if (! len || ! tree_fits_uhwi_p (len))
	{
	  /* If LEN is not constant, try MAXLEN too.
	     For MAXLEN only allow optimizing into non-_ocs function
	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
	  if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
	    {
	      if (fcode == BUILT_IN_STPCPY_CHK)
		{
		  if (! ignore)
		    return false;

		  /* If return value of __stpcpy_chk is ignored,
		     optimize into __strcpy_chk.  */
		  fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
		  if (!fn)
		    return false;

		  gimple *repl = gimple_build_call (fn, 3, dest, src, size);
		  replace_call_with_call_and_fold (gsi, repl);
		  return true;
		}

	      if (! len || TREE_SIDE_EFFECTS (len))
		return false;

	      /* If c_strlen returned something, but not a constant,
		 transform __strcpy_chk into __memcpy_chk.  */
	      fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
	      if (!fn)
		return false;

	      gimple_seq stmts = NULL;
	      len = force_gimple_operand (len, &stmts, true, NULL_TREE);
	      len = gimple_convert (&stmts, loc, size_type_node, len);
	      len = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node, len,
				  build_int_cst (size_type_node, 1));
	      gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
	      gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
	      replace_call_with_call_and_fold (gsi, repl);
	      return true;
	    }
	}
      else
	maxlen = len;

      if (! tree_int_cst_lt (maxlen, size))
	return false;
    }

  /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
  fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK
			      ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
  if (!fn)
    return false;

  gimple *repl = gimple_build_call (fn, 2, dest, src);
  replace_call_with_call_and_fold (gsi, repl);
  return true;
}

/* Fold a call to the __st{r,p}ncpy_chk builtin.  DEST, SRC, LEN, and SIZE
   are the arguments to the call.  If MAXLEN is not NULL, it is maximum
   length passed as third argument. IGNORE is true if return value can be
   ignored. FCODE is the BUILT_IN_* code of the builtin. */

static bool
gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
				 tree dest, tree src,
				 tree len, tree size,
				 enum built_in_function fcode)
{
  gimple *stmt = gsi_stmt (*gsi);
  bool ignore = gimple_call_lhs (stmt) == NULL_TREE;
  tree fn;

  if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
    {
       /* If return value of __stpncpy_chk is ignored,
          optimize into __strncpy_chk.  */
       fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
       if (fn)
	 {
	   gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
	   replace_call_with_call_and_fold (gsi, repl);
	   return true;
	 }
    }

  if (! tree_fits_uhwi_p (size))
    return false;

  tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
  if (! integer_all_onesp (size))
    {
      if (! tree_fits_uhwi_p (len))
	{
	  /* If LEN is not constant, try MAXLEN too.
	     For MAXLEN only allow optimizing into non-_ocs function
	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
	  if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
	    return false;
	}
      else
	maxlen = len;

      if (tree_int_cst_lt (size, maxlen))
	return false;
    }

  /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available.  */
  fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK
			      ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
  if (!fn)
    return false;

  gimple *repl = gimple_build_call (fn, 3, dest, src, len);
  replace_call_with_call_and_fold (gsi, repl);
  return true;
}

/* Fold function call to builtin stpcpy with arguments DEST and SRC.
   Return NULL_TREE if no simplification can be made.  */

static bool
gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi)
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
  location_t loc = gimple_location (stmt);
  tree dest = gimple_call_arg (stmt, 0);
  tree src = gimple_call_arg (stmt, 1);
  tree fn, lenp1;

  /* If the result is unused, replace stpcpy with strcpy.  */
  if (gimple_call_lhs (stmt) == NULL_TREE)
    {
      tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
      if (!fn)
	return false;
      gimple_call_set_fndecl (stmt, fn);
      fold_stmt (gsi);
      return true;
    }

  /* Set to non-null if ARG refers to an unterminated array.  */
  c_strlen_data data = { };
  /* The size of the unterminated array if SRC referes to one.  */
  tree size;
  /* True if the size is exact/constant, false if it's the lower bound
     of a range.  */
  bool exact;
  tree len = c_strlen (src, 1, &data, 1);
  if (!len
      || TREE_CODE (len) != INTEGER_CST)
    {
      data.decl = unterminated_array (src, &size, &exact);
      if (!data.decl)
	return false;
    }

  if (data.decl)
    {
      /* Avoid folding calls with unterminated arrays.  */
      if (!warning_suppressed_p (stmt, OPT_Wstringop_overread))
	warn_string_no_nul (loc, stmt, "stpcpy", src, data.decl, size,
			    exact);
      suppress_warning (stmt, OPT_Wstringop_overread);
      return false;
    }

  if (optimize_function_for_size_p (cfun)
      /* If length is zero it's small enough.  */
      && !integer_zerop (len))
    return false;

  /* If the source has a known length replace stpcpy with memcpy.  */
  fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
  if (!fn)
    return false;

  gimple_seq stmts = NULL;
  tree tem = gimple_convert (&stmts, loc, size_type_node, len);
  lenp1 = gimple_build (&stmts, loc, PLUS_EXPR, size_type_node,
			tem, build_int_cst (size_type_node, 1));
  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
  gcall *repl = gimple_build_call (fn, 3, dest, src, lenp1);
  gimple_move_vops (repl, stmt);
  gsi_insert_before (gsi, repl, GSI_SAME_STMT);
  /* Replace the result with dest + len.  */
  stmts = NULL;
  tem = gimple_convert (&stmts, loc, sizetype, len);
  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
  gassign *ret = gimple_build_assign (gimple_call_lhs (stmt),
				      POINTER_PLUS_EXPR, dest, tem);
  gsi_replace (gsi, ret, false);
  /* Finally fold the memcpy call.  */
  gimple_stmt_iterator gsi2 = *gsi;
  gsi_prev (&gsi2);
  fold_stmt (&gsi2);
  return true;
}

/* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS.  Return
   NULL_TREE if a normal call should be emitted rather than expanding
   the function inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
   BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
   passed as second argument.  */

static bool
gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
				  enum built_in_function fcode)
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
  tree dest, size, len, fn, fmt, flag;
  const char *fmt_str;

  /* Verify the required arguments in the original call.  */
  if (gimple_call_num_args (stmt) < 5)
    return false;

  dest = gimple_call_arg (stmt, 0);
  len = gimple_call_arg (stmt, 1);
  flag = gimple_call_arg (stmt, 2);
  size = gimple_call_arg (stmt, 3);
  fmt = gimple_call_arg (stmt, 4);

  if (! tree_fits_uhwi_p (size))
    return false;

  if (! integer_all_onesp (size))
    {
      tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
      if (! tree_fits_uhwi_p (len))
	{
	  /* If LEN is not constant, try MAXLEN too.
	     For MAXLEN only allow optimizing into non-_ocs function
	     if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
	  if (maxlen == NULL_TREE || ! tree_fits_uhwi_p (maxlen))
	    return false;
	}
      else
	maxlen = len;

      if (tree_int_cst_lt (size, maxlen))
	return false;
    }

  if (!init_target_chars ())
    return false;

  /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
     or if format doesn't contain % chars or is "%s".  */
  if (! integer_zerop (flag))
    {
      fmt_str = c_getstr (fmt);
      if (fmt_str == NULL)
	return false;
      if (strchr (fmt_str, target_percent) != NULL
	  && strcmp (fmt_str, target_percent_s))
	return false;
    }

  /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
     available.  */
  fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
			      ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
  if (!fn)
    return false;

  /* Replace the called function and the first 5 argument by 3 retaining
     trailing varargs.  */
  gimple_call_set_fndecl (stmt, fn);
  gimple_call_set_fntype (stmt, TREE_TYPE (fn));
  gimple_call_set_arg (stmt, 0, dest);
  gimple_call_set_arg (stmt, 1, len);
  gimple_call_set_arg (stmt, 2, fmt);
  for (unsigned i = 3; i < gimple_call_num_args (stmt) - 2; ++i)
    gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
  gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
  fold_stmt (gsi);
  return true;
}

/* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
   Return NULL_TREE if a normal call should be emitted rather than
   expanding the function inline.  FCODE is either BUILT_IN_SPRINTF_CHK
   or BUILT_IN_VSPRINTF_CHK.  */

static bool
gimple_fold_builtin_sprintf_chk (gimple_stmt_iterator *gsi,
				 enum built_in_function fcode)
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
  tree dest, size, len, fn, fmt, flag;
  const char *fmt_str;
  unsigned nargs = gimple_call_num_args (stmt);

  /* Verify the required arguments in the original call.  */
  if (nargs < 4)
    return false;
  dest = gimple_call_arg (stmt, 0);
  flag = gimple_call_arg (stmt, 1);
  size = gimple_call_arg (stmt, 2);
  fmt = gimple_call_arg (stmt, 3);

  if (! tree_fits_uhwi_p (size))
    return false;

  len = NULL_TREE;

  if (!init_target_chars ())
    return false;

  /* Check whether the format is a literal string constant.  */
  fmt_str = c_getstr (fmt);
  if (fmt_str != NULL)
    {
      /* If the format doesn't contain % args or %%, we know the size.  */
      if (strchr (fmt_str, target_percent) == 0)
	{
	  if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
	    len = build_int_cstu (size_type_node, strlen (fmt_str));
	}
      /* If the format is "%s" and first ... argument is a string literal,
	 we know the size too.  */
      else if (fcode == BUILT_IN_SPRINTF_CHK
	       && strcmp (fmt_str, target_percent_s) == 0)
	{
	  tree arg;

	  if (nargs == 5)
	    {
	      arg = gimple_call_arg (stmt, 4);
	      if (POINTER_TYPE_P (TREE_TYPE (arg)))
		{
		  len = c_strlen (arg, 1);
		  if (! len || ! tree_fits_uhwi_p (len))
		    len = NULL_TREE;
		}
	    }
	}
    }

  if (! integer_all_onesp (size))
    {
      if (! len || ! tree_int_cst_lt (len, size))
	return false;
    }

  /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
     or if format doesn't contain % chars or is "%s".  */
  if (! integer_zerop (flag))
    {
      if (fmt_str == NULL)
	return false;
      if (strchr (fmt_str, target_percent) != NULL
	  && strcmp (fmt_str, target_percent_s))
	return false;
    }

  /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
  fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
			      ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
  if (!fn)
    return false;

  /* Replace the called function and the first 4 argument by 2 retaining
     trailing varargs.  */
  gimple_call_set_fndecl (stmt, fn);
  gimple_call_set_fntype (stmt, TREE_TYPE (fn));
  gimple_call_set_arg (stmt, 0, dest);
  gimple_call_set_arg (stmt, 1, fmt);
  for (unsigned i = 2; i < gimple_call_num_args (stmt) - 2; ++i)
    gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
  gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
  fold_stmt (gsi);
  return true;
}

/* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
   ORIG may be null if this is a 2-argument call.  We don't attempt to
   simplify calls with more than 3 arguments.

   Return true if simplification was possible, otherwise false.  */

bool
gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);

  /* Verify the required arguments in the original call.  We deal with two
     types of sprintf() calls: 'sprintf (str, fmt)' and
     'sprintf (dest, "%s", orig)'.  */
  if (gimple_call_num_args (stmt) > 3)
    return false;

  tree orig = NULL_TREE;
  if (gimple_call_num_args (stmt) == 3)
    orig = gimple_call_arg (stmt, 2);

  /* Check whether the format is a literal string constant.  */
  tree fmt = gimple_call_arg (stmt, 1);
  const char *fmt_str = c_getstr (fmt);
  if (fmt_str == NULL)
    return false;

  tree dest = gimple_call_arg (stmt, 0);

  if (!init_target_chars ())
    return false;

  tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
  if (!fn)
    return false;

  /* If the format doesn't contain % args or %%, use strcpy.  */
  if (strchr (fmt_str, target_percent) == NULL)
    {
      /* Don't optimize sprintf (buf, "abc", ptr++).  */
      if (orig)
	return false;

      /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
	 'format' is known to contain no % formats.  */
      gimple_seq stmts = NULL;
      gimple *repl = gimple_build_call (fn, 2, dest, fmt);

      /* Propagate the NO_WARNING bit to avoid issuing the same
	 warning more than once.  */
      copy_warning (repl, stmt);

      gimple_seq_add_stmt_without_update (&stmts, repl);
      if (tree lhs = gimple_call_lhs (stmt))
	{
	  repl = gimple_build_assign (lhs, build_int_cst (TREE_TYPE (lhs),
							  strlen (fmt_str)));
	  gimple_seq_add_stmt_without_update (&stmts, repl);
	  gsi_replace_with_seq_vops (gsi, stmts);
	  /* gsi now points at the assignment to the lhs, get a
	     stmt iterator to the memcpy call.
	     ???  We can't use gsi_for_stmt as that doesn't work when the
	     CFG isn't built yet.  */
	  gimple_stmt_iterator gsi2 = *gsi;
	  gsi_prev (&gsi2);
	  fold_stmt (&gsi2);
	}
      else
	{
	  gsi_replace_with_seq_vops (gsi, stmts);
	  fold_stmt (gsi);
	}
      return true;
    }

  /* If the format is "%s", use strcpy if the result isn't used.  */
  else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
    {
      /* Don't crash on sprintf (str1, "%s").  */
      if (!orig)
	return false;

      /* Don't fold calls with source arguments of invalid (nonpointer)
	 types.  */
      if (!POINTER_TYPE_P (TREE_TYPE (orig)))
	return false;

      tree orig_len = NULL_TREE;
      if (gimple_call_lhs (stmt))
	{
	  orig_len = get_maxval_strlen (orig, SRK_STRLEN);
	  if (!orig_len)
	    return false;
	}

      /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
      gimple_seq stmts = NULL;
      gimple *repl = gimple_build_call (fn, 2, dest, orig);

      /* Propagate the NO_WARNING bit to avoid issuing the same
	 warning more than once.  */
      copy_warning (repl, stmt);

      gimple_seq_add_stmt_without_update (&stmts, repl);
      if (tree lhs = gimple_call_lhs (stmt))
	{
	  if (!useless_type_conversion_p (TREE_TYPE (lhs),
					  TREE_TYPE (orig_len)))
	    orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
	  repl = gimple_build_assign (lhs, orig_len);
	  gimple_seq_add_stmt_without_update (&stmts, repl);
	  gsi_replace_with_seq_vops (gsi, stmts);
	  /* gsi now points at the assignment to the lhs, get a
	     stmt iterator to the memcpy call.
	     ???  We can't use gsi_for_stmt as that doesn't work when the
	     CFG isn't built yet.  */
	  gimple_stmt_iterator gsi2 = *gsi;
	  gsi_prev (&gsi2);
	  fold_stmt (&gsi2);
	}
      else
	{
	  gsi_replace_with_seq_vops (gsi, stmts);
	  fold_stmt (gsi);
	}
      return true;
    }
  return false;
}

/* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
   FMT, and ORIG.  ORIG may be null if this is a 3-argument call.  We don't
   attempt to simplify calls with more than 4 arguments.

   Return true if simplification was possible, otherwise false.  */

bool
gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
  tree dest = gimple_call_arg (stmt, 0);
  tree destsize = gimple_call_arg (stmt, 1);
  tree fmt = gimple_call_arg (stmt, 2);
  tree orig = NULL_TREE;
  const char *fmt_str = NULL;

  if (gimple_call_num_args (stmt) > 4)
    return false;

  if (gimple_call_num_args (stmt) == 4)
    orig = gimple_call_arg (stmt, 3);

  if (!tree_fits_uhwi_p (destsize))
    return false;
  unsigned HOST_WIDE_INT destlen = tree_to_uhwi (destsize);

  /* Check whether the format is a literal string constant.  */
  fmt_str = c_getstr (fmt);
  if (fmt_str == NULL)
    return false;

  if (!init_target_chars ())
    return false;

  /* If the format doesn't contain % args or %%, use strcpy.  */
  if (strchr (fmt_str, target_percent) == NULL)
    {
      tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
      if (!fn)
	return false;

      /* Don't optimize snprintf (buf, 4, "abc", ptr++).  */
      if (orig)
	return false;

      /* We could expand this as
	 memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
	 or to
	 memcpy (str, fmt_with_nul_at_cstm1, cst);
	 but in the former case that might increase code size
	 and in the latter case grow .rodata section too much.
	 So punt for now.  */
      size_t len = strlen (fmt_str);
      if (len >= destlen)
	return false;

      gimple_seq stmts = NULL;
      gimple *repl = gimple_build_call (fn, 2, dest, fmt);
      gimple_seq_add_stmt_without_update (&stmts, repl);
      if (tree lhs = gimple_call_lhs (stmt))
	{
	  repl = gimple_build_assign (lhs,
				      build_int_cst (TREE_TYPE (lhs), len));
	  gimple_seq_add_stmt_without_update (&stmts, repl);
	  gsi_replace_with_seq_vops (gsi, stmts);
	  /* gsi now points at the assignment to the lhs, get a
	     stmt iterator to the memcpy call.
	     ???  We can't use gsi_for_stmt as that doesn't work when the
	     CFG isn't built yet.  */
	  gimple_stmt_iterator gsi2 = *gsi;
	  gsi_prev (&gsi2);
	  fold_stmt (&gsi2);
	}
      else
	{
	  gsi_replace_with_seq_vops (gsi, stmts);
	  fold_stmt (gsi);
	}
      return true;
    }

  /* If the format is "%s", use strcpy if the result isn't used.  */
  else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
    {
      tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
      if (!fn)
	return false;

      /* Don't crash on snprintf (str1, cst, "%s").  */
      if (!orig)
	return false;

      tree orig_len = get_maxval_strlen (orig, SRK_STRLEN);
      if (!orig_len || TREE_CODE (orig_len) != INTEGER_CST)
	return false;

      /* We could expand this as
	 memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
	 or to
	 memcpy (str1, str2_with_nul_at_cstm1, cst);
	 but in the former case that might increase code size
	 and in the latter case grow .rodata section too much.
	 So punt for now.  */
      if (compare_tree_int (orig_len, destlen) >= 0)
	return false;

      /* Convert snprintf (str1, cst, "%s", str2) into
	 strcpy (str1, str2) if strlen (str2) < cst.  */
      gimple_seq stmts = NULL;
      gimple *repl = gimple_build_call (fn, 2, dest, orig);
      gimple_seq_add_stmt_without_update (&stmts, repl);
      if (tree lhs = gimple_call_lhs (stmt))
	{
	  if (!useless_type_conversion_p (TREE_TYPE (lhs),
					  TREE_TYPE (orig_len)))
	    orig_len = fold_convert (TREE_TYPE (lhs), orig_len);
	  repl = gimple_build_assign (lhs, orig_len);
	  gimple_seq_add_stmt_without_update (&stmts, repl);
	  gsi_replace_with_seq_vops (gsi, stmts);
	  /* gsi now points at the assignment to the lhs, get a
	     stmt iterator to the memcpy call.
	     ???  We can't use gsi_for_stmt as that doesn't work when the
	     CFG isn't built yet.  */
	  gimple_stmt_iterator gsi2 = *gsi;
	  gsi_prev (&gsi2);
	  fold_stmt (&gsi2);
	}
      else
	{
	  gsi_replace_with_seq_vops (gsi, stmts);
	  fold_stmt (gsi);
	}
      return true;
    }
  return false;
}

/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
   FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
   more than 3 arguments, and ARG may be null in the 2-argument case.

   Return NULL_TREE if no simplification was possible, otherwise return the
   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
   code of the function to be simplified.  */

static bool 
gimple_fold_builtin_fprintf (gimple_stmt_iterator *gsi,
			     tree fp, tree fmt, tree arg,
			     enum built_in_function fcode)
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
  tree fn_fputc, fn_fputs;
  const char *fmt_str = NULL;

  /* If the return value is used, don't do the transformation.  */
  if (gimple_call_lhs (stmt) != NULL_TREE)
    return false;

  /* Check whether the format is a literal string constant.  */
  fmt_str = c_getstr (fmt);
  if (fmt_str == NULL)
    return false;

  if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
    {
      /* If we're using an unlocked function, assume the other
	 unlocked functions exist explicitly.  */
      fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
      fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
    }
  else
    {
      fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
      fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
    }

  if (!init_target_chars ())
    return false;

  /* If the format doesn't contain % args or %%, use strcpy.  */
  if (strchr (fmt_str, target_percent) == NULL)
    {
      if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
	  && arg)
	return false;

      /* If the format specifier was "", fprintf does nothing.  */
      if (fmt_str[0] == '\0')
	{
	  replace_call_with_value (gsi, NULL_TREE);
	  return true;
	}

      /* When "string" doesn't contain %, replace all cases of
	 fprintf (fp, string) with fputs (string, fp).  The fputs
	 builtin will take care of special cases like length == 1.  */
      if (fn_fputs)
	{
	  gcall *repl = gimple_build_call (fn_fputs, 2, fmt, fp);
	  replace_call_with_call_and_fold (gsi, repl);
	  return true;
	}
    }

  /* The other optimizations can be done only on the non-va_list variants.  */
  else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
    return false;

  /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
  else if (strcmp (fmt_str, target_percent_s) == 0)
    {
      if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
	return false;
      if (fn_fputs)
	{
	  gcall *repl = gimple_build_call (fn_fputs, 2, arg, fp);
	  replace_call_with_call_and_fold (gsi, repl);
	  return true;
	}
    }

  /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
  else if (strcmp (fmt_str, target_percent_c) == 0)
    {
      if (!arg
	  || ! useless_type_conversion_p (integer_type_node, TREE_TYPE (arg)))
	return false;
      if (fn_fputc)
	{
	  gcall *repl = gimple_build_call (fn_fputc, 2, arg, fp);
	  replace_call_with_call_and_fold (gsi, repl);
	  return true;
	}
    }

  return false;
}

/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
   FMT and ARG are the arguments to the call; we don't fold cases with
   more than 2 arguments, and ARG may be null if this is a 1-argument case.

   Return NULL_TREE if no simplification was possible, otherwise return the
   simplified form of the call as a tree.  FCODE is the BUILT_IN_*
   code of the function to be simplified.  */

static bool
gimple_fold_builtin_printf (gimple_stmt_iterator *gsi, tree fmt,
			    tree arg, enum built_in_function fcode)
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
  tree fn_putchar, fn_puts, newarg;
  const char *fmt_str = NULL;

  /* If the return value is used, don't do the transformation.  */
  if (gimple_call_lhs (stmt) != NULL_TREE)
    return false;

  /* Check whether the format is a literal string constant.  */
  fmt_str = c_getstr (fmt);
  if (fmt_str == NULL)
    return false;

  if (fcode == BUILT_IN_PRINTF_UNLOCKED)
    {
      /* If we're using an unlocked function, assume the other
	 unlocked functions exist explicitly.  */
      fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
      fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
    }
  else
    {
      fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
      fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
    }

  if (!init_target_chars ())
    return false;

  if (strcmp (fmt_str, target_percent_s) == 0
      || strchr (fmt_str, target_percent) == NULL)
    {
      const char *str;

      if (strcmp (fmt_str, target_percent_s) == 0)
	{
	  if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
	    return false;

	  if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
	    return false;

	  str = c_getstr (arg);
	  if (str == NULL)
	    return false;
	}
      else
	{
	  /* The format specifier doesn't contain any '%' characters.  */
	  if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
	      && arg)
	    return false;
	  str = fmt_str;
	}

      /* If the string was "", printf does nothing.  */
      if (str[0] == '\0')
	{
	  replace_call_with_value (gsi, NULL_TREE);
	  return true;
	}

      /* If the string has length of 1, call putchar.  */
      if (str[1] == '\0')
	{
	  /* Given printf("c"), (where c is any one character,)
	     convert "c"[0] to an int and pass that to the replacement
	     function.  */
	  newarg = build_int_cst (integer_type_node, str[0]);
	  if (fn_putchar)
	    {
	      gcall *repl = gimple_build_call (fn_putchar, 1, newarg);
	      replace_call_with_call_and_fold (gsi, repl);
	      return true;
	    }
	}
      else
	{
	  /* If the string was "string\n", call puts("string").  */
	  size_t len = strlen (str);
	  if ((unsigned char)str[len - 1] == target_newline
	      && (size_t) (int) len == len
	      && (int) len > 0)
	    {
	      char *newstr;

	      /* Create a NUL-terminated string that's one char shorter
		 than the original, stripping off the trailing '\n'.  */
	      newstr = xstrdup (str);
	      newstr[len - 1] = '\0';
	      newarg = build_string_literal (len, newstr);
	      free (newstr);
	      if (fn_puts)
		{
		  gcall *repl = gimple_build_call (fn_puts, 1, newarg);
		  replace_call_with_call_and_fold (gsi, repl);
		  return true;
		}
	    }
	  else
	    /* We'd like to arrange to call fputs(string,stdout) here,
	       but we need stdout and don't have a way to get it yet.  */
	    return false;
	}
    }

  /* The other optimizations can be done only on the non-va_list variants.  */
  else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
    return false;

  /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
  else if (strcmp (fmt_str, target_percent_s_newline) == 0)
    {
      if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg)))
	return false;
      if (fn_puts)
	{
	  gcall *repl = gimple_build_call (fn_puts, 1, arg);
	  replace_call_with_call_and_fold (gsi, repl);
	  return true;
	}
    }

  /* If the format specifier was "%c", call __builtin_putchar(arg).  */
  else if (strcmp (fmt_str, target_percent_c) == 0)
    {
      if (!arg || ! useless_type_conversion_p (integer_type_node,
					       TREE_TYPE (arg)))
	return false;
      if (fn_putchar)
	{
	  gcall *repl = gimple_build_call (fn_putchar, 1, arg);
	  replace_call_with_call_and_fold (gsi, repl);
	  return true;
	}
    }

  return false;
}



/* Fold a call to __builtin_strlen with known length LEN.  */

static bool
gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree arg = gimple_call_arg (stmt, 0);

  wide_int minlen;
  wide_int maxlen;

  c_strlen_data lendata = { };
  if (get_range_strlen (arg, &lendata, /* eltsize = */ 1)
      && !lendata.decl
      && lendata.minlen && TREE_CODE (lendata.minlen) == INTEGER_CST
      && lendata.maxlen && TREE_CODE (lendata.maxlen) == INTEGER_CST)
    {
      /* The range of lengths refers to either a single constant
	 string or to the longest and shortest constant string
	 referenced by the argument of the strlen() call, or to
	 the strings that can possibly be stored in the arrays
	 the argument refers to.  */
      minlen = wi::to_wide (lendata.minlen);
      maxlen = wi::to_wide (lendata.maxlen);
    }
  else
    {
      unsigned prec = TYPE_PRECISION (sizetype);

      minlen = wi::shwi (0, prec);
      maxlen = wi::to_wide (max_object_size (), prec) - 2;
    }

  if (minlen == maxlen)
    {
      /* Fold the strlen call to a constant.  */
      tree type = TREE_TYPE (lendata.minlen);
      tree len = force_gimple_operand_gsi (gsi,
					   wide_int_to_tree (type, minlen),
					   true, NULL, true, GSI_SAME_STMT);
      replace_call_with_value (gsi, len);
      return true;
    }

  /* Set the strlen() range to [0, MAXLEN].  */
  if (tree lhs = gimple_call_lhs (stmt))
    set_strlen_range (lhs, minlen, maxlen);

  return false;
}

/* Fold a call to __builtin_acc_on_device.  */

static bool
gimple_fold_builtin_acc_on_device (gimple_stmt_iterator *gsi, tree arg0)
{
  /* Defer folding until we know which compiler we're in.  */
  if (symtab->state != EXPANSION)
    return false;

  unsigned val_host = GOMP_DEVICE_HOST;
  unsigned val_dev = GOMP_DEVICE_NONE;

#ifdef ACCEL_COMPILER
  val_host = GOMP_DEVICE_NOT_HOST;
  val_dev = ACCEL_COMPILER_acc_device;
#endif

  location_t loc = gimple_location (gsi_stmt (*gsi));
  
  tree host_eq = make_ssa_name (boolean_type_node);
  gimple *host_ass = gimple_build_assign
    (host_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0), val_host));
  gimple_set_location (host_ass, loc);
  gsi_insert_before (gsi, host_ass, GSI_SAME_STMT);

  tree dev_eq = make_ssa_name (boolean_type_node);
  gimple *dev_ass = gimple_build_assign
    (dev_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0), val_dev));
  gimple_set_location (dev_ass, loc);
  gsi_insert_before (gsi, dev_ass, GSI_SAME_STMT);

  tree result = make_ssa_name (boolean_type_node);
  gimple *result_ass = gimple_build_assign
    (result, BIT_IOR_EXPR, host_eq, dev_eq);
  gimple_set_location (result_ass, loc);
  gsi_insert_before (gsi, result_ass, GSI_SAME_STMT);

  replace_call_with_value (gsi, result);

  return true;
}

/* Fold realloc (0, n) -> malloc (n).  */

static bool
gimple_fold_builtin_realloc (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree arg = gimple_call_arg (stmt, 0);
  tree size = gimple_call_arg (stmt, 1);

  if (operand_equal_p (arg, null_pointer_node, 0))
    {
      tree fn_malloc = builtin_decl_implicit (BUILT_IN_MALLOC);
      if (fn_malloc)
	{
	  gcall *repl = gimple_build_call (fn_malloc, 1, size);
	  replace_call_with_call_and_fold (gsi, repl);
	  return true;
	}
    }
  return false;
}

/* Number of bytes into which any type but aggregate or vector types
   should fit.  */
static constexpr size_t clear_padding_unit
  = MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT;
/* Buffer size on which __builtin_clear_padding folding code works.  */
static const size_t clear_padding_buf_size = 32 * clear_padding_unit;

/* Data passed through __builtin_clear_padding folding.  */
struct clear_padding_struct {
  location_t loc;
  /* 0 during __builtin_clear_padding folding, nonzero during
     clear_type_padding_in_mask.  In that case, instead of clearing the
     non-padding bits in union_ptr array clear the padding bits in there.  */
  bool clear_in_mask;
  tree base;
  tree alias_type;
  gimple_stmt_iterator *gsi;
  /* Alignment of buf->base + 0.  */
  unsigned align;
  /* Offset from buf->base.  Should be always a multiple of UNITS_PER_WORD.  */
  HOST_WIDE_INT off;
  /* Number of padding bytes before buf->off that don't have padding clear
     code emitted yet.  */
  HOST_WIDE_INT padding_bytes;
  /* The size of the whole object.  Never emit code to touch
     buf->base + buf->sz or following bytes.  */
  HOST_WIDE_INT sz;
  /* Number of bytes recorded in buf->buf.  */
  size_t size;
  /* When inside union, instead of emitting code we and bits inside of
     the union_ptr array.  */
  unsigned char *union_ptr;
  /* Set bits mean padding bits that need to be cleared by the builtin.  */
  unsigned char buf[clear_padding_buf_size + clear_padding_unit];
};

/* Emit code to clear padding requested in BUF->buf - set bits
   in there stand for padding that should be cleared.  FULL is true
   if everything from the buffer should be flushed, otherwise
   it can leave up to 2 * clear_padding_unit bytes for further
   processing.  */

static void
clear_padding_flush (clear_padding_struct *buf, bool full)
{
  gcc_assert ((clear_padding_unit % UNITS_PER_WORD) == 0);
  if (!full && buf->size < 2 * clear_padding_unit)
    return;
  gcc_assert ((buf->off % UNITS_PER_WORD) == 0);
  size_t end = buf->size;
  if (!full)
    end = ((end - clear_padding_unit - 1) / clear_padding_unit
	   * clear_padding_unit);
  size_t padding_bytes = buf->padding_bytes;
  if (buf->union_ptr)
    {
      if (buf->clear_in_mask)
	{
	  /* During clear_type_padding_in_mask, clear the padding
	     bits set in buf->buf in the buf->union_ptr mask.  */
	  for (size_t i = 0; i < end; i++)
	    {
	      if (buf->buf[i] == (unsigned char) ~0)
		padding_bytes++;
	      else
		{
		  memset (&buf->union_ptr[buf->off + i - padding_bytes],
			  0, padding_bytes);
		  padding_bytes = 0;
		  buf->union_ptr[buf->off + i] &= ~buf->buf[i];
		}
	    }
	  if (full)
	    {
	      memset (&buf->union_ptr[buf->off + end - padding_bytes],
		      0, padding_bytes);
	      buf->off = 0;
	      buf->size = 0;
	      buf->padding_bytes = 0;
	    }
	  else
	    {
	      memmove (buf->buf, buf->buf + end, buf->size - end);
	      buf->off += end;
	      buf->size -= end;
	      buf->padding_bytes = padding_bytes;
	    }
	  return;
	}
      /* Inside of a union, instead of emitting any code, instead
	 clear all bits in the union_ptr buffer that are clear
	 in buf.  Whole padding bytes don't clear anything.  */
      for (size_t i = 0; i < end; i++)
	{
	  if (buf->buf[i] == (unsigned char) ~0)
	    padding_bytes++;
	  else
	    {
	      padding_bytes = 0;
	      buf->union_ptr[buf->off + i] &= buf->buf[i];
	    }
	}
      if (full)
	{
	  buf->off = 0;
	  buf->size = 0;
	  buf->padding_bytes = 0;
	}
      else
	{
	  memmove (buf->buf, buf->buf + end, buf->size - end);
	  buf->off += end;
	  buf->size -= end;
	  buf->padding_bytes = padding_bytes;
	}
      return;
    }
  size_t wordsize = UNITS_PER_WORD;
  for (size_t i = 0; i < end; i += wordsize)
    {
      size_t nonzero_first = wordsize;
      size_t nonzero_last = 0;
      size_t zero_first = wordsize;
      size_t zero_last = 0;
      bool all_ones = true, bytes_only = true;
      if ((unsigned HOST_WIDE_INT) (buf->off + i + wordsize)
	  > (unsigned HOST_WIDE_INT) buf->sz)
	{
	  gcc_assert (wordsize > 1);
	  wordsize /= 2;
	  i -= wordsize;
	  continue;
	}
      for (size_t j = i; j < i + wordsize && j < end; j++)
	{
	  if (buf->buf[j])
	    {
	      if (nonzero_first == wordsize)
		{
		  nonzero_first = j - i;
		  nonzero_last = j - i;
		}
	      if (nonzero_last != j - i)
		all_ones = false;
	      nonzero_last = j + 1 - i;
	    }
	  else
	    {
	      if (zero_first == wordsize)
		zero_first = j - i;
	      zero_last = j + 1 - i;
	    }
	  if (buf->buf[j] != 0 && buf->buf[j] != (unsigned char) ~0)
	    {
	      all_ones = false;
	      bytes_only = false;
	    }
	}
      size_t padding_end = i;
      if (padding_bytes)
	{
	  if (nonzero_first == 0
	      && nonzero_last == wordsize
	      && all_ones)
	    {
	      /* All bits are padding and we had some padding
		 before too.  Just extend it.  */
	      padding_bytes += wordsize;
	      continue;
	    }
	  if (all_ones && nonzero_first == 0)
	    {
	      padding_bytes += nonzero_last;
	      padding_end += nonzero_last;
	      nonzero_first = wordsize;
	      nonzero_last = 0;
	    }
	  else if (bytes_only && nonzero_first == 0)
	    {
	      gcc_assert (zero_first && zero_first != wordsize);
	      padding_bytes += zero_first;
	      padding_end += zero_first;
	    }
	  tree atype, src;
	  if (padding_bytes == 1)
	    {
	      atype = char_type_node;
	      src = build_zero_cst (char_type_node);
	    }
	  else
	    {
	      atype = build_array_type_nelts (char_type_node, padding_bytes);
	      src = build_constructor (atype, NULL);
	    }
	  tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
				 build_int_cst (buf->alias_type,
						buf->off + padding_end
						- padding_bytes));
	  gimple *g = gimple_build_assign (dst, src);
	  gimple_set_location (g, buf->loc);
	  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
	  padding_bytes = 0;
	  buf->padding_bytes = 0;
	}
      if (nonzero_first == wordsize)
	/* All bits in a word are 0, there are no padding bits.  */
	continue;
      if (all_ones && nonzero_last == wordsize)
	{
	  /* All bits between nonzero_first and end of word are padding
	     bits, start counting padding_bytes.  */
	  padding_bytes = nonzero_last - nonzero_first;
	  continue;
	}
      if (bytes_only)
	{
	  /* If bitfields aren't involved in this word, prefer storing
	     individual bytes or groups of them over performing a RMW
	     operation on the whole word.  */
	  gcc_assert (i + zero_last <= end);
	  for (size_t j = padding_end; j < i + zero_last; j++)
	    {
	      if (buf->buf[j])
		{
		  size_t k;
		  for (k = j; k < i + zero_last; k++)
		    if (buf->buf[k] == 0)
		      break;
		  HOST_WIDE_INT off = buf->off + j;
		  tree atype, src;
		  if (k - j == 1)
		    {
		      atype = char_type_node;
		      src = build_zero_cst (char_type_node);
		    }
		  else
		    {
		      atype = build_array_type_nelts (char_type_node, k - j);
		      src = build_constructor (atype, NULL);
		    }
		  tree dst = build2_loc (buf->loc, MEM_REF, atype,
					 buf->base,
					 build_int_cst (buf->alias_type, off));
		  gimple *g = gimple_build_assign (dst, src);
		  gimple_set_location (g, buf->loc);
		  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
		  j = k;
		}
	    }
	  if (nonzero_last == wordsize)
	    padding_bytes = nonzero_last - zero_last;
	  continue;
	}
      for (size_t eltsz = 1; eltsz <= wordsize; eltsz <<= 1)
	{
	  if (nonzero_last - nonzero_first <= eltsz
	      && ((nonzero_first & ~(eltsz - 1))
		  == ((nonzero_last - 1) & ~(eltsz - 1))))
	    {
	      tree type;
	      if (eltsz == 1)
		type = char_type_node;
	      else
		type = lang_hooks.types.type_for_size (eltsz * BITS_PER_UNIT,
						       0);
	      size_t start = nonzero_first & ~(eltsz - 1);
	      HOST_WIDE_INT off = buf->off + i + start;
	      tree atype = type;
	      if (eltsz > 1 && buf->align < TYPE_ALIGN (type))
		atype = build_aligned_type (type, buf->align);
	      tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
				     build_int_cst (buf->alias_type, off));
	      tree src;
	      gimple *g;
	      if (all_ones
		  && nonzero_first == start
		  && nonzero_last == start + eltsz)
		src = build_zero_cst (type);
	      else
		{
		  src = make_ssa_name (type);
		  g = gimple_build_assign (src, unshare_expr (dst));
		  gimple_set_location (g, buf->loc);
		  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
		  tree mask = native_interpret_expr (type,
						     buf->buf + i + start,
						     eltsz);
		  gcc_assert (mask && TREE_CODE (mask) == INTEGER_CST);
		  mask = fold_build1 (BIT_NOT_EXPR, type, mask);
		  tree src_masked = make_ssa_name (type);
		  g = gimple_build_assign (src_masked, BIT_AND_EXPR,
					   src, mask);
		  gimple_set_location (g, buf->loc);
		  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
		  src = src_masked;
		}
	      g = gimple_build_assign (dst, src);
	      gimple_set_location (g, buf->loc);
	      gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
	      break;
	    }
	}
    }
  if (full)
    {
      if (padding_bytes)
	{
	  tree atype, src;
	  if (padding_bytes == 1)
	    {
	      atype = char_type_node;
	      src = build_zero_cst (char_type_node);
	    }
	  else
	    {
	      atype = build_array_type_nelts (char_type_node, padding_bytes);
	      src = build_constructor (atype, NULL);
	    }
	  tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
				 build_int_cst (buf->alias_type,
						buf->off + end
						- padding_bytes));
	  gimple *g = gimple_build_assign (dst, src);
	  gimple_set_location (g, buf->loc);
	  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
	}
      size_t end_rem = end % UNITS_PER_WORD;
      buf->off += end - end_rem;
      buf->size = end_rem;
      memset (buf->buf, 0, buf->size);
      buf->padding_bytes = 0;
    }
  else
    {
      memmove (buf->buf, buf->buf + end, buf->size - end);
      buf->off += end;
      buf->size -= end;
      buf->padding_bytes = padding_bytes;
    }
}

/* Append PADDING_BYTES padding bytes.  */

static void
clear_padding_add_padding (clear_padding_struct *buf,
			   HOST_WIDE_INT padding_bytes)
{
  if (padding_bytes == 0)
    return;
  if ((unsigned HOST_WIDE_INT) padding_bytes + buf->size
      > (unsigned HOST_WIDE_INT) clear_padding_buf_size)
    clear_padding_flush (buf, false);
  if ((unsigned HOST_WIDE_INT) padding_bytes + buf->size
      > (unsigned HOST_WIDE_INT) clear_padding_buf_size)
    {
      memset (buf->buf + buf->size, ~0, clear_padding_buf_size - buf->size);
      padding_bytes -= clear_padding_buf_size - buf->size;
      buf->size = clear_padding_buf_size;
      clear_padding_flush (buf, false);
      gcc_assert (buf->padding_bytes);
      /* At this point buf->buf[0] through buf->buf[buf->size - 1]
	 is guaranteed to be all ones.  */
      padding_bytes += buf->size;
      buf->size = padding_bytes % UNITS_PER_WORD;
      memset (buf->buf, ~0, buf->size);
      buf->off += padding_bytes - buf->size;
      buf->padding_bytes += padding_bytes - buf->size;
    }
  else
    {
      memset (buf->buf + buf->size, ~0, padding_bytes);
      buf->size += padding_bytes;
    }
}

static void clear_padding_type (clear_padding_struct *, tree,
				HOST_WIDE_INT, bool);

/* Clear padding bits of union type TYPE.  */

static void
clear_padding_union (clear_padding_struct *buf, tree type,
		     HOST_WIDE_INT sz, bool for_auto_init)
{
  clear_padding_struct *union_buf;
  HOST_WIDE_INT start_off = 0, next_off = 0;
  size_t start_size = 0;
  if (buf->union_ptr)
    {
      start_off = buf->off + buf->size;
      next_off = start_off + sz;
      start_size = start_off % UNITS_PER_WORD;
      start_off -= start_size;
      clear_padding_flush (buf, true);
      union_buf = buf;
    }
  else
    {
      if (sz + buf->size > clear_padding_buf_size)
	clear_padding_flush (buf, false);
      union_buf = XALLOCA (clear_padding_struct);
      union_buf->loc = buf->loc;
      union_buf->clear_in_mask = buf->clear_in_mask;
      union_buf->base = NULL_TREE;
      union_buf->alias_type = NULL_TREE;
      union_buf->gsi = NULL;
      union_buf->align = 0;
      union_buf->off = 0;
      union_buf->padding_bytes = 0;
      union_buf->sz = sz;
      union_buf->size = 0;
      if (sz + buf->size <= clear_padding_buf_size)
	union_buf->union_ptr = buf->buf + buf->size;
      else
	union_buf->union_ptr = XNEWVEC (unsigned char, sz);
      memset (union_buf->union_ptr, ~0, sz);
    }

  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    if (TREE_CODE (field) == FIELD_DECL && !DECL_PADDING_P (field))
      {
	if (DECL_SIZE_UNIT (field) == NULL_TREE)
	  {
	    if (TREE_TYPE (field) == error_mark_node)
	      continue;
	    gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
			&& !COMPLETE_TYPE_P (TREE_TYPE (field)));
	    if (!buf->clear_in_mask && !for_auto_init)
	      error_at (buf->loc, "flexible array member %qD does not have "
				  "well defined padding bits for %qs",
			field, "__builtin_clear_padding");
	    continue;
	  }
	HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
	gcc_assert (union_buf->size == 0);
	union_buf->off = start_off;
	union_buf->size = start_size;
	memset (union_buf->buf, ~0, start_size);
	clear_padding_type (union_buf, TREE_TYPE (field), fldsz, for_auto_init);
	clear_padding_add_padding (union_buf, sz - fldsz);
	clear_padding_flush (union_buf, true);
      }

  if (buf == union_buf)
    {
      buf->off = next_off;
      buf->size = next_off % UNITS_PER_WORD;
      buf->off -= buf->size;
      memset (buf->buf, ~0, buf->size);
    }
  else if (sz + buf->size <= clear_padding_buf_size)
    buf->size += sz;
  else
    {
      unsigned char *union_ptr = union_buf->union_ptr;
      while (sz)
	{
	  clear_padding_flush (buf, false);
	  HOST_WIDE_INT this_sz
	    = MIN ((unsigned HOST_WIDE_INT) sz,
		   clear_padding_buf_size - buf->size);
	  memcpy (buf->buf + buf->size, union_ptr, this_sz);
	  buf->size += this_sz;
	  union_ptr += this_sz;
	  sz -= this_sz;
	}
      XDELETE (union_buf->union_ptr);
    }
}

/* The only known floating point formats with padding bits are the
   IEEE extended ones.  */

static bool
clear_padding_real_needs_padding_p (tree type)
{
  const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
  return (fmt->b == 2
	  && fmt->signbit_ro == fmt->signbit_rw
	  && (fmt->signbit_ro == 79 || fmt->signbit_ro == 95));
}

/* Return true if TYPE might contain any padding bits.  */

static bool
clear_padding_type_may_have_padding_p (tree type)
{
  switch (TREE_CODE (type))
    {
    case RECORD_TYPE:
    case UNION_TYPE:
      return true;
    case ARRAY_TYPE:
    case COMPLEX_TYPE:
    case VECTOR_TYPE:
      return clear_padding_type_may_have_padding_p (TREE_TYPE (type));
    case REAL_TYPE:
      return clear_padding_real_needs_padding_p (type);
    default:
      return false;
    }
}

/* Emit a runtime loop:
   for (; buf.base != end; buf.base += sz)
     __builtin_clear_padding (buf.base);  */

static void
clear_padding_emit_loop (clear_padding_struct *buf, tree type,
			 tree end, bool for_auto_init)
{
  tree l1 = create_artificial_label (buf->loc);
  tree l2 = create_artificial_label (buf->loc);
  tree l3 = create_artificial_label (buf->loc);
  gimple *g = gimple_build_goto (l2);
  gimple_set_location (g, buf->loc);
  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
  g = gimple_build_label (l1);
  gimple_set_location (g, buf->loc);
  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
  clear_padding_type (buf, type, buf->sz, for_auto_init);
  clear_padding_flush (buf, true);
  g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR, buf->base,
			   size_int (buf->sz));
  gimple_set_location (g, buf->loc);
  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
  g = gimple_build_label (l2);
  gimple_set_location (g, buf->loc);
  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
  g = gimple_build_cond (NE_EXPR, buf->base, end, l1, l3);
  gimple_set_location (g, buf->loc);
  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
  g = gimple_build_label (l3);
  gimple_set_location (g, buf->loc);
  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
}

/* Clear padding bits for TYPE.  Called recursively from
   gimple_fold_builtin_clear_padding.  If FOR_AUTO_INIT is true,
   the __builtin_clear_padding is not called by the end user,
   instead, it's inserted by the compiler to initialize the
   paddings of automatic variable.  Therefore, we should not
   emit the error messages for flexible array members to confuse
   the end user.  */

static void
clear_padding_type (clear_padding_struct *buf, tree type,
		    HOST_WIDE_INT sz, bool for_auto_init)
{
  switch (TREE_CODE (type))
    {
    case RECORD_TYPE:
      HOST_WIDE_INT cur_pos;
      cur_pos = 0;
      for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL && !DECL_PADDING_P (field))
	  {
	    tree ftype = TREE_TYPE (field);
	    if (DECL_BIT_FIELD (field))
	      {
		HOST_WIDE_INT fldsz = TYPE_PRECISION (ftype);
		if (fldsz == 0)
		  continue;
		HOST_WIDE_INT pos = int_byte_position (field);
		if (pos >= sz)
		  continue;
		HOST_WIDE_INT bpos
		  = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
		bpos %= BITS_PER_UNIT;
		HOST_WIDE_INT end
		  = ROUND_UP (bpos + fldsz, BITS_PER_UNIT) / BITS_PER_UNIT;
		if (pos + end > cur_pos)
		  {
		    clear_padding_add_padding (buf, pos + end - cur_pos);
		    cur_pos = pos + end;
		  }
		gcc_assert (cur_pos > pos
			    && ((unsigned HOST_WIDE_INT) buf->size
				>= (unsigned HOST_WIDE_INT) cur_pos - pos));
		unsigned char *p = buf->buf + buf->size - (cur_pos - pos);
		if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
		  sorry_at (buf->loc, "PDP11 bit-field handling unsupported"
				      " in %qs", "__builtin_clear_padding");
		else if (BYTES_BIG_ENDIAN)
		  {
		    /* Big endian.  */
		    if (bpos + fldsz <= BITS_PER_UNIT)
		      *p &= ~(((1 << fldsz) - 1)
			      << (BITS_PER_UNIT - bpos - fldsz));
		    else
		      {
			if (bpos)
			  {
			    *p &= ~(((1U << BITS_PER_UNIT) - 1) >> bpos);
			    p++;
			    fldsz -= BITS_PER_UNIT - bpos;
			  }
			memset (p, 0, fldsz / BITS_PER_UNIT);
			p += fldsz / BITS_PER_UNIT;
			fldsz %= BITS_PER_UNIT;
			if (fldsz)
			  *p &= ((1U << BITS_PER_UNIT) - 1) >> fldsz;
		      }
		  }
		else
		  {
		    /* Little endian.  */
		    if (bpos + fldsz <= BITS_PER_UNIT)
		      *p &= ~(((1 << fldsz) - 1) << bpos);
		    else
		      {
			if (bpos)
			  {
			    *p &= ~(((1 << BITS_PER_UNIT) - 1) << bpos);
			    p++;
			    fldsz -= BITS_PER_UNIT - bpos;
			  }
			memset (p, 0, fldsz / BITS_PER_UNIT);
			p += fldsz / BITS_PER_UNIT;
			fldsz %= BITS_PER_UNIT;
			if (fldsz)
			  *p &= ~((1 << fldsz) - 1);
		      }
		  }
	      }
	    else if (DECL_SIZE_UNIT (field) == NULL_TREE)
	      {
		if (ftype == error_mark_node)
		  continue;
		gcc_assert (TREE_CODE (ftype) == ARRAY_TYPE
			    && !COMPLETE_TYPE_P (ftype));
		if (!buf->clear_in_mask && !for_auto_init)
		  error_at (buf->loc, "flexible array member %qD does not "
				      "have well defined padding bits for %qs",
			    field, "__builtin_clear_padding");
	      }
	    else if (is_empty_type (TREE_TYPE (field)))
	      continue;
	    else
	      {
		HOST_WIDE_INT pos = int_byte_position (field);
		if (pos >= sz)
		  continue;
		HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field));
		gcc_assert (pos >= 0 && fldsz >= 0 && pos >= cur_pos);
		clear_padding_add_padding (buf, pos - cur_pos);
		cur_pos = pos;
		clear_padding_type (buf, TREE_TYPE (field),
				    fldsz, for_auto_init);
		cur_pos += fldsz;
	      }
	  }
      gcc_assert (sz >= cur_pos);
      clear_padding_add_padding (buf, sz - cur_pos);
      break;
    case ARRAY_TYPE:
      HOST_WIDE_INT nelts, fldsz;
      fldsz = int_size_in_bytes (TREE_TYPE (type));
      if (fldsz == 0)
	break;
      nelts = sz / fldsz;
      if (nelts > 1
	  && sz > 8 * UNITS_PER_WORD
	  && buf->union_ptr == NULL
	  && clear_padding_type_may_have_padding_p (TREE_TYPE (type)))
	{
	  /* For sufficiently large array of more than one elements,
	     emit a runtime loop to keep code size manageable.  */
	  tree base = buf->base;
	  unsigned int prev_align = buf->align;
	  HOST_WIDE_INT off = buf->off + buf->size;
	  HOST_WIDE_INT prev_sz = buf->sz;
	  clear_padding_flush (buf, true);
	  tree elttype = TREE_TYPE (type);
	  buf->base = create_tmp_var (build_pointer_type (elttype));
	  tree end = make_ssa_name (TREE_TYPE (buf->base));
	  gimple *g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR,
					   base, size_int (off));
	  gimple_set_location (g, buf->loc);
	  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
	  g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf->base,
				   size_int (sz));
	  gimple_set_location (g, buf->loc);
	  gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
	  buf->sz = fldsz;
	  buf->align = TYPE_ALIGN (elttype);
	  buf->off = 0;
	  buf->size = 0;
	  clear_padding_emit_loop (buf, elttype, end, for_auto_init);
	  buf->base = base;
	  buf->sz = prev_sz;
	  buf->align = prev_align;
	  buf->size = off % UNITS_PER_WORD;
	  buf->off = off - buf->size;
	  memset (buf->buf, 0, buf->size);
	  break;
	}
      for (HOST_WIDE_INT i = 0; i < nelts; i++)
	clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
      break;
    case UNION_TYPE:
      clear_padding_union (buf, type, sz, for_auto_init);
      break;
    case REAL_TYPE:
      gcc_assert ((size_t) sz <= clear_padding_unit);
      if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
	clear_padding_flush (buf, false);
      if (clear_padding_real_needs_padding_p (type))
	{
	  /* Use native_interpret_expr + native_encode_expr to figure out
	     which bits are padding.  */
	  memset (buf->buf + buf->size, ~0, sz);
	  tree cst = native_interpret_expr (type, buf->buf + buf->size, sz);
	  gcc_assert (cst && TREE_CODE (cst) == REAL_CST);
	  int len = native_encode_expr (cst, buf->buf + buf->size, sz);
	  gcc_assert (len > 0 && (size_t) len == (size_t) sz);
	  for (size_t i = 0; i < (size_t) sz; i++)
	    buf->buf[buf->size + i] ^= ~0;
	}
      else
	memset (buf->buf + buf->size, 0, sz);
      buf->size += sz;
      break;
    case COMPLEX_TYPE:
      fldsz = int_size_in_bytes (TREE_TYPE (type));
      clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
      clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
      break;
    case VECTOR_TYPE:
      nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
      fldsz = int_size_in_bytes (TREE_TYPE (type));
      for (HOST_WIDE_INT i = 0; i < nelts; i++)
	clear_padding_type (buf, TREE_TYPE (type), fldsz, for_auto_init);
      break;
    case NULLPTR_TYPE:
      gcc_assert ((size_t) sz <= clear_padding_unit);
      if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
	clear_padding_flush (buf, false);
      memset (buf->buf + buf->size, ~0, sz);
      buf->size += sz;
      break;
    default:
      gcc_assert ((size_t) sz <= clear_padding_unit);
      if ((unsigned HOST_WIDE_INT) sz + buf->size > clear_padding_buf_size)
	clear_padding_flush (buf, false);
      memset (buf->buf + buf->size, 0, sz);
      buf->size += sz;
      break;
    }
}

/* Clear padding bits of TYPE in MASK.  */

void
clear_type_padding_in_mask (tree type, unsigned char *mask)
{
  clear_padding_struct buf;
  buf.loc = UNKNOWN_LOCATION;
  buf.clear_in_mask = true;
  buf.base = NULL_TREE;
  buf.alias_type = NULL_TREE;
  buf.gsi = NULL;
  buf.align = 0;
  buf.off = 0;
  buf.padding_bytes = 0;
  buf.sz = int_size_in_bytes (type);
  buf.size = 0;
  buf.union_ptr = mask;
  clear_padding_type (&buf, type, buf.sz, false);
  clear_padding_flush (&buf, true);
}

/* Fold __builtin_clear_padding builtin.  */

static bool
gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  gcc_assert (gimple_call_num_args (stmt) == 3);
  tree ptr = gimple_call_arg (stmt, 0);
  tree typearg = gimple_call_arg (stmt, 1);
  /* the 3rd argument of __builtin_clear_padding is to distinguish whether
     this call is made by the user or by the compiler for automatic variable
     initialization.  */
  bool for_auto_init = (bool) TREE_INT_CST_LOW (gimple_call_arg (stmt, 2));
  tree type = TREE_TYPE (TREE_TYPE (typearg));
  location_t loc = gimple_location (stmt);
  clear_padding_struct buf;
  gimple_stmt_iterator gsiprev = *gsi;
  /* This should be folded during the lower pass.  */
  gcc_assert (!gimple_in_ssa_p (cfun) && cfun->cfg == NULL);
  gcc_assert (COMPLETE_TYPE_P (type));
  gsi_prev (&gsiprev);

  buf.loc = loc;
  buf.clear_in_mask = false;
  buf.base = ptr;
  buf.alias_type = NULL_TREE;
  buf.gsi = gsi;
  buf.align = get_pointer_alignment (ptr);
  unsigned int talign = min_align_of_type (type) * BITS_PER_UNIT;
  buf.align = MAX (buf.align, talign);
  buf.off = 0;
  buf.padding_bytes = 0;
  buf.size = 0;
  buf.sz = int_size_in_bytes (type);
  buf.union_ptr = NULL;
  if (buf.sz < 0 && int_size_in_bytes (strip_array_types (type)) < 0)
    sorry_at (loc, "%s not supported for variable length aggregates",
	      "__builtin_clear_padding");
  /* The implementation currently assumes 8-bit host and target
     chars which is the case for all currently supported targets
     and hosts and is required e.g. for native_{encode,interpret}* APIs.  */
  else if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
    sorry_at (loc, "%s not supported on this target",
	      "__builtin_clear_padding");
  else if (!clear_padding_type_may_have_padding_p (type))
    ;
  else if (TREE_CODE (type) == ARRAY_TYPE && buf.sz < 0)
    {
      tree sz = TYPE_SIZE_UNIT (type);
      tree elttype = type;
      /* Only supports C/C++ VLAs and flattens all the VLA levels.  */
      while (TREE_CODE (elttype) == ARRAY_TYPE
	     && int_size_in_bytes (elttype) < 0)
	elttype = TREE_TYPE (elttype);
      HOST_WIDE_INT eltsz = int_size_in_bytes (elttype);
      gcc_assert (eltsz >= 0);
      if (eltsz)
	{
	  buf.base = create_tmp_var (build_pointer_type (elttype));
	  tree end = make_ssa_name (TREE_TYPE (buf.base));
	  gimple *g = gimple_build_assign (buf.base, ptr);
	  gimple_set_location (g, loc);
	  gsi_insert_before (gsi, g, GSI_SAME_STMT);
	  g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf.base, sz);
	  gimple_set_location (g, loc);
	  gsi_insert_before (gsi, g, GSI_SAME_STMT);
	  buf.sz = eltsz;
	  buf.align = TYPE_ALIGN (elttype);
	  buf.alias_type = build_pointer_type (elttype);
	  clear_padding_emit_loop (&buf, elttype, end, for_auto_init);
	}
    }
  else
    {
      if (!is_gimple_mem_ref_addr (buf.base))
	{
	  buf.base = make_ssa_name (TREE_TYPE (ptr));
	  gimple *g = gimple_build_assign (buf.base, ptr);
	  gimple_set_location (g, loc);
	  gsi_insert_before (gsi, g, GSI_SAME_STMT);
	}
      buf.alias_type = build_pointer_type (type);
      clear_padding_type (&buf, type, buf.sz, for_auto_init);
      clear_padding_flush (&buf, true);
    }

  gimple_stmt_iterator gsiprev2 = *gsi;
  gsi_prev (&gsiprev2);
  if (gsi_stmt (gsiprev) == gsi_stmt (gsiprev2))
    gsi_replace (gsi, gimple_build_nop (), true);
  else
    {
      gsi_remove (gsi, true);
      *gsi = gsiprev2;
    }
  return true;
}

/* Fold the non-target builtin at *GSI and return whether any simplification
   was made.  */

static bool
gimple_fold_builtin (gimple_stmt_iterator *gsi)
{
  gcall *stmt = as_a <gcall *>(gsi_stmt (*gsi));
  tree callee = gimple_call_fndecl (stmt);

  /* Give up for always_inline inline builtins until they are
     inlined.  */
  if (avoid_folding_inline_builtin (callee))
    return false;

  unsigned n = gimple_call_num_args (stmt);
  enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
  switch (fcode)
    {
    case BUILT_IN_BCMP:
      return gimple_fold_builtin_bcmp (gsi);
    case BUILT_IN_BCOPY:
      return gimple_fold_builtin_bcopy (gsi);
    case BUILT_IN_BZERO:
      return gimple_fold_builtin_bzero (gsi);

    case BUILT_IN_MEMSET:
      return gimple_fold_builtin_memset (gsi,
					 gimple_call_arg (stmt, 1),
					 gimple_call_arg (stmt, 2));
    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMPCPY:
    case BUILT_IN_MEMMOVE:
      return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
					    gimple_call_arg (stmt, 1), fcode);
    case BUILT_IN_SPRINTF_CHK:
    case BUILT_IN_VSPRINTF_CHK:
      return gimple_fold_builtin_sprintf_chk (gsi, fcode);
    case BUILT_IN_STRCAT_CHK:
      return gimple_fold_builtin_strcat_chk (gsi);
    case BUILT_IN_STRNCAT_CHK:
      return gimple_fold_builtin_strncat_chk (gsi);
    case BUILT_IN_STRLEN:
      return gimple_fold_builtin_strlen (gsi);
    case BUILT_IN_STRCPY:
      return gimple_fold_builtin_strcpy (gsi,
					 gimple_call_arg (stmt, 0),
					 gimple_call_arg (stmt, 1));
    case BUILT_IN_STRNCPY:
      return gimple_fold_builtin_strncpy (gsi,
					  gimple_call_arg (stmt, 0),
					  gimple_call_arg (stmt, 1),
					  gimple_call_arg (stmt, 2));
    case BUILT_IN_STRCAT:
      return gimple_fold_builtin_strcat (gsi, gimple_call_arg (stmt, 0),
					 gimple_call_arg (stmt, 1));
    case BUILT_IN_STRNCAT:
      return gimple_fold_builtin_strncat (gsi);
    case BUILT_IN_INDEX:
    case BUILT_IN_STRCHR:
      return gimple_fold_builtin_strchr (gsi, false);
    case BUILT_IN_RINDEX:
    case BUILT_IN_STRRCHR:
      return gimple_fold_builtin_strchr (gsi, true);
    case BUILT_IN_STRSTR:
      return gimple_fold_builtin_strstr (gsi);
    case BUILT_IN_STRCMP:
    case BUILT_IN_STRCMP_EQ:
    case BUILT_IN_STRCASECMP:
    case BUILT_IN_STRNCMP:
    case BUILT_IN_STRNCMP_EQ:
    case BUILT_IN_STRNCASECMP:
      return gimple_fold_builtin_string_compare (gsi);
    case BUILT_IN_MEMCHR:
      return gimple_fold_builtin_memchr (gsi);
    case BUILT_IN_FPUTS:
      return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
					gimple_call_arg (stmt, 1), false);
    case BUILT_IN_FPUTS_UNLOCKED:
      return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
					gimple_call_arg (stmt, 1), true);
    case BUILT_IN_MEMCPY_CHK:
    case BUILT_IN_MEMPCPY_CHK:
    case BUILT_IN_MEMMOVE_CHK:
    case BUILT_IN_MEMSET_CHK:
      return gimple_fold_builtin_memory_chk (gsi,
					     gimple_call_arg (stmt, 0),
					     gimple_call_arg (stmt, 1),
					     gimple_call_arg (stmt, 2),
					     gimple_call_arg (stmt, 3),
					     fcode);
    case BUILT_IN_STPCPY:
      return gimple_fold_builtin_stpcpy (gsi);
    case BUILT_IN_STRCPY_CHK:
    case BUILT_IN_STPCPY_CHK:
      return gimple_fold_builtin_stxcpy_chk (gsi,
					     gimple_call_arg (stmt, 0),
					     gimple_call_arg (stmt, 1),
					     gimple_call_arg (stmt, 2),
					     fcode);
    case BUILT_IN_STRNCPY_CHK:
    case BUILT_IN_STPNCPY_CHK:
      return gimple_fold_builtin_stxncpy_chk (gsi,
					      gimple_call_arg (stmt, 0),
					      gimple_call_arg (stmt, 1),
					      gimple_call_arg (stmt, 2),
					      gimple_call_arg (stmt, 3),
					      fcode);
    case BUILT_IN_SNPRINTF_CHK:
    case BUILT_IN_VSNPRINTF_CHK:
      return gimple_fold_builtin_snprintf_chk (gsi, fcode);

    case BUILT_IN_FPRINTF:
    case BUILT_IN_FPRINTF_UNLOCKED:
    case BUILT_IN_VFPRINTF:
      if (n == 2 || n == 3)
	return gimple_fold_builtin_fprintf (gsi,
					    gimple_call_arg (stmt, 0),
					    gimple_call_arg (stmt, 1),
					    n == 3
					    ? gimple_call_arg (stmt, 2)
					    : NULL_TREE,
					    fcode);
      break;
    case BUILT_IN_FPRINTF_CHK:
    case BUILT_IN_VFPRINTF_CHK:
      if (n == 3 || n == 4)
	return gimple_fold_builtin_fprintf (gsi,
					    gimple_call_arg (stmt, 0),
					    gimple_call_arg (stmt, 2),
					    n == 4
					    ? gimple_call_arg (stmt, 3)
					    : NULL_TREE,
					    fcode);
      break;
    case BUILT_IN_PRINTF:
    case BUILT_IN_PRINTF_UNLOCKED:
    case BUILT_IN_VPRINTF:
      if (n == 1 || n == 2)
	return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 0),
					   n == 2
					   ? gimple_call_arg (stmt, 1)
					   : NULL_TREE, fcode);
      break;
    case BUILT_IN_PRINTF_CHK:
    case BUILT_IN_VPRINTF_CHK:
      if (n == 2 || n == 3)
	return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 1),
					   n == 3
					   ? gimple_call_arg (stmt, 2)
					   : NULL_TREE, fcode);
      break;
    case BUILT_IN_ACC_ON_DEVICE:
      return gimple_fold_builtin_acc_on_device (gsi,
						gimple_call_arg (stmt, 0));
    case BUILT_IN_REALLOC:
      return gimple_fold_builtin_realloc (gsi);

    case BUILT_IN_CLEAR_PADDING:
      return gimple_fold_builtin_clear_padding (gsi);

    default:;
    }

  /* Try the generic builtin folder.  */
  bool ignore = (gimple_call_lhs (stmt) == NULL);
  tree result = fold_call_stmt (stmt, ignore);
  if (result)
    {
      if (ignore)
	STRIP_NOPS (result);
      else
	result = fold_convert (gimple_call_return_type (stmt), result);
      gimplify_and_update_call_from_tree (gsi, result);
      return true;
    }

  return false;
}

/* Transform IFN_GOACC_DIM_SIZE and IFN_GOACC_DIM_POS internal
   function calls to constants, where possible.  */

static tree
fold_internal_goacc_dim (const gimple *call)
{
  int axis = oacc_get_ifn_dim_arg (call);
  int size = oacc_get_fn_dim_size (current_function_decl, axis);
  tree result = NULL_TREE;
  tree type = TREE_TYPE (gimple_call_lhs (call));

  switch (gimple_call_internal_fn (call))
    {
    case IFN_GOACC_DIM_POS:
      /* If the size is 1, we know the answer.  */
      if (size == 1)
	result = build_int_cst (type, 0);
      break;
    case IFN_GOACC_DIM_SIZE:
      /* If the size is not dynamic, we know the answer.  */
      if (size)
	result = build_int_cst (type, size);
      break;
    default:
      break;
    }

  return result;
}

/* Return true if stmt is __atomic_compare_exchange_N call which is suitable
   for conversion into ATOMIC_COMPARE_EXCHANGE if the second argument is
   &var where var is only addressable because of such calls.  */

bool
optimize_atomic_compare_exchange_p (gimple *stmt)
{
  if (gimple_call_num_args (stmt) != 6
      || !flag_inline_atomics
      || !optimize
      || sanitize_flags_p (SANITIZE_THREAD | SANITIZE_ADDRESS)
      || !gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
      || !gimple_vdef (stmt)
      || !gimple_vuse (stmt))
    return false;

  tree fndecl = gimple_call_fndecl (stmt);
  switch (DECL_FUNCTION_CODE (fndecl))
    {
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
      break;
    default:
      return false;
    }

  tree expected = gimple_call_arg (stmt, 1);
  if (TREE_CODE (expected) != ADDR_EXPR
      || !SSA_VAR_P (TREE_OPERAND (expected, 0)))
    return false;

  tree etype = TREE_TYPE (TREE_OPERAND (expected, 0));
  if (!is_gimple_reg_type (etype)
      || !auto_var_in_fn_p (TREE_OPERAND (expected, 0), current_function_decl)
      || TREE_THIS_VOLATILE (etype)
      || VECTOR_TYPE_P (etype)
      || TREE_CODE (etype) == COMPLEX_TYPE
      /* Don't optimize floating point expected vars, VIEW_CONVERT_EXPRs
	 might not preserve all the bits.  See PR71716.  */
      || SCALAR_FLOAT_TYPE_P (etype)
      || maybe_ne (TYPE_PRECISION (etype),
		   GET_MODE_BITSIZE (TYPE_MODE (etype))))
    return false;

  tree weak = gimple_call_arg (stmt, 3);
  if (!integer_zerop (weak) && !integer_onep (weak))
    return false;

  tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
  tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
  machine_mode mode = TYPE_MODE (itype);

  if (direct_optab_handler (atomic_compare_and_swap_optab, mode)
      == CODE_FOR_nothing
      && optab_handler (sync_compare_and_swap_optab, mode) == CODE_FOR_nothing)
    return false;

  if (maybe_ne (int_size_in_bytes (etype), GET_MODE_SIZE (mode)))
    return false;

  return true;
}

/* Fold
     r = __atomic_compare_exchange_N (p, &e, d, w, s, f);
   into
     _Complex uintN_t t = ATOMIC_COMPARE_EXCHANGE (p, e, d, w * 256 + N, s, f);
     i = IMAGPART_EXPR <t>;
     r = (_Bool) i;
     e = REALPART_EXPR <t>;  */

void
fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree fndecl = gimple_call_fndecl (stmt);
  tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
  tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)));
  tree ctype = build_complex_type (itype);
  tree expected = TREE_OPERAND (gimple_call_arg (stmt, 1), 0);
  bool throws = false;
  edge e = NULL;
  gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
				   expected);
  gsi_insert_before (gsi, g, GSI_SAME_STMT);
  gimple_stmt_iterator gsiret = gsi_for_stmt (g);
  if (!useless_type_conversion_p (itype, TREE_TYPE (expected)))
    {
      g = gimple_build_assign (make_ssa_name (itype), VIEW_CONVERT_EXPR,
			       build1 (VIEW_CONVERT_EXPR, itype,
				       gimple_assign_lhs (g)));
      gsi_insert_before (gsi, g, GSI_SAME_STMT);
    }
  int flag = (integer_onep (gimple_call_arg (stmt, 3)) ? 256 : 0)
	     + int_size_in_bytes (itype);
  g = gimple_build_call_internal (IFN_ATOMIC_COMPARE_EXCHANGE, 6,
				  gimple_call_arg (stmt, 0),
				  gimple_assign_lhs (g),
				  gimple_call_arg (stmt, 2),
				  build_int_cst (integer_type_node, flag),
				  gimple_call_arg (stmt, 4),
				  gimple_call_arg (stmt, 5));
  tree lhs = make_ssa_name (ctype);
  gimple_call_set_lhs (g, lhs);
  gimple_move_vops (g, stmt);
  tree oldlhs = gimple_call_lhs (stmt);
  if (stmt_can_throw_internal (cfun, stmt))
    {
      throws = true;
      e = find_fallthru_edge (gsi_bb (*gsi)->succs);
    }
  gimple_call_set_nothrow (as_a <gcall *> (g),
			   gimple_call_nothrow_p (as_a <gcall *> (stmt)));
  gimple_call_set_lhs (stmt, NULL_TREE);
  gsi_replace (gsi, g, true);
  if (oldlhs)
    {
      g = gimple_build_assign (make_ssa_name (itype), IMAGPART_EXPR,
			       build1 (IMAGPART_EXPR, itype, lhs));
      if (throws)
	{
	  gsi_insert_on_edge_immediate (e, g);
	  *gsi = gsi_for_stmt (g);
	}
      else
	gsi_insert_after (gsi, g, GSI_NEW_STMT);
      g = gimple_build_assign (oldlhs, NOP_EXPR, gimple_assign_lhs (g));
      gsi_insert_after (gsi, g, GSI_NEW_STMT);
    }
  g = gimple_build_assign (make_ssa_name (itype), REALPART_EXPR,
			   build1 (REALPART_EXPR, itype, lhs));
  if (throws && oldlhs == NULL_TREE)
    {
      gsi_insert_on_edge_immediate (e, g);
      *gsi = gsi_for_stmt (g);
    }
  else
    gsi_insert_after (gsi, g, GSI_NEW_STMT);
  if (!useless_type_conversion_p (TREE_TYPE (expected), itype))
    {
      g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)),
			       VIEW_CONVERT_EXPR,
			       build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expected),
				       gimple_assign_lhs (g)));
      gsi_insert_after (gsi, g, GSI_NEW_STMT);
    }
  g = gimple_build_assign (expected, SSA_NAME, gimple_assign_lhs (g));
  gsi_insert_after (gsi, g, GSI_NEW_STMT);
  *gsi = gsiret;
}

/* Return true if ARG0 CODE ARG1 in infinite signed precision operation
   doesn't fit into TYPE.  The test for overflow should be regardless of
   -fwrapv, and even for unsigned types.  */

bool
arith_overflowed_p (enum tree_code code, const_tree type,
		    const_tree arg0, const_tree arg1)
{
  widest2_int warg0 = widest2_int_cst (arg0);
  widest2_int warg1 = widest2_int_cst (arg1);
  widest2_int wres;
  switch (code)
    {
    case PLUS_EXPR: wres = wi::add (warg0, warg1); break;
    case MINUS_EXPR: wres = wi::sub (warg0, warg1); break;
    case MULT_EXPR: wres = wi::mul (warg0, warg1); break;
    default: gcc_unreachable ();
    }
  signop sign = TYPE_SIGN (type);
  if (sign == UNSIGNED && wi::neg_p (wres))
    return true;
  return wi::min_precision (wres, sign) > TYPE_PRECISION (type);
}

/* If IFN_MASK_LOAD/STORE call CALL is unconditional, return a MEM_REF
   for the memory it references, otherwise return null.  VECTYPE is the
   type of the memory vector.  */

static tree
gimple_fold_mask_load_store_mem_ref (gcall *call, tree vectype)
{
  tree ptr = gimple_call_arg (call, 0);
  tree alias_align = gimple_call_arg (call, 1);
  tree mask = gimple_call_arg (call, 2);
  if (!tree_fits_uhwi_p (alias_align) || !integer_all_onesp (mask))
    return NULL_TREE;

  unsigned HOST_WIDE_INT align = tree_to_uhwi (alias_align);
  if (TYPE_ALIGN (vectype) != align)
    vectype = build_aligned_type (vectype, align);
  tree offset = build_zero_cst (TREE_TYPE (alias_align));
  return fold_build2 (MEM_REF, vectype, ptr, offset);
}

/* Try to fold IFN_MASK_LOAD call CALL.  Return true on success.  */

static bool
gimple_fold_mask_load (gimple_stmt_iterator *gsi, gcall *call)
{
  tree lhs = gimple_call_lhs (call);
  if (!lhs)
    return false;

  if (tree rhs = gimple_fold_mask_load_store_mem_ref (call, TREE_TYPE (lhs)))
    {
      gassign *new_stmt = gimple_build_assign (lhs, rhs);
      gimple_set_location (new_stmt, gimple_location (call));
      gimple_move_vops (new_stmt, call);
      gsi_replace (gsi, new_stmt, false);
      return true;
    }
  return false;
}

/* Try to fold IFN_MASK_STORE call CALL.  Return true on success.  */

static bool
gimple_fold_mask_store (gimple_stmt_iterator *gsi, gcall *call)
{
  tree rhs = gimple_call_arg (call, 3);
  if (tree lhs = gimple_fold_mask_load_store_mem_ref (call, TREE_TYPE (rhs)))
    {
      gassign *new_stmt = gimple_build_assign (lhs, rhs);
      gimple_set_location (new_stmt, gimple_location (call));
      gimple_move_vops (new_stmt, call);
      gsi_replace (gsi, new_stmt, false);
      return true;
    }
  return false;
}

/* Attempt to fold a call statement referenced by the statement iterator GSI.
   The statement may be replaced by another statement, e.g., if the call
   simplifies to a constant value. Return true if any changes were made.
   It is assumed that the operands have been previously folded.  */

static bool
gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
  tree callee;
  bool changed = false;

  /* Check for virtual calls that became direct calls.  */
  callee = gimple_call_fn (stmt);
  if (callee && TREE_CODE (callee) == OBJ_TYPE_REF)
    {
      if (gimple_call_addr_fndecl (OBJ_TYPE_REF_EXPR (callee)) != NULL_TREE)
	{
          if (dump_file && virtual_method_call_p (callee)
	      && !possible_polymorphic_call_target_p
		    (callee, stmt, cgraph_node::get (gimple_call_addr_fndecl
						     (OBJ_TYPE_REF_EXPR (callee)))))
	    {
	      fprintf (dump_file,
		       "Type inheritance inconsistent devirtualization of ");
	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	      fprintf (dump_file, " to ");
	      print_generic_expr (dump_file, callee, TDF_SLIM);
	      fprintf (dump_file, "\n");
	    }

	  gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee));
	  changed = true;
	}
      else if (flag_devirtualize && !inplace && virtual_method_call_p (callee))
	{
	  bool final;
	  vec <cgraph_node *>targets
	    = possible_polymorphic_call_targets (callee, stmt, &final);
	  if (final && targets.length () <= 1 && dbg_cnt (devirt))
	    {
	      tree lhs = gimple_call_lhs (stmt);
	      if (dump_enabled_p ())
		{
		  dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
				   "folding virtual function call to %s\n",
		 		   targets.length () == 1
		  		   ? targets[0]->name ()
		  		   : "__builtin_unreachable");
		}
	      if (targets.length () == 1)
		{
		  tree fndecl = targets[0]->decl;
		  gimple_call_set_fndecl (stmt, fndecl);
		  changed = true;
		  /* If changing the call to __cxa_pure_virtual
		     or similar noreturn function, adjust gimple_call_fntype
		     too.  */
		  if (gimple_call_noreturn_p (stmt)
		      && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
		      && TYPE_ARG_TYPES (TREE_TYPE (fndecl))
		      && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
			  == void_type_node))
		    gimple_call_set_fntype (stmt, TREE_TYPE (fndecl));
		  /* If the call becomes noreturn, remove the lhs.  */
		  if (lhs
		      && gimple_call_noreturn_p (stmt)
		      && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (stmt)))
			  || should_remove_lhs_p (lhs)))
		    {
		      if (TREE_CODE (lhs) == SSA_NAME)
			{
			  tree var = create_tmp_var (TREE_TYPE (lhs));
			  tree def = get_or_create_ssa_default_def (cfun, var);
			  gimple *new_stmt = gimple_build_assign (lhs, def);
			  gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
			}
		      gimple_call_set_lhs (stmt, NULL_TREE);
		    }
		  maybe_remove_unused_call_args (cfun, stmt);
		}
	      else
		{
		  tree fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
		  gimple *new_stmt = gimple_build_call (fndecl, 0);
		  gimple_set_location (new_stmt, gimple_location (stmt));
		  /* If the call had a SSA name as lhs morph that into
		     an uninitialized value.  */
		  if (lhs && TREE_CODE (lhs) == SSA_NAME)
		    {
		      tree var = create_tmp_var (TREE_TYPE (lhs));
		      SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var);
		      SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
		      set_ssa_default_def (cfun, var, lhs);
		    }
		  gimple_move_vops (new_stmt, stmt);
		  gsi_replace (gsi, new_stmt, false);
		  return true;
		}
	    }
	}
    }

  /* Check for indirect calls that became direct calls, and then
     no longer require a static chain.  */
  if (gimple_call_chain (stmt))
    {
      tree fn = gimple_call_fndecl (stmt);
      if (fn && !DECL_STATIC_CHAIN (fn))
	{
	  gimple_call_set_chain (stmt, NULL);
	  changed = true;
	}
    }

  if (inplace)
    return changed;

  /* Check for builtins that CCP can handle using information not
     available in the generic fold routines.  */
  if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    {
      if (gimple_fold_builtin (gsi))
        changed = true;
    }
  else if (gimple_call_builtin_p (stmt, BUILT_IN_MD))
    {
	changed |= targetm.gimple_fold_builtin (gsi);
    }
  else if (gimple_call_internal_p (stmt))
    {
      enum tree_code subcode = ERROR_MARK;
      tree result = NULL_TREE;
      bool cplx_result = false;
      tree overflow = NULL_TREE;
      switch (gimple_call_internal_fn (stmt))
	{
	case IFN_BUILTIN_EXPECT:
	  result = fold_builtin_expect (gimple_location (stmt),
					gimple_call_arg (stmt, 0),
					gimple_call_arg (stmt, 1),
					gimple_call_arg (stmt, 2),
					NULL_TREE);
	  break;
	case IFN_UBSAN_OBJECT_SIZE:
	  {
	    tree offset = gimple_call_arg (stmt, 1);
	    tree objsize = gimple_call_arg (stmt, 2);
	    if (integer_all_onesp (objsize)
		|| (TREE_CODE (offset) == INTEGER_CST
		    && TREE_CODE (objsize) == INTEGER_CST
		    && tree_int_cst_le (offset, objsize)))
	      {
		replace_call_with_value (gsi, NULL_TREE);
		return true;
	      }
	  }
	  break;
	case IFN_UBSAN_PTR:
	  if (integer_zerop (gimple_call_arg (stmt, 1)))
	    {
	      replace_call_with_value (gsi, NULL_TREE);
	      return true;
	    }
	  break;
	case IFN_UBSAN_BOUNDS:
	  {
	    tree index = gimple_call_arg (stmt, 1);
	    tree bound = gimple_call_arg (stmt, 2);
	    if (TREE_CODE (index) == INTEGER_CST
		&& TREE_CODE (bound) == INTEGER_CST)
	      {
		index = fold_convert (TREE_TYPE (bound), index);
		if (TREE_CODE (index) == INTEGER_CST
		    && tree_int_cst_le (index, bound))
		  {
		    replace_call_with_value (gsi, NULL_TREE);
		    return true;
		  }
	      }
	  }
	  break;
	case IFN_GOACC_DIM_SIZE:
	case IFN_GOACC_DIM_POS:
	  result = fold_internal_goacc_dim (stmt);
	  break;
	case IFN_UBSAN_CHECK_ADD:
	  subcode = PLUS_EXPR;
	  break;
	case IFN_UBSAN_CHECK_SUB:
	  subcode = MINUS_EXPR;
	  break;
	case IFN_UBSAN_CHECK_MUL:
	  subcode = MULT_EXPR;
	  break;
	case IFN_ADD_OVERFLOW:
	  subcode = PLUS_EXPR;
	  cplx_result = true;
	  break;
	case IFN_SUB_OVERFLOW:
	  subcode = MINUS_EXPR;
	  cplx_result = true;
	  break;
	case IFN_MUL_OVERFLOW:
	  subcode = MULT_EXPR;
	  cplx_result = true;
	  break;
	case IFN_MASK_LOAD:
	  changed |= gimple_fold_mask_load (gsi, stmt);
	  break;
	case IFN_MASK_STORE:
	  changed |= gimple_fold_mask_store (gsi, stmt);
	  break;
	default:
	  break;
	}
      if (subcode != ERROR_MARK)
	{
	  tree arg0 = gimple_call_arg (stmt, 0);
	  tree arg1 = gimple_call_arg (stmt, 1);
	  tree type = TREE_TYPE (arg0);
	  if (cplx_result)
	    {
	      tree lhs = gimple_call_lhs (stmt);
	      if (lhs == NULL_TREE)
		type = NULL_TREE;
	      else
		type = TREE_TYPE (TREE_TYPE (lhs));
	    }
	  if (type == NULL_TREE)
	    ;
	  /* x = y + 0; x = y - 0; x = y * 0; */
	  else if (integer_zerop (arg1))
	    result = subcode == MULT_EXPR ? integer_zero_node : arg0;
	  /* x = 0 + y; x = 0 * y; */
	  else if (subcode != MINUS_EXPR && integer_zerop (arg0))
	    result = subcode == MULT_EXPR ? integer_zero_node : arg1;
	  /* x = y - y; */
	  else if (subcode == MINUS_EXPR && operand_equal_p (arg0, arg1, 0))
	    result = integer_zero_node;
	  /* x = y * 1; x = 1 * y; */
	  else if (subcode == MULT_EXPR && integer_onep (arg1))
	    result = arg0;
	  else if (subcode == MULT_EXPR && integer_onep (arg0))
	    result = arg1;
	  else if (TREE_CODE (arg0) == INTEGER_CST
		   && TREE_CODE (arg1) == INTEGER_CST)
	    {
	      if (cplx_result)
		result = int_const_binop (subcode, fold_convert (type, arg0),
					  fold_convert (type, arg1));
	      else
		result = int_const_binop (subcode, arg0, arg1);
	      if (result && arith_overflowed_p (subcode, type, arg0, arg1))
		{
		  if (cplx_result)
		    overflow = build_one_cst (type);
		  else
		    result = NULL_TREE;
		}
	    }
	  if (result)
	    {
	      if (result == integer_zero_node)
		result = build_zero_cst (type);
	      else if (cplx_result && TREE_TYPE (result) != type)
		{
		  if (TREE_CODE (result) == INTEGER_CST)
		    {
		      if (arith_overflowed_p (PLUS_EXPR, type, result,
					      integer_zero_node))
			overflow = build_one_cst (type);
		    }
		  else if ((!TYPE_UNSIGNED (TREE_TYPE (result))
			    && TYPE_UNSIGNED (type))
			   || (TYPE_PRECISION (type)
			       < (TYPE_PRECISION (TREE_TYPE (result))
				  + (TYPE_UNSIGNED (TREE_TYPE (result))
				     && !TYPE_UNSIGNED (type)))))
		    result = NULL_TREE;
		  if (result)
		    result = fold_convert (type, result);
		}
	    }
	}

      if (result)
	{
	  if (TREE_CODE (result) == INTEGER_CST && TREE_OVERFLOW (result))
	    result = drop_tree_overflow (result);
	  if (cplx_result)
	    {
	      if (overflow == NULL_TREE)
		overflow = build_zero_cst (TREE_TYPE (result));
	      tree ctype = build_complex_type (TREE_TYPE (result));
	      if (TREE_CODE (result) == INTEGER_CST
		  && TREE_CODE (overflow) == INTEGER_CST)
		result = build_complex (ctype, result, overflow);
	      else
		result = build2_loc (gimple_location (stmt), COMPLEX_EXPR,
				     ctype, result, overflow);
	    }
	  gimplify_and_update_call_from_tree (gsi, result);
	  changed = true;
	}
    }

  return changed;
}


/* Return true whether NAME has a use on STMT.  */

static bool
has_use_on_stmt (tree name, gimple *stmt)
{
  imm_use_iterator iter;
  use_operand_p use_p;
  FOR_EACH_IMM_USE_FAST (use_p, iter, name)
    if (USE_STMT (use_p) == stmt)
      return true;
  return false;
}

/* Worker for fold_stmt_1 dispatch to pattern based folding with
   gimple_simplify.

   Replaces *GSI with the simplification result in RCODE and OPS
   and the associated statements in *SEQ.  Does the replacement
   according to INPLACE and returns true if the operation succeeded.  */

static bool
replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
				  gimple_match_op *res_op,
				  gimple_seq *seq, bool inplace)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree *ops = res_op->ops;
  unsigned int num_ops = res_op->num_ops;

  /* Play safe and do not allow abnormals to be mentioned in
     newly created statements.  See also maybe_push_res_to_seq.
     As an exception allow such uses if there was a use of the
     same SSA name on the old stmt.  */
  for (unsigned int i = 0; i < num_ops; ++i)
    if (TREE_CODE (ops[i]) == SSA_NAME
	&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i])
	&& !has_use_on_stmt (ops[i], stmt))
      return false;

  if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
    for (unsigned int i = 0; i < 2; ++i)
      if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
	  && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i))
	  && !has_use_on_stmt (TREE_OPERAND (ops[0], i), stmt))
	return false;

  /* Don't insert new statements when INPLACE is true, even if we could
     reuse STMT for the final statement.  */
  if (inplace && !gimple_seq_empty_p (*seq))
    return false;

  if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
    {
      gcc_assert (res_op->code.is_tree_code ());
      if (TREE_CODE_CLASS ((enum tree_code) res_op->code) == tcc_comparison
	  /* GIMPLE_CONDs condition may not throw.  */
	  && (!flag_exceptions
	      || !cfun->can_throw_non_call_exceptions
	      || !operation_could_trap_p (res_op->code,
					  FLOAT_TYPE_P (TREE_TYPE (ops[0])),
					  false, NULL_TREE)))
	gimple_cond_set_condition (cond_stmt, res_op->code, ops[0], ops[1]);
      else if (res_op->code == SSA_NAME)
	gimple_cond_set_condition (cond_stmt, NE_EXPR, ops[0],
				   build_zero_cst (TREE_TYPE (ops[0])));
      else if (res_op->code == INTEGER_CST)
	{
	  if (integer_zerop (ops[0]))
	    gimple_cond_make_false (cond_stmt);
	  else
	    gimple_cond_make_true (cond_stmt);
	}
      else if (!inplace)
	{
	  tree res = maybe_push_res_to_seq (res_op, seq);
	  if (!res)
	    return false;
	  gimple_cond_set_condition (cond_stmt, NE_EXPR, res,
				     build_zero_cst (TREE_TYPE (res)));
	}
      else
	return false;
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "gimple_simplified to ");
	  if (!gimple_seq_empty_p (*seq))
	    print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
	  print_gimple_stmt (dump_file, gsi_stmt (*gsi),
			     0, TDF_SLIM);
	}
      gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
      return true;
    }
  else if (is_gimple_assign (stmt)
	   && res_op->code.is_tree_code ())
    {
      if (!inplace
	  || gimple_num_ops (stmt) > get_gimple_rhs_num_ops (res_op->code))
	{
	  maybe_build_generic_op (res_op);
	  gimple_assign_set_rhs_with_ops (gsi, res_op->code,
					  res_op->op_or_null (0),
					  res_op->op_or_null (1),
					  res_op->op_or_null (2));
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "gimple_simplified to ");
	      if (!gimple_seq_empty_p (*seq))
		print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
	      print_gimple_stmt (dump_file, gsi_stmt (*gsi),
				 0, TDF_SLIM);
	    }
	  gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
	  return true;
	}
    }
  else if (res_op->code.is_fn_code ()
	   && gimple_call_combined_fn (stmt) == res_op->code)
    {
      gcc_assert (num_ops == gimple_call_num_args (stmt));
      for (unsigned int i = 0; i < num_ops; ++i)
	gimple_call_set_arg (stmt, i, ops[i]);
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "gimple_simplified to ");
	  if (!gimple_seq_empty_p (*seq))
	    print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
	  print_gimple_stmt (dump_file, gsi_stmt (*gsi), 0, TDF_SLIM);
	}
      gsi_insert_seq_before (gsi, *seq, GSI_SAME_STMT);
      return true;
    }
  else if (!inplace)
    {
      if (gimple_has_lhs (stmt))
	{
	  tree lhs = gimple_get_lhs (stmt);
	  if (!maybe_push_res_to_seq (res_op, seq, lhs))
	    return false;
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file, "gimple_simplified to ");
	      print_gimple_seq (dump_file, *seq, 0, TDF_SLIM);
	    }
	  gsi_replace_with_seq_vops (gsi, *seq);
	  return true;
	}
      else
	gcc_unreachable ();
    }

  return false;
}

/* Canonicalize MEM_REFs invariant address operand after propagation.  */

static bool
maybe_canonicalize_mem_ref_addr (tree *t, bool is_debug = false)
{
  bool res = false;
  tree *orig_t = t;

  if (TREE_CODE (*t) == ADDR_EXPR)
    t = &TREE_OPERAND (*t, 0);

  /* The C and C++ frontends use an ARRAY_REF for indexing with their
     generic vector extension.  The actual vector referenced is
     view-converted to an array type for this purpose.  If the index
     is constant the canonical representation in the middle-end is a
     BIT_FIELD_REF so re-write the former to the latter here.  */
  if (TREE_CODE (*t) == ARRAY_REF
      && TREE_CODE (TREE_OPERAND (*t, 0)) == VIEW_CONVERT_EXPR
      && TREE_CODE (TREE_OPERAND (*t, 1)) == INTEGER_CST
      && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))))
    {
      tree vtype = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0));
      if (VECTOR_TYPE_P (vtype))
	{
	  tree low = array_ref_low_bound (*t);
	  if (TREE_CODE (low) == INTEGER_CST)
	    {
	      if (tree_int_cst_le (low, TREE_OPERAND (*t, 1)))
		{
		  widest_int idx = wi::sub (wi::to_widest (TREE_OPERAND (*t, 1)),
					    wi::to_widest (low));
		  idx = wi::mul (idx, wi::to_widest
					 (TYPE_SIZE (TREE_TYPE (*t))));
		  widest_int ext
		    = wi::add (idx, wi::to_widest (TYPE_SIZE (TREE_TYPE (*t))));
		  if (wi::les_p (ext, wi::to_widest (TYPE_SIZE (vtype))))
		    {
		      *t = build3_loc (EXPR_LOCATION (*t), BIT_FIELD_REF,
				       TREE_TYPE (*t),
				       TREE_OPERAND (TREE_OPERAND (*t, 0), 0),
				       TYPE_SIZE (TREE_TYPE (*t)),
				       wide_int_to_tree (bitsizetype, idx));
		      res = true;
		    }
		}
	    }
	}
    }

  while (handled_component_p (*t))
    t = &TREE_OPERAND (*t, 0);

  /* Canonicalize MEM [&foo.bar, 0] which appears after propagating
     of invariant addresses into a SSA name MEM_REF address.  */
  if (TREE_CODE (*t) == MEM_REF
      || TREE_CODE (*t) == TARGET_MEM_REF)
    {
      tree addr = TREE_OPERAND (*t, 0);
      if (TREE_CODE (addr) == ADDR_EXPR
	  && (TREE_CODE (TREE_OPERAND (addr, 0)) == MEM_REF
	      || handled_component_p (TREE_OPERAND (addr, 0))))
	{
	  tree base;
	  poly_int64 coffset;
	  base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
						&coffset);
	  if (!base)
	    {
	      if (is_debug)
		return false;
	      gcc_unreachable ();
	    }

	  TREE_OPERAND (*t, 0) = build_fold_addr_expr (base);
	  TREE_OPERAND (*t, 1) = int_const_binop (PLUS_EXPR,
						  TREE_OPERAND (*t, 1),
						  size_int (coffset));
	  res = true;
	}
      gcc_checking_assert (TREE_CODE (TREE_OPERAND (*t, 0)) == DEBUG_EXPR_DECL
			   || is_gimple_mem_ref_addr (TREE_OPERAND (*t, 0)));
    }

  /* Canonicalize back MEM_REFs to plain reference trees if the object
     accessed is a decl that has the same access semantics as the MEM_REF.  */
  if (TREE_CODE (*t) == MEM_REF
      && TREE_CODE (TREE_OPERAND (*t, 0)) == ADDR_EXPR
      && integer_zerop (TREE_OPERAND (*t, 1))
      && MR_DEPENDENCE_CLIQUE (*t) == 0)
    {
      tree decl = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
      tree alias_type = TREE_TYPE (TREE_OPERAND (*t, 1));
      if (/* Same volatile qualification.  */
	  TREE_THIS_VOLATILE (*t) == TREE_THIS_VOLATILE (decl)
	  /* Same TBAA behavior with -fstrict-aliasing.  */
	  && !TYPE_REF_CAN_ALIAS_ALL (alias_type)
	  && (TYPE_MAIN_VARIANT (TREE_TYPE (decl))
	      == TYPE_MAIN_VARIANT (TREE_TYPE (alias_type)))
	  /* Same alignment.  */
	  && TYPE_ALIGN (TREE_TYPE (decl)) == TYPE_ALIGN (TREE_TYPE (*t))
	  /* We have to look out here to not drop a required conversion
	     from the rhs to the lhs if *t appears on the lhs or vice-versa
	     if it appears on the rhs.  Thus require strict type
	     compatibility.  */
	  && types_compatible_p (TREE_TYPE (*t), TREE_TYPE (decl)))
	{
	  *t = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
	  res = true;
	}
    }

  else if (TREE_CODE (*orig_t) == ADDR_EXPR
	   && TREE_CODE (*t) == MEM_REF
	   && TREE_CODE (TREE_OPERAND (*t, 0)) == INTEGER_CST)
    {
      tree base;
      poly_int64 coffset;
      base = get_addr_base_and_unit_offset (TREE_OPERAND (*orig_t, 0),
					    &coffset);
      if (base)
	{
	  gcc_assert (TREE_CODE (base) == MEM_REF);
	  poly_int64 moffset;
	  if (mem_ref_offset (base).to_shwi (&moffset))
	    {
	      coffset += moffset;
	      if (wi::to_poly_wide (TREE_OPERAND (base, 0)).to_shwi (&moffset))
		{
		  coffset += moffset;
		  *orig_t = build_int_cst (TREE_TYPE (*orig_t), coffset);
		  return true;
		}
	    }
	}
    }

  /* Canonicalize TARGET_MEM_REF in particular with respect to
     the indexes becoming constant.  */
  else if (TREE_CODE (*t) == TARGET_MEM_REF)
    {
      tree tem = maybe_fold_tmr (*t);
      if (tem)
	{
	  *t = tem;
	  if (TREE_CODE (*orig_t) == ADDR_EXPR)
	    recompute_tree_invariant_for_addr_expr (*orig_t);
	  res = true;
	}
    }

  return res;
}

/* Worker for both fold_stmt and fold_stmt_inplace.  The INPLACE argument
   distinguishes both cases.  */

static bool
fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
{
  bool changed = false;
  gimple *stmt = gsi_stmt (*gsi);
  bool nowarning = warning_suppressed_p (stmt, OPT_Wstrict_overflow);
  unsigned i;
  fold_defer_overflow_warnings ();

  /* First do required canonicalization of [TARGET_]MEM_REF addresses
     after propagation.
     ???  This shouldn't be done in generic folding but in the
     propagation helpers which also know whether an address was
     propagated.
     Also canonicalize operand order.  */
  switch (gimple_code (stmt))
    {
    case GIMPLE_ASSIGN:
      if (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
	{
	  tree *rhs = gimple_assign_rhs1_ptr (stmt);
	  if ((REFERENCE_CLASS_P (*rhs)
	       || TREE_CODE (*rhs) == ADDR_EXPR)
	      && maybe_canonicalize_mem_ref_addr (rhs))
	    changed = true;
	  tree *lhs = gimple_assign_lhs_ptr (stmt);
	  if (REFERENCE_CLASS_P (*lhs)
	      && maybe_canonicalize_mem_ref_addr (lhs))
	    changed = true;
	}
      else
	{
	  /* Canonicalize operand order.  */
	  enum tree_code code = gimple_assign_rhs_code (stmt);
	  if (TREE_CODE_CLASS (code) == tcc_comparison
	      || commutative_tree_code (code)
	      || commutative_ternary_tree_code (code))
	    {
	      tree rhs1 = gimple_assign_rhs1 (stmt);
	      tree rhs2 = gimple_assign_rhs2 (stmt);
	      if (tree_swap_operands_p (rhs1, rhs2))
		{
		  gimple_assign_set_rhs1 (stmt, rhs2);
		  gimple_assign_set_rhs2 (stmt, rhs1);
		  if (TREE_CODE_CLASS (code) == tcc_comparison)
		    gimple_assign_set_rhs_code (stmt,
						swap_tree_comparison (code));
		  changed = true;
		}
	    }
	}
      break;
    case GIMPLE_CALL:
      {
	for (i = 0; i < gimple_call_num_args (stmt); ++i)
	  {
	    tree *arg = gimple_call_arg_ptr (stmt, i);
	    if (REFERENCE_CLASS_P (*arg)
		&& maybe_canonicalize_mem_ref_addr (arg))
	      changed = true;
	  }
	tree *lhs = gimple_call_lhs_ptr (stmt);
	if (*lhs
	    && REFERENCE_CLASS_P (*lhs)
	    && maybe_canonicalize_mem_ref_addr (lhs))
	  changed = true;
	break;
      }
    case GIMPLE_ASM:
      {
	gasm *asm_stmt = as_a <gasm *> (stmt);
	for (i = 0; i < gimple_asm_noutputs (asm_stmt); ++i)
	  {
	    tree link = gimple_asm_output_op (asm_stmt, i);
	    tree op = TREE_VALUE (link);
	    if (REFERENCE_CLASS_P (op)
		&& maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
	      changed = true;
	  }
	for (i = 0; i < gimple_asm_ninputs (asm_stmt); ++i)
	  {
	    tree link = gimple_asm_input_op (asm_stmt, i);
	    tree op = TREE_VALUE (link);
	    if ((REFERENCE_CLASS_P (op)
		 || TREE_CODE (op) == ADDR_EXPR)
		&& maybe_canonicalize_mem_ref_addr (&TREE_VALUE (link)))
	      changed = true;
	  }
      }
      break;
    case GIMPLE_DEBUG:
      if (gimple_debug_bind_p (stmt))
	{
	  tree *val = gimple_debug_bind_get_value_ptr (stmt);
	  if (*val
	      && (REFERENCE_CLASS_P (*val)
		  || TREE_CODE (*val) == ADDR_EXPR)
	      && maybe_canonicalize_mem_ref_addr (val, true))
	    changed = true;
	}
      break;
    case GIMPLE_COND:
      {
	/* Canonicalize operand order.  */
	tree lhs = gimple_cond_lhs (stmt);
	tree rhs = gimple_cond_rhs (stmt);
	if (tree_swap_operands_p (lhs, rhs))
	  {
	    gcond *gc = as_a <gcond *> (stmt);
	    gimple_cond_set_lhs (gc, rhs);
	    gimple_cond_set_rhs (gc, lhs);
	    gimple_cond_set_code (gc,
				  swap_tree_comparison (gimple_cond_code (gc)));
	    changed = true;
	  }
      }
    default:;
    }

  /* Dispatch to pattern-based folding.  */
  if (!inplace
      || is_gimple_assign (stmt)
      || gimple_code (stmt) == GIMPLE_COND)
    {
      gimple_seq seq = NULL;
      gimple_match_op res_op;
      if (gimple_simplify (stmt, &res_op, inplace ? NULL : &seq,
			   valueize, valueize))
	{
	  if (replace_stmt_with_simplification (gsi, &res_op, &seq, inplace))
	    changed = true;
	  else
	    gimple_seq_discard (seq);
	}
    }

  stmt = gsi_stmt (*gsi);

  /* Fold the main computation performed by the statement.  */
  switch (gimple_code (stmt))
    {
    case GIMPLE_ASSIGN:
      {
	/* Try to canonicalize for boolean-typed X the comparisons
	   X == 0, X == 1, X != 0, and X != 1.  */
	if (gimple_assign_rhs_code (stmt) == EQ_EXPR
	    || gimple_assign_rhs_code (stmt) == NE_EXPR)
	  {
	    tree lhs = gimple_assign_lhs (stmt);
	    tree op1 = gimple_assign_rhs1 (stmt);
	    tree op2 = gimple_assign_rhs2 (stmt);
	    tree type = TREE_TYPE (op1);

	    /* Check whether the comparison operands are of the same boolean
	       type as the result type is.
	       Check that second operand is an integer-constant with value
	       one or zero.  */
	    if (TREE_CODE (op2) == INTEGER_CST
		&& (integer_zerop (op2) || integer_onep (op2))
		&& useless_type_conversion_p (TREE_TYPE (lhs), type))
	      {
		enum tree_code cmp_code = gimple_assign_rhs_code (stmt);
		bool is_logical_not = false;

		/* X == 0 and X != 1 is a logical-not.of X
		   X == 1 and X != 0 is X  */
		if ((cmp_code == EQ_EXPR && integer_zerop (op2))
		    || (cmp_code == NE_EXPR && integer_onep (op2)))
		  is_logical_not = true;

		if (is_logical_not == false)
		  gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op1), op1);
		/* Only for one-bit precision typed X the transformation
		   !X -> ~X is valied.  */
		else if (TYPE_PRECISION (type) == 1)
		  gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, op1);
		/* Otherwise we use !X -> X ^ 1.  */
		else
		  gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op1,
						  build_int_cst (type, 1));
		changed = true;
		break;
	      }
	  }

	unsigned old_num_ops = gimple_num_ops (stmt);
	tree lhs = gimple_assign_lhs (stmt);
	tree new_rhs = fold_gimple_assign (gsi);
	if (new_rhs
	    && !useless_type_conversion_p (TREE_TYPE (lhs),
					   TREE_TYPE (new_rhs)))
	  new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs);
	if (new_rhs
	    && (!inplace
		|| get_gimple_rhs_num_ops (TREE_CODE (new_rhs)) < old_num_ops))
	  {
	    gimple_assign_set_rhs_from_tree (gsi, new_rhs);
	    changed = true;
	  }
	break;
      }

    case GIMPLE_CALL:
      changed |= gimple_fold_call (gsi, inplace);
      break;

    case GIMPLE_DEBUG:
      if (gimple_debug_bind_p (stmt))
	{
	  tree val = gimple_debug_bind_get_value (stmt);
	  if (val
	      && REFERENCE_CLASS_P (val))
	    {
	      tree tem = maybe_fold_reference (val);
	      if (tem)
		{
		  gimple_debug_bind_set_value (stmt, tem);
		  changed = true;
		}
	    }
	  else if (val
		   && TREE_CODE (val) == ADDR_EXPR)
	    {
	      tree ref = TREE_OPERAND (val, 0);
	      tree tem = maybe_fold_reference (ref);
	      if (tem)
		{
		  tem = build_fold_addr_expr_with_type (tem, TREE_TYPE (val));
		  gimple_debug_bind_set_value (stmt, tem);
		  changed = true;
		}
	    }
	}
      break;

    case GIMPLE_RETURN:
      {
	greturn *ret_stmt = as_a<greturn *> (stmt);
	tree ret = gimple_return_retval(ret_stmt);

	if (ret && TREE_CODE (ret) == SSA_NAME && valueize)
	  {
	    tree val = valueize (ret);
	    if (val && val != ret
		&& may_propagate_copy (ret, val))
	      {
		gimple_return_set_retval (ret_stmt, val);
		changed = true;
	      }
	  }
      }
      break;

    default:;
    }

  stmt = gsi_stmt (*gsi);

  fold_undefer_overflow_warnings (changed && !nowarning, stmt, 0);
  return changed;
}

/* Valueziation callback that ends up not following SSA edges.  */

tree
no_follow_ssa_edges (tree)
{
  return NULL_TREE;
}

/* Valueization callback that ends up following single-use SSA edges only.  */

tree
follow_single_use_edges (tree val)
{
  if (TREE_CODE (val) == SSA_NAME
      && !has_single_use (val))
    return NULL_TREE;
  return val;
}

/* Valueization callback that follows all SSA edges.  */

tree
follow_all_ssa_edges (tree val)
{
  return val;
}

/* Fold the statement pointed to by GSI.  In some cases, this function may
   replace the whole statement with a new one.  Returns true iff folding
   makes any changes.
   The statement pointed to by GSI should be in valid gimple form but may
   be in unfolded state as resulting from for example constant propagation
   which can produce *&x = 0.  */

bool
fold_stmt (gimple_stmt_iterator *gsi)
{
  return fold_stmt_1 (gsi, false, no_follow_ssa_edges);
}

bool
fold_stmt (gimple_stmt_iterator *gsi, tree (*valueize) (tree))
{
  return fold_stmt_1 (gsi, false, valueize);
}

/* Perform the minimal folding on statement *GSI.  Only operations like
   *&x created by constant propagation are handled.  The statement cannot
   be replaced with a new one.  Return true if the statement was
   changed, false otherwise.
   The statement *GSI should be in valid gimple form but may
   be in unfolded state as resulting from for example constant propagation
   which can produce *&x = 0.  */

bool
fold_stmt_inplace (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  bool changed = fold_stmt_1 (gsi, true, no_follow_ssa_edges);
  gcc_assert (gsi_stmt (*gsi) == stmt);
  return changed;
}

/* Canonicalize and possibly invert the boolean EXPR; return NULL_TREE 
   if EXPR is null or we don't know how.
   If non-null, the result always has boolean type.  */

static tree
canonicalize_bool (tree expr, bool invert)
{
  if (!expr)
    return NULL_TREE;
  else if (invert)
    {
      if (integer_nonzerop (expr))
	return boolean_false_node;
      else if (integer_zerop (expr))
	return boolean_true_node;
      else if (TREE_CODE (expr) == SSA_NAME)
	return fold_build2 (EQ_EXPR, boolean_type_node, expr,
			    build_int_cst (TREE_TYPE (expr), 0));
      else if (COMPARISON_CLASS_P (expr))
	return fold_build2 (invert_tree_comparison (TREE_CODE (expr), false),
			    boolean_type_node,
			    TREE_OPERAND (expr, 0),
			    TREE_OPERAND (expr, 1));
      else
	return NULL_TREE;
    }
  else
    {
      if (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
	return expr;
      if (integer_nonzerop (expr))
	return boolean_true_node;
      else if (integer_zerop (expr))
	return boolean_false_node;
      else if (TREE_CODE (expr) == SSA_NAME)
	return fold_build2 (NE_EXPR, boolean_type_node, expr,
			    build_int_cst (TREE_TYPE (expr), 0));
      else if (COMPARISON_CLASS_P (expr))
	return fold_build2 (TREE_CODE (expr),
			    boolean_type_node,
			    TREE_OPERAND (expr, 0),
			    TREE_OPERAND (expr, 1));
      else
	return NULL_TREE;
    }
}

/* Check to see if a boolean expression EXPR is logically equivalent to the
   comparison (OP1 CODE OP2).  Check for various identities involving
   SSA_NAMEs.  */

static bool
same_bool_comparison_p (const_tree expr, enum tree_code code,
			const_tree op1, const_tree op2)
{
  gimple *s;

  /* The obvious case.  */
  if (TREE_CODE (expr) == code
      && operand_equal_p (TREE_OPERAND (expr, 0), op1, 0)
      && operand_equal_p (TREE_OPERAND (expr, 1), op2, 0))
    return true;

  /* Check for comparing (name, name != 0) and the case where expr
     is an SSA_NAME with a definition matching the comparison.  */
  if (TREE_CODE (expr) == SSA_NAME
      && TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE)
    {
      if (operand_equal_p (expr, op1, 0))
	return ((code == NE_EXPR && integer_zerop (op2))
		|| (code == EQ_EXPR && integer_nonzerop (op2)));
      s = SSA_NAME_DEF_STMT (expr);
      if (is_gimple_assign (s)
	  && gimple_assign_rhs_code (s) == code
	  && operand_equal_p (gimple_assign_rhs1 (s), op1, 0)
	  && operand_equal_p (gimple_assign_rhs2 (s), op2, 0))
	return true;
    }

  /* If op1 is of the form (name != 0) or (name == 0), and the definition
     of name is a comparison, recurse.  */
  if (TREE_CODE (op1) == SSA_NAME
      && TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE)
    {
      s = SSA_NAME_DEF_STMT (op1);
      if (is_gimple_assign (s)
	  && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison)
	{
	  enum tree_code c = gimple_assign_rhs_code (s);
	  if ((c == NE_EXPR && integer_zerop (op2))
	      || (c == EQ_EXPR && integer_nonzerop (op2)))
	    return same_bool_comparison_p (expr, c,
					   gimple_assign_rhs1 (s),
					   gimple_assign_rhs2 (s));
	  if ((c == EQ_EXPR && integer_zerop (op2))
	      || (c == NE_EXPR && integer_nonzerop (op2)))
	    return same_bool_comparison_p (expr,
					   invert_tree_comparison (c, false),
					   gimple_assign_rhs1 (s),
					   gimple_assign_rhs2 (s));
	}
    }
  return false;
}

/* Check to see if two boolean expressions OP1 and OP2 are logically
   equivalent.  */

static bool
same_bool_result_p (const_tree op1, const_tree op2)
{
  /* Simple cases first.  */
  if (operand_equal_p (op1, op2, 0))
    return true;

  /* Check the cases where at least one of the operands is a comparison.
     These are a bit smarter than operand_equal_p in that they apply some
     identifies on SSA_NAMEs.  */
  if (COMPARISON_CLASS_P (op2)
      && same_bool_comparison_p (op1, TREE_CODE (op2),
				 TREE_OPERAND (op2, 0),
				 TREE_OPERAND (op2, 1)))
    return true;
  if (COMPARISON_CLASS_P (op1)
      && same_bool_comparison_p (op2, TREE_CODE (op1),
				 TREE_OPERAND (op1, 0),
				 TREE_OPERAND (op1, 1)))
    return true;

  /* Default case.  */
  return false;
}

/* Forward declarations for some mutually recursive functions.  */

static tree
and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
		   enum tree_code code2, tree op2a, tree op2b);
static tree
and_var_with_comparison (tree type, tree var, bool invert,
			 enum tree_code code2, tree op2a, tree op2b);
static tree
and_var_with_comparison_1 (tree type, gimple *stmt,
			   enum tree_code code2, tree op2a, tree op2b);
static tree
or_comparisons_1 (tree, enum tree_code code1, tree op1a, tree op1b,
		  enum tree_code code2, tree op2a, tree op2b);
static tree
or_var_with_comparison (tree, tree var, bool invert,
			enum tree_code code2, tree op2a, tree op2b);
static tree
or_var_with_comparison_1 (tree, gimple *stmt,
			  enum tree_code code2, tree op2a, tree op2b);

/* Helper function for and_comparisons_1:  try to simplify the AND of the
   ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
   If INVERT is true, invert the value of the VAR before doing the AND.
   Return NULL_EXPR if we can't simplify this to a single expression.  */

static tree
and_var_with_comparison (tree type, tree var, bool invert,
			 enum tree_code code2, tree op2a, tree op2b)
{
  tree t;
  gimple *stmt = SSA_NAME_DEF_STMT (var);

  /* We can only deal with variables whose definitions are assignments.  */
  if (!is_gimple_assign (stmt))
    return NULL_TREE;
  
  /* If we have an inverted comparison, apply DeMorgan's law and rewrite
     !var AND (op2a code2 op2b) => !(var OR !(op2a code2 op2b))
     Then we only have to consider the simpler non-inverted cases.  */
  if (invert)
    t = or_var_with_comparison_1 (type, stmt,
				  invert_tree_comparison (code2, false),
				  op2a, op2b);
  else
    t = and_var_with_comparison_1 (type, stmt, code2, op2a, op2b);
  return canonicalize_bool (t, invert);
}

/* Try to simplify the AND of the ssa variable defined by the assignment
   STMT with the comparison specified by (OP2A CODE2 OP2B).
   Return NULL_EXPR if we can't simplify this to a single expression.  */

static tree
and_var_with_comparison_1 (tree type, gimple *stmt,
			   enum tree_code code2, tree op2a, tree op2b)
{
  tree var = gimple_assign_lhs (stmt);
  tree true_test_var = NULL_TREE;
  tree false_test_var = NULL_TREE;
  enum tree_code innercode = gimple_assign_rhs_code (stmt);

  /* Check for identities like (var AND (var == 0)) => false.  */
  if (TREE_CODE (op2a) == SSA_NAME
      && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
    {
      if ((code2 == NE_EXPR && integer_zerop (op2b))
	  || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
	{
	  true_test_var = op2a;
	  if (var == true_test_var)
	    return var;
	}
      else if ((code2 == EQ_EXPR && integer_zerop (op2b))
	       || (code2 == NE_EXPR && integer_nonzerop (op2b)))
	{
	  false_test_var = op2a;
	  if (var == false_test_var)
	    return boolean_false_node;
	}
    }

  /* If the definition is a comparison, recurse on it.  */
  if (TREE_CODE_CLASS (innercode) == tcc_comparison)
    {
      tree t = and_comparisons_1 (type, innercode,
				  gimple_assign_rhs1 (stmt),
				  gimple_assign_rhs2 (stmt),
				  code2,
				  op2a,
				  op2b);
      if (t)
	return t;
    }

  /* If the definition is an AND or OR expression, we may be able to
     simplify by reassociating.  */
  if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
      && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
    {
      tree inner1 = gimple_assign_rhs1 (stmt);
      tree inner2 = gimple_assign_rhs2 (stmt);
      gimple *s;
      tree t;
      tree partial = NULL_TREE;
      bool is_and = (innercode == BIT_AND_EXPR);
      
      /* Check for boolean identities that don't require recursive examination
	 of inner1/inner2:
	 inner1 AND (inner1 AND inner2) => inner1 AND inner2 => var
	 inner1 AND (inner1 OR inner2) => inner1
	 !inner1 AND (inner1 AND inner2) => false
	 !inner1 AND (inner1 OR inner2) => !inner1 AND inner2
         Likewise for similar cases involving inner2.  */
      if (inner1 == true_test_var)
	return (is_and ? var : inner1);
      else if (inner2 == true_test_var)
	return (is_and ? var : inner2);
      else if (inner1 == false_test_var)
	return (is_and
		? boolean_false_node
		: and_var_with_comparison (type, inner2, false, code2, op2a,
					   op2b));
      else if (inner2 == false_test_var)
	return (is_and
		? boolean_false_node
		: and_var_with_comparison (type, inner1, false, code2, op2a,
					   op2b));

      /* Next, redistribute/reassociate the AND across the inner tests.
	 Compute the first partial result, (inner1 AND (op2a code op2b))  */
      if (TREE_CODE (inner1) == SSA_NAME
	  && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
	  && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
	  && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s),
					      gimple_assign_rhs1 (s),
					      gimple_assign_rhs2 (s),
					      code2, op2a, op2b)))
	{
	  /* Handle the AND case, where we are reassociating:
	     (inner1 AND inner2) AND (op2a code2 op2b)
	     => (t AND inner2)
	     If the partial result t is a constant, we win.  Otherwise
	     continue on to try reassociating with the other inner test.  */
	  if (is_and)
	    {
	      if (integer_onep (t))
		return inner2;
	      else if (integer_zerop (t))
		return boolean_false_node;
	    }

	  /* Handle the OR case, where we are redistributing:
	     (inner1 OR inner2) AND (op2a code2 op2b)
	     => (t OR (inner2 AND (op2a code2 op2b)))  */
	  else if (integer_onep (t))
	    return boolean_true_node;

	  /* Save partial result for later.  */
	  partial = t;
	}
      
      /* Compute the second partial result, (inner2 AND (op2a code op2b)) */
      if (TREE_CODE (inner2) == SSA_NAME
	  && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
	  && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
	  && (t = maybe_fold_and_comparisons (type, gimple_assign_rhs_code (s),
					      gimple_assign_rhs1 (s),
					      gimple_assign_rhs2 (s),
					      code2, op2a, op2b)))
	{
	  /* Handle the AND case, where we are reassociating:
	     (inner1 AND inner2) AND (op2a code2 op2b)
	     => (inner1 AND t)  */
	  if (is_and)
	    {
	      if (integer_onep (t))
		return inner1;
	      else if (integer_zerop (t))
		return boolean_false_node;
	      /* If both are the same, we can apply the identity
		 (x AND x) == x.  */
	      else if (partial && same_bool_result_p (t, partial))
		return t;
	    }

	  /* Handle the OR case. where we are redistributing:
	     (inner1 OR inner2) AND (op2a code2 op2b)
	     => (t OR (inner1 AND (op2a code2 op2b)))
	     => (t OR partial)  */
	  else
	    {
	      if (integer_onep (t))
		return boolean_true_node;
	      else if (partial)
		{
		  /* We already got a simplification for the other
		     operand to the redistributed OR expression.  The
		     interesting case is when at least one is false.
		     Or, if both are the same, we can apply the identity
		     (x OR x) == x.  */
		  if (integer_zerop (partial))
		    return t;
		  else if (integer_zerop (t))
		    return partial;
		  else if (same_bool_result_p (t, partial))
		    return t;
		}
	    }
	}
    }
  return NULL_TREE;
}

/* Try to simplify the AND of two comparisons defined by
   (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
   If this can be done without constructing an intermediate value,
   return the resulting tree; otherwise NULL_TREE is returned.
   This function is deliberately asymmetric as it recurses on SSA_DEFs
   in the first comparison but not the second.  */

static tree
and_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
		   enum tree_code code2, tree op2a, tree op2b)
{
  tree truth_type = truth_type_for (TREE_TYPE (op1a));

  /* First check for ((x CODE1 y) AND (x CODE2 y)).  */
  if (operand_equal_p (op1a, op2a, 0)
      && operand_equal_p (op1b, op2b, 0))
    {
      /* Result will be either NULL_TREE, or a combined comparison.  */
      tree t = combine_comparisons (UNKNOWN_LOCATION,
				    TRUTH_ANDIF_EXPR, code1, code2,
				    truth_type, op1a, op1b);
      if (t)
	return t;
    }

  /* Likewise the swapped case of the above.  */
  if (operand_equal_p (op1a, op2b, 0)
      && operand_equal_p (op1b, op2a, 0))
    {
      /* Result will be either NULL_TREE, or a combined comparison.  */
      tree t = combine_comparisons (UNKNOWN_LOCATION,
				    TRUTH_ANDIF_EXPR, code1,
				    swap_tree_comparison (code2),
				    truth_type, op1a, op1b);
      if (t)
	return t;
    }

  /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
     NAME's definition is a truth value.  See if there are any simplifications
     that can be done against the NAME's definition.  */
  if (TREE_CODE (op1a) == SSA_NAME
      && (code1 == NE_EXPR || code1 == EQ_EXPR)
      && (integer_zerop (op1b) || integer_onep (op1b)))
    {
      bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
		     || (code1 == NE_EXPR && integer_onep (op1b)));
      gimple *stmt = SSA_NAME_DEF_STMT (op1a);
      switch (gimple_code (stmt))
	{
	case GIMPLE_ASSIGN:
	  /* Try to simplify by copy-propagating the definition.  */
	  return and_var_with_comparison (type, op1a, invert, code2, op2a,
					  op2b);

	case GIMPLE_PHI:
	  /* If every argument to the PHI produces the same result when
	     ANDed with the second comparison, we win.
	     Do not do this unless the type is bool since we need a bool
	     result here anyway.  */
	  if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
	    {
	      tree result = NULL_TREE;
	      unsigned i;
	      for (i = 0; i < gimple_phi_num_args (stmt); i++)
		{
		  tree arg = gimple_phi_arg_def (stmt, i);
		  
		  /* If this PHI has itself as an argument, ignore it.
		     If all the other args produce the same result,
		     we're still OK.  */
		  if (arg == gimple_phi_result (stmt))
		    continue;
		  else if (TREE_CODE (arg) == INTEGER_CST)
		    {
		      if (invert ? integer_nonzerop (arg) : integer_zerop (arg))
			{
			  if (!result)
			    result = boolean_false_node;
			  else if (!integer_zerop (result))
			    return NULL_TREE;
			}
		      else if (!result)
			result = fold_build2 (code2, boolean_type_node,
					      op2a, op2b);
		      else if (!same_bool_comparison_p (result,
							code2, op2a, op2b))
			return NULL_TREE;
		    }
		  else if (TREE_CODE (arg) == SSA_NAME
			   && !SSA_NAME_IS_DEFAULT_DEF (arg))
		    {
		      tree temp;
		      gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
		      /* In simple cases we can look through PHI nodes,
			 but we have to be careful with loops.
			 See PR49073.  */
		      if (! dom_info_available_p (CDI_DOMINATORS)
			  || gimple_bb (def_stmt) == gimple_bb (stmt)
			  || dominated_by_p (CDI_DOMINATORS,
					     gimple_bb (def_stmt),
					     gimple_bb (stmt)))
			return NULL_TREE;
		      temp = and_var_with_comparison (type, arg, invert, code2,
						      op2a, op2b);
		      if (!temp)
			return NULL_TREE;
		      else if (!result)
			result = temp;
		      else if (!same_bool_result_p (result, temp))
			return NULL_TREE;
		    }
		  else
		    return NULL_TREE;
		}
	      return result;
	    }

	default:
	  break;
	}
    }
  return NULL_TREE;
}

/* Helper function for maybe_fold_and_comparisons and maybe_fold_or_comparisons
   : try to simplify the AND/OR of the ssa variable VAR with the comparison
   specified by (OP2A CODE2 OP2B) from match.pd.  Return NULL_EXPR if we can't
   simplify this to a single expression.  As we are going to lower the cost
   of building SSA names / gimple stmts significantly, we need to allocate
   them ont the stack.  This will cause the code to be a bit ugly.  */

static tree
maybe_fold_comparisons_from_match_pd (tree type, enum tree_code code,
				      enum tree_code code1,
				      tree op1a, tree op1b,
				      enum tree_code code2, tree op2a,
				      tree op2b)
{
  /* Allocate gimple stmt1 on the stack.  */
  gassign *stmt1
    = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
  gimple_init (stmt1, GIMPLE_ASSIGN, 3);
  gimple_assign_set_rhs_code (stmt1, code1);
  gimple_assign_set_rhs1 (stmt1, op1a);
  gimple_assign_set_rhs2 (stmt1, op1b);

  /* Allocate gimple stmt2 on the stack.  */
  gassign *stmt2
    = (gassign *) XALLOCAVEC (char, gimple_size (GIMPLE_ASSIGN, 3));
  gimple_init (stmt2, GIMPLE_ASSIGN, 3);
  gimple_assign_set_rhs_code (stmt2, code2);
  gimple_assign_set_rhs1 (stmt2, op2a);
  gimple_assign_set_rhs2 (stmt2, op2b);

  /* Allocate SSA names(lhs1) on the stack.  */
  tree lhs1 = (tree)XALLOCA (tree_ssa_name);
  memset (lhs1, 0, sizeof (tree_ssa_name));
  TREE_SET_CODE (lhs1, SSA_NAME);
  TREE_TYPE (lhs1) = type;
  init_ssa_name_imm_use (lhs1);

  /* Allocate SSA names(lhs2) on the stack.  */
  tree lhs2 = (tree)XALLOCA (tree_ssa_name);
  memset (lhs2, 0, sizeof (tree_ssa_name));
  TREE_SET_CODE (lhs2, SSA_NAME);
  TREE_TYPE (lhs2) = type;
  init_ssa_name_imm_use (lhs2);

  gimple_assign_set_lhs (stmt1, lhs1);
  gimple_assign_set_lhs (stmt2, lhs2);

  gimple_match_op op (gimple_match_cond::UNCOND, code,
		      type, gimple_assign_lhs (stmt1),
		      gimple_assign_lhs (stmt2));
  if (op.resimplify (NULL, follow_all_ssa_edges))
    {
      if (gimple_simplified_result_is_gimple_val (&op))
	{
	  tree res = op.ops[0];
	  if (res == lhs1)
	    return build2 (code1, type, op1a, op1b);
	  else if (res == lhs2)
	    return build2 (code2, type, op2a, op2b);
	  else
	    return res;
	}
      else if (op.code.is_tree_code ()
	       && TREE_CODE_CLASS ((tree_code)op.code) == tcc_comparison)
	{
	  tree op0 = op.ops[0];
	  tree op1 = op.ops[1];
	  if (op0 == lhs1 || op0 == lhs2 || op1 == lhs1 || op1 == lhs2)
	    return NULL_TREE;  /* not simple */

	  return build2 ((enum tree_code)op.code, op.type, op0, op1);
	}
    }

  return NULL_TREE;
}

/* Try to simplify the AND of two comparisons, specified by
   (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
   If this can be simplified to a single expression (without requiring
   introducing more SSA variables to hold intermediate values),
   return the resulting tree.  Otherwise return NULL_TREE.
   If the result expression is non-null, it has boolean type.  */

tree
maybe_fold_and_comparisons (tree type,
			    enum tree_code code1, tree op1a, tree op1b,
			    enum tree_code code2, tree op2a, tree op2b)
{
  if (tree t = and_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b))
    return t;

  if (tree t = and_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b))
    return t;

  if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_AND_EXPR, code1,
						     op1a, op1b, code2, op2a,
						     op2b))
    return t;

  return NULL_TREE;
}

/* Helper function for or_comparisons_1:  try to simplify the OR of the
   ssa variable VAR with the comparison specified by (OP2A CODE2 OP2B).
   If INVERT is true, invert the value of VAR before doing the OR.
   Return NULL_EXPR if we can't simplify this to a single expression.  */

static tree
or_var_with_comparison (tree type, tree var, bool invert,
			enum tree_code code2, tree op2a, tree op2b)
{
  tree t;
  gimple *stmt = SSA_NAME_DEF_STMT (var);

  /* We can only deal with variables whose definitions are assignments.  */
  if (!is_gimple_assign (stmt))
    return NULL_TREE;
  
  /* If we have an inverted comparison, apply DeMorgan's law and rewrite
     !var OR (op2a code2 op2b) => !(var AND !(op2a code2 op2b))
     Then we only have to consider the simpler non-inverted cases.  */
  if (invert)
    t = and_var_with_comparison_1 (type, stmt,
				   invert_tree_comparison (code2, false),
				   op2a, op2b);
  else
    t = or_var_with_comparison_1 (type, stmt, code2, op2a, op2b);
  return canonicalize_bool (t, invert);
}

/* Try to simplify the OR of the ssa variable defined by the assignment
   STMT with the comparison specified by (OP2A CODE2 OP2B).
   Return NULL_EXPR if we can't simplify this to a single expression.  */

static tree
or_var_with_comparison_1 (tree type, gimple *stmt,
			  enum tree_code code2, tree op2a, tree op2b)
{
  tree var = gimple_assign_lhs (stmt);
  tree true_test_var = NULL_TREE;
  tree false_test_var = NULL_TREE;
  enum tree_code innercode = gimple_assign_rhs_code (stmt);

  /* Check for identities like (var OR (var != 0)) => true .  */
  if (TREE_CODE (op2a) == SSA_NAME
      && TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE)
    {
      if ((code2 == NE_EXPR && integer_zerop (op2b))
	  || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
	{
	  true_test_var = op2a;
	  if (var == true_test_var)
	    return var;
	}
      else if ((code2 == EQ_EXPR && integer_zerop (op2b))
	       || (code2 == NE_EXPR && integer_nonzerop (op2b)))
	{
	  false_test_var = op2a;
	  if (var == false_test_var)
	    return boolean_true_node;
	}
    }

  /* If the definition is a comparison, recurse on it.  */
  if (TREE_CODE_CLASS (innercode) == tcc_comparison)
    {
      tree t = or_comparisons_1 (type, innercode,
				 gimple_assign_rhs1 (stmt),
				 gimple_assign_rhs2 (stmt),
				 code2,
				 op2a,
				 op2b);
      if (t)
	return t;
    }
  
  /* If the definition is an AND or OR expression, we may be able to
     simplify by reassociating.  */
  if (TREE_CODE (TREE_TYPE (var)) == BOOLEAN_TYPE
      && (innercode == BIT_AND_EXPR || innercode == BIT_IOR_EXPR))
    {
      tree inner1 = gimple_assign_rhs1 (stmt);
      tree inner2 = gimple_assign_rhs2 (stmt);
      gimple *s;
      tree t;
      tree partial = NULL_TREE;
      bool is_or = (innercode == BIT_IOR_EXPR);
      
      /* Check for boolean identities that don't require recursive examination
	 of inner1/inner2:
	 inner1 OR (inner1 OR inner2) => inner1 OR inner2 => var
	 inner1 OR (inner1 AND inner2) => inner1
	 !inner1 OR (inner1 OR inner2) => true
	 !inner1 OR (inner1 AND inner2) => !inner1 OR inner2
      */
      if (inner1 == true_test_var)
	return (is_or ? var : inner1);
      else if (inner2 == true_test_var)
	return (is_or ? var : inner2);
      else if (inner1 == false_test_var)
	return (is_or
		? boolean_true_node
		: or_var_with_comparison (type, inner2, false, code2, op2a,
					  op2b));
      else if (inner2 == false_test_var)
	return (is_or
		? boolean_true_node
		: or_var_with_comparison (type, inner1, false, code2, op2a,
					  op2b));
      
      /* Next, redistribute/reassociate the OR across the inner tests.
	 Compute the first partial result, (inner1 OR (op2a code op2b))  */
      if (TREE_CODE (inner1) == SSA_NAME
	  && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner1))
	  && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
	  && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
					     gimple_assign_rhs1 (s),
					     gimple_assign_rhs2 (s),
					     code2, op2a, op2b)))
	{
	  /* Handle the OR case, where we are reassociating:
	     (inner1 OR inner2) OR (op2a code2 op2b)
	     => (t OR inner2)
	     If the partial result t is a constant, we win.  Otherwise
	     continue on to try reassociating with the other inner test.  */
	  if (is_or)
	    {
	      if (integer_onep (t))
		return boolean_true_node;
	      else if (integer_zerop (t))
		return inner2;
	    }
	  
	  /* Handle the AND case, where we are redistributing:
	     (inner1 AND inner2) OR (op2a code2 op2b)
	     => (t AND (inner2 OR (op2a code op2b)))  */
	  else if (integer_zerop (t))
	    return boolean_false_node;

	  /* Save partial result for later.  */
	  partial = t;
	}
      
      /* Compute the second partial result, (inner2 OR (op2a code op2b)) */
      if (TREE_CODE (inner2) == SSA_NAME
	  && is_gimple_assign (s = SSA_NAME_DEF_STMT (inner2))
	  && TREE_CODE_CLASS (gimple_assign_rhs_code (s)) == tcc_comparison
	  && (t = maybe_fold_or_comparisons (type, gimple_assign_rhs_code (s),
					     gimple_assign_rhs1 (s),
					     gimple_assign_rhs2 (s),
					     code2, op2a, op2b)))
	{
	  /* Handle the OR case, where we are reassociating:
	     (inner1 OR inner2) OR (op2a code2 op2b)
	     => (inner1 OR t)
	     => (t OR partial)  */
	  if (is_or)
	    {
	      if (integer_zerop (t))
		return inner1;
	      else if (integer_onep (t))
		return boolean_true_node;
	      /* If both are the same, we can apply the identity
		 (x OR x) == x.  */
	      else if (partial && same_bool_result_p (t, partial))
		return t;
	    }
	  
	  /* Handle the AND case, where we are redistributing:
	     (inner1 AND inner2) OR (op2a code2 op2b)
	     => (t AND (inner1 OR (op2a code2 op2b)))
	     => (t AND partial)  */
	  else 
	    {
	      if (integer_zerop (t))
		return boolean_false_node;
	      else if (partial)
		{
		  /* We already got a simplification for the other
		     operand to the redistributed AND expression.  The
		     interesting case is when at least one is true.
		     Or, if both are the same, we can apply the identity
		     (x AND x) == x.  */
		  if (integer_onep (partial))
		    return t;
		  else if (integer_onep (t))
		    return partial;
		  else if (same_bool_result_p (t, partial))
		    return t;
		}
	    }
	}
    }
  return NULL_TREE;
}

/* Try to simplify the OR of two comparisons defined by
   (OP1A CODE1 OP1B) and (OP2A CODE2 OP2B), respectively.
   If this can be done without constructing an intermediate value,
   return the resulting tree; otherwise NULL_TREE is returned.
   This function is deliberately asymmetric as it recurses on SSA_DEFs
   in the first comparison but not the second.  */

static tree
or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b,
		  enum tree_code code2, tree op2a, tree op2b)
{
  tree truth_type = truth_type_for (TREE_TYPE (op1a));

  /* First check for ((x CODE1 y) OR (x CODE2 y)).  */
  if (operand_equal_p (op1a, op2a, 0)
      && operand_equal_p (op1b, op2b, 0))
    {
      /* Result will be either NULL_TREE, or a combined comparison.  */
      tree t = combine_comparisons (UNKNOWN_LOCATION,
				    TRUTH_ORIF_EXPR, code1, code2,
				    truth_type, op1a, op1b);
      if (t)
	return t;
    }

  /* Likewise the swapped case of the above.  */
  if (operand_equal_p (op1a, op2b, 0)
      && operand_equal_p (op1b, op2a, 0))
    {
      /* Result will be either NULL_TREE, or a combined comparison.  */
      tree t = combine_comparisons (UNKNOWN_LOCATION,
				    TRUTH_ORIF_EXPR, code1,
				    swap_tree_comparison (code2),
				    truth_type, op1a, op1b);
      if (t)
	return t;
    }

  /* Perhaps the first comparison is (NAME != 0) or (NAME == 1) where
     NAME's definition is a truth value.  See if there are any simplifications
     that can be done against the NAME's definition.  */
  if (TREE_CODE (op1a) == SSA_NAME
      && (code1 == NE_EXPR || code1 == EQ_EXPR)
      && (integer_zerop (op1b) || integer_onep (op1b)))
    {
      bool invert = ((code1 == EQ_EXPR && integer_zerop (op1b))
		     || (code1 == NE_EXPR && integer_onep (op1b)));
      gimple *stmt = SSA_NAME_DEF_STMT (op1a);
      switch (gimple_code (stmt))
	{
	case GIMPLE_ASSIGN:
	  /* Try to simplify by copy-propagating the definition.  */
	  return or_var_with_comparison (type, op1a, invert, code2, op2a,
					 op2b);

	case GIMPLE_PHI:
	  /* If every argument to the PHI produces the same result when
	     ORed with the second comparison, we win.
	     Do not do this unless the type is bool since we need a bool
	     result here anyway.  */
	  if (TREE_CODE (TREE_TYPE (op1a)) == BOOLEAN_TYPE)
	    {
	      tree result = NULL_TREE;
	      unsigned i;
	      for (i = 0; i < gimple_phi_num_args (stmt); i++)
		{
		  tree arg = gimple_phi_arg_def (stmt, i);
		  
		  /* If this PHI has itself as an argument, ignore it.
		     If all the other args produce the same result,
		     we're still OK.  */
		  if (arg == gimple_phi_result (stmt))
		    continue;
		  else if (TREE_CODE (arg) == INTEGER_CST)
		    {
		      if (invert ? integer_zerop (arg) : integer_nonzerop (arg))
			{
			  if (!result)
			    result = boolean_true_node;
			  else if (!integer_onep (result))
			    return NULL_TREE;
			}
		      else if (!result)
			result = fold_build2 (code2, boolean_type_node,
					      op2a, op2b);
		      else if (!same_bool_comparison_p (result,
							code2, op2a, op2b))
			return NULL_TREE;
		    }
		  else if (TREE_CODE (arg) == SSA_NAME
			   && !SSA_NAME_IS_DEFAULT_DEF (arg))
		    {
		      tree temp;
		      gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
		      /* In simple cases we can look through PHI nodes,
			 but we have to be careful with loops.
			 See PR49073.  */
		      if (! dom_info_available_p (CDI_DOMINATORS)
			  || gimple_bb (def_stmt) == gimple_bb (stmt)
			  || dominated_by_p (CDI_DOMINATORS,
					     gimple_bb (def_stmt),
					     gimple_bb (stmt)))
			return NULL_TREE;
		      temp = or_var_with_comparison (type, arg, invert, code2,
						     op2a, op2b);
		      if (!temp)
			return NULL_TREE;
		      else if (!result)
			result = temp;
		      else if (!same_bool_result_p (result, temp))
			return NULL_TREE;
		    }
		  else
		    return NULL_TREE;
		}
	      return result;
	    }

	default:
	  break;
	}
    }
  return NULL_TREE;
}

/* Try to simplify the OR of two comparisons, specified by
   (OP1A CODE1 OP1B) and (OP2B CODE2 OP2B), respectively.
   If this can be simplified to a single expression (without requiring
   introducing more SSA variables to hold intermediate values),
   return the resulting tree.  Otherwise return NULL_TREE.
   If the result expression is non-null, it has boolean type.  */

tree
maybe_fold_or_comparisons (tree type,
			   enum tree_code code1, tree op1a, tree op1b,
			   enum tree_code code2, tree op2a, tree op2b)
{
  if (tree t = or_comparisons_1 (type, code1, op1a, op1b, code2, op2a, op2b))
    return t;

  if (tree t = or_comparisons_1 (type, code2, op2a, op2b, code1, op1a, op1b))
    return t;

  if (tree t = maybe_fold_comparisons_from_match_pd (type, BIT_IOR_EXPR, code1,
						     op1a, op1b, code2, op2a,
						     op2b))
    return t;

  return NULL_TREE;
}

/* Fold STMT to a constant using VALUEIZE to valueize SSA names.

   Either NULL_TREE, a simplified but non-constant or a constant
   is returned.

   ???  This should go into a gimple-fold-inline.h file to be eventually
   privatized with the single valueize function used in the various TUs
   to avoid the indirect function call overhead.  */

tree
gimple_fold_stmt_to_constant_1 (gimple *stmt, tree (*valueize) (tree),
				tree (*gvalueize) (tree))
{
  gimple_match_op res_op;
  /* ???  The SSA propagators do not correctly deal with following SSA use-def
     edges if there are intermediate VARYING defs.  For this reason
     do not follow SSA edges here even though SCCVN can technically
     just deal fine with that.  */
  if (gimple_simplify (stmt, &res_op, NULL, gvalueize, valueize))
    {
      tree res = NULL_TREE;
      if (gimple_simplified_result_is_gimple_val (&res_op))
	res = res_op.ops[0];
      else if (mprts_hook)
	res = mprts_hook (&res_op);
      if (res)
	{
	  if (dump_file && dump_flags & TDF_DETAILS)
	    {
	      fprintf (dump_file, "Match-and-simplified ");
	      print_gimple_expr (dump_file, stmt, 0, TDF_SLIM);
	      fprintf (dump_file, " to ");
	      print_generic_expr (dump_file, res);
	      fprintf (dump_file, "\n");
	    }
	  return res;
	}
    }

  location_t loc = gimple_location (stmt);
  switch (gimple_code (stmt))
    {
    case GIMPLE_ASSIGN:
      {
        enum tree_code subcode = gimple_assign_rhs_code (stmt);

        switch (get_gimple_rhs_class (subcode))
          {
          case GIMPLE_SINGLE_RHS:
            {
              tree rhs = gimple_assign_rhs1 (stmt);
              enum tree_code_class kind = TREE_CODE_CLASS (subcode);

              if (TREE_CODE (rhs) == SSA_NAME)
                {
                  /* If the RHS is an SSA_NAME, return its known constant value,
                     if any.  */
                  return (*valueize) (rhs);
                }
	      /* Handle propagating invariant addresses into address
		 operations.  */
	      else if (TREE_CODE (rhs) == ADDR_EXPR
		       && !is_gimple_min_invariant (rhs))
		{
		  poly_int64 offset = 0;
		  tree base;
		  base = get_addr_base_and_unit_offset_1 (TREE_OPERAND (rhs, 0),
							  &offset,
							  valueize);
		  if (base
		      && (CONSTANT_CLASS_P (base)
			  || decl_address_invariant_p (base)))
		    return build_invariant_address (TREE_TYPE (rhs),
						    base, offset);
		}
	      else if (TREE_CODE (rhs) == CONSTRUCTOR
		       && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
		       && known_eq (CONSTRUCTOR_NELTS (rhs),
				    TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
		{
		  unsigned i, nelts;
		  tree val;

		  nelts = CONSTRUCTOR_NELTS (rhs);
		  tree_vector_builder vec (TREE_TYPE (rhs), nelts, 1);
		  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
		    {
		      val = (*valueize) (val);
		      if (TREE_CODE (val) == INTEGER_CST
			  || TREE_CODE (val) == REAL_CST
			  || TREE_CODE (val) == FIXED_CST)
			vec.quick_push (val);
		      else
			return NULL_TREE;
		    }

		  return vec.build ();
		}
	      if (subcode == OBJ_TYPE_REF)
		{
		  tree val = (*valueize) (OBJ_TYPE_REF_EXPR (rhs));
		  /* If callee is constant, we can fold away the wrapper.  */
		  if (is_gimple_min_invariant (val))
		    return val;
		}

              if (kind == tcc_reference)
		{
		  if ((TREE_CODE (rhs) == VIEW_CONVERT_EXPR
		       || TREE_CODE (rhs) == REALPART_EXPR
		       || TREE_CODE (rhs) == IMAGPART_EXPR)
		      && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
		    {
		      tree val = (*valueize) (TREE_OPERAND (rhs, 0));
		      return fold_unary_loc (EXPR_LOCATION (rhs),
					     TREE_CODE (rhs),
					     TREE_TYPE (rhs), val);
		    }
		  else if (TREE_CODE (rhs) == BIT_FIELD_REF
			   && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
		    {
		      tree val = (*valueize) (TREE_OPERAND (rhs, 0));
		      return fold_ternary_loc (EXPR_LOCATION (rhs),
					       TREE_CODE (rhs),
					       TREE_TYPE (rhs), val,
					       TREE_OPERAND (rhs, 1),
					       TREE_OPERAND (rhs, 2));
		    }
		  else if (TREE_CODE (rhs) == MEM_REF
			   && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
		    {
		      tree val = (*valueize) (TREE_OPERAND (rhs, 0));
		      if (TREE_CODE (val) == ADDR_EXPR
			  && is_gimple_min_invariant (val))
			{
			  tree tem = fold_build2 (MEM_REF, TREE_TYPE (rhs),
						  unshare_expr (val),
						  TREE_OPERAND (rhs, 1));
			  if (tem)
			    rhs = tem;
			}
		    }
		  return fold_const_aggregate_ref_1 (rhs, valueize);
		}
              else if (kind == tcc_declaration)
                return get_symbol_constant_value (rhs);
              return rhs;
            }

          case GIMPLE_UNARY_RHS:
	    return NULL_TREE;

          case GIMPLE_BINARY_RHS:
	    /* Translate &x + CST into an invariant form suitable for
	       further propagation.  */
	    if (subcode == POINTER_PLUS_EXPR)
	      {
		tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
		tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
		if (TREE_CODE (op0) == ADDR_EXPR
		    && TREE_CODE (op1) == INTEGER_CST)
		  {
		    tree off = fold_convert (ptr_type_node, op1);
		    return build1_loc
			(loc, ADDR_EXPR, TREE_TYPE (op0),
			 fold_build2 (MEM_REF,
				      TREE_TYPE (TREE_TYPE (op0)),
				      unshare_expr (op0), off));
		  }
	      }
	    /* Canonicalize bool != 0 and bool == 0 appearing after
	       valueization.  While gimple_simplify handles this
	       it can get confused by the ~X == 1 -> X == 0 transform
	       which we cant reduce to a SSA name or a constant
	       (and we have no way to tell gimple_simplify to not
	       consider those transforms in the first place).  */
	    else if (subcode == EQ_EXPR
		     || subcode == NE_EXPR)
	      {
		tree lhs = gimple_assign_lhs (stmt);
		tree op0 = gimple_assign_rhs1 (stmt);
		if (useless_type_conversion_p (TREE_TYPE (lhs),
					       TREE_TYPE (op0)))
		  {
		    tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
		    op0 = (*valueize) (op0);
		    if (TREE_CODE (op0) == INTEGER_CST)
		      std::swap (op0, op1);
		    if (TREE_CODE (op1) == INTEGER_CST
			&& ((subcode == NE_EXPR && integer_zerop (op1))
			    || (subcode == EQ_EXPR && integer_onep (op1))))
		      return op0;
		  }
	      }
	    return NULL_TREE;

          case GIMPLE_TERNARY_RHS:
            {
              /* Handle ternary operators that can appear in GIMPLE form.  */
              tree op0 = (*valueize) (gimple_assign_rhs1 (stmt));
              tree op1 = (*valueize) (gimple_assign_rhs2 (stmt));
              tree op2 = (*valueize) (gimple_assign_rhs3 (stmt));
              return fold_ternary_loc (loc, subcode,
				       TREE_TYPE (gimple_assign_lhs (stmt)),
				       op0, op1, op2);
            }

          default:
            gcc_unreachable ();
          }
      }

    case GIMPLE_CALL:
      {
	tree fn;
	gcall *call_stmt = as_a <gcall *> (stmt);

	if (gimple_call_internal_p (stmt))
	  {
	    enum tree_code subcode = ERROR_MARK;
	    switch (gimple_call_internal_fn (stmt))
	      {
	      case IFN_UBSAN_CHECK_ADD:
		subcode = PLUS_EXPR;
		break;
	      case IFN_UBSAN_CHECK_SUB:
		subcode = MINUS_EXPR;
		break;
	      case IFN_UBSAN_CHECK_MUL:
		subcode = MULT_EXPR;
		break;
	      case IFN_BUILTIN_EXPECT:
		  {
		    tree arg0 = gimple_call_arg (stmt, 0);
		    tree op0 = (*valueize) (arg0);
		    if (TREE_CODE (op0) == INTEGER_CST)
		      return op0;
		    return NULL_TREE;
		  }
	      default:
		return NULL_TREE;
	      }
	    tree arg0 = gimple_call_arg (stmt, 0);
	    tree arg1 = gimple_call_arg (stmt, 1);
	    tree op0 = (*valueize) (arg0);
	    tree op1 = (*valueize) (arg1);

	    if (TREE_CODE (op0) != INTEGER_CST
		|| TREE_CODE (op1) != INTEGER_CST)
	      {
		switch (subcode)
		  {
		  case MULT_EXPR:
		    /* x * 0 = 0 * x = 0 without overflow.  */
		    if (integer_zerop (op0) || integer_zerop (op1))
		      return build_zero_cst (TREE_TYPE (arg0));
		    break;
		  case MINUS_EXPR:
		    /* y - y = 0 without overflow.  */
		    if (operand_equal_p (op0, op1, 0))
		      return build_zero_cst (TREE_TYPE (arg0));
		    break;
		  default:
		    break;
		  }
	      }
	    tree res
	      = fold_binary_loc (loc, subcode, TREE_TYPE (arg0), op0, op1);
	    if (res
		&& TREE_CODE (res) == INTEGER_CST
		&& !TREE_OVERFLOW (res))
	      return res;
	    return NULL_TREE;
	  }

	fn = (*valueize) (gimple_call_fn (stmt));
	if (TREE_CODE (fn) == ADDR_EXPR
	    && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
	    && fndecl_built_in_p (TREE_OPERAND (fn, 0))
	    && gimple_builtin_call_types_compatible_p (stmt,
						       TREE_OPERAND (fn, 0)))
	  {
	    tree *args = XALLOCAVEC (tree, gimple_call_num_args (stmt));
	    tree retval;
	    unsigned i;
	    for (i = 0; i < gimple_call_num_args (stmt); ++i)
	      args[i] = (*valueize) (gimple_call_arg (stmt, i));
	    retval = fold_builtin_call_array (loc,
					 gimple_call_return_type (call_stmt),
					 fn, gimple_call_num_args (stmt), args);
	    if (retval)
	      {
		/* fold_call_expr wraps the result inside a NOP_EXPR.  */
		STRIP_NOPS (retval);
		retval = fold_convert (gimple_call_return_type (call_stmt),
				       retval);
	      }
	    return retval;
	  }
	return NULL_TREE;
      }

    default:
      return NULL_TREE;
    }
}

/* Fold STMT to a constant using VALUEIZE to valueize SSA names.
   Returns NULL_TREE if folding to a constant is not possible, otherwise
   returns a constant according to is_gimple_min_invariant.  */

tree
gimple_fold_stmt_to_constant (gimple *stmt, tree (*valueize) (tree))
{
  tree res = gimple_fold_stmt_to_constant_1 (stmt, valueize);
  if (res && is_gimple_min_invariant (res))
    return res;
  return NULL_TREE;
}


/* The following set of functions are supposed to fold references using
   their constant initializers.  */

/* See if we can find constructor defining value of BASE.
   When we know the consructor with constant offset (such as
   base is array[40] and we do know constructor of array), then
   BIT_OFFSET is adjusted accordingly.

   As a special case, return error_mark_node when constructor
   is not explicitly available, but it is known to be zero
   such as 'static const int a;'.  */
static tree
get_base_constructor (tree base, poly_int64_pod *bit_offset,
		      tree (*valueize)(tree))
{
  poly_int64 bit_offset2, size, max_size;
  bool reverse;

  if (TREE_CODE (base) == MEM_REF)
    {
      poly_offset_int boff = *bit_offset + mem_ref_offset (base) * BITS_PER_UNIT;
      if (!boff.to_shwi (bit_offset))
	return NULL_TREE;

      if (valueize
	  && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
	base = valueize (TREE_OPERAND (base, 0));
      if (!base || TREE_CODE (base) != ADDR_EXPR)
        return NULL_TREE;
      base = TREE_OPERAND (base, 0);
    }
  else if (valueize
	   && TREE_CODE (base) == SSA_NAME)
    base = valueize (base);

  /* Get a CONSTRUCTOR.  If BASE is a VAR_DECL, get its
     DECL_INITIAL.  If BASE is a nested reference into another
     ARRAY_REF or COMPONENT_REF, make a recursive call to resolve
     the inner reference.  */
  switch (TREE_CODE (base))
    {
    case VAR_DECL:
    case CONST_DECL:
      {
	tree init = ctor_for_folding (base);

	/* Our semantic is exact opposite of ctor_for_folding;
	   NULL means unknown, while error_mark_node is 0.  */
	if (init == error_mark_node)
	  return NULL_TREE;
	if (!init)
	  return error_mark_node;
	return init;
      }

    case VIEW_CONVERT_EXPR:
      return get_base_constructor (TREE_OPERAND (base, 0),
				   bit_offset, valueize);

    case ARRAY_REF:
    case COMPONENT_REF:
      base = get_ref_base_and_extent (base, &bit_offset2, &size, &max_size,
				      &reverse);
      if (!known_size_p (max_size) || maybe_ne (size, max_size))
	return NULL_TREE;
      *bit_offset +=  bit_offset2;
      return get_base_constructor (base, bit_offset, valueize);

    case CONSTRUCTOR:
      return base;

    default:
      if (CONSTANT_CLASS_P (base))
	return base;

      return NULL_TREE;
    }
}

/* CTOR is CONSTRUCTOR of an array type.  Fold a reference of SIZE bits
   to the memory at bit OFFSET.     When non-null, TYPE is the expected
   type of the reference; otherwise the type of the referenced element
   is used instead. When SIZE is zero, attempt to fold a reference to
   the entire element which OFFSET refers to.  Increment *SUBOFF by
   the bit offset of the accessed element.  */

static tree
fold_array_ctor_reference (tree type, tree ctor,
			   unsigned HOST_WIDE_INT offset,
			   unsigned HOST_WIDE_INT size,
			   tree from_decl,
			   unsigned HOST_WIDE_INT *suboff)
{
  offset_int low_bound;
  offset_int elt_size;
  offset_int access_index;
  tree domain_type = NULL_TREE;
  HOST_WIDE_INT inner_offset;

  /* Compute low bound and elt size.  */
  if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
    domain_type = TYPE_DOMAIN (TREE_TYPE (ctor));
  if (domain_type && TYPE_MIN_VALUE (domain_type))
    {
      /* Static constructors for variably sized objects make no sense.  */
      if (TREE_CODE (TYPE_MIN_VALUE (domain_type)) != INTEGER_CST)
	return NULL_TREE;
      low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
    }
  else
    low_bound = 0;
  /* Static constructors for variably sized objects make no sense.  */
  if (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor)))) != INTEGER_CST)
    return NULL_TREE;
  elt_size = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))));

  /* When TYPE is non-null, verify that it specifies a constant-sized
     access of a multiple of the array element size.  Avoid division
     by zero below when ELT_SIZE is zero, such as with the result of
     an initializer for a zero-length array or an empty struct.  */
  if (elt_size == 0
      || (type
	  && (!TYPE_SIZE_UNIT (type)
	      || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)))
    return NULL_TREE;

  /* Compute the array index we look for.  */
  access_index = wi::udiv_trunc (offset_int (offset / BITS_PER_UNIT),
				 elt_size);
  access_index += low_bound;

  /* And offset within the access.  */
  inner_offset = offset % (elt_size.to_uhwi () * BITS_PER_UNIT);

  unsigned HOST_WIDE_INT elt_sz = elt_size.to_uhwi ();
  if (size > elt_sz * BITS_PER_UNIT)
    {
      /* native_encode_expr constraints.  */
      if (size > MAX_BITSIZE_MODE_ANY_MODE
	  || size % BITS_PER_UNIT != 0
	  || inner_offset % BITS_PER_UNIT != 0
	  || elt_sz > MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT)
	return NULL_TREE;

      unsigned ctor_idx;
      tree val = get_array_ctor_element_at_index (ctor, access_index,
						  &ctor_idx);
      if (!val && ctor_idx >= CONSTRUCTOR_NELTS  (ctor))
	return build_zero_cst (type);

      /* native-encode adjacent ctor elements.  */
      unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
      unsigned bufoff = 0;
      offset_int index = 0;
      offset_int max_index = access_index;
      constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
      if (!val)
	val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
      else if (!CONSTANT_CLASS_P (val))
	return NULL_TREE;
      if (!elt->index)
	;
      else if (TREE_CODE (elt->index) == RANGE_EXPR)
	{
	  index = wi::to_offset (TREE_OPERAND (elt->index, 0));
	  max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
	}
      else
	index = max_index = wi::to_offset (elt->index);
      index = wi::umax (index, access_index);
      do
	{
	  if (bufoff + elt_sz > sizeof (buf))
	    elt_sz = sizeof (buf) - bufoff;
	  int len = native_encode_expr (val, buf + bufoff, elt_sz,
					inner_offset / BITS_PER_UNIT);
	  if (len != (int) elt_sz - inner_offset / BITS_PER_UNIT)
	    return NULL_TREE;
	  inner_offset = 0;
	  bufoff += len;

	  access_index += 1;
	  if (wi::cmpu (access_index, index) == 0)
	    val = elt->value;
	  else if (wi::cmpu (access_index, max_index) > 0)
	    {
	      ctor_idx++;
	      if (ctor_idx >= CONSTRUCTOR_NELTS (ctor))
		{
		  val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
		  ++max_index;
		}
	      else
		{
		  elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
		  index = 0;
		  max_index = access_index;
		  if (!elt->index)
		    ;
		  else if (TREE_CODE (elt->index) == RANGE_EXPR)
		    {
		      index = wi::to_offset (TREE_OPERAND (elt->index, 0));
		      max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
		    }
		  else
		    index = max_index = wi::to_offset (elt->index);
		  index = wi::umax (index, access_index);
		  if (wi::cmpu (access_index, index) == 0)
		    val = elt->value;
		  else
		    val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
		}
	    }
	}
      while (bufoff < size / BITS_PER_UNIT);
      *suboff += size;
      return native_interpret_expr (type, buf, size / BITS_PER_UNIT);
    }

  if (tree val = get_array_ctor_element_at_index (ctor, access_index))
    {
      if (!size && TREE_CODE (val) != CONSTRUCTOR)
	{
	  /* For the final reference to the entire accessed element
	     (SIZE is zero), reset INNER_OFFSET, disegard TYPE (which
	     may be null) in favor of the type of the element, and set
	     SIZE to the size of the accessed element.  */
	  inner_offset = 0;
	  type = TREE_TYPE (val);
	  size = elt_sz * BITS_PER_UNIT;
	}
      else if (size && access_index < CONSTRUCTOR_NELTS (ctor) - 1
	       && TREE_CODE (val) == CONSTRUCTOR
	       && (elt_sz * BITS_PER_UNIT - inner_offset) < size)
	/* If this isn't the last element in the CTOR and a CTOR itself
	   and it does not cover the whole object we are requesting give up
	   since we're not set up for combining from multiple CTORs.  */
	return NULL_TREE;

      *suboff += access_index.to_uhwi () * elt_sz * BITS_PER_UNIT;
      return fold_ctor_reference (type, val, inner_offset, size, from_decl,
				  suboff);
    }

  /* Memory not explicitly mentioned in constructor is 0 (or
     the reference is out of range).  */
  return type ? build_zero_cst (type) : NULL_TREE;
}

/* CTOR is CONSTRUCTOR of an aggregate or vector.  Fold a reference
   of SIZE bits to the memory at bit OFFSET.   When non-null, TYPE
   is the expected type of the reference; otherwise the type of
   the referenced member is used instead.  When SIZE is zero,
   attempt to fold a reference to the entire member which OFFSET
   refers to; in this case.  Increment *SUBOFF by the bit offset
   of the accessed member.  */

static tree
fold_nonarray_ctor_reference (tree type, tree ctor,
			      unsigned HOST_WIDE_INT offset,
			      unsigned HOST_WIDE_INT size,
			      tree from_decl,
			      unsigned HOST_WIDE_INT *suboff)
{
  unsigned HOST_WIDE_INT cnt;
  tree cfield, cval;

  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield,
			    cval)
    {
      tree byte_offset = DECL_FIELD_OFFSET (cfield);
      tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
      tree field_size = DECL_SIZE (cfield);

      if (!field_size)
	{
	  /* Determine the size of the flexible array member from
	     the size of the initializer provided for it.  */
	  field_size = TYPE_SIZE (TREE_TYPE (cval));
	}

      /* Variable sized objects in static constructors makes no sense,
	 but field_size can be NULL for flexible array members.  */
      gcc_assert (TREE_CODE (field_offset) == INTEGER_CST
		  && TREE_CODE (byte_offset) == INTEGER_CST
		  && (field_size != NULL_TREE
		      ? TREE_CODE (field_size) == INTEGER_CST
		      : TREE_CODE (TREE_TYPE (cfield)) == ARRAY_TYPE));

      /* Compute bit offset of the field.  */
      offset_int bitoffset
	= (wi::to_offset (field_offset)
	   + (wi::to_offset (byte_offset) << LOG2_BITS_PER_UNIT));
      /* Compute bit offset where the field ends.  */
      offset_int bitoffset_end;
      if (field_size != NULL_TREE)
	bitoffset_end = bitoffset + wi::to_offset (field_size);
      else
	bitoffset_end = 0;

      /* Compute the bit offset of the end of the desired access.
	 As a special case, if the size of the desired access is
	 zero, assume the access is to the entire field (and let
	 the caller make any necessary adjustments by storing
	 the actual bounds of the field in FIELDBOUNDS).  */
      offset_int access_end = offset_int (offset);
      if (size)
	access_end += size;
      else
	access_end = bitoffset_end;

      /* Is there any overlap between the desired access at
	 [OFFSET, OFFSET+SIZE) and the offset of the field within
	 the object at [BITOFFSET, BITOFFSET_END)?  */
      if (wi::cmps (access_end, bitoffset) > 0
	  && (field_size == NULL_TREE
	      || wi::lts_p (offset, bitoffset_end)))
	{
	  *suboff += bitoffset.to_uhwi ();

	  if (!size && TREE_CODE (cval) != CONSTRUCTOR)
	    {
	      /* For the final reference to the entire accessed member
		 (SIZE is zero), reset OFFSET, disegard TYPE (which may
		 be null) in favor of the type of the member, and set
		 SIZE to the size of the accessed member.  */
	      offset = bitoffset.to_uhwi ();
	      type = TREE_TYPE (cval);
	      size = (bitoffset_end - bitoffset).to_uhwi ();
	    }

	  /* We do have overlap.  Now see if the field is large enough
	     to cover the access.  Give up for accesses that extend
	     beyond the end of the object or that span multiple fields.  */
	  if (wi::cmps (access_end, bitoffset_end) > 0)
	    return NULL_TREE;
	  if (offset < bitoffset)
	    return NULL_TREE;

	  offset_int inner_offset = offset_int (offset) - bitoffset;
	  return fold_ctor_reference (type, cval,
				      inner_offset.to_uhwi (), size,
				      from_decl, suboff);
	}
    }

  if (!type)
    return NULL_TREE;

  return build_zero_cst (type);
}

/* CTOR is value initializing memory.  Fold a reference of TYPE and
   bit size POLY_SIZE to the memory at bit POLY_OFFSET.  When POLY_SIZE
   is zero, attempt to fold a reference to the entire subobject
   which OFFSET refers to.  This is used when folding accesses to
   string members of aggregates.  When non-null, set *SUBOFF to
   the bit offset of the accessed subobject.  */

tree
fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
		     const poly_uint64 &poly_size, tree from_decl,
		     unsigned HOST_WIDE_INT *suboff /* = NULL */)
{
  tree ret;

  /* We found the field with exact match.  */
  if (type
      && useless_type_conversion_p (type, TREE_TYPE (ctor))
      && known_eq (poly_offset, 0U))
    return canonicalize_constructor_val (unshare_expr (ctor), from_decl);

  /* The remaining optimizations need a constant size and offset.  */
  unsigned HOST_WIDE_INT size, offset;
  if (!poly_size.is_constant (&size) || !poly_offset.is_constant (&offset))
    return NULL_TREE;

  /* We are at the end of walk, see if we can view convert the
     result.  */
  if (!AGGREGATE_TYPE_P (TREE_TYPE (ctor)) && !offset
      /* VIEW_CONVERT_EXPR is defined only for matching sizes.  */
      && !compare_tree_int (TYPE_SIZE (type), size)
      && !compare_tree_int (TYPE_SIZE (TREE_TYPE (ctor)), size))
    {
      ret = canonicalize_constructor_val (unshare_expr (ctor), from_decl);
      if (ret)
	{
	  ret = fold_unary (VIEW_CONVERT_EXPR, type, ret);
	  if (ret)
	    STRIP_USELESS_TYPE_CONVERSION (ret);
	}
      return ret;
    }
  /* For constants and byte-aligned/sized reads try to go through
     native_encode/interpret.  */
  if (CONSTANT_CLASS_P (ctor)
      && BITS_PER_UNIT == 8
      && offset % BITS_PER_UNIT == 0
      && offset / BITS_PER_UNIT <= INT_MAX
      && size % BITS_PER_UNIT == 0
      && size <= MAX_BITSIZE_MODE_ANY_MODE
      && can_native_interpret_type_p (type))
    {
      unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
      int len = native_encode_expr (ctor, buf, size / BITS_PER_UNIT,
				    offset / BITS_PER_UNIT);
      if (len > 0)
	return native_interpret_expr (type, buf, len);
    }
  if (TREE_CODE (ctor) == CONSTRUCTOR)
    {
      unsigned HOST_WIDE_INT dummy = 0;
      if (!suboff)
	suboff = &dummy;

      tree ret;
      if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE
	  || TREE_CODE (TREE_TYPE (ctor)) == VECTOR_TYPE)
	ret = fold_array_ctor_reference (type, ctor, offset, size,
					 from_decl, suboff);
      else
	ret = fold_nonarray_ctor_reference (type, ctor, offset, size,
					    from_decl, suboff);

      /* Fall back to native_encode_initializer.  Needs to be done
	 only in the outermost fold_ctor_reference call (because it itself
	 recurses into CONSTRUCTORs) and doesn't update suboff.  */
      if (ret == NULL_TREE
	  && suboff == &dummy
	  && BITS_PER_UNIT == 8
	  && offset % BITS_PER_UNIT == 0
	  && offset / BITS_PER_UNIT <= INT_MAX
	  && size % BITS_PER_UNIT == 0
	  && size <= MAX_BITSIZE_MODE_ANY_MODE
	  && can_native_interpret_type_p (type))
	{
	  unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
	  int len = native_encode_initializer (ctor, buf, size / BITS_PER_UNIT,
					       offset / BITS_PER_UNIT);
	  if (len > 0)
	    return native_interpret_expr (type, buf, len);
	}

      return ret;
    }

  return NULL_TREE;
}

/* Return the tree representing the element referenced by T if T is an
   ARRAY_REF or COMPONENT_REF into constant aggregates valuezing SSA
   names using VALUEIZE.  Return NULL_TREE otherwise.  */

tree
fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree))
{
  tree ctor, idx, base;
  poly_int64 offset, size, max_size;
  tree tem;
  bool reverse;

  if (TREE_THIS_VOLATILE (t))
    return NULL_TREE;

  if (DECL_P (t))
    return get_symbol_constant_value (t);

  tem = fold_read_from_constant_string (t);
  if (tem)
    return tem;

  switch (TREE_CODE (t))
    {
    case ARRAY_REF:
    case ARRAY_RANGE_REF:
      /* Constant indexes are handled well by get_base_constructor.
	 Only special case variable offsets.
	 FIXME: This code can't handle nested references with variable indexes
	 (they will be handled only by iteration of ccp).  Perhaps we can bring
	 get_ref_base_and_extent here and make it use a valueize callback.  */
      if (TREE_CODE (TREE_OPERAND (t, 1)) == SSA_NAME
	  && valueize
	  && (idx = (*valueize) (TREE_OPERAND (t, 1)))
	  && poly_int_tree_p (idx))
	{
	  tree low_bound, unit_size;

	  /* If the resulting bit-offset is constant, track it.  */
	  if ((low_bound = array_ref_low_bound (t),
	       poly_int_tree_p (low_bound))
	      && (unit_size = array_ref_element_size (t),
		  tree_fits_uhwi_p (unit_size)))
	    {
	      poly_offset_int woffset
		= wi::sext (wi::to_poly_offset (idx)
			    - wi::to_poly_offset (low_bound),
			    TYPE_PRECISION (sizetype));
	      woffset *= tree_to_uhwi (unit_size);
	      woffset *= BITS_PER_UNIT;
	      if (woffset.to_shwi (&offset))
		{
		  base = TREE_OPERAND (t, 0);
		  ctor = get_base_constructor (base, &offset, valueize);
		  /* Empty constructor.  Always fold to 0.  */
		  if (ctor == error_mark_node)
		    return build_zero_cst (TREE_TYPE (t));
		  /* Out of bound array access.  Value is undefined,
		     but don't fold.  */
		  if (maybe_lt (offset, 0))
		    return NULL_TREE;
		  /* We cannot determine ctor.  */
		  if (!ctor)
		    return NULL_TREE;
		  return fold_ctor_reference (TREE_TYPE (t), ctor, offset,
					      tree_to_uhwi (unit_size)
					      * BITS_PER_UNIT,
					      base);
		}
	    }
	}
      /* Fallthru.  */

    case COMPONENT_REF:
    case BIT_FIELD_REF:
    case TARGET_MEM_REF:
    case MEM_REF:
      base = get_ref_base_and_extent (t, &offset, &size, &max_size, &reverse);
      ctor = get_base_constructor (base, &offset, valueize);

      /* Empty constructor.  Always fold to 0.  */
      if (ctor == error_mark_node)
	return build_zero_cst (TREE_TYPE (t));
      /* We do not know precise address.  */
      if (!known_size_p (max_size) || maybe_ne (max_size, size))
	return NULL_TREE;
      /* We cannot determine ctor.  */
      if (!ctor)
	return NULL_TREE;

      /* Out of bound array access.  Value is undefined, but don't fold.  */
      if (maybe_lt (offset, 0))
	return NULL_TREE;

      tem = fold_ctor_reference (TREE_TYPE (t), ctor, offset, size, base);
      if (tem)
	return tem;

      /* For bit field reads try to read the representative and
	 adjust.  */
      if (TREE_CODE (t) == COMPONENT_REF
	  && DECL_BIT_FIELD (TREE_OPERAND (t, 1))
	  && DECL_BIT_FIELD_REPRESENTATIVE (TREE_OPERAND (t, 1)))
	{
	  HOST_WIDE_INT csize, coffset;
	  tree field = TREE_OPERAND (t, 1);
	  tree repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
	  if (INTEGRAL_TYPE_P (TREE_TYPE (repr))
	      && size.is_constant (&csize)
	      && offset.is_constant (&coffset)
	      && (coffset % BITS_PER_UNIT != 0
		  || csize % BITS_PER_UNIT != 0)
	      && !reverse
	      && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
	    {
	      poly_int64 bitoffset;
	      poly_uint64 field_offset, repr_offset;
	      if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
		  && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
		bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
	      else
		bitoffset = 0;
	      bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
			    - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
	      HOST_WIDE_INT bitoff;
	      int diff = (TYPE_PRECISION (TREE_TYPE (repr))
			  - TYPE_PRECISION (TREE_TYPE (field)));
	      if (bitoffset.is_constant (&bitoff)
		  && bitoff >= 0
		  && bitoff <= diff)
		{
		  offset -= bitoff;
		  size = tree_to_uhwi (DECL_SIZE (repr));

		  tem = fold_ctor_reference (TREE_TYPE (repr), ctor, offset,
					     size, base);
		  if (tem && TREE_CODE (tem) == INTEGER_CST)
		    {
		      if (!BYTES_BIG_ENDIAN)
			tem = wide_int_to_tree (TREE_TYPE (field),
						wi::lrshift (wi::to_wide (tem),
							     bitoff));
		      else
			tem = wide_int_to_tree (TREE_TYPE (field),
						wi::lrshift (wi::to_wide (tem),
							     diff - bitoff));
		      return tem;
		    }
		}
	    }
	}
      break;

    case REALPART_EXPR:
    case IMAGPART_EXPR:
      {
	tree c = fold_const_aggregate_ref_1 (TREE_OPERAND (t, 0), valueize);
	if (c && TREE_CODE (c) == COMPLEX_CST)
	  return fold_build1_loc (EXPR_LOCATION (t),
				  TREE_CODE (t), TREE_TYPE (t), c);
	break;
      }

    default:
      break;
    }

  return NULL_TREE;
}

tree
fold_const_aggregate_ref (tree t)
{
  return fold_const_aggregate_ref_1 (t, NULL);
}

/* Lookup virtual method with index TOKEN in a virtual table V
   at OFFSET.  
   Set CAN_REFER if non-NULL to false if method
   is not referable or if the virtual table is ill-formed (such as rewriten
   by non-C++ produced symbol). Otherwise just return NULL in that calse.  */

tree
gimple_get_virt_method_for_vtable (HOST_WIDE_INT token,
				   tree v,
				   unsigned HOST_WIDE_INT offset,
				   bool *can_refer)
{
  tree vtable = v, init, fn;
  unsigned HOST_WIDE_INT size;
  unsigned HOST_WIDE_INT elt_size, access_index;
  tree domain_type;

  if (can_refer)
    *can_refer = true;

  /* First of all double check we have virtual table.  */
  if (!VAR_P (v) || !DECL_VIRTUAL_P (v))
    {
      /* Pass down that we lost track of the target.  */
      if (can_refer)
	*can_refer = false;
      return NULL_TREE;
    }

  init = ctor_for_folding (v);

  /* The virtual tables should always be born with constructors
     and we always should assume that they are avaialble for
     folding.  At the moment we do not stream them in all cases,
     but it should never happen that ctor seem unreachable.  */
  gcc_assert (init);
  if (init == error_mark_node)
    {
      /* Pass down that we lost track of the target.  */
      if (can_refer)
	*can_refer = false;
      return NULL_TREE;
    }
  gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
  size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))));
  offset *= BITS_PER_UNIT;
  offset += token * size;

  /* Lookup the value in the constructor that is assumed to be array.
     This is equivalent to
     fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init,
			       offset, size, NULL);
     but in a constant time.  We expect that frontend produced a simple
     array without indexed initializers.  */

  gcc_checking_assert (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
  domain_type = TYPE_DOMAIN (TREE_TYPE (init));
  gcc_checking_assert (integer_zerop (TYPE_MIN_VALUE (domain_type)));
  elt_size = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (init))));

  access_index = offset / BITS_PER_UNIT / elt_size;
  gcc_checking_assert (offset % (elt_size * BITS_PER_UNIT) == 0);

  /* The C++ FE can now produce indexed fields, and we check if the indexes
     match.  */
  if (access_index < CONSTRUCTOR_NELTS (init))
    {
      fn = CONSTRUCTOR_ELT (init, access_index)->value;
      tree idx = CONSTRUCTOR_ELT (init, access_index)->index;
      gcc_checking_assert (!idx || tree_to_uhwi (idx) == access_index);
      STRIP_NOPS (fn);
    }
  else
    fn = NULL;

  /* For type inconsistent program we may end up looking up virtual method
     in virtual table that does not contain TOKEN entries.  We may overrun
     the virtual table and pick up a constant or RTTI info pointer.
     In any case the call is undefined.  */
  if (!fn
      || (TREE_CODE (fn) != ADDR_EXPR && TREE_CODE (fn) != FDESC_EXPR)
      || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
    fn = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
  else
    {
      fn = TREE_OPERAND (fn, 0);

      /* When cgraph node is missing and function is not public, we cannot
	 devirtualize.  This can happen in WHOPR when the actual method
	 ends up in other partition, because we found devirtualization
	 possibility too late.  */
      if (!can_refer_decl_in_current_unit_p (fn, vtable))
	{
	  if (can_refer)
	    {
	      *can_refer = false;
	      return fn;
	    }
	  return NULL_TREE;
	}
    }

  /* Make sure we create a cgraph node for functions we'll reference.
     They can be non-existent if the reference comes from an entry
     of an external vtable for example.  */
  cgraph_node::get_create (fn);

  return fn;
}

/* Return a declaration of a function which an OBJ_TYPE_REF references. TOKEN
   is integer form of OBJ_TYPE_REF_TOKEN of the reference expression.
   KNOWN_BINFO carries the binfo describing the true type of
   OBJ_TYPE_REF_OBJECT(REF).
   Set CAN_REFER if non-NULL to false if method
   is not referable or if the virtual table is ill-formed (such as rewriten
   by non-C++ produced symbol). Otherwise just return NULL in that calse.  */

tree
gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo,
				  bool *can_refer)
{
  unsigned HOST_WIDE_INT offset;
  tree v;

  v = BINFO_VTABLE (known_binfo);
  /* If there is no virtual methods table, leave the OBJ_TYPE_REF alone.  */
  if (!v)
    return NULL_TREE;

  if (!vtable_pointer_value_to_vtable (v, &v, &offset))
    {
      if (can_refer)
	*can_refer = false;
      return NULL_TREE;
    }
  return gimple_get_virt_method_for_vtable (token, v, offset, can_refer);
}

/* Given a pointer value T, return a simplified version of an
   indirection through T, or NULL_TREE if no simplification is
   possible.  Note that the resulting type may be different from
   the type pointed to in the sense that it is still compatible
   from the langhooks point of view. */

tree
gimple_fold_indirect_ref (tree t)
{
  tree ptype = TREE_TYPE (t), type = TREE_TYPE (ptype);
  tree sub = t;
  tree subtype;

  STRIP_NOPS (sub);
  subtype = TREE_TYPE (sub);
  if (!POINTER_TYPE_P (subtype)
      || TYPE_REF_CAN_ALIAS_ALL (ptype))
    return NULL_TREE;

  if (TREE_CODE (sub) == ADDR_EXPR)
    {
      tree op = TREE_OPERAND (sub, 0);
      tree optype = TREE_TYPE (op);
      /* *&p => p */
      if (useless_type_conversion_p (type, optype))
        return op;

      /* *(foo *)&fooarray => fooarray[0] */
      if (TREE_CODE (optype) == ARRAY_TYPE
	  && TREE_CODE (TYPE_SIZE (TREE_TYPE (optype))) == INTEGER_CST
	  && useless_type_conversion_p (type, TREE_TYPE (optype)))
       {
         tree type_domain = TYPE_DOMAIN (optype);
         tree min_val = size_zero_node;
         if (type_domain && TYPE_MIN_VALUE (type_domain))
           min_val = TYPE_MIN_VALUE (type_domain);
	 if (TREE_CODE (min_val) == INTEGER_CST)
	   return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
       }
      /* *(foo *)&complexfoo => __real__ complexfoo */
      else if (TREE_CODE (optype) == COMPLEX_TYPE
               && useless_type_conversion_p (type, TREE_TYPE (optype)))
        return fold_build1 (REALPART_EXPR, type, op);
      /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
      else if (TREE_CODE (optype) == VECTOR_TYPE
               && useless_type_conversion_p (type, TREE_TYPE (optype)))
        {
          tree part_width = TYPE_SIZE (type);
          tree index = bitsize_int (0);
          return fold_build3 (BIT_FIELD_REF, type, op, part_width, index);
        }
    }

  /* *(p + CST) -> ...  */
  if (TREE_CODE (sub) == POINTER_PLUS_EXPR
      && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST)
    {
      tree addr = TREE_OPERAND (sub, 0);
      tree off = TREE_OPERAND (sub, 1);
      tree addrtype;

      STRIP_NOPS (addr);
      addrtype = TREE_TYPE (addr);

      /* ((foo*)&vectorfoo)[1] -> BIT_FIELD_REF<vectorfoo,...> */
      if (TREE_CODE (addr) == ADDR_EXPR
	  && TREE_CODE (TREE_TYPE (addrtype)) == VECTOR_TYPE
	  && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype)))
	  && tree_fits_uhwi_p (off))
	{
          unsigned HOST_WIDE_INT offset = tree_to_uhwi (off);
          tree part_width = TYPE_SIZE (type);
          unsigned HOST_WIDE_INT part_widthi
            = tree_to_shwi (part_width) / BITS_PER_UNIT;
          unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT;
          tree index = bitsize_int (indexi);
	  if (known_lt (offset / part_widthi,
			TYPE_VECTOR_SUBPARTS (TREE_TYPE (addrtype))))
            return fold_build3 (BIT_FIELD_REF, type, TREE_OPERAND (addr, 0),
                                part_width, index);
	}

      /* ((foo*)&complexfoo)[1] -> __imag__ complexfoo */
      if (TREE_CODE (addr) == ADDR_EXPR
	  && TREE_CODE (TREE_TYPE (addrtype)) == COMPLEX_TYPE
	  && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (addrtype))))
        {
          tree size = TYPE_SIZE_UNIT (type);
          if (tree_int_cst_equal (size, off))
            return fold_build1 (IMAGPART_EXPR, type, TREE_OPERAND (addr, 0));
        }

      /* *(p + CST) -> MEM_REF <p, CST>.  */
      if (TREE_CODE (addr) != ADDR_EXPR
	  || DECL_P (TREE_OPERAND (addr, 0)))
	return fold_build2 (MEM_REF, type,
			    addr,
			    wide_int_to_tree (ptype, wi::to_wide (off)));
    }

  /* *(foo *)fooarrptr => (*fooarrptr)[0] */
  if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
      && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (subtype)))) == INTEGER_CST
      && useless_type_conversion_p (type, TREE_TYPE (TREE_TYPE (subtype))))
    {
      tree type_domain;
      tree min_val = size_zero_node;
      tree osub = sub;
      sub = gimple_fold_indirect_ref (sub);
      if (! sub)
	sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), osub);
      type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
      if (type_domain && TYPE_MIN_VALUE (type_domain))
        min_val = TYPE_MIN_VALUE (type_domain);
      if (TREE_CODE (min_val) == INTEGER_CST)
	return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
    }

  return NULL_TREE;
}

/* Return true if CODE is an operation that when operating on signed
   integer types involves undefined behavior on overflow and the
   operation can be expressed with unsigned arithmetic.  */

bool
arith_code_with_undefined_signed_overflow (tree_code code)
{
  switch (code)
    {
    case ABS_EXPR:
    case PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case NEGATE_EXPR:
    case POINTER_PLUS_EXPR:
      return true;
    default:
      return false;
    }
}

/* Rewrite STMT, an assignment with a signed integer or pointer arithmetic
   operation that can be transformed to unsigned arithmetic by converting
   its operand, carrying out the operation in the corresponding unsigned
   type and converting the result back to the original type.

   Returns a sequence of statements that replace STMT and also contain
   a modified form of STMT itself.  */

gimple_seq
rewrite_to_defined_overflow (gimple *stmt)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "rewriting stmt with undefined signed "
	       "overflow ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    }

  tree lhs = gimple_assign_lhs (stmt);
  tree type = unsigned_type_for (TREE_TYPE (lhs));
  gimple_seq stmts = NULL;
  if (gimple_assign_rhs_code (stmt) == ABS_EXPR)
    gimple_assign_set_rhs_code (stmt, ABSU_EXPR);
  else
    for (unsigned i = 1; i < gimple_num_ops (stmt); ++i)
      {
	tree op = gimple_op (stmt, i);
	op = gimple_convert (&stmts, type, op);
	gimple_set_op (stmt, i, op);
      }
  gimple_assign_set_lhs (stmt, make_ssa_name (type, stmt));
  if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
    gimple_assign_set_rhs_code (stmt, PLUS_EXPR);
  gimple_set_modified (stmt, true);
  gimple_seq_add_stmt (&stmts, stmt);
  gimple *cvt = gimple_build_assign (lhs, NOP_EXPR, gimple_assign_lhs (stmt));
  gimple_seq_add_stmt (&stmts, cvt);

  return stmts;
}


/* The valueization hook we use for the gimple_build API simplification.
   This makes us match fold_buildN behavior by only combining with
   statements in the sequence(s) we are currently building.  */

static tree
gimple_build_valueize (tree op)
{
  if (gimple_bb (SSA_NAME_DEF_STMT (op)) == NULL)
    return op;
  return NULL_TREE;
}

/* Build the expression CODE OP0 of type TYPE with location LOC,
   simplifying it first if possible.  Returns the built
   expression value and appends statements possibly defining it
   to SEQ.  */

tree
gimple_build (gimple_seq *seq, location_t loc,
	      enum tree_code code, tree type, tree op0)
{
  tree res = gimple_simplify (code, type, op0, seq, gimple_build_valueize);
  if (!res)
    {
      res = create_tmp_reg_or_ssa_name (type);
      gimple *stmt;
      if (code == REALPART_EXPR
	  || code == IMAGPART_EXPR
	  || code == VIEW_CONVERT_EXPR)
	stmt = gimple_build_assign (res, code, build1 (code, type, op0));
      else
	stmt = gimple_build_assign (res, code, op0);
      gimple_set_location (stmt, loc);
      gimple_seq_add_stmt_without_update (seq, stmt);
    }
  return res;
}

/* Build the expression OP0 CODE OP1 of type TYPE with location LOC,
   simplifying it first if possible.  Returns the built
   expression value and appends statements possibly defining it
   to SEQ.  */

tree
gimple_build (gimple_seq *seq, location_t loc,
	      enum tree_code code, tree type, tree op0, tree op1)
{
  tree res = gimple_simplify (code, type, op0, op1, seq, gimple_build_valueize);
  if (!res)
    {
      res = create_tmp_reg_or_ssa_name (type);
      gimple *stmt = gimple_build_assign (res, code, op0, op1);
      gimple_set_location (stmt, loc);
      gimple_seq_add_stmt_without_update (seq, stmt);
    }
  return res;
}

/* Build the expression (CODE OP0 OP1 OP2) of type TYPE with location LOC,
   simplifying it first if possible.  Returns the built
   expression value and appends statements possibly defining it
   to SEQ.  */

tree
gimple_build (gimple_seq *seq, location_t loc,
	      enum tree_code code, tree type, tree op0, tree op1, tree op2)
{
  tree res = gimple_simplify (code, type, op0, op1, op2,
			      seq, gimple_build_valueize);
  if (!res)
    {
      res = create_tmp_reg_or_ssa_name (type);
      gimple *stmt;
      if (code == BIT_FIELD_REF)
	stmt = gimple_build_assign (res, code,
				    build3 (code, type, op0, op1, op2));
      else
	stmt = gimple_build_assign (res, code, op0, op1, op2);
      gimple_set_location (stmt, loc);
      gimple_seq_add_stmt_without_update (seq, stmt);
    }
  return res;
}

/* Build the call FN () with a result of type TYPE (or no result if TYPE is
   void) with a location LOC.  Returns the built expression value (or NULL_TREE
   if TYPE is void) and appends statements possibly defining it to SEQ.  */

tree
gimple_build (gimple_seq *seq, location_t loc, combined_fn fn, tree type)
{
  tree res = NULL_TREE;
  gcall *stmt;
  if (internal_fn_p (fn))
    stmt = gimple_build_call_internal (as_internal_fn (fn), 0);
  else
    {
      tree decl = builtin_decl_implicit (as_builtin_fn (fn));
      stmt = gimple_build_call (decl, 0);
    }
  if (!VOID_TYPE_P (type))
    {
      res = create_tmp_reg_or_ssa_name (type);
      gimple_call_set_lhs (stmt, res);
    }
  gimple_set_location (stmt, loc);
  gimple_seq_add_stmt_without_update (seq, stmt);
  return res;
}

/* Build the call FN (ARG0) with a result of type TYPE
   (or no result if TYPE is void) with location LOC,
   simplifying it first if possible.  Returns the built
   expression value (or NULL_TREE if TYPE is void) and appends
   statements possibly defining it to SEQ.  */

tree
gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
	      tree type, tree arg0)
{
  tree res = gimple_simplify (fn, type, arg0, seq, gimple_build_valueize);
  if (!res)
    {
      gcall *stmt;
      if (internal_fn_p (fn))
	stmt = gimple_build_call_internal (as_internal_fn (fn), 1, arg0);
      else
	{
	  tree decl = builtin_decl_implicit (as_builtin_fn (fn));
	  stmt = gimple_build_call (decl, 1, arg0);
	}
      if (!VOID_TYPE_P (type))
	{
	  res = create_tmp_reg_or_ssa_name (type);
	  gimple_call_set_lhs (stmt, res);
	}
      gimple_set_location (stmt, loc);
      gimple_seq_add_stmt_without_update (seq, stmt);
    }
  return res;
}

/* Build the call FN (ARG0, ARG1) with a result of type TYPE
   (or no result if TYPE is void) with location LOC,
   simplifying it first if possible.  Returns the built
   expression value (or NULL_TREE if TYPE is void) and appends
   statements possibly defining it to SEQ.  */

tree
gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
	      tree type, tree arg0, tree arg1)
{
  tree res = gimple_simplify (fn, type, arg0, arg1, seq, gimple_build_valueize);
  if (!res)
    {
      gcall *stmt;
      if (internal_fn_p (fn))
	stmt = gimple_build_call_internal (as_internal_fn (fn), 2, arg0, arg1);
      else
	{
	  tree decl = builtin_decl_implicit (as_builtin_fn (fn));
	  stmt = gimple_build_call (decl, 2, arg0, arg1);
	}
      if (!VOID_TYPE_P (type))
	{
	  res = create_tmp_reg_or_ssa_name (type);
	  gimple_call_set_lhs (stmt, res);
	}
      gimple_set_location (stmt, loc);
      gimple_seq_add_stmt_without_update (seq, stmt);
    }
  return res;
}

/* Build the call FN (ARG0, ARG1, ARG2) with a result of type TYPE
   (or no result if TYPE is void) with location LOC,
   simplifying it first if possible.  Returns the built
   expression value (or NULL_TREE if TYPE is void) and appends
   statements possibly defining it to SEQ.  */

tree
gimple_build (gimple_seq *seq, location_t loc, combined_fn fn,
	      tree type, tree arg0, tree arg1, tree arg2)
{
  tree res = gimple_simplify (fn, type, arg0, arg1, arg2,
			      seq, gimple_build_valueize);
  if (!res)
    {
      gcall *stmt;
      if (internal_fn_p (fn))
	stmt = gimple_build_call_internal (as_internal_fn (fn),
					   3, arg0, arg1, arg2);
      else
	{
	  tree decl = builtin_decl_implicit (as_builtin_fn (fn));
	  stmt = gimple_build_call (decl, 3, arg0, arg1, arg2);
	}
      if (!VOID_TYPE_P (type))
	{
	  res = create_tmp_reg_or_ssa_name (type);
	  gimple_call_set_lhs (stmt, res);
	}
      gimple_set_location (stmt, loc);
      gimple_seq_add_stmt_without_update (seq, stmt);
    }
  return res;
}

/* Build the conversion (TYPE) OP with a result of type TYPE
   with location LOC if such conversion is neccesary in GIMPLE,
   simplifying it first.
   Returns the built expression value and appends
   statements possibly defining it to SEQ.  */

tree
gimple_convert (gimple_seq *seq, location_t loc, tree type, tree op)
{
  if (useless_type_conversion_p (type, TREE_TYPE (op)))
    return op;
  return gimple_build (seq, loc, NOP_EXPR, type, op);
}

/* Build the conversion (ptrofftype) OP with a result of a type
   compatible with ptrofftype with location LOC if such conversion
   is neccesary in GIMPLE, simplifying it first.
   Returns the built expression value and appends
   statements possibly defining it to SEQ.  */

tree
gimple_convert_to_ptrofftype (gimple_seq *seq, location_t loc, tree op)
{
  if (ptrofftype_p (TREE_TYPE (op)))
    return op;
  return gimple_convert (seq, loc, sizetype, op);
}

/* Build a vector of type TYPE in which each element has the value OP.
   Return a gimple value for the result, appending any new statements
   to SEQ.  */

tree
gimple_build_vector_from_val (gimple_seq *seq, location_t loc, tree type,
			      tree op)
{
  if (!TYPE_VECTOR_SUBPARTS (type).is_constant ()
      && !CONSTANT_CLASS_P (op))
    return gimple_build (seq, loc, VEC_DUPLICATE_EXPR, type, op);

  tree res, vec = build_vector_from_val (type, op);
  if (is_gimple_val (vec))
    return vec;
  if (gimple_in_ssa_p (cfun))
    res = make_ssa_name (type);
  else
    res = create_tmp_reg (type);
  gimple *stmt = gimple_build_assign (res, vec);
  gimple_set_location (stmt, loc);
  gimple_seq_add_stmt_without_update (seq, stmt);
  return res;
}

/* Build a vector from BUILDER, handling the case in which some elements
   are non-constant.  Return a gimple value for the result, appending any
   new instructions to SEQ.

   BUILDER must not have a stepped encoding on entry.  This is because
   the function is not geared up to handle the arithmetic that would
   be needed in the variable case, and any code building a vector that
   is known to be constant should use BUILDER->build () directly.  */

tree
gimple_build_vector (gimple_seq *seq, location_t loc,
		     tree_vector_builder *builder)
{
  gcc_assert (builder->nelts_per_pattern () <= 2);
  unsigned int encoded_nelts = builder->encoded_nelts ();
  for (unsigned int i = 0; i < encoded_nelts; ++i)
    if (!CONSTANT_CLASS_P ((*builder)[i]))
      {
	tree type = builder->type ();
	unsigned int nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
	vec<constructor_elt, va_gc> *v;
	vec_alloc (v, nelts);
	for (i = 0; i < nelts; ++i)
	  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, builder->elt (i));

	tree res;
	if (gimple_in_ssa_p (cfun))
	  res = make_ssa_name (type);
	else
	  res = create_tmp_reg (type);
	gimple *stmt = gimple_build_assign (res, build_constructor (type, v));
	gimple_set_location (stmt, loc);
	gimple_seq_add_stmt_without_update (seq, stmt);
	return res;
      }
  return builder->build ();
}

/* Emit gimple statements into &stmts that take a value given in OLD_SIZE
   and generate a value guaranteed to be rounded upwards to ALIGN.

   Return the tree node representing this size, it is of TREE_TYPE TYPE.  */

tree
gimple_build_round_up (gimple_seq *seq, location_t loc, tree type,
		       tree old_size, unsigned HOST_WIDE_INT align)
{
  unsigned HOST_WIDE_INT tg_mask = align - 1;
  /* tree new_size = (old_size + tg_mask) & ~tg_mask;  */
  gcc_assert (INTEGRAL_TYPE_P (type));
  tree tree_mask = build_int_cst (type, tg_mask);
  tree oversize = gimple_build (seq, loc, PLUS_EXPR, type, old_size,
				tree_mask);

  tree mask = build_int_cst (type, -align);
  return gimple_build (seq, loc, BIT_AND_EXPR, type, oversize, mask);
}

/* Return true if the result of assignment STMT 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
gimple_assign_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p,
				   int depth)
{
  enum tree_code code = gimple_assign_rhs_code (stmt);
  tree type = TREE_TYPE (gimple_assign_lhs (stmt));
  switch (get_gimple_rhs_class (code))
    {
    case GIMPLE_UNARY_RHS:
      return tree_unary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt),
					     type,
					     gimple_assign_rhs1 (stmt),
					     strict_overflow_p, depth);
    case GIMPLE_BINARY_RHS:
      return tree_binary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt),
					      type,
					      gimple_assign_rhs1 (stmt),
					      gimple_assign_rhs2 (stmt),
					      strict_overflow_p, depth);
    case GIMPLE_TERNARY_RHS:
      return false;
    case GIMPLE_SINGLE_RHS:
      return tree_single_nonnegative_warnv_p (gimple_assign_rhs1 (stmt),
					      strict_overflow_p, depth);
    case GIMPLE_INVALID_RHS:
      break;
    }
  gcc_unreachable ();
}

/* Return true if return value of call STMT 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
gimple_call_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p,
				 int depth)
{
  tree arg0 = gimple_call_num_args (stmt) > 0 ?
    gimple_call_arg (stmt, 0) : NULL_TREE;
  tree arg1 = gimple_call_num_args (stmt) > 1 ?
    gimple_call_arg (stmt, 1) : NULL_TREE;
  tree lhs = gimple_call_lhs (stmt);
  return (lhs
	  && tree_call_nonnegative_warnv_p (TREE_TYPE (lhs),
					    gimple_call_combined_fn (stmt),
					    arg0, arg1,
					    strict_overflow_p, depth));
}

/* Return true if return value of call STMT 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
gimple_phi_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p,
				int depth)
{
  for (unsigned i = 0; i < gimple_phi_num_args (stmt); ++i)
    {
      tree arg = gimple_phi_arg_def (stmt, i);
      if (!tree_single_nonnegative_warnv_p (arg, strict_overflow_p, depth + 1))
	return false;
    }
  return true;
}

/* Return true if STMT is known to compute a non-negative value.
   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
gimple_stmt_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p,
				 int depth)
{
  switch (gimple_code (stmt))
    {
    case GIMPLE_ASSIGN:
      return gimple_assign_nonnegative_warnv_p (stmt, strict_overflow_p,
						depth);
    case GIMPLE_CALL:
      return gimple_call_nonnegative_warnv_p (stmt, strict_overflow_p,
					      depth);
    case GIMPLE_PHI:
      return gimple_phi_nonnegative_warnv_p (stmt, strict_overflow_p,
					     depth);
    default:
      return false;
    }
}

/* Return true if the floating-point value computed by assignment STMT
   is known to have 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
gimple_assign_integer_valued_real_p (gimple *stmt, int depth)
{
  enum tree_code code = gimple_assign_rhs_code (stmt);
  switch (get_gimple_rhs_class (code))
    {
    case GIMPLE_UNARY_RHS:
      return integer_valued_real_unary_p (gimple_assign_rhs_code (stmt),
					  gimple_assign_rhs1 (stmt), depth);
    case GIMPLE_BINARY_RHS:
      return integer_valued_real_binary_p (gimple_assign_rhs_code (stmt),
					   gimple_assign_rhs1 (stmt),
					   gimple_assign_rhs2 (stmt), depth);
    case GIMPLE_TERNARY_RHS:
      return false;
    case GIMPLE_SINGLE_RHS:
      return integer_valued_real_single_p (gimple_assign_rhs1 (stmt), depth);
    case GIMPLE_INVALID_RHS:
      break;
    }
  gcc_unreachable ();
}

/* Return true if the floating-point value computed by call STMT is known
   to have 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
gimple_call_integer_valued_real_p (gimple *stmt, int depth)
{
  tree arg0 = (gimple_call_num_args (stmt) > 0
	       ? gimple_call_arg (stmt, 0)
	       : NULL_TREE);
  tree arg1 = (gimple_call_num_args (stmt) > 1
	       ? gimple_call_arg (stmt, 1)
	       : NULL_TREE);
  return integer_valued_real_call_p (gimple_call_combined_fn (stmt),
				     arg0, arg1, depth);
}

/* Return true if the floating-point result of phi STMT is known to have
   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
gimple_phi_integer_valued_real_p (gimple *stmt, int depth)
{
  for (unsigned i = 0; i < gimple_phi_num_args (stmt); ++i)
    {
      tree arg = gimple_phi_arg_def (stmt, i);
      if (!integer_valued_real_single_p (arg, depth + 1))
	return false;
    }
  return true;
}

/* Return true if the floating-point value computed by STMT is known
   to have 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
gimple_stmt_integer_valued_real_p (gimple *stmt, int depth)
{
  switch (gimple_code (stmt))
    {
    case GIMPLE_ASSIGN:
      return gimple_assign_integer_valued_real_p (stmt, depth);
    case GIMPLE_CALL:
      return gimple_call_integer_valued_real_p (stmt, depth);
    case GIMPLE_PHI:
      return gimple_phi_integer_valued_real_p (stmt, depth);
    default:
      return false;
    }
}
