/* Alias analysis for trees.
   Copyright (C) 2004-2022 Free Software Foundation, Inc.
   Contributed by Diego Novillo <dnovillo@redhat.com>

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 "timevar.h"	/* for TV_ALIAS_STMT_WALK */
#include "ssa.h"
#include "cgraph.h"
#include "tree-pretty-print.h"
#include "alias.h"
#include "fold-const.h"
#include "langhooks.h"
#include "dumpfile.h"
#include "tree-eh.h"
#include "tree-dfa.h"
#include "ipa-reference.h"
#include "varasm.h"
#include "ipa-modref-tree.h"
#include "ipa-modref.h"
#include "attr-fnspec.h"
#include "errors.h"
#include "dbgcnt.h"
#include "gimple-pretty-print.h"
#include "print-tree.h"
#include "tree-ssa-alias-compare.h"
#include "builtins.h"
#include "internal-fn.h"

/* Broad overview of how alias analysis on gimple works:

   Statements clobbering or using memory are linked through the
   virtual operand factored use-def chain.  The virtual operand
   is unique per function, its symbol is accessible via gimple_vop (cfun).
   Virtual operands are used for efficiently walking memory statements
   in the gimple IL and are useful for things like value-numbering as
   a generation count for memory references.

   SSA_NAME pointers may have associated points-to information
   accessible via the SSA_NAME_PTR_INFO macro.  Flow-insensitive
   points-to information is (re-)computed by the TODO_rebuild_alias
   pass manager todo.  Points-to information is also used for more
   precise tracking of call-clobbered and call-used variables and
   related disambiguations.

   This file contains functions for disambiguating memory references,
   the so called alias-oracle and tools for walking of the gimple IL.

   The main alias-oracle entry-points are

   bool stmt_may_clobber_ref_p (gimple *, tree)

     This function queries if a statement may invalidate (parts of)
     the memory designated by the reference tree argument.

   bool ref_maybe_used_by_stmt_p (gimple *, tree)

     This function queries if a statement may need (parts of) the
     memory designated by the reference tree argument.

   There are variants of these functions that only handle the call
   part of a statement, call_may_clobber_ref_p and ref_maybe_used_by_call_p.
   Note that these do not disambiguate against a possible call lhs.

   bool refs_may_alias_p (tree, tree)

     This function tries to disambiguate two reference trees.

   bool ptr_deref_may_alias_global_p (tree, bool)

     This function queries if dereferencing a pointer variable may
     alias global memory.  If bool argument is true, global memory
     is considered to also include function local memory that escaped.

   More low-level disambiguators are available and documented in
   this file.  Low-level disambiguators dealing with points-to
   information are in tree-ssa-structalias.cc.  */

static int nonoverlapping_refs_since_match_p (tree, tree, tree, tree, bool);
static bool nonoverlapping_component_refs_p (const_tree, const_tree);

/* Query statistics for the different low-level disambiguators.
   A high-level query may trigger multiple of them.  */

static struct {
  unsigned HOST_WIDE_INT refs_may_alias_p_may_alias;
  unsigned HOST_WIDE_INT refs_may_alias_p_no_alias;
  unsigned HOST_WIDE_INT ref_maybe_used_by_call_p_may_alias;
  unsigned HOST_WIDE_INT ref_maybe_used_by_call_p_no_alias;
  unsigned HOST_WIDE_INT call_may_clobber_ref_p_may_alias;
  unsigned HOST_WIDE_INT call_may_clobber_ref_p_no_alias;
  unsigned HOST_WIDE_INT aliasing_component_refs_p_may_alias;
  unsigned HOST_WIDE_INT aliasing_component_refs_p_no_alias;
  unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_may_alias;
  unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_no_alias;
  unsigned HOST_WIDE_INT nonoverlapping_refs_since_match_p_may_alias;
  unsigned HOST_WIDE_INT nonoverlapping_refs_since_match_p_must_overlap;
  unsigned HOST_WIDE_INT nonoverlapping_refs_since_match_p_no_alias;
  unsigned HOST_WIDE_INT stmt_kills_ref_p_no;
  unsigned HOST_WIDE_INT stmt_kills_ref_p_yes;
  unsigned HOST_WIDE_INT modref_use_may_alias;
  unsigned HOST_WIDE_INT modref_use_no_alias;
  unsigned HOST_WIDE_INT modref_clobber_may_alias;
  unsigned HOST_WIDE_INT modref_clobber_no_alias;
  unsigned HOST_WIDE_INT modref_kill_no;
  unsigned HOST_WIDE_INT modref_kill_yes;
  unsigned HOST_WIDE_INT modref_tests;
  unsigned HOST_WIDE_INT modref_baseptr_tests;
} alias_stats;

void
dump_alias_stats (FILE *s)
{
  fprintf (s, "\nAlias oracle query stats:\n");
  fprintf (s, "  refs_may_alias_p: "
	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n",
	   alias_stats.refs_may_alias_p_no_alias,
	   alias_stats.refs_may_alias_p_no_alias
	   + alias_stats.refs_may_alias_p_may_alias);
  fprintf (s, "  ref_maybe_used_by_call_p: "
	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n",
	   alias_stats.ref_maybe_used_by_call_p_no_alias,
	   alias_stats.refs_may_alias_p_no_alias
	   + alias_stats.ref_maybe_used_by_call_p_may_alias);
  fprintf (s, "  call_may_clobber_ref_p: "
	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n",
	   alias_stats.call_may_clobber_ref_p_no_alias,
	   alias_stats.call_may_clobber_ref_p_no_alias
	   + alias_stats.call_may_clobber_ref_p_may_alias);
  fprintf (s, "  stmt_kills_ref_p: "
	   HOST_WIDE_INT_PRINT_DEC" kills, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n",
	   alias_stats.stmt_kills_ref_p_yes + alias_stats.modref_kill_yes,
	   alias_stats.stmt_kills_ref_p_yes + alias_stats.modref_kill_yes
	   + alias_stats.stmt_kills_ref_p_no + alias_stats.modref_kill_no);
  fprintf (s, "  nonoverlapping_component_refs_p: "
	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n",
	   alias_stats.nonoverlapping_component_refs_p_no_alias,
	   alias_stats.nonoverlapping_component_refs_p_no_alias
	   + alias_stats.nonoverlapping_component_refs_p_may_alias);
  fprintf (s, "  nonoverlapping_refs_since_match_p: "
	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
	   HOST_WIDE_INT_PRINT_DEC" must overlaps, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n",
	   alias_stats.nonoverlapping_refs_since_match_p_no_alias,
	   alias_stats.nonoverlapping_refs_since_match_p_must_overlap,
	   alias_stats.nonoverlapping_refs_since_match_p_no_alias
	   + alias_stats.nonoverlapping_refs_since_match_p_may_alias
	   + alias_stats.nonoverlapping_refs_since_match_p_must_overlap);
  fprintf (s, "  aliasing_component_refs_p: "
	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n",
	   alias_stats.aliasing_component_refs_p_no_alias,
	   alias_stats.aliasing_component_refs_p_no_alias
	   + alias_stats.aliasing_component_refs_p_may_alias);
  dump_alias_stats_in_alias_c (s);
  fprintf (s, "\nModref stats:\n");
  fprintf (s, "  modref kill: "
	   HOST_WIDE_INT_PRINT_DEC" kills, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n",
	   alias_stats.modref_kill_yes,
	   alias_stats.modref_kill_yes
	   + alias_stats.modref_kill_no);
  fprintf (s, "  modref use: "
	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n",
	   alias_stats.modref_use_no_alias,
	   alias_stats.modref_use_no_alias
	   + alias_stats.modref_use_may_alias);
  fprintf (s, "  modref clobber: "
	   HOST_WIDE_INT_PRINT_DEC" disambiguations, "
	   HOST_WIDE_INT_PRINT_DEC" queries\n"
	   "  " HOST_WIDE_INT_PRINT_DEC" tbaa queries (%f per modref query)\n"
	   "  " HOST_WIDE_INT_PRINT_DEC" base compares (%f per modref query)\n",
	   alias_stats.modref_clobber_no_alias,
	   alias_stats.modref_clobber_no_alias
	   + alias_stats.modref_clobber_may_alias,
	   alias_stats.modref_tests,
	   ((double)alias_stats.modref_tests)
	   / (alias_stats.modref_clobber_no_alias
	      + alias_stats.modref_clobber_may_alias),
	   alias_stats.modref_baseptr_tests,
	   ((double)alias_stats.modref_baseptr_tests)
	   / (alias_stats.modref_clobber_no_alias
	      + alias_stats.modref_clobber_may_alias));
}


/* Return true, if dereferencing PTR may alias with a global variable.
   When ESCAPED_LOCAL_P is true escaped local memory is also considered
   global.  */

bool
ptr_deref_may_alias_global_p (tree ptr, bool escaped_local_p)
{
  struct ptr_info_def *pi;

  /* If we end up with a pointer constant here that may point
     to global memory.  */
  if (TREE_CODE (ptr) != SSA_NAME)
    return true;

  pi = SSA_NAME_PTR_INFO (ptr);

  /* If we do not have points-to information for this variable,
     we have to punt.  */
  if (!pi)
    return true;

  /* ???  This does not use TBAA to prune globals ptr may not access.  */
  return pt_solution_includes_global (&pi->pt, escaped_local_p);
}

/* Return true if dereferencing PTR may alias DECL.
   The caller is responsible for applying TBAA to see if PTR
   may access DECL at all.  */

static bool
ptr_deref_may_alias_decl_p (tree ptr, tree decl)
{
  struct ptr_info_def *pi;

  /* Conversions are irrelevant for points-to information and
     data-dependence analysis can feed us those.  */
  STRIP_NOPS (ptr);

  /* Anything we do not explicilty handle aliases.  */
  if ((TREE_CODE (ptr) != SSA_NAME
       && TREE_CODE (ptr) != ADDR_EXPR
       && TREE_CODE (ptr) != POINTER_PLUS_EXPR)
      || !POINTER_TYPE_P (TREE_TYPE (ptr))
      || (!VAR_P (decl)
	  && TREE_CODE (decl) != PARM_DECL
	  && TREE_CODE (decl) != RESULT_DECL))
    return true;

  /* Disregard pointer offsetting.  */
  if (TREE_CODE (ptr) == POINTER_PLUS_EXPR)
    {
      do
	{
	  ptr = TREE_OPERAND (ptr, 0);
	}
      while (TREE_CODE (ptr) == POINTER_PLUS_EXPR);
      return ptr_deref_may_alias_decl_p (ptr, decl);
    }

  /* ADDR_EXPR pointers either just offset another pointer or directly
     specify the pointed-to set.  */
  if (TREE_CODE (ptr) == ADDR_EXPR)
    {
      tree base = get_base_address (TREE_OPERAND (ptr, 0));
      if (base
	  && (TREE_CODE (base) == MEM_REF
	      || TREE_CODE (base) == TARGET_MEM_REF))
	ptr = TREE_OPERAND (base, 0);
      else if (base
	       && DECL_P (base))
	return compare_base_decls (base, decl) != 0;
      else if (base
	       && CONSTANT_CLASS_P (base))
	return false;
      else
	return true;
    }

  /* Non-aliased variables cannot be pointed to.  */
  if (!may_be_aliased (decl))
    return false;

  /* If we do not have useful points-to information for this pointer
     we cannot disambiguate anything else.  */
  pi = SSA_NAME_PTR_INFO (ptr);
  if (!pi)
    return true;

  return pt_solution_includes (&pi->pt, decl);
}

/* Return true if dereferenced PTR1 and PTR2 may alias.
   The caller is responsible for applying TBAA to see if accesses
   through PTR1 and PTR2 may conflict at all.  */

bool
ptr_derefs_may_alias_p (tree ptr1, tree ptr2)
{
  struct ptr_info_def *pi1, *pi2;

  /* Conversions are irrelevant for points-to information and
     data-dependence analysis can feed us those.  */
  STRIP_NOPS (ptr1);
  STRIP_NOPS (ptr2);

  /* Disregard pointer offsetting.  */
  if (TREE_CODE (ptr1) == POINTER_PLUS_EXPR)
    {
      do
	{
	  ptr1 = TREE_OPERAND (ptr1, 0);
	}
      while (TREE_CODE (ptr1) == POINTER_PLUS_EXPR);
      return ptr_derefs_may_alias_p (ptr1, ptr2);
    }
  if (TREE_CODE (ptr2) == POINTER_PLUS_EXPR)
    {
      do
	{
	  ptr2 = TREE_OPERAND (ptr2, 0);
	}
      while (TREE_CODE (ptr2) == POINTER_PLUS_EXPR);
      return ptr_derefs_may_alias_p (ptr1, ptr2);
    }

  /* ADDR_EXPR pointers either just offset another pointer or directly
     specify the pointed-to set.  */
  if (TREE_CODE (ptr1) == ADDR_EXPR)
    {
      tree base = get_base_address (TREE_OPERAND (ptr1, 0));
      if (base
	  && (TREE_CODE (base) == MEM_REF
	      || TREE_CODE (base) == TARGET_MEM_REF))
	return ptr_derefs_may_alias_p (TREE_OPERAND (base, 0), ptr2);
      else if (base
	       && DECL_P (base))
	return ptr_deref_may_alias_decl_p (ptr2, base);
      /* Try ptr2 when ptr1 points to a constant.  */
      else if (base
	       && !CONSTANT_CLASS_P (base))
	return true;
    }
  if (TREE_CODE (ptr2) == ADDR_EXPR)
    {
      tree base = get_base_address (TREE_OPERAND (ptr2, 0));
      if (base
	  && (TREE_CODE (base) == MEM_REF
	      || TREE_CODE (base) == TARGET_MEM_REF))
	return ptr_derefs_may_alias_p (ptr1, TREE_OPERAND (base, 0));
      else if (base
	       && DECL_P (base))
	return ptr_deref_may_alias_decl_p (ptr1, base);
      else
	return true;
    }

  /* From here we require SSA name pointers.  Anything else aliases.  */
  if (TREE_CODE (ptr1) != SSA_NAME
      || TREE_CODE (ptr2) != SSA_NAME
      || !POINTER_TYPE_P (TREE_TYPE (ptr1))
      || !POINTER_TYPE_P (TREE_TYPE (ptr2)))
    return true;

  /* We may end up with two empty points-to solutions for two same pointers.
     In this case we still want to say both pointers alias, so shortcut
     that here.  */
  if (ptr1 == ptr2)
    return true;

  /* If we do not have useful points-to information for either pointer
     we cannot disambiguate anything else.  */
  pi1 = SSA_NAME_PTR_INFO (ptr1);
  pi2 = SSA_NAME_PTR_INFO (ptr2);
  if (!pi1 || !pi2)
    return true;

  /* ???  This does not use TBAA to prune decls from the intersection
     that not both pointers may access.  */
  return pt_solutions_intersect (&pi1->pt, &pi2->pt);
}

/* Return true if dereferencing PTR may alias *REF.
   The caller is responsible for applying TBAA to see if PTR
   may access *REF at all.  */

static bool
ptr_deref_may_alias_ref_p_1 (tree ptr, ao_ref *ref)
{
  tree base = ao_ref_base (ref);

  if (TREE_CODE (base) == MEM_REF
      || TREE_CODE (base) == TARGET_MEM_REF)
    return ptr_derefs_may_alias_p (ptr, TREE_OPERAND (base, 0));
  else if (DECL_P (base))
    return ptr_deref_may_alias_decl_p (ptr, base);

  return true;
}

/* Returns true if PTR1 and PTR2 compare unequal because of points-to.  */

bool
ptrs_compare_unequal (tree ptr1, tree ptr2)
{
  /* First resolve the pointers down to a SSA name pointer base or
     a VAR_DECL, PARM_DECL or RESULT_DECL.  This explicitely does
     not yet try to handle LABEL_DECLs, FUNCTION_DECLs, CONST_DECLs
     or STRING_CSTs which needs points-to adjustments to track them
     in the points-to sets.  */
  tree obj1 = NULL_TREE;
  tree obj2 = NULL_TREE;
  if (TREE_CODE (ptr1) == ADDR_EXPR)
    {
      tree tem = get_base_address (TREE_OPERAND (ptr1, 0));
      if (! tem)
	return false;
      if (VAR_P (tem)
	  || TREE_CODE (tem) == PARM_DECL
	  || TREE_CODE (tem) == RESULT_DECL)
	obj1 = tem;
      else if (TREE_CODE (tem) == MEM_REF)
	ptr1 = TREE_OPERAND (tem, 0);
    }
  if (TREE_CODE (ptr2) == ADDR_EXPR)
    {
      tree tem = get_base_address (TREE_OPERAND (ptr2, 0));
      if (! tem)
	return false;
      if (VAR_P (tem)
	  || TREE_CODE (tem) == PARM_DECL
	  || TREE_CODE (tem) == RESULT_DECL)
	obj2 = tem;
      else if (TREE_CODE (tem) == MEM_REF)
	ptr2 = TREE_OPERAND (tem, 0);
    }

  /* Canonicalize ptr vs. object.  */
  if (TREE_CODE (ptr1) == SSA_NAME && obj2)
    {
      std::swap (ptr1, ptr2);
      std::swap (obj1, obj2);
    }

  if (obj1 && obj2)
    /* Other code handles this correctly, no need to duplicate it here.  */;
  else if (obj1 && TREE_CODE (ptr2) == SSA_NAME)
    {
      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr2);
      /* We may not use restrict to optimize pointer comparisons.
         See PR71062.  So we have to assume that restrict-pointed-to
	 may be in fact obj1.  */
      if (!pi
	  || pi->pt.vars_contains_restrict
	  || pi->pt.vars_contains_interposable)
	return false;
      if (VAR_P (obj1)
	  && (TREE_STATIC (obj1) || DECL_EXTERNAL (obj1)))
	{
	  varpool_node *node = varpool_node::get (obj1);
	  /* If obj1 may bind to NULL give up (see below).  */
	  if (! node
	      || ! node->nonzero_address ()
	      || ! decl_binds_to_current_def_p (obj1))
	    return false;
	}
      return !pt_solution_includes (&pi->pt, obj1);
    }

  /* ???  We'd like to handle ptr1 != NULL and ptr1 != ptr2
     but those require pt.null to be conservatively correct.  */

  return false;
}

/* Returns whether reference REF to BASE may refer to global memory.
   When ESCAPED_LOCAL_P is true escaped local memory is also considered
   global.  */

static bool
ref_may_alias_global_p_1 (tree base, bool escaped_local_p)
{
  if (DECL_P (base))
    return (is_global_var (base)
	    || (escaped_local_p
		&& pt_solution_includes (&cfun->gimple_df->escaped, base)));
  else if (TREE_CODE (base) == MEM_REF
	   || TREE_CODE (base) == TARGET_MEM_REF)
    return ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0),
					 escaped_local_p);
  return true;
}

bool
ref_may_alias_global_p (ao_ref *ref, bool escaped_local_p)
{
  tree base = ao_ref_base (ref);
  return ref_may_alias_global_p_1 (base, escaped_local_p);
}

bool
ref_may_alias_global_p (tree ref, bool escaped_local_p)
{
  tree base = get_base_address (ref);
  return ref_may_alias_global_p_1 (base, escaped_local_p);
}

/* Return true whether STMT may clobber global memory.
   When ESCAPED_LOCAL_P is true escaped local memory is also considered
   global.  */

bool
stmt_may_clobber_global_p (gimple *stmt, bool escaped_local_p)
{
  tree lhs;

  if (!gimple_vdef (stmt))
    return false;

  /* ???  We can ask the oracle whether an artificial pointer
     dereference with a pointer with points-to information covering
     all global memory (what about non-address taken memory?) maybe
     clobbered by this call.  As there is at the moment no convenient
     way of doing that without generating garbage do some manual
     checking instead.
     ???  We could make a NULL ao_ref argument to the various
     predicates special, meaning any global memory.  */

  switch (gimple_code (stmt))
    {
    case GIMPLE_ASSIGN:
      lhs = gimple_assign_lhs (stmt);
      return (TREE_CODE (lhs) != SSA_NAME
	      && ref_may_alias_global_p (lhs, escaped_local_p));
    case GIMPLE_CALL:
      return true;
    default:
      return true;
    }
}


/* Dump alias information on FILE.  */

void
dump_alias_info (FILE *file)
{
  unsigned i;
  tree ptr;
  const char *funcname
    = lang_hooks.decl_printable_name (current_function_decl, 2);
  tree var;

  fprintf (file, "\n\nAlias information for %s\n\n", funcname);

  fprintf (file, "Aliased symbols\n\n");

  FOR_EACH_LOCAL_DECL (cfun, i, var)
    {
      if (may_be_aliased (var))
	dump_variable (file, var);
    }

  fprintf (file, "\nCall clobber information\n");

  fprintf (file, "\nESCAPED");
  dump_points_to_solution (file, &cfun->gimple_df->escaped);

  fprintf (file, "\n\nFlow-insensitive points-to information\n\n");

  FOR_EACH_SSA_NAME (i, ptr, cfun)
    {
      struct ptr_info_def *pi;

      if (!POINTER_TYPE_P (TREE_TYPE (ptr))
	  || SSA_NAME_IN_FREE_LIST (ptr))
	continue;

      pi = SSA_NAME_PTR_INFO (ptr);
      if (pi)
	dump_points_to_info_for (file, ptr);
    }

  fprintf (file, "\n");
}


/* Dump alias information on stderr.  */

DEBUG_FUNCTION void
debug_alias_info (void)
{
  dump_alias_info (stderr);
}


/* Dump the points-to set *PT into FILE.  */

void
dump_points_to_solution (FILE *file, struct pt_solution *pt)
{
  if (pt->anything)
    fprintf (file, ", points-to anything");

  if (pt->nonlocal)
    fprintf (file, ", points-to non-local");

  if (pt->escaped)
    fprintf (file, ", points-to escaped");

  if (pt->ipa_escaped)
    fprintf (file, ", points-to unit escaped");

  if (pt->null)
    fprintf (file, ", points-to NULL");

  if (pt->vars)
    {
      fprintf (file, ", points-to vars: ");
      dump_decl_set (file, pt->vars);
      if (pt->vars_contains_nonlocal
	  || pt->vars_contains_escaped
	  || pt->vars_contains_escaped_heap
	  || pt->vars_contains_restrict)
	{
	  const char *comma = "";
	  fprintf (file, " (");
	  if (pt->vars_contains_nonlocal)
	    {
	      fprintf (file, "nonlocal");
	      comma = ", ";
	    }
	  if (pt->vars_contains_escaped)
	    {
	      fprintf (file, "%sescaped", comma);
	      comma = ", ";
	    }
	  if (pt->vars_contains_escaped_heap)
	    {
	      fprintf (file, "%sescaped heap", comma);
	      comma = ", ";
	    }
	  if (pt->vars_contains_restrict)
	    {
	      fprintf (file, "%srestrict", comma);
	      comma = ", ";
	    }
	  if (pt->vars_contains_interposable)
	    fprintf (file, "%sinterposable", comma);
	  fprintf (file, ")");
	}
    }
}


/* Unified dump function for pt_solution.  */

DEBUG_FUNCTION void
debug (pt_solution &ref)
{
  dump_points_to_solution (stderr, &ref);
}

DEBUG_FUNCTION void
debug (pt_solution *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}


/* Dump points-to information for SSA_NAME PTR into FILE.  */

void
dump_points_to_info_for (FILE *file, tree ptr)
{
  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);

  print_generic_expr (file, ptr, dump_flags);

  if (pi)
    dump_points_to_solution (file, &pi->pt);
  else
    fprintf (file, ", points-to anything");

  fprintf (file, "\n");
}


/* Dump points-to information for VAR into stderr.  */

DEBUG_FUNCTION void
debug_points_to_info_for (tree var)
{
  dump_points_to_info_for (stderr, var);
}


/* Initializes the alias-oracle reference representation *R from REF.  */

void
ao_ref_init (ao_ref *r, tree ref)
{
  r->ref = ref;
  r->base = NULL_TREE;
  r->offset = 0;
  r->size = -1;
  r->max_size = -1;
  r->ref_alias_set = -1;
  r->base_alias_set = -1;
  r->volatile_p = ref ? TREE_THIS_VOLATILE (ref) : false;
}

/* Returns the base object of the memory reference *REF.  */

tree
ao_ref_base (ao_ref *ref)
{
  bool reverse;

  if (ref->base)
    return ref->base;
  ref->base = get_ref_base_and_extent (ref->ref, &ref->offset, &ref->size,
				       &ref->max_size, &reverse);
  return ref->base;
}

/* Returns the base object alias set of the memory reference *REF.  */

alias_set_type
ao_ref_base_alias_set (ao_ref *ref)
{
  tree base_ref;
  if (ref->base_alias_set != -1)
    return ref->base_alias_set;
  if (!ref->ref)
    return 0;
  base_ref = ref->ref;
  if (TREE_CODE (base_ref) == WITH_SIZE_EXPR)
    base_ref = TREE_OPERAND (base_ref, 0);
  while (handled_component_p (base_ref))
    base_ref = TREE_OPERAND (base_ref, 0);
  ref->base_alias_set = get_alias_set (base_ref);
  return ref->base_alias_set;
}

/* Returns the reference alias set of the memory reference *REF.  */

alias_set_type
ao_ref_alias_set (ao_ref *ref)
{
  if (ref->ref_alias_set != -1)
    return ref->ref_alias_set;
  if (!ref->ref)
    return 0;
  ref->ref_alias_set = get_alias_set (ref->ref);
  return ref->ref_alias_set;
}

/* Returns a type satisfying
   get_deref_alias_set (type) == ao_ref_base_alias_set (REF).  */

tree
ao_ref_base_alias_ptr_type (ao_ref *ref)
{
  tree base_ref;

  if (!ref->ref)
    return NULL_TREE;
  base_ref = ref->ref;
  if (TREE_CODE (base_ref) == WITH_SIZE_EXPR)
    base_ref = TREE_OPERAND (base_ref, 0);
  while (handled_component_p (base_ref))
    base_ref = TREE_OPERAND (base_ref, 0);
  tree ret = reference_alias_ptr_type (base_ref);
  return ret;
}

/* Returns a type satisfying
   get_deref_alias_set (type) == ao_ref_alias_set (REF).  */

tree
ao_ref_alias_ptr_type (ao_ref *ref)
{
  if (!ref->ref)
    return NULL_TREE;
  tree ret = reference_alias_ptr_type (ref->ref);
  return ret;
}

/* Return the alignment of the access *REF and store it in the *ALIGN
   and *BITPOS pairs.  Returns false if no alignment could be determined.
   See get_object_alignment_2 for details.  */

bool
ao_ref_alignment (ao_ref *ref, unsigned int *align,
		  unsigned HOST_WIDE_INT *bitpos)
{
  if (ref->ref)
    return get_object_alignment_1 (ref->ref, align, bitpos);

  /* When we just have ref->base we cannot use get_object_alignment since
     that will eventually use the type of the appearant access while for
     example ao_ref_init_from_ptr_and_range is not careful to adjust that.  */
  *align = BITS_PER_UNIT;
  HOST_WIDE_INT offset;
  if (!ref->offset.is_constant (&offset)
      || !get_object_alignment_2 (ref->base, align, bitpos, true))
    return false;
  *bitpos += (unsigned HOST_WIDE_INT)offset * BITS_PER_UNIT;
  *bitpos = *bitpos & (*align - 1);
  return true;
}

/* Init an alias-oracle reference representation from a gimple pointer
   PTR a range specified by OFFSET, SIZE and MAX_SIZE under the assumption
   that RANGE_KNOWN is set.

   The access is assumed to be only to or after of the pointer target adjusted
   by the offset, not before it (even in the case RANGE_KNOWN is false).  */

void
ao_ref_init_from_ptr_and_range (ao_ref *ref, tree ptr,
				bool range_known,
				poly_int64 offset,
				poly_int64 size,
				poly_int64 max_size)
{
  poly_int64 t, extra_offset = 0;

  ref->ref = NULL_TREE;
  if (TREE_CODE (ptr) == SSA_NAME)
    {
      gimple *stmt = SSA_NAME_DEF_STMT (ptr);
      if (gimple_assign_single_p (stmt)
	  && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
	ptr = gimple_assign_rhs1 (stmt);
      else if (is_gimple_assign (stmt)
	       && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
	       && ptrdiff_tree_p (gimple_assign_rhs2 (stmt), &extra_offset))
	{
	  ptr = gimple_assign_rhs1 (stmt);
	  extra_offset *= BITS_PER_UNIT;
	}
    }

  if (TREE_CODE (ptr) == ADDR_EXPR)
    {
      ref->base = get_addr_base_and_unit_offset (TREE_OPERAND (ptr, 0), &t);
      if (ref->base)
	ref->offset = BITS_PER_UNIT * t;
      else
	{
	  range_known = false;
	  ref->offset = 0;
	  ref->base = get_base_address (TREE_OPERAND (ptr, 0));
	}
    }
  else
    {
      gcc_assert (POINTER_TYPE_P (TREE_TYPE (ptr)));
      ref->base = build2 (MEM_REF, char_type_node,
			  ptr, null_pointer_node);
      ref->offset = 0;
    }
  ref->offset += extra_offset + offset;
  if (range_known)
    {
      ref->max_size = max_size;
      ref->size = size;
    }
  else
    ref->max_size = ref->size = -1;
  ref->ref_alias_set = 0;
  ref->base_alias_set = 0;
  ref->volatile_p = false;
}

/* Init an alias-oracle reference representation from a gimple pointer
   PTR and a gimple size SIZE in bytes.  If SIZE is NULL_TREE then the
   size is assumed to be unknown.  The access is assumed to be only
   to or after of the pointer target, not before it.  */

void
ao_ref_init_from_ptr_and_size (ao_ref *ref, tree ptr, tree size)
{
  poly_int64 size_hwi;
  if (size
      && poly_int_tree_p (size, &size_hwi)
      && coeffs_in_range_p (size_hwi, 0, HOST_WIDE_INT_MAX / BITS_PER_UNIT))
    {
      size_hwi = size_hwi * BITS_PER_UNIT;
      ao_ref_init_from_ptr_and_range (ref, ptr, true, 0, size_hwi, size_hwi);
    }
  else
    ao_ref_init_from_ptr_and_range (ref, ptr, false, 0, -1, -1);
}

/* S1 and S2 are TYPE_SIZE or DECL_SIZE.  Compare them:
   Return -1 if S1 < S2
   Return 1 if S1 > S2
   Return 0 if equal or incomparable.  */

static int
compare_sizes (tree s1, tree s2)
{
  if (!s1 || !s2)
    return 0;

  poly_uint64 size1;
  poly_uint64 size2;

  if (!poly_int_tree_p (s1, &size1) || !poly_int_tree_p (s2, &size2))
    return 0;
  if (known_lt (size1, size2))
    return -1;
  if (known_lt (size2, size1))
    return 1;
  return 0;
}

/* Compare TYPE1 and TYPE2 by its size.
   Return -1 if size of TYPE1 < size of TYPE2
   Return 1 if size of TYPE1 > size of TYPE2
   Return 0 if types are of equal sizes or we can not compare them.  */

static int
compare_type_sizes (tree type1, tree type2)
{
  /* Be conservative for arrays and vectors.  We want to support partial
     overlap on int[3] and int[3] as tested in gcc.dg/torture/alias-2.c.  */
  while (TREE_CODE (type1) == ARRAY_TYPE
	 || TREE_CODE (type1) == VECTOR_TYPE)
    type1 = TREE_TYPE (type1);
  while (TREE_CODE (type2) == ARRAY_TYPE
	 || TREE_CODE (type2) == VECTOR_TYPE)
    type2 = TREE_TYPE (type2);
  return compare_sizes (TYPE_SIZE (type1), TYPE_SIZE (type2));
}

/* Return 1 if TYPE1 and TYPE2 are to be considered equivalent for the
   purpose of TBAA.  Return 0 if they are distinct and -1 if we cannot
   decide.  */

static inline int
same_type_for_tbaa (tree type1, tree type2)
{
  type1 = TYPE_MAIN_VARIANT (type1);
  type2 = TYPE_MAIN_VARIANT (type2);

  /* Handle the most common case first.  */
  if (type1 == type2)
    return 1;

  /* If we would have to do structural comparison bail out.  */
  if (TYPE_STRUCTURAL_EQUALITY_P (type1)
      || TYPE_STRUCTURAL_EQUALITY_P (type2))
    return -1;

  /* Compare the canonical types.  */
  if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))
    return 1;

  /* ??? Array types are not properly unified in all cases as we have
     spurious changes in the index types for example.  Removing this
     causes all sorts of problems with the Fortran frontend.  */
  if (TREE_CODE (type1) == ARRAY_TYPE
      && TREE_CODE (type2) == ARRAY_TYPE)
    return -1;

  /* ??? In Ada, an lvalue of an unconstrained type can be used to access an
     object of one of its constrained subtypes, e.g. when a function with an
     unconstrained parameter passed by reference is called on an object and
     inlined.  But, even in the case of a fixed size, type and subtypes are
     not equivalent enough as to share the same TYPE_CANONICAL, since this
     would mean that conversions between them are useless, whereas they are
     not (e.g. type and subtypes can have different modes).  So, in the end,
     they are only guaranteed to have the same alias set.  */
  alias_set_type set1 = get_alias_set (type1);
  alias_set_type set2 = get_alias_set (type2);
  if (set1 == set2)
    return -1;

  /* Pointers to void are considered compatible with all other pointers,
     so for two pointers see what the alias set resolution thinks.  */
  if (POINTER_TYPE_P (type1)
      && POINTER_TYPE_P (type2)
      && alias_sets_conflict_p (set1, set2))
    return -1;

  /* The types are known to be not equal.  */
  return 0;
}

/* Return true if TYPE is a composite type (i.e. we may apply one of handled
   components on it).  */

static bool
type_has_components_p (tree type)
{
  return AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)
	 || TREE_CODE (type) == COMPLEX_TYPE;
}

/* MATCH1 and MATCH2 which are part of access path of REF1 and REF2
   respectively are either pointing to same address or are completely
   disjoint. If PARTIAL_OVERLAP is true, assume that outermost arrays may
   just partly overlap.

   Try to disambiguate using the access path starting from the match
   and return false if there is no conflict.

   Helper for aliasing_component_refs_p.  */

static bool
aliasing_matching_component_refs_p (tree match1, tree ref1,
				    poly_int64 offset1, poly_int64 max_size1,
				    tree match2, tree ref2,
				    poly_int64 offset2, poly_int64 max_size2,
				    bool partial_overlap)
{
  poly_int64 offadj, sztmp, msztmp;
  bool reverse;

  if (!partial_overlap)
    {
      get_ref_base_and_extent (match2, &offadj, &sztmp, &msztmp, &reverse);
      offset2 -= offadj;
      get_ref_base_and_extent (match1, &offadj, &sztmp, &msztmp, &reverse);
      offset1 -= offadj;
      if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
	{
	  ++alias_stats.aliasing_component_refs_p_no_alias;
	  return false;
	}
    }

  int cmp = nonoverlapping_refs_since_match_p (match1, ref1, match2, ref2,
					       partial_overlap);
  if (cmp == 1
      || (cmp == -1 && nonoverlapping_component_refs_p (ref1, ref2)))
    {
      ++alias_stats.aliasing_component_refs_p_no_alias;
      return false;
    }
  ++alias_stats.aliasing_component_refs_p_may_alias;
  return true;
}

/* Return true if REF is reference to zero sized trailing array. I.e.
   struct foo {int bar; int array[0];} *fooptr;
   fooptr->array.  */

static bool
component_ref_to_zero_sized_trailing_array_p (tree ref)
{
  return (TREE_CODE (ref) == COMPONENT_REF
	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 1))) == ARRAY_TYPE
	  && (!TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)))
	      || integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)))))
	  && array_ref_flexible_size_p (ref));
}

/* Worker for aliasing_component_refs_p. Most parameters match parameters of
   aliasing_component_refs_p.

   Walk access path REF2 and try to find type matching TYPE1
   (which is a start of possibly aliasing access path REF1).
   If match is found, try to disambiguate.

   Return 0 for sucessful disambiguation.
   Return 1 if match was found but disambiguation failed
   Return -1 if there is no match.
   In this case MAYBE_MATCH is set to 0 if there is no type matching TYPE1
   in access patch REF2 and -1 if we are not sure.  */

static int
aliasing_component_refs_walk (tree ref1, tree type1, tree base1,
			      poly_int64 offset1, poly_int64 max_size1,
			      tree end_struct_ref1,
			      tree ref2, tree base2,
			      poly_int64 offset2, poly_int64 max_size2,
			      bool *maybe_match)
{
  tree ref = ref2;
  int same_p = 0;

  while (true)
    {
      /* We walk from inner type to the outer types. If type we see is
	 already too large to be part of type1, terminate the search.  */
      int cmp = compare_type_sizes (type1, TREE_TYPE (ref));

      if (cmp < 0
	  && (!end_struct_ref1
	      || compare_type_sizes (TREE_TYPE (end_struct_ref1),
				     TREE_TYPE (ref)) < 0))
	break;
      /* If types may be of same size, see if we can decide about their
	 equality.  */
      if (cmp == 0)
	{
	  same_p = same_type_for_tbaa (TREE_TYPE (ref), type1);
	  if (same_p == 1)
	    break;
	  /* In case we can't decide whether types are same try to
	     continue looking for the exact match.
	     Remember however that we possibly saw a match
	     to bypass the access path continuations tests we do later.  */
	  if (same_p == -1)
	    *maybe_match = true;
	}
      if (!handled_component_p (ref))
	break;
      ref = TREE_OPERAND (ref, 0);
    }
  if (same_p == 1)
    {
      bool partial_overlap = false;

      /* We assume that arrays can overlap by multiple of their elements
	 size as tested in gcc.dg/torture/alias-2.c.
	 This partial overlap happen only when both arrays are bases of
	 the access and not contained within another component ref.
	 To be safe we also assume partial overlap for VLAs. */
      if (TREE_CODE (TREE_TYPE (base1)) == ARRAY_TYPE
	  && (!TYPE_SIZE (TREE_TYPE (base1))
	      || TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) != INTEGER_CST
	      || ref == base2))
	{
	  /* Setting maybe_match to true triggers
	     nonoverlapping_component_refs_p test later that still may do
	     useful disambiguation.  */
	  *maybe_match = true;
	  partial_overlap = true;
	}
      return aliasing_matching_component_refs_p (base1, ref1,
						 offset1, max_size1,
						 ref, ref2,
						 offset2, max_size2,
						 partial_overlap);
    }
  return -1;
}

/* Consider access path1 base1....ref1 and access path2 base2...ref2.
   Return true if they can be composed to single access path
   base1...ref1...base2...ref2.

   REF_TYPE1 if type of REF1.  END_STRUCT_PAST_END1 is true if there is
   a trailing array access after REF1 in the non-TBAA part of the access.
   REF1_ALIAS_SET is the alias set of REF1.

   BASE_TYPE2 is type of base2.  END_STRUCT_REF2 is non-NULL if there is
   a trailing array access in the TBAA part of access path2.
   BASE2_ALIAS_SET is the alias set of base2.  */

bool
access_path_may_continue_p (tree ref_type1, bool end_struct_past_end1,
			    alias_set_type ref1_alias_set,
			    tree base_type2, tree end_struct_ref2,
			    alias_set_type base2_alias_set)
{
  /* Access path can not continue past types with no components.  */
  if (!type_has_components_p (ref_type1))
    return false;

  /* If first access path ends by too small type to hold base of
     the second access path, typically paths can not continue.

     Punt if end_struct_past_end1 is true.  We want to support arbitrary
     type puning past first COMPONENT_REF to union because redundant store
     elimination depends on this, see PR92152.  For this reason we can not
     check size of the reference because types may partially overlap.  */
  if (!end_struct_past_end1)
    {
      if (compare_type_sizes (ref_type1, base_type2) < 0)
	return false;
      /* If the path2 contains trailing array access we can strenghten the check
	 to verify that also the size of element of the trailing array fits.
	 In fact we could check for offset + type_size, but we do not track
	 offsets and this is quite side case.  */
      if (end_struct_ref2
	  && compare_type_sizes (ref_type1, TREE_TYPE (end_struct_ref2)) < 0)
	return false;
    }
  return (base2_alias_set == ref1_alias_set
	  || alias_set_subset_of (base2_alias_set, ref1_alias_set));
}

/* Determine if the two component references REF1 and REF2 which are
   based on access types TYPE1 and TYPE2 and of which at least one is based
   on an indirect reference may alias.  
   REF1_ALIAS_SET, BASE1_ALIAS_SET, REF2_ALIAS_SET and BASE2_ALIAS_SET
   are the respective alias sets.  */

static bool
aliasing_component_refs_p (tree ref1,
			   alias_set_type ref1_alias_set,
			   alias_set_type base1_alias_set,
			   poly_int64 offset1, poly_int64 max_size1,
			   tree ref2,
			   alias_set_type ref2_alias_set,
			   alias_set_type base2_alias_set,
			   poly_int64 offset2, poly_int64 max_size2)
{
  /* If one reference is a component references through pointers try to find a
     common base and apply offset based disambiguation.  This handles
     for example
       struct A { int i; int j; } *q;
       struct B { struct A a; int k; } *p;
     disambiguating q->i and p->a.j.  */
  tree base1, base2;
  tree type1, type2;
  bool maybe_match = false;
  tree end_struct_ref1 = NULL, end_struct_ref2 = NULL;
  bool end_struct_past_end1 = false;
  bool end_struct_past_end2 = false;

  /* Choose bases and base types to search for.
     The access path is as follows:
       base....end_of_tbaa_ref...actual_ref
     At one place in the access path may be a reference to zero sized or
     trailing array.

     We generally discard the segment after end_of_tbaa_ref however
     we need to be careful in case it contains zero sized or trailing array.
     These may happen after reference to union and in this case we need to
     not disambiguate type puning scenarios.

     We set:
	base1 to point to base

	ref1 to point to end_of_tbaa_ref

	end_struct_ref1 to point the trailing reference (if it exists
 	in range base....end_of_tbaa_ref

	end_struct_past_end1 is true if this trailing reference occurs in
	end_of_tbaa_ref...actual_ref.  */
  base1 = ref1;
  while (handled_component_p (base1))
    {
      /* Generally access paths are monotous in the size of object. The
	 exception are trailing arrays of structures. I.e.
	   struct a {int array[0];};
	 or
	   struct a {int array1[0]; int array[];};
	 Such struct has size 0 but accesses to a.array may have non-zero size.
	 In this case the size of TREE_TYPE (base1) is smaller than
	 size of TREE_TYPE (TREE_OPERAND (base1, 0)).

	 Because we compare sizes of arrays just by sizes of their elements,
	 we only need to care about zero sized array fields here.  */
      if (component_ref_to_zero_sized_trailing_array_p (base1))
	{
	  gcc_checking_assert (!end_struct_ref1);
          end_struct_ref1 = base1;
	}
      if (ends_tbaa_access_path_p (base1))
	{
	  ref1 = TREE_OPERAND (base1, 0);
	  if (end_struct_ref1)
	    {
	      end_struct_past_end1 = true;
	      end_struct_ref1 = NULL;
	    }
	}
      base1 = TREE_OPERAND (base1, 0);
    }
  type1 = TREE_TYPE (base1);
  base2 = ref2;
  while (handled_component_p (base2))
    {
      if (component_ref_to_zero_sized_trailing_array_p (base2))
	{
	  gcc_checking_assert (!end_struct_ref2);
	  end_struct_ref2 = base2;
	}
      if (ends_tbaa_access_path_p (base2))
	{
	  ref2 = TREE_OPERAND (base2, 0);
	  if (end_struct_ref2)
	    {
	      end_struct_past_end2 = true;
	      end_struct_ref2 = NULL;
	    }
	}
      base2 = TREE_OPERAND (base2, 0);
    }
  type2 = TREE_TYPE (base2);

  /* Now search for the type1 in the access path of ref2.  This
     would be a common base for doing offset based disambiguation on.
     This however only makes sense if type2 is big enough to hold type1.  */
  int cmp_outer = compare_type_sizes (type2, type1);

  /* If type2 is big enough to contain type1 walk its access path.
     We also need to care of arrays at the end of structs that may extend
     beyond the end of structure.  If this occurs in the TBAA part of the
     access path, we need to consider the increased type as well.  */
  if (cmp_outer >= 0
      || (end_struct_ref2
	  && compare_type_sizes (TREE_TYPE (end_struct_ref2), type1) >= 0))
    {
      int res = aliasing_component_refs_walk (ref1, type1, base1,
					      offset1, max_size1,
					      end_struct_ref1,
					      ref2, base2, offset2, max_size2,
					      &maybe_match);
      if (res != -1)
	return res;
    }

  /* If we didn't find a common base, try the other way around.  */
  if (cmp_outer <= 0 
      || (end_struct_ref1
	  && compare_type_sizes (TREE_TYPE (end_struct_ref1), type1) <= 0))
    {
      int res = aliasing_component_refs_walk (ref2, type2, base2,
					      offset2, max_size2,
					      end_struct_ref2,
					      ref1, base1, offset1, max_size1,
					      &maybe_match);
      if (res != -1)
	return res;
    }

  /* In the following code we make an assumption that the types in access
     paths do not overlap and thus accesses alias only if one path can be
     continuation of another.  If we was not able to decide about equivalence,
     we need to give up.  */
  if (maybe_match)
    {
      if (!nonoverlapping_component_refs_p (ref1, ref2))
	{
	  ++alias_stats.aliasing_component_refs_p_may_alias;
	  return true;
	}
      ++alias_stats.aliasing_component_refs_p_no_alias;
      return false;
    }

  if (access_path_may_continue_p (TREE_TYPE (ref1), end_struct_past_end1,
				  ref1_alias_set,
				  type2, end_struct_ref2,
				  base2_alias_set)
      || access_path_may_continue_p (TREE_TYPE (ref2), end_struct_past_end2,
				     ref2_alias_set,
				     type1, end_struct_ref1,
				     base1_alias_set))
    {
      ++alias_stats.aliasing_component_refs_p_may_alias;
      return true;
    }
  ++alias_stats.aliasing_component_refs_p_no_alias;
  return false;
}

/* FIELD1 and FIELD2 are two fields of component refs.  We assume
   that bases of both component refs are either equivalent or nonoverlapping.
   We do not assume that the containers of FIELD1 and FIELD2 are of the
   same type or size.

   Return 0 in case the base address of component_refs are same then 
   FIELD1 and FIELD2 have same address. Note that FIELD1 and FIELD2
   may not be of same type or size.

   Return 1 if FIELD1 and FIELD2 are non-overlapping.

   Return -1 otherwise.

   Main difference between 0 and -1 is to let
   nonoverlapping_component_refs_since_match_p discover the semantically
   equivalent part of the access path.

   Note that this function is used even with -fno-strict-aliasing
   and makes use of no TBAA assumptions.  */

static int
nonoverlapping_component_refs_p_1 (const_tree field1, const_tree field2)
{
  /* If both fields are of the same type, we could save hard work of
     comparing offsets.  */
  tree type1 = DECL_CONTEXT (field1);
  tree type2 = DECL_CONTEXT (field2);

  if (TREE_CODE (type1) == RECORD_TYPE
      && DECL_BIT_FIELD_REPRESENTATIVE (field1))
    field1 = DECL_BIT_FIELD_REPRESENTATIVE (field1);
  if (TREE_CODE (type2) == RECORD_TYPE
      && DECL_BIT_FIELD_REPRESENTATIVE (field2))
    field2 = DECL_BIT_FIELD_REPRESENTATIVE (field2);

  /* ??? Bitfields can overlap at RTL level so punt on them.
     FIXME: RTL expansion should be fixed by adjusting the access path
     when producing MEM_ATTRs for MEMs which are wider than 
     the bitfields similarly as done in set_mem_attrs_minus_bitpos.  */
  if (DECL_BIT_FIELD (field1) && DECL_BIT_FIELD (field2))
    return -1;

  /* Assume that different FIELD_DECLs never overlap within a RECORD_TYPE.  */
  if (type1 == type2 && TREE_CODE (type1) == RECORD_TYPE)
    return field1 != field2;

  /* In common case the offsets and bit offsets will be the same.
     However if frontends do not agree on the alignment, they may be
     different even if they actually represent same address.
     Try the common case first and if that fails calcualte the
     actual bit offset.  */
  if (tree_int_cst_equal (DECL_FIELD_OFFSET (field1),
			  DECL_FIELD_OFFSET (field2))
      && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (field1),
			     DECL_FIELD_BIT_OFFSET (field2)))
    return 0;

  /* Note that it may be possible to use component_ref_field_offset
     which would provide offsets as trees. However constructing and folding
     trees is expensive and does not seem to be worth the compile time
     cost.  */

  poly_uint64 offset1, offset2;
  poly_uint64 bit_offset1, bit_offset2;

  if (poly_int_tree_p (DECL_FIELD_OFFSET (field1), &offset1)
      && poly_int_tree_p (DECL_FIELD_OFFSET (field2), &offset2)
      && poly_int_tree_p (DECL_FIELD_BIT_OFFSET (field1), &bit_offset1)
      && poly_int_tree_p (DECL_FIELD_BIT_OFFSET (field2), &bit_offset2))
    {
      offset1 = (offset1 << LOG2_BITS_PER_UNIT) + bit_offset1;
      offset2 = (offset2 << LOG2_BITS_PER_UNIT) + bit_offset2;

      if (known_eq (offset1, offset2))
	return 0;

      poly_uint64 size1, size2;

      if (poly_int_tree_p (DECL_SIZE (field1), &size1)
	  && poly_int_tree_p (DECL_SIZE (field2), &size2)
	  && !ranges_maybe_overlap_p (offset1, size1, offset2, size2))
	return 1;
    }
  /* Resort to slower overlap checking by looking for matching types in
     the middle of access path.  */
  return -1;
}

/* Return low bound of array. Do not produce new trees
   and thus do not care about particular type of integer constant
   and placeholder exprs.  */

static tree
cheap_array_ref_low_bound (tree ref)
{
  tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));

  /* Avoid expensive array_ref_low_bound.
     low bound is either stored in operand2, or it is TYPE_MIN_VALUE of domain
     type or it is zero.  */
  if (TREE_OPERAND (ref, 2))
    return TREE_OPERAND (ref, 2);
  else if (domain_type && TYPE_MIN_VALUE (domain_type))
    return TYPE_MIN_VALUE (domain_type);
  else
    return integer_zero_node;
}

/* REF1 and REF2 are ARRAY_REFs with either same base address or which are
   completely disjoint.

   Return 1 if the refs are non-overlapping.
   Return 0 if they are possibly overlapping but if so the overlap again
   starts on the same address.
   Return -1 otherwise.  */

int
nonoverlapping_array_refs_p (tree ref1, tree ref2)
{
  tree index1 = TREE_OPERAND (ref1, 1);
  tree index2 = TREE_OPERAND (ref2, 1);
  tree low_bound1 = cheap_array_ref_low_bound (ref1);
  tree low_bound2 = cheap_array_ref_low_bound (ref2);

  /* Handle zero offsets first: we do not need to match type size in this
     case.  */
  if (operand_equal_p (index1, low_bound1, 0)
      && operand_equal_p (index2, low_bound2, 0))
    return 0;

  /* If type sizes are different, give up.

     Avoid expensive array_ref_element_size.
     If operand 3 is present it denotes size in the alignmnet units.
     Otherwise size is TYPE_SIZE of the element type.
     Handle only common cases where types are of the same "kind".  */
  if ((TREE_OPERAND (ref1, 3) == NULL) != (TREE_OPERAND (ref2, 3) == NULL))
    return -1;

  tree elmt_type1 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref1, 0)));
  tree elmt_type2 = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref2, 0)));

  if (TREE_OPERAND (ref1, 3))
    {
      if (TYPE_ALIGN (elmt_type1) != TYPE_ALIGN (elmt_type2)
	  || !operand_equal_p (TREE_OPERAND (ref1, 3),
			       TREE_OPERAND (ref2, 3), 0))
	return -1;
    }
  else
    {
      if (!operand_equal_p (TYPE_SIZE_UNIT (elmt_type1),
			    TYPE_SIZE_UNIT (elmt_type2), 0))
	return -1;
    }

  /* Since we know that type sizes are the same, there is no need to return
     -1 after this point. Partial overlap can not be introduced.  */

  /* We may need to fold trees in this case.
     TODO: Handle integer constant case at least.  */
  if (!operand_equal_p (low_bound1, low_bound2, 0))
    return 0;

  if (TREE_CODE (index1) == INTEGER_CST && TREE_CODE (index2) == INTEGER_CST)
    {
      if (tree_int_cst_equal (index1, index2))
	return 0;
      return 1;
    }
  /* TODO: We can use VRP to further disambiguate here. */
  return 0;
}

/* Try to disambiguate REF1 and REF2 under the assumption that MATCH1 and
   MATCH2 either point to the same address or are disjoint.
   MATCH1 and MATCH2 are assumed to be ref in the access path of REF1 and REF2
   respectively or NULL in the case we established equivalence of bases.
   If PARTIAL_OVERLAP is true assume that the toplevel arrays may actually
   overlap by exact multiply of their element size.

   This test works by matching the initial segment of the access path
   and does not rely on TBAA thus is safe for !flag_strict_aliasing if
   match was determined without use of TBAA oracle.

   Return 1 if we can determine that component references REF1 and REF2,
   that are within a common DECL, cannot overlap.

   Return 0 if paths are same and thus there is nothing to disambiguate more
   (i.e. there is must alias assuming there is must alias between MATCH1 and
   MATCH2)

   Return -1 if we can not determine 0 or 1 - this happens when we met
   non-matching types was met in the path.
   In this case it may make sense to continue by other disambiguation
   oracles.  */

static int
nonoverlapping_refs_since_match_p (tree match1, tree ref1,
				   tree match2, tree ref2,
				   bool partial_overlap)
{
  int ntbaa1 = 0, ntbaa2 = 0;
  /* Early return if there are no references to match, we do not need
     to walk the access paths.

     Do not consider this as may-alias for stats - it is more useful
     to have information how many disambiguations happened provided that
     the query was meaningful.  */

  if (match1 == ref1 || !handled_component_p (ref1)
      || match2 == ref2 || !handled_component_p (ref2))
    return -1;

  auto_vec<tree, 16> component_refs1;
  auto_vec<tree, 16> component_refs2;

  /* Create the stack of handled components for REF1.  */
  while (handled_component_p (ref1) && ref1 != match1)
    {
      /* We use TBAA only to re-synchronize after mismatched refs.  So we
	 do not need to truncate access path after TBAA part ends.  */
      if (ends_tbaa_access_path_p (ref1))
	ntbaa1 = 0;
      else
	ntbaa1++;
      component_refs1.safe_push (ref1);
      ref1 = TREE_OPERAND (ref1, 0);
    }

  /* Create the stack of handled components for REF2.  */
  while (handled_component_p (ref2) && ref2 != match2)
    {
      if (ends_tbaa_access_path_p (ref2))
	ntbaa2 = 0;
      else
	ntbaa2++;
      component_refs2.safe_push (ref2);
      ref2 = TREE_OPERAND (ref2, 0);
    }

  if (!flag_strict_aliasing)
    {
      ntbaa1 = 0;
      ntbaa2 = 0;
    }

  bool mem_ref1 = TREE_CODE (ref1) == MEM_REF && ref1 != match1;
  bool mem_ref2 = TREE_CODE (ref2) == MEM_REF && ref2 != match2;

  /* If only one of access path starts with MEM_REF check that offset is 0
     so the addresses stays the same after stripping it.
     TODO: In this case we may walk the other access path until we get same
     offset.

     If both starts with MEM_REF, offset has to be same.  */
  if ((mem_ref1 && !mem_ref2 && !integer_zerop (TREE_OPERAND (ref1, 1)))
      || (mem_ref2 && !mem_ref1 && !integer_zerop (TREE_OPERAND (ref2, 1)))
      || (mem_ref1 && mem_ref2
	  && !tree_int_cst_equal (TREE_OPERAND (ref1, 1),
				  TREE_OPERAND (ref2, 1))))
    {
      ++alias_stats.nonoverlapping_refs_since_match_p_may_alias;
      return -1;
    }

  /* TARGET_MEM_REF are never wrapped in handled components, so we do not need
     to handle them here at all.  */
  gcc_checking_assert (TREE_CODE (ref1) != TARGET_MEM_REF
		       && TREE_CODE (ref2) != TARGET_MEM_REF);

  /* Pop the stacks in parallel and examine the COMPONENT_REFs of the same
     rank.  This is sufficient because we start from the same DECL and you
     cannot reference several fields at a time with COMPONENT_REFs (unlike
     with ARRAY_RANGE_REFs for arrays) so you always need the same number
     of them to access a sub-component, unless you're in a union, in which
     case the return value will precisely be false.  */
  while (true)
    {
      /* Track if we seen unmatched ref with non-zero offset.  In this case
	 we must look for partial overlaps.  */
      bool seen_unmatched_ref_p = false;

      /* First match ARRAY_REFs an try to disambiguate.  */
      if (!component_refs1.is_empty ()
	  && !component_refs2.is_empty ())
	{
	  unsigned int narray_refs1=0, narray_refs2=0;

	  /* We generally assume that both access paths starts by same sequence
	     of refs.  However if number of array refs is not in sync, try
	     to recover and pop elts until number match.  This helps the case
	     where one access path starts by array and other by element.  */
	  for (narray_refs1 = 0; narray_refs1 < component_refs1.length ();
	       narray_refs1++)
	    if (TREE_CODE (component_refs1 [component_refs1.length()
					    - 1 - narray_refs1]) != ARRAY_REF)
	      break;

	  for (narray_refs2 = 0; narray_refs2 < component_refs2.length ();
	       narray_refs2++)
	    if (TREE_CODE (component_refs2 [component_refs2.length()
					    - 1 - narray_refs2]) != ARRAY_REF)
	      break;
	  for (; narray_refs1 > narray_refs2; narray_refs1--)
	    {
	      ref1 = component_refs1.pop ();
	      ntbaa1--;

	      /* If index is non-zero we need to check whether the reference
		 does not break the main invariant that bases are either
		 disjoint or equal.  Consider the example:

		 unsigned char out[][1];
		 out[1]="a";
		 out[i][0];

		 Here bases out and out are same, but after removing the
		 [i] index, this invariant no longer holds, because
		 out[i] points to the middle of array out.

		 TODO: If size of type of the skipped reference is an integer
		 multiply of the size of type of the other reference this
		 invariant can be verified, but even then it is not completely
		 safe with !flag_strict_aliasing if the other reference contains
		 unbounded array accesses.
		 See   */

	      if (!operand_equal_p (TREE_OPERAND (ref1, 1),
				    cheap_array_ref_low_bound (ref1), 0))
		return 0;
	    }
	  for (; narray_refs2 > narray_refs1; narray_refs2--)
	    {
	      ref2 = component_refs2.pop ();
	      ntbaa2--;
	      if (!operand_equal_p (TREE_OPERAND (ref2, 1),
				    cheap_array_ref_low_bound (ref2), 0))
		return 0;
	    }
	  /* Try to disambiguate matched arrays.  */
	  for (unsigned int i = 0; i < narray_refs1; i++)
	    {
	      int cmp = nonoverlapping_array_refs_p (component_refs1.pop (),
						     component_refs2.pop ());
	      ntbaa1--;
	      ntbaa2--;
	      if (cmp == 1 && !partial_overlap)
		{
		  ++alias_stats
		    .nonoverlapping_refs_since_match_p_no_alias;
		  return 1;
		}
	      if (cmp == -1)
		{
		  seen_unmatched_ref_p = true;
		  /* We can not maintain the invariant that bases are either
		     same or completely disjoint.  However we can still recover
		     from type based alias analysis if we reach references to
		     same sizes.  We do not attempt to match array sizes, so
		     just finish array walking and look for component refs.  */
		  if (ntbaa1 < 0 || ntbaa2 < 0)
		    {
		      ++alias_stats.nonoverlapping_refs_since_match_p_may_alias;
		      return -1;
		    }
		  for (i++; i < narray_refs1; i++)
		    {
		      component_refs1.pop ();
		      component_refs2.pop ();
		      ntbaa1--;
		      ntbaa2--;
		    }
		  break;
		}
	      partial_overlap = false;
	    }
	}

      /* Next look for component_refs.  */
      do
	{
	  if (component_refs1.is_empty ())
	    {
	      ++alias_stats
		.nonoverlapping_refs_since_match_p_must_overlap;
	      return 0;
	    }
	  ref1 = component_refs1.pop ();
	  ntbaa1--;
	  if (TREE_CODE (ref1) != COMPONENT_REF)
	    {
	      seen_unmatched_ref_p = true;
	      if (ntbaa1 < 0 || ntbaa2 < 0)
		{
		  ++alias_stats.nonoverlapping_refs_since_match_p_may_alias;
		  return -1;
		}
	    }
	}
      while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref1, 0))));

      do
	{
	  if (component_refs2.is_empty ())
	    {
	      ++alias_stats
		.nonoverlapping_refs_since_match_p_must_overlap;
	      return 0;
	    }
	  ref2 = component_refs2.pop ();
	  ntbaa2--;
	  if (TREE_CODE (ref2) != COMPONENT_REF)
	    {
	      if (ntbaa1 < 0 || ntbaa2 < 0)
		{
		  ++alias_stats.nonoverlapping_refs_since_match_p_may_alias;
		  return -1;
		}
	      seen_unmatched_ref_p = true;
	    }
	}
      while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref2, 0))));

      /* BIT_FIELD_REF and VIEW_CONVERT_EXPR are taken off the vectors
	 earlier.  */
      gcc_checking_assert (TREE_CODE (ref1) == COMPONENT_REF
			   && TREE_CODE (ref2) == COMPONENT_REF);

      tree field1 = TREE_OPERAND (ref1, 1);
      tree field2 = TREE_OPERAND (ref2, 1);

      /* ??? We cannot simply use the type of operand #0 of the refs here
	 as the Fortran compiler smuggles type punning into COMPONENT_REFs
	 for common blocks instead of using unions like everyone else.  */
      tree type1 = DECL_CONTEXT (field1);
      tree type2 = DECL_CONTEXT (field2);

      partial_overlap = false;

      /* If we skipped array refs on type of different sizes, we can
	 no longer be sure that there are not partial overlaps.  */
      if (seen_unmatched_ref_p && ntbaa1 >= 0 && ntbaa2 >= 0
	  && !operand_equal_p (TYPE_SIZE (type1), TYPE_SIZE (type2), 0))
	{
	  ++alias_stats
	    .nonoverlapping_refs_since_match_p_may_alias;
	  return -1;
	}

      int cmp = nonoverlapping_component_refs_p_1 (field1, field2);
      if (cmp == -1)
	{
	  ++alias_stats
	    .nonoverlapping_refs_since_match_p_may_alias;
	  return -1;
	}
      else if (cmp == 1)
	{
	  ++alias_stats
	    .nonoverlapping_refs_since_match_p_no_alias;
	  return 1;
	}
    }
}

/* Return TYPE_UID which can be used to match record types we consider
   same for TBAA purposes.  */

static inline int
ncr_type_uid (const_tree field)
{
  /* ??? We cannot simply use the type of operand #0 of the refs here
     as the Fortran compiler smuggles type punning into COMPONENT_REFs
     for common blocks instead of using unions like everyone else.  */
  tree type = DECL_FIELD_CONTEXT (field);
  /* With LTO types considered same_type_for_tbaa_p 
     from different translation unit may not have same
     main variant.  They however have same TYPE_CANONICAL.  */
  if (TYPE_CANONICAL (type))
    return TYPE_UID (TYPE_CANONICAL (type));
  return TYPE_UID (type);
}

/* qsort compare function to sort FIELD_DECLs after their
   DECL_FIELD_CONTEXT TYPE_UID.  */

static inline int
ncr_compar (const void *field1_, const void *field2_)
{
  const_tree field1 = *(const_tree *) const_cast <void *>(field1_);
  const_tree field2 = *(const_tree *) const_cast <void *>(field2_);
  unsigned int uid1 = ncr_type_uid (field1);
  unsigned int uid2 = ncr_type_uid (field2);

  if (uid1 < uid2)
    return -1;
  else if (uid1 > uid2)
    return 1;
  return 0;
}

/* Return true if we can determine that the fields referenced cannot
   overlap for any pair of objects.  This relies on TBAA.  */

static bool
nonoverlapping_component_refs_p (const_tree x, const_tree y)
{
  /* Early return if we have nothing to do.

     Do not consider this as may-alias for stats - it is more useful
     to have information how many disambiguations happened provided that
     the query was meaningful.  */
  if (!flag_strict_aliasing
      || !x || !y
      || !handled_component_p (x)
      || !handled_component_p (y))
    return false;

  auto_vec<const_tree, 16> fieldsx;
  while (handled_component_p (x))
    {
      if (TREE_CODE (x) == COMPONENT_REF)
	{
	  tree field = TREE_OPERAND (x, 1);
	  tree type = DECL_FIELD_CONTEXT (field);
	  if (TREE_CODE (type) == RECORD_TYPE)
	    fieldsx.safe_push (field);
	}
      else if (ends_tbaa_access_path_p (x))
	fieldsx.truncate (0);
      x = TREE_OPERAND (x, 0);
    }
  if (fieldsx.length () == 0)
    return false;
  auto_vec<const_tree, 16> fieldsy;
  while (handled_component_p (y))
    {
      if (TREE_CODE (y) == COMPONENT_REF)
	{
	  tree field = TREE_OPERAND (y, 1);
	  tree type = DECL_FIELD_CONTEXT (field);
	  if (TREE_CODE (type) == RECORD_TYPE)
	    fieldsy.safe_push (TREE_OPERAND (y, 1));
	}
      else if (ends_tbaa_access_path_p (y))
	fieldsy.truncate (0);
      y = TREE_OPERAND (y, 0);
    }
  if (fieldsy.length () == 0)
    {
      ++alias_stats.nonoverlapping_component_refs_p_may_alias;
      return false;
    }

  /* Most common case first.  */
  if (fieldsx.length () == 1
      && fieldsy.length () == 1)
   {
     if (same_type_for_tbaa (DECL_FIELD_CONTEXT (fieldsx[0]),
			     DECL_FIELD_CONTEXT (fieldsy[0])) == 1
	 && nonoverlapping_component_refs_p_1 (fieldsx[0], fieldsy[0]) == 1)
      {
         ++alias_stats.nonoverlapping_component_refs_p_no_alias;
         return true;
      }
     else
      {
         ++alias_stats.nonoverlapping_component_refs_p_may_alias;
         return false;
      }
   }

  if (fieldsx.length () == 2)
    {
      if (ncr_compar (&fieldsx[0], &fieldsx[1]) == 1)
	std::swap (fieldsx[0], fieldsx[1]);
    }
  else
    fieldsx.qsort (ncr_compar);

  if (fieldsy.length () == 2)
    {
      if (ncr_compar (&fieldsy[0], &fieldsy[1]) == 1)
	std::swap (fieldsy[0], fieldsy[1]);
    }
  else
    fieldsy.qsort (ncr_compar);

  unsigned i = 0, j = 0;
  do
    {
      const_tree fieldx = fieldsx[i];
      const_tree fieldy = fieldsy[j];

      /* We're left with accessing different fields of a structure,
	 no possible overlap.  */
      if (same_type_for_tbaa (DECL_FIELD_CONTEXT (fieldx),
			      DECL_FIELD_CONTEXT (fieldy)) == 1
	  && nonoverlapping_component_refs_p_1 (fieldx, fieldy) == 1)
	{
	  ++alias_stats.nonoverlapping_component_refs_p_no_alias;
	  return true;
	}

      if (ncr_type_uid (fieldx) < ncr_type_uid (fieldy))
	{
	  i++;
	  if (i == fieldsx.length ())
	    break;
	}
      else
	{
	  j++;
	  if (j == fieldsy.length ())
	    break;
	}
    }
  while (1);

  ++alias_stats.nonoverlapping_component_refs_p_may_alias;
  return false;
}


/* Return true if two memory references based on the variables BASE1
   and BASE2 constrained to [OFFSET1, OFFSET1 + MAX_SIZE1) and
   [OFFSET2, OFFSET2 + MAX_SIZE2) may alias.  REF1 and REF2
   if non-NULL are the complete memory reference trees.  */

static bool
decl_refs_may_alias_p (tree ref1, tree base1,
		       poly_int64 offset1, poly_int64 max_size1,
		       poly_int64 size1,
		       tree ref2, tree base2,
		       poly_int64 offset2, poly_int64 max_size2,
		       poly_int64 size2)
{
  gcc_checking_assert (DECL_P (base1) && DECL_P (base2));

  /* If both references are based on different variables, they cannot alias.  */
  if (compare_base_decls (base1, base2) == 0)
    return false;

  /* If both references are based on the same variable, they cannot alias if
     the accesses do not overlap.  */
  if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
    return false;

  /* If there is must alias, there is no use disambiguating further.  */
  if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
    return true;

  /* For components with variable position, the above test isn't sufficient,
     so we disambiguate component references manually.  */
  if (ref1 && ref2
      && handled_component_p (ref1) && handled_component_p (ref2)
      && nonoverlapping_refs_since_match_p (NULL, ref1, NULL, ref2, false) == 1)
    return false;

  return true;     
}

/* Return true if access with BASE is view converted.
   Base must not be stripped from inner MEM_REF (&decl)
   which is done by ao_ref_base and thus one extra walk
   of handled components is needed.  */

static bool
view_converted_memref_p (tree base)
{
  if (TREE_CODE (base) != MEM_REF && TREE_CODE (base) != TARGET_MEM_REF)
    return false;
  return same_type_for_tbaa (TREE_TYPE (base),
			     TREE_TYPE (TREE_OPERAND (base, 1))) != 1;
}

/* Return true if an indirect reference based on *PTR1 constrained
   to [OFFSET1, OFFSET1 + MAX_SIZE1) may alias a variable based on BASE2
   constrained to [OFFSET2, OFFSET2 + MAX_SIZE2).  *PTR1 and BASE2 have
   the alias sets BASE1_ALIAS_SET and BASE2_ALIAS_SET which can be -1
   in which case they are computed on-demand.  REF1 and REF2
   if non-NULL are the complete memory reference trees.  */

static bool
indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
			       poly_int64 offset1, poly_int64 max_size1,
			       poly_int64 size1,
			       alias_set_type ref1_alias_set,
			       alias_set_type base1_alias_set,
			       tree ref2 ATTRIBUTE_UNUSED, tree base2,
			       poly_int64 offset2, poly_int64 max_size2,
			       poly_int64 size2,
			       alias_set_type ref2_alias_set,
			       alias_set_type base2_alias_set, bool tbaa_p)
{
  tree ptr1;
  tree ptrtype1, dbase2;

  gcc_checking_assert ((TREE_CODE (base1) == MEM_REF
			|| TREE_CODE (base1) == TARGET_MEM_REF)
		       && DECL_P (base2));

  ptr1 = TREE_OPERAND (base1, 0);
  poly_offset_int moff = mem_ref_offset (base1) << LOG2_BITS_PER_UNIT;

  /* If only one reference is based on a variable, they cannot alias if
     the pointer access is beyond the extent of the variable access.
     (the pointer base cannot validly point to an offset less than zero
     of the variable).
     ???  IVOPTs creates bases that do not honor this restriction,
     so do not apply this optimization for TARGET_MEM_REFs.  */
  if (TREE_CODE (base1) != TARGET_MEM_REF
      && !ranges_maybe_overlap_p (offset1 + moff, -1, offset2, max_size2))
    return false;

  /* If the pointer based access is bigger than the variable they cannot
     alias.  This is similar to the check below where we use TBAA to
     increase the size of the pointer based access based on the dynamic
     type of a containing object we can infer from it.  */
  poly_int64 dsize2;
  if (known_size_p (size1)
      && poly_int_tree_p (DECL_SIZE (base2), &dsize2)
      && known_lt (dsize2, size1))
    return false;

  /* They also cannot alias if the pointer may not point to the decl.  */
  if (!ptr_deref_may_alias_decl_p (ptr1, base2))
    return false;

  /* Disambiguations that rely on strict aliasing rules follow.  */
  if (!flag_strict_aliasing || !tbaa_p)
    return true;

  /* If the alias set for a pointer access is zero all bets are off.  */
  if (base1_alias_set == 0 || base2_alias_set == 0)
    return true;

  /* When we are trying to disambiguate an access with a pointer dereference
     as base versus one with a decl as base we can use both the size
     of the decl and its dynamic type for extra disambiguation.
     ???  We do not know anything about the dynamic type of the decl
     other than that its alias-set contains base2_alias_set as a subset
     which does not help us here.  */
  /* As we know nothing useful about the dynamic type of the decl just
     use the usual conflict check rather than a subset test.
     ???  We could introduce -fvery-strict-aliasing when the language
     does not allow decls to have a dynamic type that differs from their
     static type.  Then we can check 
     !alias_set_subset_of (base1_alias_set, base2_alias_set) instead.  */
  if (base1_alias_set != base2_alias_set
      && !alias_sets_conflict_p (base1_alias_set, base2_alias_set))
    return false;

  ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1));

  /* If the size of the access relevant for TBAA through the pointer
     is bigger than the size of the decl we can't possibly access the
     decl via that pointer.  */
  if (/* ???  This in turn may run afoul when a decl of type T which is
	 a member of union type U is accessed through a pointer to
	 type U and sizeof T is smaller than sizeof U.  */
      TREE_CODE (TREE_TYPE (ptrtype1)) != UNION_TYPE
      && TREE_CODE (TREE_TYPE (ptrtype1)) != QUAL_UNION_TYPE
      && compare_sizes (DECL_SIZE (base2),
		        TYPE_SIZE (TREE_TYPE (ptrtype1))) < 0)
    return false;

  if (!ref2)
    return true;

  /* If the decl is accessed via a MEM_REF, reconstruct the base
     we can use for TBAA and an appropriately adjusted offset.  */
  dbase2 = ref2;
  while (handled_component_p (dbase2))
    dbase2 = TREE_OPERAND (dbase2, 0);
  poly_int64 doffset1 = offset1;
  poly_offset_int doffset2 = offset2;
  if (TREE_CODE (dbase2) == MEM_REF
      || TREE_CODE (dbase2) == TARGET_MEM_REF)
    {
      doffset2 -= mem_ref_offset (dbase2) << LOG2_BITS_PER_UNIT;
      tree ptrtype2 = TREE_TYPE (TREE_OPERAND (dbase2, 1));
      /* If second reference is view-converted, give up now.  */
      if (same_type_for_tbaa (TREE_TYPE (dbase2), TREE_TYPE (ptrtype2)) != 1)
	return true;
    }

  /* If first reference is view-converted, give up now.  */
  if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1)
    return true;

  /* If both references are through the same type, they do not alias
     if the accesses do not overlap.  This does extra disambiguation
     for mixed/pointer accesses but requires strict aliasing.
     For MEM_REFs we require that the component-ref offset we computed
     is relative to the start of the type which we ensure by
     comparing rvalue and access type and disregarding the constant
     pointer offset.

     But avoid treating variable length arrays as "objects", instead assume they
     can overlap by an exact multiple of their element size.
     See gcc.dg/torture/alias-2.c.  */
  if (((TREE_CODE (base1) != TARGET_MEM_REF
       || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
       && (TREE_CODE (dbase2) != TARGET_MEM_REF
	   || (!TMR_INDEX (dbase2) && !TMR_INDEX2 (dbase2))))
      && same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (dbase2)) == 1)
    {
      bool partial_overlap = (TREE_CODE (TREE_TYPE (base1)) == ARRAY_TYPE
			      && (TYPE_SIZE (TREE_TYPE (base1))
			      && TREE_CODE (TYPE_SIZE (TREE_TYPE (base1)))
				 != INTEGER_CST));
      if (!partial_overlap
	  && !ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2))
	return false;
      if (!ref1 || !ref2
	  /* If there is must alias, there is no use disambiguating further.  */
	  || (!partial_overlap
	      && known_eq (size1, max_size1) && known_eq (size2, max_size2)))
	return true;
      int res = nonoverlapping_refs_since_match_p (base1, ref1, base2, ref2,
						   partial_overlap);
      if (res == -1)
	return !nonoverlapping_component_refs_p (ref1, ref2);
      return !res;
    }

  /* Do access-path based disambiguation.  */
  if (ref1 && ref2
      && (handled_component_p (ref1) || handled_component_p (ref2)))
    return aliasing_component_refs_p (ref1,
				      ref1_alias_set, base1_alias_set,
				      offset1, max_size1,
				      ref2,
				      ref2_alias_set, base2_alias_set,
				      offset2, max_size2);

  return true;
}

/* Return true if two indirect references based on *PTR1
   and *PTR2 constrained to [OFFSET1, OFFSET1 + MAX_SIZE1) and
   [OFFSET2, OFFSET2 + MAX_SIZE2) may alias.  *PTR1 and *PTR2 have
   the alias sets BASE1_ALIAS_SET and BASE2_ALIAS_SET which can be -1
   in which case they are computed on-demand.  REF1 and REF2
   if non-NULL are the complete memory reference trees. */

static bool
indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
			   poly_int64 offset1, poly_int64 max_size1,
			   poly_int64 size1,
			   alias_set_type ref1_alias_set,
			   alias_set_type base1_alias_set,
			   tree ref2 ATTRIBUTE_UNUSED, tree base2,
			   poly_int64 offset2, poly_int64 max_size2,
			   poly_int64 size2,
			   alias_set_type ref2_alias_set,
			   alias_set_type base2_alias_set, bool tbaa_p)
{
  tree ptr1;
  tree ptr2;
  tree ptrtype1, ptrtype2;

  gcc_checking_assert ((TREE_CODE (base1) == MEM_REF
			|| TREE_CODE (base1) == TARGET_MEM_REF)
		       && (TREE_CODE (base2) == MEM_REF
			   || TREE_CODE (base2) == TARGET_MEM_REF));

  ptr1 = TREE_OPERAND (base1, 0);
  ptr2 = TREE_OPERAND (base2, 0);

  /* If both bases are based on pointers they cannot alias if they may not
     point to the same memory object or if they point to the same object
     and the accesses do not overlap.  */
  if ((!cfun || gimple_in_ssa_p (cfun))
      && operand_equal_p (ptr1, ptr2, 0)
      && (((TREE_CODE (base1) != TARGET_MEM_REF
	    || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
	   && (TREE_CODE (base2) != TARGET_MEM_REF
	       || (!TMR_INDEX (base2) && !TMR_INDEX2 (base2))))
	  || (TREE_CODE (base1) == TARGET_MEM_REF
	      && TREE_CODE (base2) == TARGET_MEM_REF
	      && (TMR_STEP (base1) == TMR_STEP (base2)
		  || (TMR_STEP (base1) && TMR_STEP (base2)
		      && operand_equal_p (TMR_STEP (base1),
					  TMR_STEP (base2), 0)))
	      && (TMR_INDEX (base1) == TMR_INDEX (base2)
		  || (TMR_INDEX (base1) && TMR_INDEX (base2)
		      && operand_equal_p (TMR_INDEX (base1),
					  TMR_INDEX (base2), 0)))
	      && (TMR_INDEX2 (base1) == TMR_INDEX2 (base2)
		  || (TMR_INDEX2 (base1) && TMR_INDEX2 (base2)
		      && operand_equal_p (TMR_INDEX2 (base1),
					  TMR_INDEX2 (base2), 0))))))
    {
      poly_offset_int moff1 = mem_ref_offset (base1) << LOG2_BITS_PER_UNIT;
      poly_offset_int moff2 = mem_ref_offset (base2) << LOG2_BITS_PER_UNIT;
      if (!ranges_maybe_overlap_p (offset1 + moff1, max_size1,
				   offset2 + moff2, max_size2))
	return false;
      /* If there is must alias, there is no use disambiguating further.  */
      if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
	return true;
      if (ref1 && ref2)
	{
	  int res = nonoverlapping_refs_since_match_p (NULL, ref1, NULL, ref2,
						       false);
	  if (res != -1)
	    return !res;
	}
    }
  if (!ptr_derefs_may_alias_p (ptr1, ptr2))
    return false;

  /* Disambiguations that rely on strict aliasing rules follow.  */
  if (!flag_strict_aliasing || !tbaa_p)
    return true;

  ptrtype1 = TREE_TYPE (TREE_OPERAND (base1, 1));
  ptrtype2 = TREE_TYPE (TREE_OPERAND (base2, 1));

  /* If the alias set for a pointer access is zero all bets are off.  */
  if (base1_alias_set == 0
      || base2_alias_set == 0)
    return true;

  /* Do type-based disambiguation.  */
  if (base1_alias_set != base2_alias_set
      && !alias_sets_conflict_p (base1_alias_set, base2_alias_set))
    return false;

  /* If either reference is view-converted, give up now.  */
  if (same_type_for_tbaa (TREE_TYPE (base1), TREE_TYPE (ptrtype1)) != 1
      || same_type_for_tbaa (TREE_TYPE (base2), TREE_TYPE (ptrtype2)) != 1)
    return true;

  /* If both references are through the same type, they do not alias
     if the accesses do not overlap.  This does extra disambiguation
     for mixed/pointer accesses but requires strict aliasing.  */
  if ((TREE_CODE (base1) != TARGET_MEM_REF
       || (!TMR_INDEX (base1) && !TMR_INDEX2 (base1)))
      && (TREE_CODE (base2) != TARGET_MEM_REF
	  || (!TMR_INDEX (base2) && !TMR_INDEX2 (base2)))
      && same_type_for_tbaa (TREE_TYPE (ptrtype1),
			     TREE_TYPE (ptrtype2)) == 1)
    {
      /* But avoid treating arrays as "objects", instead assume they
         can overlap by an exact multiple of their element size.
         See gcc.dg/torture/alias-2.c.  */
      bool partial_overlap = TREE_CODE (TREE_TYPE (ptrtype1)) == ARRAY_TYPE;

      if (!partial_overlap
	  && !ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
	return false;
      if (!ref1 || !ref2
	  || (!partial_overlap
	      && known_eq (size1, max_size1) && known_eq (size2, max_size2)))
	return true;
      int res = nonoverlapping_refs_since_match_p (base1, ref1, base2, ref2,
						   partial_overlap);
      if (res == -1)
	return !nonoverlapping_component_refs_p (ref1, ref2);
      return !res;
    }

  /* Do access-path based disambiguation.  */
  if (ref1 && ref2
      && (handled_component_p (ref1) || handled_component_p (ref2)))
    return aliasing_component_refs_p (ref1,
				      ref1_alias_set, base1_alias_set,
				      offset1, max_size1,
				      ref2,
				      ref2_alias_set, base2_alias_set,
				      offset2, max_size2);

  return true;
}

/* Return true, if the two memory references REF1 and REF2 may alias.  */

static bool
refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
{
  tree base1, base2;
  poly_int64 offset1 = 0, offset2 = 0;
  poly_int64 max_size1 = -1, max_size2 = -1;
  bool var1_p, var2_p, ind1_p, ind2_p;

  gcc_checking_assert ((!ref1->ref
			|| TREE_CODE (ref1->ref) == SSA_NAME
			|| DECL_P (ref1->ref)
			|| TREE_CODE (ref1->ref) == STRING_CST
			|| handled_component_p (ref1->ref)
			|| TREE_CODE (ref1->ref) == MEM_REF
			|| TREE_CODE (ref1->ref) == TARGET_MEM_REF
			|| TREE_CODE (ref1->ref) == WITH_SIZE_EXPR)
		       && (!ref2->ref
			   || TREE_CODE (ref2->ref) == SSA_NAME
			   || DECL_P (ref2->ref)
			   || TREE_CODE (ref2->ref) == STRING_CST
			   || handled_component_p (ref2->ref)
			   || TREE_CODE (ref2->ref) == MEM_REF
			   || TREE_CODE (ref2->ref) == TARGET_MEM_REF
			   || TREE_CODE (ref2->ref) == WITH_SIZE_EXPR));

  /* Decompose the references into their base objects and the access.  */
  base1 = ao_ref_base (ref1);
  offset1 = ref1->offset;
  max_size1 = ref1->max_size;
  base2 = ao_ref_base (ref2);
  offset2 = ref2->offset;
  max_size2 = ref2->max_size;

  /* We can end up with registers or constants as bases for example from
     *D.1663_44 = VIEW_CONVERT_EXPR<struct DB_LSN>(__tmp$B0F64_59);
     which is seen as a struct copy.  */
  if (TREE_CODE (base1) == SSA_NAME
      || TREE_CODE (base1) == CONST_DECL
      || TREE_CODE (base1) == CONSTRUCTOR
      || TREE_CODE (base1) == ADDR_EXPR
      || CONSTANT_CLASS_P (base1)
      || TREE_CODE (base2) == SSA_NAME
      || TREE_CODE (base2) == CONST_DECL
      || TREE_CODE (base2) == CONSTRUCTOR
      || TREE_CODE (base2) == ADDR_EXPR
      || CONSTANT_CLASS_P (base2))
    return false;

  /* Two volatile accesses always conflict.  */
  if (ref1->volatile_p
      && ref2->volatile_p)
    return true;

  /* refN->ref may convey size information, do not confuse our workers
     with that but strip it - ao_ref_base took it into account already.  */
  tree ref1ref = ref1->ref;
  if (ref1ref && TREE_CODE (ref1ref) == WITH_SIZE_EXPR)
    ref1ref = TREE_OPERAND (ref1ref, 0);
  tree ref2ref = ref2->ref;
  if (ref2ref && TREE_CODE (ref2ref) == WITH_SIZE_EXPR)
    ref2ref = TREE_OPERAND (ref2ref, 0);

  /* Defer to simple offset based disambiguation if we have
     references based on two decls.  Do this before defering to
     TBAA to handle must-alias cases in conformance with the
     GCC extension of allowing type-punning through unions.  */
  var1_p = DECL_P (base1);
  var2_p = DECL_P (base2);
  if (var1_p && var2_p)
    return decl_refs_may_alias_p (ref1ref, base1, offset1, max_size1,
				  ref1->size,
				  ref2ref, base2, offset2, max_size2,
				  ref2->size);

  /* We can end up referring to code via function and label decls.
     As we likely do not properly track code aliases conservatively
     bail out.  */
  if (TREE_CODE (base1) == FUNCTION_DECL
      || TREE_CODE (base1) == LABEL_DECL
      || TREE_CODE (base2) == FUNCTION_DECL
      || TREE_CODE (base2) == LABEL_DECL)
    return true;

  /* Handle restrict based accesses.
     ???  ao_ref_base strips inner MEM_REF [&decl], recover from that
     here.  */
  tree rbase1 = base1;
  tree rbase2 = base2;
  if (var1_p)
    {
      rbase1 = ref1ref;
      if (rbase1)
	while (handled_component_p (rbase1))
	  rbase1 = TREE_OPERAND (rbase1, 0);
    }
  if (var2_p)
    {
      rbase2 = ref2ref;
      if (rbase2)
	while (handled_component_p (rbase2))
	  rbase2 = TREE_OPERAND (rbase2, 0);
    }
  if (rbase1 && rbase2
      && (TREE_CODE (rbase1) == MEM_REF || TREE_CODE (rbase1) == TARGET_MEM_REF)
      && (TREE_CODE (rbase2) == MEM_REF || TREE_CODE (rbase2) == TARGET_MEM_REF)
      /* If the accesses are in the same restrict clique... */
      && MR_DEPENDENCE_CLIQUE (rbase1) == MR_DEPENDENCE_CLIQUE (rbase2)
      /* But based on different pointers they do not alias.  */
      && MR_DEPENDENCE_BASE (rbase1) != MR_DEPENDENCE_BASE (rbase2))
    return false;

  ind1_p = (TREE_CODE (base1) == MEM_REF
	    || TREE_CODE (base1) == TARGET_MEM_REF);
  ind2_p = (TREE_CODE (base2) == MEM_REF
	    || TREE_CODE (base2) == TARGET_MEM_REF);

  /* Canonicalize the pointer-vs-decl case.  */
  if (ind1_p && var2_p)
    {
      std::swap (offset1, offset2);
      std::swap (max_size1, max_size2);
      std::swap (base1, base2);
      std::swap (ref1, ref2);
      std::swap (ref1ref, ref2ref);
      var1_p = true;
      ind1_p = false;
      var2_p = false;
      ind2_p = true;
    }

  /* First defer to TBAA if possible.  */
  if (tbaa_p
      && flag_strict_aliasing
      && !alias_sets_conflict_p (ao_ref_alias_set (ref1),
				 ao_ref_alias_set (ref2)))
    return false;

  /* If the reference is based on a pointer that points to memory
     that may not be written to then the other reference cannot possibly
     clobber it.  */
  if ((TREE_CODE (TREE_OPERAND (base2, 0)) == SSA_NAME
       && SSA_NAME_POINTS_TO_READONLY_MEMORY (TREE_OPERAND (base2, 0)))
      || (ind1_p
	  && TREE_CODE (TREE_OPERAND (base1, 0)) == SSA_NAME
	  && SSA_NAME_POINTS_TO_READONLY_MEMORY (TREE_OPERAND (base1, 0))))
    return false;

  /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators.  */
  if (var1_p && ind2_p)
    return indirect_ref_may_alias_decl_p (ref2ref, base2,
					  offset2, max_size2, ref2->size,
					  ao_ref_alias_set (ref2),
					  ao_ref_base_alias_set (ref2),
					  ref1ref, base1,
					  offset1, max_size1, ref1->size,
					  ao_ref_alias_set (ref1),
					  ao_ref_base_alias_set (ref1),
					  tbaa_p);
  else if (ind1_p && ind2_p)
    return indirect_refs_may_alias_p (ref1ref, base1,
				      offset1, max_size1, ref1->size,
				      ao_ref_alias_set (ref1),
				      ao_ref_base_alias_set (ref1),
				      ref2ref, base2,
				      offset2, max_size2, ref2->size,
				      ao_ref_alias_set (ref2),
				      ao_ref_base_alias_set (ref2),
				      tbaa_p);

  gcc_unreachable ();
}

/* Return true, if the two memory references REF1 and REF2 may alias
   and update statistics.  */

bool
refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
{
  bool res = refs_may_alias_p_2 (ref1, ref2, tbaa_p);
  if (res)
    ++alias_stats.refs_may_alias_p_may_alias;
  else
    ++alias_stats.refs_may_alias_p_no_alias;
  return res;
}

static bool
refs_may_alias_p (tree ref1, ao_ref *ref2, bool tbaa_p)
{
  ao_ref r1;
  ao_ref_init (&r1, ref1);
  return refs_may_alias_p_1 (&r1, ref2, tbaa_p);
}

bool
refs_may_alias_p (tree ref1, tree ref2, bool tbaa_p)
{
  ao_ref r1, r2;
  ao_ref_init (&r1, ref1);
  ao_ref_init (&r2, ref2);
  return refs_may_alias_p_1 (&r1, &r2, tbaa_p);
}

/* Returns true if there is a anti-dependence for the STORE that
   executes after the LOAD.  */

bool
refs_anti_dependent_p (tree load, tree store)
{
  ao_ref r1, r2;
  ao_ref_init (&r1, load);
  ao_ref_init (&r2, store);
  return refs_may_alias_p_1 (&r1, &r2, false);
}

/* Returns true if there is a output dependence for the stores
   STORE1 and STORE2.  */

bool
refs_output_dependent_p (tree store1, tree store2)
{
  ao_ref r1, r2;
  ao_ref_init (&r1, store1);
  ao_ref_init (&r2, store2);
  return refs_may_alias_p_1 (&r1, &r2, false);
}

/* Returns true if and only if REF may alias any access stored in TT.
   IF TBAA_P is true, use TBAA oracle.  */

static bool
modref_may_conflict (const gcall *stmt,
		     modref_tree <alias_set_type> *tt, ao_ref *ref, bool tbaa_p)
{
  alias_set_type base_set, ref_set;
  bool global_memory_ok = false;

  if (tt->every_base)
    return true;

  if (!dbg_cnt (ipa_mod_ref))
    return true;

  base_set = ao_ref_base_alias_set (ref);

  ref_set = ao_ref_alias_set (ref);

  int num_tests = 0, max_tests = param_modref_max_tests;
  for (auto base_node : tt->bases)
    {
      if (tbaa_p && flag_strict_aliasing)
	{
	  if (num_tests >= max_tests)
	    return true;
	  alias_stats.modref_tests++;
	  if (!alias_sets_conflict_p (base_set, base_node->base))
	    continue;
	  num_tests++;
	}

      if (base_node->every_ref)
	return true;

      for (auto ref_node : base_node->refs)
	{
	  /* Do not repeat same test as before.  */
	  if ((ref_set != base_set || base_node->base != ref_node->ref)
	      && tbaa_p && flag_strict_aliasing)
	    {
	      if (num_tests >= max_tests)
		return true;
	      alias_stats.modref_tests++;
	      if (!alias_sets_conflict_p (ref_set, ref_node->ref))
		continue;
	      num_tests++;
	    }

	  if (ref_node->every_access)
	    return true;

	  /* TBAA checks did not disambiguate, try individual accesses.  */
	  for (auto access_node : ref_node->accesses)
	    {
	      if (num_tests >= max_tests)
		return true;

	      if (access_node.parm_index == MODREF_GLOBAL_MEMORY_PARM)
		{
		  if (global_memory_ok)
		    continue;
		  if (ref_may_alias_global_p (ref, true))
		    return true;
		  global_memory_ok = true;
		  num_tests++;
		  continue;
		}

	      tree arg = access_node.get_call_arg (stmt);
	      if (!arg)
		return true;

	      alias_stats.modref_baseptr_tests++;

	      if (integer_zerop (arg) && flag_delete_null_pointer_checks)
		continue;

	      /* PTA oracle will be unhapy of arg is not an pointer.  */
	      if (!POINTER_TYPE_P (TREE_TYPE (arg)))
		return true;

	      /* If we don't have base pointer, give up.  */
	      if (!ref->ref && !ref->base)
		continue;

	      ao_ref ref2;
	      if (access_node.get_ao_ref (stmt, &ref2))
		{
		  ref2.ref_alias_set = ref_node->ref;
		  ref2.base_alias_set = base_node->base;
		  if (refs_may_alias_p_1 (&ref2, ref, tbaa_p))
		    return true;
		}
	      else if (ptr_deref_may_alias_ref_p_1 (arg, ref))
		return true;

	      num_tests++;
	    }
	}
    }
  return false;
}

/* Check if REF conflicts with call using "fn spec" attribute.
   If CLOBBER is true we are checking for writes, otherwise check loads.

   Return 0 if there are no conflicts (except for possible function call
   argument reads), 1 if there are conflicts and -1 if we can not decide by
   fn spec.  */

static int
check_fnspec (gcall *call, ao_ref *ref, bool clobber)
{
  attr_fnspec fnspec = gimple_call_fnspec (call);
  if (fnspec.known_p ())
    {
      if (clobber
	  ? !fnspec.global_memory_written_p ()
	  : !fnspec.global_memory_read_p ())
	{
	  for (unsigned int i = 0; i < gimple_call_num_args (call); i++)
	    if (POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (call, i)))
		&& (!fnspec.arg_specified_p (i)
		    || (clobber ? fnspec.arg_maybe_written_p (i)
			: fnspec.arg_maybe_read_p (i))))
	      {
		ao_ref dref;
		tree size = NULL_TREE;
		unsigned int size_arg;

		if (!fnspec.arg_specified_p (i))
		  ;
		else if (fnspec.arg_max_access_size_given_by_arg_p
			   (i, &size_arg))
		  size = gimple_call_arg (call, size_arg);
		else if (fnspec.arg_access_size_given_by_type_p (i))
		  {
		    tree callee = gimple_call_fndecl (call);
		    tree t = TYPE_ARG_TYPES (TREE_TYPE (callee));

		    for (unsigned int p = 0; p < i; p++)
		      t = TREE_CHAIN (t);
		    size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_VALUE (t)));
		  }
		ao_ref_init_from_ptr_and_size (&dref,
					       gimple_call_arg (call, i),
					       size);
		if (refs_may_alias_p_1 (&dref, ref, false))
		  return 1;
	      }
	  if (clobber
	      && fnspec.errno_maybe_written_p ()
	      && flag_errno_math
	      && targetm.ref_may_alias_errno (ref))
	    return 1;
	  return 0;
	}
    }

 /* FIXME: we should handle barriers more consistently, but for now leave the
    check here.  */
  if (gimple_call_builtin_p (call, BUILT_IN_NORMAL))
    switch (DECL_FUNCTION_CODE (gimple_call_fndecl (call)))
      {
      /* __sync_* builtins and some OpenMP builtins act as threading
	 barriers.  */
#undef DEF_SYNC_BUILTIN
#define DEF_SYNC_BUILTIN(ENUM, NAME, TYPE, ATTRS) case ENUM:
#include "sync-builtins.def"
#undef DEF_SYNC_BUILTIN
      case BUILT_IN_GOMP_ATOMIC_START:
      case BUILT_IN_GOMP_ATOMIC_END:
      case BUILT_IN_GOMP_BARRIER:
      case BUILT_IN_GOMP_BARRIER_CANCEL:
      case BUILT_IN_GOMP_TASKWAIT:
      case BUILT_IN_GOMP_TASKGROUP_END:
      case BUILT_IN_GOMP_CRITICAL_START:
      case BUILT_IN_GOMP_CRITICAL_END:
      case BUILT_IN_GOMP_CRITICAL_NAME_START:
      case BUILT_IN_GOMP_CRITICAL_NAME_END:
      case BUILT_IN_GOMP_LOOP_END:
      case BUILT_IN_GOMP_LOOP_END_CANCEL:
      case BUILT_IN_GOMP_ORDERED_START:
      case BUILT_IN_GOMP_ORDERED_END:
      case BUILT_IN_GOMP_SECTIONS_END:
      case BUILT_IN_GOMP_SECTIONS_END_CANCEL:
      case BUILT_IN_GOMP_SINGLE_COPY_START:
      case BUILT_IN_GOMP_SINGLE_COPY_END:
	return 1;

      default:
	return -1;
      }
  return -1;
}

/* If the call CALL may use the memory reference REF return true,
   otherwise return false.  */

static bool
ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *ref, bool tbaa_p)
{
  tree base, callee;
  unsigned i;
  int flags = gimple_call_flags (call);

  if (flags & (ECF_CONST|ECF_NOVOPS))
    goto process_args;

  /* A call that is not without side-effects might involve volatile
     accesses and thus conflicts with all other volatile accesses.  */
  if (ref->volatile_p)
    return true;

  if (gimple_call_internal_p (call))
    switch (gimple_call_internal_fn (call))
      {
      case IFN_MASK_STORE:
      case IFN_SCATTER_STORE:
      case IFN_MASK_SCATTER_STORE:
      case IFN_LEN_STORE:
	return false;
      case IFN_MASK_STORE_LANES:
	goto process_args;
      case IFN_MASK_LOAD:
      case IFN_LEN_LOAD:
      case IFN_MASK_LOAD_LANES:
	{
	  ao_ref rhs_ref;
	  tree lhs = gimple_call_lhs (call);
	  if (lhs)
	    {
	      ao_ref_init_from_ptr_and_size (&rhs_ref,
					     gimple_call_arg (call, 0),
					     TYPE_SIZE_UNIT (TREE_TYPE (lhs)));
	      rhs_ref.ref_alias_set = rhs_ref.base_alias_set
		= tbaa_p ? get_deref_alias_set (TREE_TYPE
					(gimple_call_arg (call, 1))) : 0;
	      return refs_may_alias_p_1 (ref, &rhs_ref, tbaa_p);
	    }
	  break;
	}
      default:;
      }

  callee = gimple_call_fndecl (call);
  if (callee != NULL_TREE)
    {
      struct cgraph_node *node = cgraph_node::get (callee);
      /* We can not safely optimize based on summary of calle if it does
	 not always bind to current def: it is possible that memory load
	 was optimized out earlier and the interposed variant may not be
	 optimized this way.  */
      if (node && node->binds_to_current_def_p ())
	{
	  modref_summary *summary = get_modref_function_summary (node);
	  if (summary && !summary->calls_interposable)
	    {
	      if (!modref_may_conflict (call, summary->loads, ref, tbaa_p))
		{
		  alias_stats.modref_use_no_alias++;
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file,
			       "ipa-modref: call stmt ");
		      print_gimple_stmt (dump_file, call, 0);
		      fprintf (dump_file,
			       "ipa-modref: call to %s does not use ",
			       node->dump_name ());
		      if (!ref->ref && ref->base)
			{
			  fprintf (dump_file, "base: ");
			  print_generic_expr (dump_file, ref->base);
			}
		      else if (ref->ref)
			{
			  fprintf (dump_file, "ref: ");
			  print_generic_expr (dump_file, ref->ref);
			}
		      fprintf (dump_file, " alias sets: %i->%i\n",
			       ao_ref_base_alias_set (ref),
			       ao_ref_alias_set (ref));
		    }
		  goto process_args;
		}
	      alias_stats.modref_use_may_alias++;
	    }
       }
    }

  base = ao_ref_base (ref);
  if (!base)
    return true;

  /* If the reference is based on a decl that is not aliased the call
     cannot possibly use it.  */
  if (DECL_P (base)
      && !may_be_aliased (base)
      /* But local statics can be used through recursion.  */
      && !is_global_var (base))
    goto process_args;

  if (int res = check_fnspec (call, ref, false))
    {
      if (res == 1)
	return true;
    }
  else
    goto process_args;

  /* Check if base is a global static variable that is not read
     by the function.  */
  if (callee != NULL_TREE && VAR_P (base) && TREE_STATIC (base))
    {
      struct cgraph_node *node = cgraph_node::get (callee);
      bitmap read;
      int id;

      /* FIXME: Callee can be an OMP builtin that does not have a call graph
	 node yet.  We should enforce that there are nodes for all decls in the
	 IL and remove this check instead.  */
      if (node
	  && (id = ipa_reference_var_uid (base)) != -1
	  && (read = ipa_reference_get_read_global (node))
	  && !bitmap_bit_p (read, id))
	goto process_args;
    }

  /* Check if the base variable is call-used.  */
  if (DECL_P (base))
    {
      if (pt_solution_includes (gimple_call_use_set (call), base))
	return true;
    }
  else if ((TREE_CODE (base) == MEM_REF
	    || TREE_CODE (base) == TARGET_MEM_REF)
	   && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
    {
      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
      if (!pi)
	return true;

      if (pt_solutions_intersect (gimple_call_use_set (call), &pi->pt))
	return true;
    }
  else
    return true;

  /* Inspect call arguments for passed-by-value aliases.  */
process_args:
  for (i = 0; i < gimple_call_num_args (call); ++i)
    {
      tree op = gimple_call_arg (call, i);
      int flags = gimple_call_arg_flags (call, i);

      if (flags & (EAF_UNUSED | EAF_NO_DIRECT_READ))
	continue;

      if (TREE_CODE (op) == WITH_SIZE_EXPR)
	op = TREE_OPERAND (op, 0);

      if (TREE_CODE (op) != SSA_NAME
	  && !is_gimple_min_invariant (op))
	{
	  ao_ref r;
	  ao_ref_init (&r, op);
	  if (refs_may_alias_p_1 (&r, ref, tbaa_p))
	    return true;
	}
    }

  return false;
}

static bool
ref_maybe_used_by_call_p (gcall *call, ao_ref *ref, bool tbaa_p)
{
  bool res;
  res = ref_maybe_used_by_call_p_1 (call, ref, tbaa_p);
  if (res)
    ++alias_stats.ref_maybe_used_by_call_p_may_alias;
  else
    ++alias_stats.ref_maybe_used_by_call_p_no_alias;
  return res;
}


/* If the statement STMT may use the memory reference REF return
   true, otherwise return false.  */

bool
ref_maybe_used_by_stmt_p (gimple *stmt, ao_ref *ref, bool tbaa_p)
{
  if (is_gimple_assign (stmt))
    {
      tree rhs;

      /* All memory assign statements are single.  */
      if (!gimple_assign_single_p (stmt))
	return false;

      rhs = gimple_assign_rhs1 (stmt);
      if (is_gimple_reg (rhs)
	  || is_gimple_min_invariant (rhs)
	  || gimple_assign_rhs_code (stmt) == CONSTRUCTOR)
	return false;

      return refs_may_alias_p (rhs, ref, tbaa_p);
    }
  else if (is_gimple_call (stmt))
    return ref_maybe_used_by_call_p (as_a <gcall *> (stmt), ref, tbaa_p);
  else if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
    {
      tree retval = gimple_return_retval (return_stmt);
      if (retval
	  && TREE_CODE (retval) != SSA_NAME
	  && !is_gimple_min_invariant (retval)
	  && refs_may_alias_p (retval, ref, tbaa_p))
	return true;
      /* If ref escapes the function then the return acts as a use.  */
      tree base = ao_ref_base (ref);
      if (!base)
	;
      else if (DECL_P (base))
	return is_global_var (base);
      else if (TREE_CODE (base) == MEM_REF
	       || TREE_CODE (base) == TARGET_MEM_REF)
	return ptr_deref_may_alias_global_p (TREE_OPERAND (base, 0), false);
      return false;
    }

  return true;
}

bool
ref_maybe_used_by_stmt_p (gimple *stmt, tree ref, bool tbaa_p)
{
  ao_ref r;
  ao_ref_init (&r, ref);
  return ref_maybe_used_by_stmt_p (stmt, &r, tbaa_p);
}

/* If the call in statement CALL may clobber the memory reference REF
   return true, otherwise return false.  */

bool
call_may_clobber_ref_p_1 (gcall *call, ao_ref *ref, bool tbaa_p)
{
  tree base;
  tree callee;

  /* If the call is pure or const it cannot clobber anything.  */
  if (gimple_call_flags (call)
      & (ECF_PURE|ECF_CONST|ECF_LOOPING_CONST_OR_PURE|ECF_NOVOPS))
    return false;
  if (gimple_call_internal_p (call))
    switch (auto fn = gimple_call_internal_fn (call))
      {
	/* Treat these internal calls like ECF_PURE for aliasing,
	   they don't write to any memory the program should care about.
	   They have important other side-effects, and read memory,
	   so can't be ECF_NOVOPS.  */
      case IFN_UBSAN_NULL:
      case IFN_UBSAN_BOUNDS:
      case IFN_UBSAN_VPTR:
      case IFN_UBSAN_OBJECT_SIZE:
      case IFN_UBSAN_PTR:
      case IFN_ASAN_CHECK:
	return false;
      case IFN_MASK_STORE:
      case IFN_LEN_STORE:
      case IFN_MASK_STORE_LANES:
	{
	  tree rhs = gimple_call_arg (call,
				      internal_fn_stored_value_index (fn));
	  ao_ref lhs_ref;
	  ao_ref_init_from_ptr_and_size (&lhs_ref, gimple_call_arg (call, 0),
					 TYPE_SIZE_UNIT (TREE_TYPE (rhs)));
	  lhs_ref.ref_alias_set = lhs_ref.base_alias_set
	    = tbaa_p ? get_deref_alias_set
				   (TREE_TYPE (gimple_call_arg (call, 1))) : 0;
	  return refs_may_alias_p_1 (ref, &lhs_ref, tbaa_p);
	}
      default:
	break;
      }

  callee = gimple_call_fndecl (call);

  if (callee != NULL_TREE && !ref->volatile_p)
    {
      struct cgraph_node *node = cgraph_node::get (callee);
      if (node)
	{
	  modref_summary *summary = get_modref_function_summary (node);
	  if (summary)
	    {
	      if (!modref_may_conflict (call, summary->stores, ref, tbaa_p)
		  && (!summary->writes_errno
		      || !targetm.ref_may_alias_errno (ref)))
		{
		  alias_stats.modref_clobber_no_alias++;
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file,
			       "ipa-modref: call stmt ");
		      print_gimple_stmt (dump_file, call, 0);
		      fprintf (dump_file,
			       "ipa-modref: call to %s does not clobber ",
			       node->dump_name ());
		      if (!ref->ref && ref->base)
			{
			  fprintf (dump_file, "base: ");
			  print_generic_expr (dump_file, ref->base);
			}
		      else if (ref->ref)
			{
			  fprintf (dump_file, "ref: ");
			  print_generic_expr (dump_file, ref->ref);
			}
		      fprintf (dump_file, " alias sets: %i->%i\n",
			       ao_ref_base_alias_set (ref),
			       ao_ref_alias_set (ref));
		    }
		  return false;
		}
	      alias_stats.modref_clobber_may_alias++;
	  }
	}
    }

  base = ao_ref_base (ref);
  if (!base)
    return true;

  if (TREE_CODE (base) == SSA_NAME
      || CONSTANT_CLASS_P (base))
    return false;

  /* A call that is not without side-effects might involve volatile
     accesses and thus conflicts with all other volatile accesses.  */
  if (ref->volatile_p)
    return true;

  /* If the reference is based on a decl that is not aliased the call
     cannot possibly clobber it.  */
  if (DECL_P (base)
      && !may_be_aliased (base)
      /* But local non-readonly statics can be modified through recursion
         or the call may implement a threading barrier which we must
	 treat as may-def.  */
      && (TREE_READONLY (base)
	  || !is_global_var (base)))
    return false;

  /* If the reference is based on a pointer that points to memory
     that may not be written to then the call cannot possibly clobber it.  */
  if ((TREE_CODE (base) == MEM_REF
       || TREE_CODE (base) == TARGET_MEM_REF)
      && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
      && SSA_NAME_POINTS_TO_READONLY_MEMORY (TREE_OPERAND (base, 0)))
    return false;

  if (int res = check_fnspec (call, ref, true))
    {
      if (res == 1)
	return true;
    }
  else
    return false;

  /* Check if base is a global static variable that is not written
     by the function.  */
  if (callee != NULL_TREE && VAR_P (base) && TREE_STATIC (base))
    {
      struct cgraph_node *node = cgraph_node::get (callee);
      bitmap written;
      int id;

      if (node
	  && (id = ipa_reference_var_uid (base)) != -1
	  && (written = ipa_reference_get_written_global (node))
	  && !bitmap_bit_p (written, id))
	return false;
    }

  /* Check if the base variable is call-clobbered.  */
  if (DECL_P (base))
    return pt_solution_includes (gimple_call_clobber_set (call), base);
  else if ((TREE_CODE (base) == MEM_REF
	    || TREE_CODE (base) == TARGET_MEM_REF)
	   && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
    {
      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
      if (!pi)
	return true;

      return pt_solutions_intersect (gimple_call_clobber_set (call), &pi->pt);
    }

  return true;
}

/* If the call in statement CALL may clobber the memory reference REF
   return true, otherwise return false.  */

bool
call_may_clobber_ref_p (gcall *call, tree ref, bool tbaa_p)
{
  bool res;
  ao_ref r;
  ao_ref_init (&r, ref);
  res = call_may_clobber_ref_p_1 (call, &r, tbaa_p);
  if (res)
    ++alias_stats.call_may_clobber_ref_p_may_alias;
  else
    ++alias_stats.call_may_clobber_ref_p_no_alias;
  return res;
}


/* If the statement STMT may clobber the memory reference REF return true,
   otherwise return false.  */

bool
stmt_may_clobber_ref_p_1 (gimple *stmt, ao_ref *ref, bool tbaa_p)
{
  if (is_gimple_call (stmt))
    {
      tree lhs = gimple_call_lhs (stmt);
      if (lhs
	  && TREE_CODE (lhs) != SSA_NAME)
	{
	  ao_ref r;
	  ao_ref_init (&r, lhs);
	  if (refs_may_alias_p_1 (ref, &r, tbaa_p))
	    return true;
	}

      return call_may_clobber_ref_p_1 (as_a <gcall *> (stmt), ref, tbaa_p);
    }
  else if (gimple_assign_single_p (stmt))
    {
      tree lhs = gimple_assign_lhs (stmt);
      if (TREE_CODE (lhs) != SSA_NAME)
	{
	  ao_ref r;
	  ao_ref_init (&r, lhs);
	  return refs_may_alias_p_1 (ref, &r, tbaa_p);
	}
    }
  else if (gimple_code (stmt) == GIMPLE_ASM)
    return true;

  return false;
}

bool
stmt_may_clobber_ref_p (gimple *stmt, tree ref, bool tbaa_p)
{
  ao_ref r;
  ao_ref_init (&r, ref);
  return stmt_may_clobber_ref_p_1 (stmt, &r, tbaa_p);
}

/* Return true if store1 and store2 described by corresponding tuples
   <BASE, OFFSET, SIZE, MAX_SIZE> have the same size and store to the same
   address.  */

static bool
same_addr_size_stores_p (tree base1, poly_int64 offset1, poly_int64 size1,
			 poly_int64 max_size1,
			 tree base2, poly_int64 offset2, poly_int64 size2,
			 poly_int64 max_size2)
{
  /* Offsets need to be 0.  */
  if (maybe_ne (offset1, 0)
      || maybe_ne (offset2, 0))
    return false;

  bool base1_obj_p = SSA_VAR_P (base1);
  bool base2_obj_p = SSA_VAR_P (base2);

  /* We need one object.  */
  if (base1_obj_p == base2_obj_p)
    return false;
  tree obj = base1_obj_p ? base1 : base2;

  /* And we need one MEM_REF.  */
  bool base1_memref_p = TREE_CODE (base1) == MEM_REF;
  bool base2_memref_p = TREE_CODE (base2) == MEM_REF;
  if (base1_memref_p == base2_memref_p)
    return false;
  tree memref = base1_memref_p ? base1 : base2;

  /* Sizes need to be valid.  */
  if (!known_size_p (max_size1)
      || !known_size_p (max_size2)
      || !known_size_p (size1)
      || !known_size_p (size2))
    return false;

  /* Max_size needs to match size.  */
  if (maybe_ne (max_size1, size1)
      || maybe_ne (max_size2, size2))
    return false;

  /* Sizes need to match.  */
  if (maybe_ne (size1, size2))
    return false;


  /* Check that memref is a store to pointer with singleton points-to info.  */
  if (!integer_zerop (TREE_OPERAND (memref, 1)))
    return false;
  tree ptr = TREE_OPERAND (memref, 0);
  if (TREE_CODE (ptr) != SSA_NAME)
    return false;
  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
  unsigned int pt_uid;
  if (pi == NULL
      || !pt_solution_singleton_or_null_p (&pi->pt, &pt_uid))
    return false;

  /* Be conservative with non-call exceptions when the address might
     be NULL.  */
  if (cfun->can_throw_non_call_exceptions && pi->pt.null)
    return false;

  /* Check that ptr points relative to obj.  */
  unsigned int obj_uid = DECL_PT_UID (obj);
  if (obj_uid != pt_uid)
    return false;

  /* Check that the object size is the same as the store size.  That ensures us
     that ptr points to the start of obj.  */
  return (DECL_SIZE (obj)
	  && poly_int_tree_p (DECL_SIZE (obj))
	  && known_eq (wi::to_poly_offset (DECL_SIZE (obj)), size1));
}

/* Return true if REF is killed by an store described by
   BASE, OFFSET, SIZE and MAX_SIZE.  */

static bool
store_kills_ref_p (tree base, poly_int64 offset, poly_int64 size,
		   poly_int64 max_size, ao_ref *ref)
{
  poly_int64 ref_offset = ref->offset;
  /* We can get MEM[symbol: sZ, index: D.8862_1] here,
     so base == ref->base does not always hold.  */
  if (base != ref->base)
    {
      /* Try using points-to info.  */
      if (same_addr_size_stores_p (base, offset, size, max_size, ref->base,
				   ref->offset, ref->size, ref->max_size))
	return true;

      /* If both base and ref->base are MEM_REFs, only compare the
	 first operand, and if the second operand isn't equal constant,
	 try to add the offsets into offset and ref_offset.  */
      if (TREE_CODE (base) == MEM_REF && TREE_CODE (ref->base) == MEM_REF
	  && TREE_OPERAND (base, 0) == TREE_OPERAND (ref->base, 0))
	{
	  if (!tree_int_cst_equal (TREE_OPERAND (base, 1),
				   TREE_OPERAND (ref->base, 1)))
	    {
	      poly_offset_int off1 = mem_ref_offset (base);
	      off1 <<= LOG2_BITS_PER_UNIT;
	      off1 += offset;
	      poly_offset_int off2 = mem_ref_offset (ref->base);
	      off2 <<= LOG2_BITS_PER_UNIT;
	      off2 += ref_offset;
	      if (!off1.to_shwi (&offset) || !off2.to_shwi (&ref_offset))
		size = -1;
	    }
	}
      else
	size = -1;
    }
  /* For a must-alias check we need to be able to constrain
     the access properly.  */
  return (known_eq (size, max_size)
	  && known_subrange_p (ref_offset, ref->max_size, offset, size));
}

/* If STMT kills the memory reference REF return true, otherwise
   return false.  */

bool
stmt_kills_ref_p (gimple *stmt, ao_ref *ref)
{
  if (!ao_ref_base (ref))
    return false;

  if (gimple_has_lhs (stmt)
      && TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME
      /* The assignment is not necessarily carried out if it can throw
	 and we can catch it in the current function where we could inspect
	 the previous value.  Similarly if the function can throw externally
	 and the ref does not die on the function return.
	 ???  We only need to care about the RHS throwing.  For aggregate
	 assignments or similar calls and non-call exceptions the LHS
	 might throw as well.
	 ???  We also should care about possible longjmp, but since we
	 do not understand that longjmp is not using global memory we will
	 not consider a kill here since the function call will be considered
	 as possibly using REF.	 */
      && !stmt_can_throw_internal (cfun, stmt)
      && (!stmt_can_throw_external (cfun, stmt)
	  || !ref_may_alias_global_p (ref, false)))
    {
      tree lhs = gimple_get_lhs (stmt);
      /* If LHS is literally a base of the access we are done.  */
      if (ref->ref)
	{
	  tree base = ref->ref;
	  tree innermost_dropped_array_ref = NULL_TREE;
	  if (handled_component_p (base))
	    {
	      tree saved_lhs0 = NULL_TREE;
	      if (handled_component_p (lhs))
		{
		  saved_lhs0 = TREE_OPERAND (lhs, 0);
		  TREE_OPERAND (lhs, 0) = integer_zero_node;
		}
	      do
		{
		  /* Just compare the outermost handled component, if
		     they are equal we have found a possible common
		     base.  */
		  tree saved_base0 = TREE_OPERAND (base, 0);
		  TREE_OPERAND (base, 0) = integer_zero_node;
		  bool res = operand_equal_p (lhs, base, 0);
		  TREE_OPERAND (base, 0) = saved_base0;
		  if (res)
		    break;
		  /* Remember if we drop an array-ref that we need to
		     double-check not being at struct end.  */ 
		  if (TREE_CODE (base) == ARRAY_REF
		      || TREE_CODE (base) == ARRAY_RANGE_REF)
		    innermost_dropped_array_ref = base;
		  /* Otherwise drop handled components of the access.  */
		  base = saved_base0;
		}
	      while (handled_component_p (base));
	      if (saved_lhs0)
		TREE_OPERAND (lhs, 0) = saved_lhs0;
	    }
	  /* Finally check if the lhs has the same address and size as the
	     base candidate of the access.  Watch out if we have dropped
	     an array-ref that might have flexible size, this means ref->ref
	     may be outside of the TYPE_SIZE of its base.  */
	  if ((! innermost_dropped_array_ref
	       || ! array_ref_flexible_size_p (innermost_dropped_array_ref))
	      && (lhs == base
		  || (((TYPE_SIZE (TREE_TYPE (lhs))
			== TYPE_SIZE (TREE_TYPE (base)))
		       || (TYPE_SIZE (TREE_TYPE (lhs))
			   && TYPE_SIZE (TREE_TYPE (base))
			   && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)),
					       TYPE_SIZE (TREE_TYPE (base)),
					       0)))
		      && operand_equal_p (lhs, base,
					  OEP_ADDRESS_OF
					  | OEP_MATCH_SIDE_EFFECTS))))
	    {
	      ++alias_stats.stmt_kills_ref_p_yes;
	      return true;
	    }
	}

      /* Now look for non-literal equal bases with the restriction of
         handling constant offset and size.  */
      /* For a must-alias check we need to be able to constrain
	 the access properly.  */
      if (!ref->max_size_known_p ())
	{
	  ++alias_stats.stmt_kills_ref_p_no;
	  return false;
	}
      poly_int64 size, offset, max_size;
      bool reverse;
      tree base = get_ref_base_and_extent (lhs, &offset, &size, &max_size,
					   &reverse);
      if (store_kills_ref_p (base, offset, size, max_size, ref))
	{
	  ++alias_stats.stmt_kills_ref_p_yes;
	  return true;
	}
    }

  if (is_gimple_call (stmt))
    {
      tree callee = gimple_call_fndecl (stmt);
      struct cgraph_node *node;
      modref_summary *summary;

      /* Try to disambiguate using modref summary.  Modref records a vector
	 of stores with known offsets relative to function parameters that must
	 happen every execution of function.  Find if we have a matching
	 store and verify that function can not use the value.  */
      if (callee != NULL_TREE
	  && (node = cgraph_node::get (callee)) != NULL
	  && node->binds_to_current_def_p ()
	  && (summary = get_modref_function_summary (node)) != NULL
	  && summary->kills.length ()
	  /* Check that we can not trap while evaulating function
	     parameters.  This check is overly conservative.  */
	  && (!cfun->can_throw_non_call_exceptions
	      || (!stmt_can_throw_internal (cfun, stmt)
		  && (!stmt_can_throw_external (cfun, stmt)
		      || !ref_may_alias_global_p (ref, false)))))
	{
	  for (auto kill : summary->kills)
	    {
	      ao_ref dref;

	      /* We only can do useful compares if we know the access range
		 precisely.  */
	      if (!kill.get_ao_ref (as_a <gcall *> (stmt), &dref))
		continue;
	      if (store_kills_ref_p (ao_ref_base (&dref), dref.offset,
				     dref.size, dref.max_size, ref))
		{
		  /* For store to be killed it needs to not be used
		     earlier.  */
		  if (ref_maybe_used_by_call_p_1 (as_a <gcall *> (stmt), ref,
						  true)
		      || !dbg_cnt (ipa_mod_ref))
		    break;
		  if (dump_file && (dump_flags & TDF_DETAILS))
		    {
		      fprintf (dump_file,
			       "ipa-modref: call stmt ");
		      print_gimple_stmt (dump_file, stmt, 0);
		      fprintf (dump_file,
			       "ipa-modref: call to %s kills ",
			       node->dump_name ());
		      print_generic_expr (dump_file, ref->base);
		    }
		    ++alias_stats.modref_kill_yes;
		    return true;
		}
	    }
	  ++alias_stats.modref_kill_no;
	}
      if (callee != NULL_TREE
	  && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
	switch (DECL_FUNCTION_CODE (callee))
	  {
	  case BUILT_IN_FREE:
	    {
	      tree ptr = gimple_call_arg (stmt, 0);
	      tree base = ao_ref_base (ref);
	      if (base && TREE_CODE (base) == MEM_REF
		  && TREE_OPERAND (base, 0) == ptr)
		{
		  ++alias_stats.stmt_kills_ref_p_yes;
		  return true;
		}
	      break;
	    }

	  case BUILT_IN_MEMCPY:
	  case BUILT_IN_MEMPCPY:
	  case BUILT_IN_MEMMOVE:
	  case BUILT_IN_MEMSET:
	  case BUILT_IN_MEMCPY_CHK:
	  case BUILT_IN_MEMPCPY_CHK:
	  case BUILT_IN_MEMMOVE_CHK:
	  case BUILT_IN_MEMSET_CHK:
	  case BUILT_IN_STRNCPY:
	  case BUILT_IN_STPNCPY:
	  case BUILT_IN_CALLOC:
	    {
	      /* For a must-alias check we need to be able to constrain
		 the access properly.  */
	      if (!ref->max_size_known_p ())
		{
		  ++alias_stats.stmt_kills_ref_p_no;
		  return false;
		}
	      tree dest;
	      tree len;

	      /* In execution order a calloc call will never kill
		 anything.  However, DSE will (ab)use this interface
		 to ask if a calloc call writes the same memory locations
		 as a later assignment, memset, etc.  So handle calloc
		 in the expected way.  */
	      if (DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC)
		{
		  tree arg0 = gimple_call_arg (stmt, 0);
		  tree arg1 = gimple_call_arg (stmt, 1);
		  if (TREE_CODE (arg0) != INTEGER_CST
		      || TREE_CODE (arg1) != INTEGER_CST)
		    {
		      ++alias_stats.stmt_kills_ref_p_no;
		      return false;
		    }

		  dest = gimple_call_lhs (stmt);
		  if (!dest)
		    {
		      ++alias_stats.stmt_kills_ref_p_no;
		      return false;
		    }
		  len = fold_build2 (MULT_EXPR, TREE_TYPE (arg0), arg0, arg1);
		}
	      else
		{
		  dest = gimple_call_arg (stmt, 0);
		  len = gimple_call_arg (stmt, 2);
		}
	      if (!poly_int_tree_p (len))
		return false;
	      ao_ref dref;
	      ao_ref_init_from_ptr_and_size (&dref, dest, len);
	      if (store_kills_ref_p (ao_ref_base (&dref), dref.offset,
				     dref.size, dref.max_size, ref))
		{
		  ++alias_stats.stmt_kills_ref_p_yes;
		  return true;
		}
	      break;
	    }

	  case BUILT_IN_VA_END:
	    {
	      tree ptr = gimple_call_arg (stmt, 0);
	      if (TREE_CODE (ptr) == ADDR_EXPR)
		{
		  tree base = ao_ref_base (ref);
		  if (TREE_OPERAND (ptr, 0) == base)
		    {
		      ++alias_stats.stmt_kills_ref_p_yes;
		      return true;
		    }
		}
	      break;
	    }

	  default:;
	  }
    }
  ++alias_stats.stmt_kills_ref_p_no;
  return false;
}

bool
stmt_kills_ref_p (gimple *stmt, tree ref)
{
  ao_ref r;
  ao_ref_init (&r, ref);
  return stmt_kills_ref_p (stmt, &r);
}


/* Walk the virtual use-def chain of VUSE until hitting the virtual operand
   TARGET or a statement clobbering the memory reference REF in which
   case false is returned.  The walk starts with VUSE, one argument of PHI.  */

static bool
maybe_skip_until (gimple *phi, tree &target, basic_block target_bb,
		  ao_ref *ref, tree vuse, bool tbaa_p, unsigned int &limit,
		  bitmap *visited, bool abort_on_visited,
		  void *(*translate)(ao_ref *, tree, void *, translate_flags *),
		  translate_flags disambiguate_only,
		  void *data)
{
  basic_block bb = gimple_bb (phi);

  if (!*visited)
    *visited = BITMAP_ALLOC (NULL);

  bitmap_set_bit (*visited, SSA_NAME_VERSION (PHI_RESULT (phi)));

  /* Walk until we hit the target.  */
  while (vuse != target)
    {
      gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
      /* If we are searching for the target VUSE by walking up to
         TARGET_BB dominating the original PHI we are finished once
	 we reach a default def or a definition in a block dominating
	 that block.  Update TARGET and return.  */
      if (!target
	  && (gimple_nop_p (def_stmt)
	      || dominated_by_p (CDI_DOMINATORS,
				 target_bb, gimple_bb (def_stmt))))
	{
	  target = vuse;
	  return true;
	}

      /* Recurse for PHI nodes.  */
      if (gimple_code (def_stmt) == GIMPLE_PHI)
	{
	  /* An already visited PHI node ends the walk successfully.  */
	  if (bitmap_bit_p (*visited, SSA_NAME_VERSION (PHI_RESULT (def_stmt))))
	    return !abort_on_visited;
	  vuse = get_continuation_for_phi (def_stmt, ref, tbaa_p, limit,
					   visited, abort_on_visited,
					   translate, data, disambiguate_only);
	  if (!vuse)
	    return false;
	  continue;
	}
      else if (gimple_nop_p (def_stmt))
	return false;
      else
	{
	  /* A clobbering statement or the end of the IL ends it failing.  */
	  if ((int)limit <= 0)
	    return false;
	  --limit;
	  if (stmt_may_clobber_ref_p_1 (def_stmt, ref, tbaa_p))
	    {
	      translate_flags tf = disambiguate_only;
	      if (translate
		  && (*translate) (ref, vuse, data, &tf) == NULL)
		;
	      else
		return false;
	    }
	}
      /* If we reach a new basic-block see if we already skipped it
         in a previous walk that ended successfully.  */
      if (gimple_bb (def_stmt) != bb)
	{
	  if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (vuse)))
	    return !abort_on_visited;
	  bb = gimple_bb (def_stmt);
	}
      vuse = gimple_vuse (def_stmt);
    }
  return true;
}


/* Starting from a PHI node for the virtual operand of the memory reference
   REF find a continuation virtual operand that allows to continue walking
   statements dominating PHI skipping only statements that cannot possibly
   clobber REF.  Decrements LIMIT for each alias disambiguation done
   and aborts the walk, returning NULL_TREE if it reaches zero.
   Returns NULL_TREE if no suitable virtual operand can be found.  */

tree
get_continuation_for_phi (gimple *phi, ao_ref *ref, bool tbaa_p,
			  unsigned int &limit, bitmap *visited,
			  bool abort_on_visited,
			  void *(*translate)(ao_ref *, tree, void *,
					     translate_flags *),
			  void *data,
			  translate_flags disambiguate_only)
{
  unsigned nargs = gimple_phi_num_args (phi);

  /* Through a single-argument PHI we can simply look through.  */
  if (nargs == 1)
    return PHI_ARG_DEF (phi, 0);

  /* For two or more arguments try to pairwise skip non-aliasing code
     until we hit the phi argument definition that dominates the other one.  */
  basic_block phi_bb = gimple_bb (phi);
  tree arg0, arg1;
  unsigned i;

  /* Find a candidate for the virtual operand which definition
     dominates those of all others.  */
  /* First look if any of the args themselves satisfy this.  */
  for (i = 0; i < nargs; ++i)
    {
      arg0 = PHI_ARG_DEF (phi, i);
      if (SSA_NAME_IS_DEFAULT_DEF (arg0))
	break;
      basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (arg0));
      if (def_bb != phi_bb
	  && dominated_by_p (CDI_DOMINATORS, phi_bb, def_bb))
	break;
      arg0 = NULL_TREE;
    }
  /* If not, look if we can reach such candidate by walking defs
     until we hit the immediate dominator.  maybe_skip_until will
     do that for us.  */
  basic_block dom = get_immediate_dominator (CDI_DOMINATORS, phi_bb);

  /* Then check against the (to be) found candidate.  */
  for (i = 0; i < nargs; ++i)
    {
      arg1 = PHI_ARG_DEF (phi, i);
      if (arg1 == arg0)
	;
      else if (! maybe_skip_until (phi, arg0, dom, ref, arg1, tbaa_p,
				   limit, visited,
				   abort_on_visited,
				   translate,
				   /* Do not valueize when walking over
				      backedges.  */
				   dominated_by_p
				     (CDI_DOMINATORS,
				      gimple_bb (SSA_NAME_DEF_STMT (arg1)),
				      phi_bb)
				   ? TR_DISAMBIGUATE
				   : disambiguate_only, data))
	return NULL_TREE;
    }

  return arg0;
}

/* Based on the memory reference REF and its virtual use VUSE call
   WALKER for each virtual use that is equivalent to VUSE, including VUSE
   itself.  That is, for each virtual use for which its defining statement
   does not clobber REF.

   WALKER is called with REF, the current virtual use and DATA.  If
   WALKER returns non-NULL the walk stops and its result is returned.
   At the end of a non-successful walk NULL is returned.

   TRANSLATE if non-NULL is called with a pointer to REF, the virtual
   use which definition is a statement that may clobber REF and DATA.
   If TRANSLATE returns (void *)-1 the walk stops and NULL is returned.
   If TRANSLATE returns non-NULL the walk stops and its result is returned.
   If TRANSLATE returns NULL the walk continues and TRANSLATE is supposed
   to adjust REF and *DATA to make that valid.

   VALUEIZE if non-NULL is called with the next VUSE that is considered
   and return value is substituted for that.  This can be used to
   implement optimistic value-numbering for example.  Note that the
   VUSE argument is assumed to be valueized already.

   LIMIT specifies the number of alias queries we are allowed to do,
   the walk stops when it reaches zero and NULL is returned.  LIMIT
   is decremented by the number of alias queries (plus adjustments
   done by the callbacks) upon return.

   TODO: Cache the vector of equivalent vuses per ref, vuse pair.  */

void *
walk_non_aliased_vuses (ao_ref *ref, tree vuse, bool tbaa_p,
			void *(*walker)(ao_ref *, tree, void *),
			void *(*translate)(ao_ref *, tree, void *,
					   translate_flags *),
			tree (*valueize)(tree),
			unsigned &limit, void *data)
{
  bitmap visited = NULL;
  void *res;
  bool translated = false;

  timevar_push (TV_ALIAS_STMT_WALK);

  do
    {
      gimple *def_stmt;

      /* ???  Do we want to account this to TV_ALIAS_STMT_WALK?  */
      res = (*walker) (ref, vuse, data);
      /* Abort walk.  */
      if (res == (void *)-1)
	{
	  res = NULL;
	  break;
	}
      /* Lookup succeeded.  */
      else if (res != NULL)
	break;

      if (valueize)
	{
	  vuse = valueize (vuse);
	  if (!vuse)
	    {
	      res = NULL;
	      break;
	    }
	}
      def_stmt = SSA_NAME_DEF_STMT (vuse);
      if (gimple_nop_p (def_stmt))
	break;
      else if (gimple_code (def_stmt) == GIMPLE_PHI)
	vuse = get_continuation_for_phi (def_stmt, ref, tbaa_p, limit,
					 &visited, translated, translate, data);
      else
	{
	  if ((int)limit <= 0)
	    {
	      res = NULL;
	      break;
	    }
	  --limit;
	  if (stmt_may_clobber_ref_p_1 (def_stmt, ref, tbaa_p))
	    {
	      if (!translate)
		break;
	      translate_flags disambiguate_only = TR_TRANSLATE;
	      res = (*translate) (ref, vuse, data, &disambiguate_only);
	      /* Failed lookup and translation.  */
	      if (res == (void *)-1)
		{
		  res = NULL;
		  break;
		}
	      /* Lookup succeeded.  */
	      else if (res != NULL)
		break;
	      /* Translation succeeded, continue walking.  */
	      translated = translated || disambiguate_only == TR_TRANSLATE;
	    }
	  vuse = gimple_vuse (def_stmt);
	}
    }
  while (vuse);

  if (visited)
    BITMAP_FREE (visited);

  timevar_pop (TV_ALIAS_STMT_WALK);

  return res;
}


/* Based on the memory reference REF call WALKER for each vdef whose
   defining statement may clobber REF, starting with VDEF.  If REF
   is NULL_TREE, each defining statement is visited.

   WALKER is called with REF, the current vdef and DATA.  If WALKER
   returns true the walk is stopped, otherwise it continues.

   If function entry is reached, FUNCTION_ENTRY_REACHED is set to true.
   The pointer may be NULL and then we do not track this information.

   At PHI nodes walk_aliased_vdefs forks into one walk for each
   PHI argument (but only one walk continues at merge points), the
   return value is true if any of the walks was successful.

   The function returns the number of statements walked or -1 if
   LIMIT stmts were walked and the walk was aborted at this point.
   If LIMIT is zero the walk is not aborted.  */

static int
walk_aliased_vdefs_1 (ao_ref *ref, tree vdef,
		      bool (*walker)(ao_ref *, tree, void *), void *data,
		      bitmap *visited, unsigned int cnt,
		      bool *function_entry_reached, unsigned limit)
{
  do
    {
      gimple *def_stmt = SSA_NAME_DEF_STMT (vdef);

      if (*visited
	  && !bitmap_set_bit (*visited, SSA_NAME_VERSION (vdef)))
	return cnt;

      if (gimple_nop_p (def_stmt))
	{
	  if (function_entry_reached)
	    *function_entry_reached = true;
	  return cnt;
	}
      else if (gimple_code (def_stmt) == GIMPLE_PHI)
	{
	  unsigned i;
	  if (!*visited)
	    *visited = BITMAP_ALLOC (NULL);
	  for (i = 0; i < gimple_phi_num_args (def_stmt); ++i)
	    {
	      int res = walk_aliased_vdefs_1 (ref,
					      gimple_phi_arg_def (def_stmt, i),
					      walker, data, visited, cnt,
					      function_entry_reached, limit);
	      if (res == -1)
		return -1;
	      cnt = res;
	    }
	  return cnt;
	}

      /* ???  Do we want to account this to TV_ALIAS_STMT_WALK?  */
      cnt++;
      if (cnt == limit)
	return -1;
      if ((!ref
	   || stmt_may_clobber_ref_p_1 (def_stmt, ref))
	  && (*walker) (ref, vdef, data))
	return cnt;

      vdef = gimple_vuse (def_stmt);
    }
  while (1);
}

int
walk_aliased_vdefs (ao_ref *ref, tree vdef,
		    bool (*walker)(ao_ref *, tree, void *), void *data,
		    bitmap *visited,
		    bool *function_entry_reached, unsigned int limit)
{
  bitmap local_visited = NULL;
  int ret;

  timevar_push (TV_ALIAS_STMT_WALK);

  if (function_entry_reached)
    *function_entry_reached = false;

  ret = walk_aliased_vdefs_1 (ref, vdef, walker, data,
			      visited ? visited : &local_visited, 0,
			      function_entry_reached, limit);
  if (local_visited)
    BITMAP_FREE (local_visited);

  timevar_pop (TV_ALIAS_STMT_WALK);

  return ret;
}

/* Verify validity of the fnspec string.
   See attr-fnspec.h for details.  */

void
attr_fnspec::verify ()
{
  bool err = false;
  if (!len)
    return;

  /* Check return value specifier.  */
  if (len < return_desc_size)
    err = true;
  else if ((len - return_desc_size) % arg_desc_size)
    err = true;
  else if ((str[0] < '1' || str[0] > '4')
	   && str[0] != '.' && str[0] != 'm')
    err = true;

  switch (str[1])
    {
      case ' ':
      case 'p':
      case 'P':
      case 'c':
      case 'C':
	break;
      default:
	err = true;
    }
  if (err)
    internal_error ("invalid fn spec attribute \"%s\"", str);

  /* Now check all parameters.  */
  for (unsigned int i = 0; arg_specified_p (i); i++)
    {
      unsigned int idx = arg_idx (i);
      switch (str[idx])
	{
	  case 'x':
	  case 'X':
	  case 'r':
	  case 'R':
	  case 'o':
	  case 'O':
	  case 'w':
	  case 'W':
	  case '.':
	    if ((str[idx + 1] >= '1' && str[idx + 1] <= '9')
		|| str[idx + 1] == 't')
	      {
		if (str[idx] != 'r' && str[idx] != 'R'
		    && str[idx] != 'w' && str[idx] != 'W'
		    && str[idx] != 'o' && str[idx] != 'O')
		  err = true;
		if (str[idx + 1] != 't'
		    /* Size specified is scalar, so it should be described
		       by ". " if specified at all.  */
		    && (arg_specified_p (str[idx + 1] - '1')
			&& str[arg_idx (str[idx + 1] - '1')] != '.'))
		  err = true;
	      }
	    else if (str[idx + 1] != ' ')
	      err = true;
	    break;
	  default:
	    if (str[idx] < '1' || str[idx] > '9')
	      err = true;
	}
      if (err)
	internal_error ("invalid fn spec attribute \"%s\" arg %i", str, i);
    }
}

/* Return ture if TYPE1 and TYPE2 will always give the same answer
   when compared wit hother types using same_type_for_tbaa_p.  */

static bool
types_equal_for_same_type_for_tbaa_p (tree type1, tree type2,
				      bool lto_streaming_safe)
{
  /* We use same_type_for_tbaa_p to match types in the access path.
     This check is overly conservative.  */
  type1 = TYPE_MAIN_VARIANT (type1);
  type2 = TYPE_MAIN_VARIANT (type2);

  if (TYPE_STRUCTURAL_EQUALITY_P (type1)
      != TYPE_STRUCTURAL_EQUALITY_P (type2))
    return false;
  if (TYPE_STRUCTURAL_EQUALITY_P (type1))
    return true;

  if (lto_streaming_safe)
    return type1 == type2;
  else
    return TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2);
}

/* Compare REF1 and REF2 and return flags specifying their differences.
   If LTO_STREAMING_SAFE is true do not use alias sets and canonical
   types that are going to be recomputed.
   If TBAA is true also compare TBAA metadata.  */

int
ao_compare::compare_ao_refs (ao_ref *ref1, ao_ref *ref2,
			     bool lto_streaming_safe,
			     bool tbaa)
{
  if (TREE_THIS_VOLATILE (ref1->ref) != TREE_THIS_VOLATILE (ref2->ref))
    return SEMANTICS;
  tree base1 = ao_ref_base (ref1);
  tree base2 = ao_ref_base (ref2);

  if (!known_eq (ref1->offset, ref2->offset)
      || !known_eq (ref1->size, ref2->size)
      || !known_eq (ref1->max_size, ref2->max_size))
    return SEMANTICS;

  /* For variable accesses we need to compare actual paths
     to check that both refs are accessing same address and the access size.  */
  if (!known_eq (ref1->size, ref1->max_size))
    {
      if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (ref1->ref)),
			    TYPE_SIZE (TREE_TYPE (ref2->ref)), 0))
	return SEMANTICS;
      tree r1 = ref1->ref;
      tree r2 = ref2->ref;

      /* Handle toplevel COMPONENT_REFs of bitfields.
	 Those are special since they are not allowed in
	 ADDR_EXPR.  */
      if (TREE_CODE (r1) == COMPONENT_REF
	  && DECL_BIT_FIELD (TREE_OPERAND (r1, 1)))
	{
	  if (TREE_CODE (r2) != COMPONENT_REF
	      || !DECL_BIT_FIELD (TREE_OPERAND (r2, 1)))
	    return SEMANTICS;
	  tree field1 = TREE_OPERAND (r1, 1);
	  tree field2 = TREE_OPERAND (r2, 1);
	  if (!operand_equal_p (DECL_FIELD_OFFSET (field1),
				DECL_FIELD_OFFSET (field2), 0)
	      || !operand_equal_p (DECL_FIELD_BIT_OFFSET (field1),
				   DECL_FIELD_BIT_OFFSET (field2), 0)
	      || !operand_equal_p (DECL_SIZE (field1), DECL_SIZE (field2), 0)
	      || !types_compatible_p (TREE_TYPE (r1),
				      TREE_TYPE (r2)))
	    return SEMANTICS;
	  r1 = TREE_OPERAND (r1, 0);
	  r2 = TREE_OPERAND (r2, 0);
	}
      else if (TREE_CODE (r2) == COMPONENT_REF
	       && DECL_BIT_FIELD (TREE_OPERAND (r2, 1)))
	return SEMANTICS;

      /* Similarly for bit field refs.  */
      if (TREE_CODE (r1) == BIT_FIELD_REF)
	{
 	  if (TREE_CODE (r2) != BIT_FIELD_REF
	      || !operand_equal_p (TREE_OPERAND (r1, 1),
				   TREE_OPERAND (r2, 1), 0)
	      || !operand_equal_p (TREE_OPERAND (r1, 2),
				   TREE_OPERAND (r2, 2), 0)
	      || !types_compatible_p (TREE_TYPE (r1),
				      TREE_TYPE (r2)))
	    return SEMANTICS;
	  r1 = TREE_OPERAND (r1, 0);
	  r2 = TREE_OPERAND (r2, 0);
	}
      else if (TREE_CODE (r2) == BIT_FIELD_REF)
	return SEMANTICS;

      /* Now we can compare the address of actual memory access.  */
      if (!operand_equal_p (r1, r2, OEP_ADDRESS_OF | OEP_MATCH_SIDE_EFFECTS))
	return SEMANTICS;
    }
  /* For constant accesses we get more matches by comparing offset only.  */
  else if (!operand_equal_p (base1, base2,
			     OEP_ADDRESS_OF | OEP_MATCH_SIDE_EFFECTS))
    return SEMANTICS;

  /* We can't simply use get_object_alignment_1 on the full
     reference as for accesses with variable indexes this reports
     too conservative alignment.  */
  unsigned int align1, align2;
  unsigned HOST_WIDE_INT bitpos1, bitpos2;
  bool known1 = get_object_alignment_1 (base1, &align1, &bitpos1);
  bool known2 = get_object_alignment_1 (base2, &align2, &bitpos2);
  /* ??? For MEMREF get_object_alignment_1 determines aligned from
     TYPE_ALIGN but still returns false.  This seem to contradict
     its description.  So compare even if alignment is unknown.   */
  if (known1 != known2
      || (bitpos1 != bitpos2 || align1 != align2))
    return SEMANTICS;

  /* Now we know that accesses are semantically same.  */
  int flags = 0;

  /* ao_ref_base strips inner MEM_REF [&decl], recover from that here.  */
  tree rbase1 = ref1->ref;
  if (rbase1)
    while (handled_component_p (rbase1))
      rbase1 = TREE_OPERAND (rbase1, 0);
  tree rbase2 = ref2->ref;
  while (handled_component_p (rbase2))
    rbase2 = TREE_OPERAND (rbase2, 0);

  /* MEM_REFs and TARGET_MEM_REFs record dependence cliques which are used to
     implement restrict pointers.  MR_DEPENDENCE_CLIQUE 0 means no information.
     Otherwise we need to match bases and cliques.  */
  if ((((TREE_CODE (rbase1) == MEM_REF || TREE_CODE (rbase1) == TARGET_MEM_REF)
	&& MR_DEPENDENCE_CLIQUE (rbase1))
       || ((TREE_CODE (rbase2) == MEM_REF || TREE_CODE (rbase2) == TARGET_MEM_REF)
	   && MR_DEPENDENCE_CLIQUE (rbase2)))
      && (TREE_CODE (rbase1) != TREE_CODE (rbase2)
	  || MR_DEPENDENCE_CLIQUE (rbase1) != MR_DEPENDENCE_CLIQUE (rbase2)
	  || (MR_DEPENDENCE_BASE (rbase1) != MR_DEPENDENCE_BASE (rbase2))))
    flags |= DEPENDENCE_CLIQUE;

  if (!tbaa)
    return flags;

  /* Alias sets are not stable across LTO sreaming; be conservative here
     and compare types the alias sets are ultimately based on.  */
  if (lto_streaming_safe)
    {
      tree t1 = ao_ref_alias_ptr_type (ref1);
      tree t2 = ao_ref_alias_ptr_type (ref2);
      if (!alias_ptr_types_compatible_p (t1, t2))
	flags |= REF_ALIAS_SET;

      t1 = ao_ref_base_alias_ptr_type (ref1);
      t2 = ao_ref_base_alias_ptr_type (ref2);
      if (!alias_ptr_types_compatible_p (t1, t2))
	flags |= BASE_ALIAS_SET;
    }
  else
    {
      if (ao_ref_alias_set (ref1) != ao_ref_alias_set (ref2))
	flags |= REF_ALIAS_SET;
      if (ao_ref_base_alias_set (ref1) != ao_ref_base_alias_set (ref2))
	flags |= BASE_ALIAS_SET;
    }

  /* Access path is used only on non-view-converted references.  */
  bool view_converted = view_converted_memref_p (rbase1);
  if (view_converted_memref_p (rbase2) != view_converted)
    return flags | ACCESS_PATH;
  else if (view_converted)
    return flags;


  /* Find start of access paths and look for trailing arrays.  */
  tree c1 = ref1->ref, c2 = ref2->ref;
  tree end_struct_ref1 = NULL, end_struct_ref2 = NULL;
  int nskipped1 = 0, nskipped2 = 0;
  int i = 0;

  for (tree p1 = ref1->ref; handled_component_p (p1); p1 = TREE_OPERAND (p1, 0))
    {
      if (component_ref_to_zero_sized_trailing_array_p (p1))
	end_struct_ref1 = p1;
      if (ends_tbaa_access_path_p (p1))
	c1 = p1, nskipped1 = i;
      i++;
    }
  for (tree p2 = ref2->ref; handled_component_p (p2); p2 = TREE_OPERAND (p2, 0))
    {
      if (component_ref_to_zero_sized_trailing_array_p (p2))
	end_struct_ref2 = p2;
      if (ends_tbaa_access_path_p (p2))
	c2 = p2, nskipped1 = i;
      i++;
    }

  /* For variable accesses we can not rely on offset match bellow.
     We know that paths are struturally same, so only check that
     starts of TBAA paths did not diverge.  */
  if (!known_eq (ref1->size, ref1->max_size)
      && nskipped1 != nskipped2)
    return flags | ACCESS_PATH;

  /* Information about trailing refs is used by
     aliasing_component_refs_p that is applied only if paths
     has handled components..  */
  if (!handled_component_p (c1) && !handled_component_p (c2))
    ;
  else if ((end_struct_ref1 != NULL) != (end_struct_ref2 != NULL))
    return flags | ACCESS_PATH;
  if (end_struct_ref1
      && TYPE_MAIN_VARIANT (TREE_TYPE (end_struct_ref1))
	 != TYPE_MAIN_VARIANT (TREE_TYPE (end_struct_ref2)))
    return flags | ACCESS_PATH;

  /* Now compare all handled components of the access path.
     We have three oracles that cares about access paths:
       - aliasing_component_refs_p
       - nonoverlapping_refs_since_match_p
       - nonoverlapping_component_refs_p
     We need to match things these oracles compare.

     It is only necessary to check types for compatibility
     and offsets.  Rest of what oracles compares are actual
     addresses.  Those are already known to be same:
       - for constant accesses we check offsets
       - for variable accesses we already matched
	 the path lexically with operand_equal_p.  */
  while (true)
    {
      bool comp1 = handled_component_p (c1);
      bool comp2 = handled_component_p (c2);

      if (comp1 != comp2)
	return flags | ACCESS_PATH;
      if (!comp1)
	break;

      if (TREE_CODE (c1) != TREE_CODE (c2))
	return flags | ACCESS_PATH;

      /* aliasing_component_refs_p attempts to find type match within
	 the paths.  For that reason both types needs to be equal
	 with respect to same_type_for_tbaa_p.  */
      if (!types_equal_for_same_type_for_tbaa_p (TREE_TYPE (c1),
						 TREE_TYPE (c2),
						 lto_streaming_safe))
	return flags | ACCESS_PATH;
      if (component_ref_to_zero_sized_trailing_array_p (c1)
	  != component_ref_to_zero_sized_trailing_array_p (c2))
	return flags | ACCESS_PATH;

      /* aliasing_matching_component_refs_p compares
	 offsets within the path.  Other properties are ignored.
	 Do not bother to verify offsets in variable accesses.  Here we
	 already compared them by operand_equal_p so they are
	 structurally same.  */
      if (!known_eq (ref1->size, ref1->max_size))
	{
	  poly_int64 offadj1, sztmc1, msztmc1;
	  bool reverse1;
	  get_ref_base_and_extent (c1, &offadj1, &sztmc1, &msztmc1, &reverse1);
	  poly_int64 offadj2, sztmc2, msztmc2;
	  bool reverse2;
	  get_ref_base_and_extent (c2, &offadj2, &sztmc2, &msztmc2, &reverse2);
	  if (!known_eq (offadj1, offadj2))
	    return flags | ACCESS_PATH;
	}
      c1 = TREE_OPERAND (c1, 0);
      c2 = TREE_OPERAND (c2, 0);
    }
  /* Finally test the access type.  */
  if (!types_equal_for_same_type_for_tbaa_p (TREE_TYPE (c1),
					     TREE_TYPE (c2),
					     lto_streaming_safe))
    return flags | ACCESS_PATH;
  return flags;
}

/* Hash REF to HSTATE.  If LTO_STREAMING_SAFE do not use alias sets
   and canonical types.  */
void
ao_compare::hash_ao_ref (ao_ref *ref, bool lto_streaming_safe, bool tbaa,
			 inchash::hash &hstate)
{
  tree base = ao_ref_base (ref);
  tree tbase = base;

  if (!known_eq (ref->size, ref->max_size))
    {
      tree r = ref->ref;
      if (TREE_CODE (r) == COMPONENT_REF
	  && DECL_BIT_FIELD (TREE_OPERAND (r, 1)))
	{
	  tree field = TREE_OPERAND (r, 1);
	  hash_operand (DECL_FIELD_OFFSET (field), hstate, 0);
	  hash_operand (DECL_FIELD_BIT_OFFSET (field), hstate, 0);
	  hash_operand (DECL_SIZE (field), hstate, 0);
	  r = TREE_OPERAND (r, 0);
	}
      if (TREE_CODE (r) == BIT_FIELD_REF)
	{
	  hash_operand (TREE_OPERAND (r, 1), hstate, 0);
	  hash_operand (TREE_OPERAND (r, 2), hstate, 0);
	  r = TREE_OPERAND (r, 0);
	}
      hash_operand (TYPE_SIZE (TREE_TYPE (ref->ref)), hstate, 0);
      hash_operand (r, hstate, OEP_ADDRESS_OF | OEP_MATCH_SIDE_EFFECTS);
    }
  else
    {
      hash_operand (tbase, hstate, OEP_ADDRESS_OF | OEP_MATCH_SIDE_EFFECTS);
      hstate.add_poly_int (ref->offset);
      hstate.add_poly_int (ref->size);
      hstate.add_poly_int (ref->max_size);
    }
  if (!lto_streaming_safe && tbaa)
    {
      hstate.add_int (ao_ref_alias_set (ref));
      hstate.add_int (ao_ref_base_alias_set (ref));
    }
}
