/* Support for simple predicate analysis.

   Copyright (C) 2001-2022 Free Software Foundation, Inc.
   Contributed by Xinliang David Li <davidxl@google.com>
   Generalized by Martin Sebor <msebor@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/>.  */

#define INCLUDE_STRING
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "tree-ssa.h"
#include "tree-cfg.h"
#include "cfghooks.h"
#include "attribs.h"
#include "builtins.h"
#include "calls.h"
#include "value-query.h"
#include "cfganal.h"
#include "tree-eh.h"

#include "gimple-predicate-analysis.h"

#define DEBUG_PREDICATE_ANALYZER 1

/* In our predicate normal form we have MAX_NUM_CHAINS or predicates
   and in those MAX_CHAIN_LEN (inverted) and predicates.  */
#define MAX_NUM_CHAINS 8
#define MAX_CHAIN_LEN 5

/* Return true if X1 is the negation of X2.  */

static inline bool
pred_neg_p (const pred_info &x1, const pred_info &x2)
{
  if (!operand_equal_p (x1.pred_lhs, x2.pred_lhs, 0)
      || !operand_equal_p (x1.pred_rhs, x2.pred_rhs, 0))
    return false;

  tree_code c1 = x1.cond_code, c2;
  if (x1.invert == x2.invert)
    c2 = invert_tree_comparison (x2.cond_code, false);
  else
    c2 = x2.cond_code;

  return c1 == c2;
}

/* Return whether the condition (VAL CMPC BOUNDARY) is true.  */

static bool
is_value_included_in (tree val, tree boundary, tree_code cmpc)
{
  /* Only handle integer constant here.  */
  if (TREE_CODE (val) != INTEGER_CST || TREE_CODE (boundary) != INTEGER_CST)
    return true;

  bool inverted = false;
  if (cmpc == GE_EXPR || cmpc == GT_EXPR || cmpc == NE_EXPR)
    {
      cmpc = invert_tree_comparison (cmpc, false);
      inverted = true;
    }

  bool result;
  if (cmpc == EQ_EXPR)
    result = tree_int_cst_equal (val, boundary);
  else if (cmpc == LT_EXPR)
    result = tree_int_cst_lt (val, boundary);
  else
    {
      gcc_assert (cmpc == LE_EXPR);
      result = tree_int_cst_le (val, boundary);
    }

  if (inverted)
    result ^= 1;

  return result;
}

/* Format the vector of edges EV as a string.  */

static std::string
format_edge_vec (const vec<edge> &ev)
{
  std::string str;

  unsigned n = ev.length ();
  for (unsigned i = 0; i < n; ++i)
    {
      char es[32];
      const_edge e = ev[i];
      sprintf (es, "%u -> %u", e->src->index, e->dest->index);
      str += es;
      if (i + 1 < n)
	str += ", ";
    }
  return str;
}

/* Format the first N elements of the array of vector of edges EVA as
   a string.  */

static std::string
format_edge_vecs (const vec<edge> eva[], unsigned n)
{
  std::string str;

  for (unsigned i = 0; i != n; ++i)
    {
      str += '{';
      str += format_edge_vec (eva[i]);
      str += '}';
      if (i + 1 < n)
	str += ", ";
    }
  return str;
}

/* Dump a single pred_info to F.  */

static void
dump_pred_info (FILE *f, const pred_info &pred)
{
  if (pred.invert)
    fprintf (f, "NOT (");
  print_generic_expr (f, pred.pred_lhs);
  fprintf (f, " %s ", op_symbol_code (pred.cond_code));
  print_generic_expr (f, pred.pred_rhs);
  if (pred.invert)
    fputc (')', f);
}

/* Dump a pred_chain to F.  */

static void
dump_pred_chain (FILE *f, const pred_chain &chain)
{
  unsigned np = chain.length ();
  for (unsigned j = 0; j < np; j++)
    {
      if (j > 0)
	fprintf (f, " AND (");
      else
	fputc ('(', f);
      dump_pred_info (f, chain[j]);
      fputc (')', f);
    }
}

/* Return the 'normalized' conditional code with operand swapping
   and condition inversion controlled by SWAP_COND and INVERT.  */

static tree_code
get_cmp_code (tree_code orig_cmp_code, bool swap_cond, bool invert)
{
  tree_code tc = orig_cmp_code;

  if (swap_cond)
    tc = swap_tree_comparison (orig_cmp_code);
  if (invert)
    tc = invert_tree_comparison (tc, false);

  switch (tc)
    {
    case LT_EXPR:
    case LE_EXPR:
    case GT_EXPR:
    case GE_EXPR:
    case EQ_EXPR:
    case NE_EXPR:
      break;
    default:
      return ERROR_MARK;
    }
  return tc;
}

/* Return true if PRED is common among all predicate chains in PREDS
   (and therefore can be factored out).  */

static bool
find_matching_predicate_in_rest_chains (const pred_info &pred,
					const pred_chain_union &preds)
{
  /* Trival case.  */
  if (preds.length () == 1)
    return true;

  for (unsigned i = 1; i < preds.length (); i++)
    {
      bool found = false;
      const pred_chain &chain = preds[i];
      unsigned n = chain.length ();
      for (unsigned j = 0; j < n; j++)
	{
	  const pred_info &pred2 = chain[j];
	  /* Can relax the condition comparison to not use address
	     comparison.  However, the most common case is that
	     multiple control dependent paths share a common path
	     prefix, so address comparison should be ok.  */
	  if (operand_equal_p (pred2.pred_lhs, pred.pred_lhs, 0)
	      && operand_equal_p (pred2.pred_rhs, pred.pred_rhs, 0)
	      && pred2.invert == pred.invert)
	    {
	      found = true;
	      break;
	    }
	}
      if (!found)
	return false;
    }
  return true;
}

/* Find a predicate to examine against paths of interest.  If there
   is no predicate of the "FLAG_VAR CMP CONST" form, try to find one
   of that's the form "FLAG_VAR CMP FLAG_VAR" with value range info.
   PHI is the phi node whose incoming (interesting) paths need to be
   examined.  On success, return the comparison code, set defintion
   gimple of FLAG_DEF and BOUNDARY_CST.  Otherwise return ERROR_MARK.  */

static tree_code
find_var_cmp_const (pred_chain_union preds, gphi *phi, gimple **flag_def,
		    tree *boundary_cst)
{
  tree_code vrinfo_code = ERROR_MARK;
  gimple *vrinfo_def = NULL;
  tree vrinfo_cst = NULL;

  gcc_assert (preds.length () > 0);
  pred_chain chain = preds[0];
  for (unsigned i = 0; i < chain.length (); i++)
    {
      bool use_vrinfo_p = false;
      const pred_info &pred = chain[i];
      tree cond_lhs = pred.pred_lhs;
      tree cond_rhs = pred.pred_rhs;
      if (cond_lhs == NULL_TREE || cond_rhs == NULL_TREE)
	continue;

      tree_code code = get_cmp_code (pred.cond_code, false, pred.invert);
      if (code == ERROR_MARK)
	continue;

      /* Convert to the canonical form SSA_NAME CMP CONSTANT.  */
      if (TREE_CODE (cond_lhs) == SSA_NAME
	  && is_gimple_constant (cond_rhs))
	;
      else if (TREE_CODE (cond_rhs) == SSA_NAME
	       && is_gimple_constant (cond_lhs))
	{
	  std::swap (cond_lhs, cond_rhs);
	  if ((code = get_cmp_code (code, true, false)) == ERROR_MARK)
	    continue;
	}
      /* Check if we can take advantage of FLAG_VAR COMP FLAG_VAR predicate
	 with value range info.  Note only first of such case is handled.  */
      else if (vrinfo_code == ERROR_MARK
	       && TREE_CODE (cond_lhs) == SSA_NAME
	       && TREE_CODE (cond_rhs) == SSA_NAME)
	{
	  gimple* lhs_def = SSA_NAME_DEF_STMT (cond_lhs);
	  if (!lhs_def || gimple_code (lhs_def) != GIMPLE_PHI
	      || gimple_bb (lhs_def) != gimple_bb (phi))
	    {
	      std::swap (cond_lhs, cond_rhs);
	      if ((code = get_cmp_code (code, true, false)) == ERROR_MARK)
		continue;
	    }

	  /* Check value range info of rhs, do following transforms:
	       flag_var < [min, max]  ->  flag_var < max
	       flag_var > [min, max]  ->  flag_var > min

	     We can also transform LE_EXPR/GE_EXPR to LT_EXPR/GT_EXPR:
	       flag_var <= [min, max] ->  flag_var < [min, max+1]
	       flag_var >= [min, max] ->  flag_var > [min-1, max]
	     if no overflow/wrap.  */
	  tree type = TREE_TYPE (cond_lhs);
	  value_range r;
	  if (!INTEGRAL_TYPE_P (type)
	      || !get_range_query (cfun)->range_of_expr (r, cond_rhs)
	      || r.kind () != VR_RANGE)
	    continue;

	  wide_int min = r.lower_bound ();
	  wide_int max = r.upper_bound ();
	  if (code == LE_EXPR
	      && max != wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type)))
	    {
	      code = LT_EXPR;
	      max = max + 1;
	    }
	  if (code == GE_EXPR
	      && min != wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type)))
	    {
	      code = GT_EXPR;
	      min = min - 1;
	    }
	  if (code == LT_EXPR)
	    cond_rhs = wide_int_to_tree (type, max);
	  else if (code == GT_EXPR)
	    cond_rhs = wide_int_to_tree (type, min);
	  else
	    continue;

	  use_vrinfo_p = true;
	}
      else
	continue;

      if ((*flag_def = SSA_NAME_DEF_STMT (cond_lhs)) == NULL)
	continue;

      if (gimple_code (*flag_def) != GIMPLE_PHI
	  || gimple_bb (*flag_def) != gimple_bb (phi)
	  || !find_matching_predicate_in_rest_chains (pred, preds))
	continue;

      /* Return if any "flag_var comp const" predicate is found.  */
      if (!use_vrinfo_p)
	{
	  *boundary_cst = cond_rhs;
	  return code;
	}
      /* Record if any "flag_var comp flag_var[vinfo]" predicate is found.  */
      else if (vrinfo_code == ERROR_MARK)
	{
	  vrinfo_code = code;
	  vrinfo_def = *flag_def;
	  vrinfo_cst = cond_rhs;
	}
    }
  /* Return the "flag_var cmp flag_var[vinfo]" predicate we found.  */
  if (vrinfo_code != ERROR_MARK)
    {
      *flag_def = vrinfo_def;
      *boundary_cst = vrinfo_cst;
    }
  return vrinfo_code;
}

/* Return true if all interesting opnds are pruned, false otherwise.
   PHI is the phi node with interesting operands, OPNDS is the bitmap
   of the interesting operand positions, FLAG_DEF is the statement
   defining the flag guarding the use of the PHI output, BOUNDARY_CST
   is the const value used in the predicate associated with the flag,
   CMP_CODE is the comparison code used in the predicate, VISITED_PHIS
   is the pointer set of phis visited, and VISITED_FLAG_PHIS is
   the pointer to the pointer set of flag definitions that are also
   phis.

   Example scenario:

   BB1:
     flag_1 = phi <0, 1>			// (1)
     var_1  = phi <undef, some_val>


   BB2:
     flag_2 = phi <0,   flag_1, flag_1>		// (2)
     var_2  = phi <undef, var_1, var_1>
     if (flag_2 == 1)
       goto BB3;

   BB3:
     use of var_2				// (3)

   Because some flag arg in (1) is not constant, if we do not look into
   the flag phis recursively, it is conservatively treated as unknown and
   var_1 is thought to flow into use at (3).  Since var_1 is potentially
   uninitialized a false warning will be emitted.
   Checking recursively into (1), the compiler can find out that only
   some_val (which is defined) can flow into (3) which is OK.  */

bool
uninit_analysis::prune_phi_opnds (gphi *phi, unsigned opnds, gphi *flag_def,
				  tree boundary_cst, tree_code cmp_code,
				  hash_set<gphi *> *visited_phis,
				  bitmap *visited_flag_phis)
{
  /* The Boolean predicate guarding the PHI definition.  Initialized
     lazily from PHI in the first call to is_use_guarded() and cached
     for subsequent iterations.  */
  uninit_analysis def_preds (m_eval);

  unsigned n = MIN (m_eval.max_phi_args, gimple_phi_num_args (flag_def));
  for (unsigned i = 0; i < n; i++)
    {
      if (!MASK_TEST_BIT (opnds, i))
	continue;

      tree flag_arg = gimple_phi_arg_def (flag_def, i);
      if (!is_gimple_constant (flag_arg))
	{
	  if (TREE_CODE (flag_arg) != SSA_NAME)
	    return false;

	  gphi *flag_arg_def = dyn_cast<gphi *> (SSA_NAME_DEF_STMT (flag_arg));
	  if (!flag_arg_def)
	    return false;

	  tree phi_arg = gimple_phi_arg_def (phi, i);
	  if (TREE_CODE (phi_arg) != SSA_NAME)
	    return false;

	  gphi *phi_arg_def = dyn_cast<gphi *> (SSA_NAME_DEF_STMT (phi_arg));
	  if (!phi_arg_def)
	    return false;

	  if (gimple_bb (phi_arg_def) != gimple_bb (flag_arg_def))
	    return false;

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

	  tree phi_result = gimple_phi_result (flag_arg_def);
	  if (bitmap_bit_p (*visited_flag_phis, SSA_NAME_VERSION (phi_result)))
	    return false;

	  bitmap_set_bit (*visited_flag_phis, SSA_NAME_VERSION (phi_result));

	  /* Now recursively try to prune the interesting phi args.  */
	  unsigned opnds_arg_phi = m_eval.phi_arg_set (phi_arg_def);
	  if (!prune_phi_opnds (phi_arg_def, opnds_arg_phi, flag_arg_def,
				boundary_cst, cmp_code, visited_phis,
				visited_flag_phis))
	    return false;

	  bitmap_clear_bit (*visited_flag_phis, SSA_NAME_VERSION (phi_result));
	  continue;
	}

      /* Now check if the constant is in the guarded range.  */
      if (is_value_included_in (flag_arg, boundary_cst, cmp_code))
	{
	  /* Now that we know that this undefined edge is not pruned.
	     If the operand is defined by another phi, we can further
	     prune the incoming edges of that phi by checking
	     the predicates of this operands.  */

	  tree opnd = gimple_phi_arg_def (phi, i);
	  gimple *opnd_def = SSA_NAME_DEF_STMT (opnd);
	  if (gphi *opnd_def_phi = dyn_cast <gphi *> (opnd_def))
	    {
	      unsigned opnds2 = m_eval.phi_arg_set (opnd_def_phi);
	      if (!MASK_EMPTY (opnds2))
		{
		  edge opnd_edge = gimple_phi_arg_edge (phi, i);
		  if (def_preds.is_use_guarded (phi, opnd_edge->src,
						opnd_def_phi, opnds2,
						visited_phis))
		    return false;
		}
	    }
	  else
	    return false;
	}
    }

  return true;
}

/* Recursively compute the set PHI's incoming edges with "uninteresting"
   operands of a phi chain, i.e., those for which EVAL returns false.
   CD_ROOT is the control dependence root from which edges are collected
   up the CFG nodes that it's dominated by.  *EDGES holds the result, and
   VISITED is used for detecting cycles.  */

void
uninit_analysis::collect_phi_def_edges (gphi *phi, basic_block cd_root,
					vec<edge> *edges,
					hash_set<gimple *> *visited)
{
  if (visited->elements () == 0
      && DEBUG_PREDICATE_ANALYZER
      && dump_file)
    {
      fprintf (dump_file, "%s for cd_root %u and ",
	       __func__, cd_root->index);
      print_gimple_stmt (dump_file, phi, 0);

    }

  if (visited->add (phi))
    return;

  unsigned n = gimple_phi_num_args (phi);
  unsigned opnds_arg_phi = m_eval.phi_arg_set (phi);
  for (unsigned i = 0; i < n; i++)
    {
      if (!MASK_TEST_BIT (opnds_arg_phi, i))
	{
	  /* Add the edge for a not maybe-undefined edge value.  */
	  edge opnd_edge = gimple_phi_arg_edge (phi, i);
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fprintf (dump_file,
		       "\tFound def edge %i -> %i for cd_root %i "
		       "and operand %u of: ",
		       opnd_edge->src->index, opnd_edge->dest->index,
		       cd_root->index, i);
	      print_gimple_stmt (dump_file, phi, 0);
	    }
	  edges->safe_push (opnd_edge);
	  continue;
	}
      else
	{
	  tree opnd = gimple_phi_arg_def (phi, i);
	  if (TREE_CODE (opnd) == SSA_NAME)
	    {
	      gimple *def = SSA_NAME_DEF_STMT (opnd);
	      if (gimple_code (def) == GIMPLE_PHI
		  && dominated_by_p (CDI_DOMINATORS, gimple_bb (def), cd_root))
		/* Process PHI defs of maybe-undefined edge values
		   recursively.  */
		collect_phi_def_edges (as_a<gphi *> (def), cd_root, edges,
				       visited);
	    }
	}
    }
}

/* Return a bitset of all PHI arguments or zero if there are too many.  */

unsigned
uninit_analysis::func_t::phi_arg_set (gphi *phi)
{
  unsigned n = gimple_phi_num_args (phi);

  if (max_phi_args < n)
    return 0;

  /* Set the least significant N bits.  */
  return (1U << n) - 1;
}

/* Determine if the predicate set of the use does not overlap with that
   of the interesting paths.  The most common senario of guarded use is
   in Example 1:
     Example 1:
	   if (some_cond)
	   {
	      x = ...;   // set x to valid
	      flag = true;
	   }

	    ... some code ...

	   if (flag)
	      use (x);   // use when x is valid

     The real world examples are usually more complicated, but similar
     and usually result from inlining:

	 bool init_func (int * x)
	 {
	     if (some_cond)
		return false;
	     *x  =  ...;   // set *x to valid
	     return true;
	 }

	 void foo (..)
	 {
	     int x;

	     if (!init_func (&x))
		return;

	     .. some_code ...
	     use (x);      // use when x is valid
	 }

     Another possible use scenario is in the following trivial example:

     Example 2:
	  if (n > 0)
	     x = 1;
	  ...
	  if (n > 0)
	    {
	      if (m < 2)
		 ... = x;
	    }

     Predicate analysis needs to compute the composite predicate:

       1) 'x' use predicate: (n > 0) .AND. (m < 2)
       2) 'x' default value  (non-def) predicate: .NOT. (n > 0)
       (the predicate chain for phi operand defs can be computed
       starting from a bb that is control equivalent to the phi's
       bb and is dominating the operand def.)

       and check overlapping:
	  (n > 0) .AND. (m < 2) .AND. (.NOT. (n > 0))
	<==> false

     This implementation provides a framework that can handle different
     scenarios.  (Note that many simple cases are handled properly without
     the predicate analysis if jump threading eliminates the merge point
     thus makes path-sensitive analysis unnecessary.)

     PHI is the phi node whose incoming (undefined) paths need to be
     pruned, and OPNDS is the bitmap holding interesting operand
     positions.  VISITED is the pointer set of phi stmts being
     checked.  */

bool
uninit_analysis::overlap (gphi *phi, unsigned opnds, hash_set<gphi *> *visited,
			  const predicate &use_preds)
{
  gimple *flag_def = NULL;
  tree boundary_cst = NULL_TREE;
  bitmap visited_flag_phis = NULL;

  /* Find within the common prefix of multiple predicate chains
     a predicate that is a comparison of a flag variable against
     a constant.  */
  tree_code cmp_code = find_var_cmp_const (use_preds.chain (), phi, &flag_def,
					   &boundary_cst);
  if (cmp_code == ERROR_MARK)
    return true;

  /* Now check all the uninit incoming edges have a constant flag
     value that is in conflict with the use guard/predicate.  */
  gphi *phi_def = as_a<gphi *> (flag_def);
  bool all_pruned = prune_phi_opnds (phi, opnds, phi_def, boundary_cst,
				     cmp_code, visited,
				     &visited_flag_phis);

  if (visited_flag_phis)
    BITMAP_FREE (visited_flag_phis);

  return !all_pruned;
}

/* Return true if two predicates PRED1 and X2 are equivalent.  Assume
   the expressions have already properly re-associated.  */

static inline bool
pred_equal_p (const pred_info &pred1, const pred_info &pred2)
{
  if (!operand_equal_p (pred1.pred_lhs, pred2.pred_lhs, 0)
      || !operand_equal_p (pred1.pred_rhs, pred2.pred_rhs, 0))
    return false;

  tree_code c1 = pred1.cond_code, c2;
  if (pred1.invert != pred2.invert
      && TREE_CODE_CLASS (pred2.cond_code) == tcc_comparison)
    c2 = invert_tree_comparison (pred2.cond_code, false);
  else
    c2 = pred2.cond_code;

  return c1 == c2;
}

/* Return true if PRED tests inequality (i.e., X != Y).  */

static inline bool
is_neq_relop_p (const pred_info &pred)
{

  return ((pred.cond_code == NE_EXPR && !pred.invert)
	  || (pred.cond_code == EQ_EXPR && pred.invert));
}

/* Returns true if PRED is of the form X != 0.  */

static inline bool
is_neq_zero_form_p (const pred_info &pred)
{
  if (!is_neq_relop_p (pred) || !integer_zerop (pred.pred_rhs)
      || TREE_CODE (pred.pred_lhs) != SSA_NAME)
    return false;
  return true;
}

/* Return true if PRED is equivalent to X != 0.  */

static inline bool
pred_expr_equal_p (const pred_info &pred, tree expr)
{
  if (!is_neq_zero_form_p (pred))
    return false;

  return operand_equal_p (pred.pred_lhs, expr, 0);
}

/* Return true if VAL satisfies (x CMPC BOUNDARY) predicate.  CMPC can
   be either one of the range comparison codes ({GE,LT,EQ,NE}_EXPR and
   the like), or BIT_AND_EXPR.  EXACT_P is only meaningful for the latter.
   Modify the question from VAL & BOUNDARY != 0 to VAL & BOUNDARY == VAL.
   For other values of CMPC, EXACT_P is ignored.  */

static bool
value_sat_pred_p (tree val, tree boundary, tree_code cmpc,
		  bool exact_p = false)
{
  if (cmpc != BIT_AND_EXPR)
    return is_value_included_in (val, boundary, cmpc);

  wide_int andw = wi::to_wide (val) & wi::to_wide (boundary);
  if (exact_p)
    return andw == wi::to_wide (val);

  return andw.to_uhwi ();
}

/* Return true if the domain of single predicate expression PRED1
   is a subset of that of PRED2, and false if it cannot be proved.  */

static bool
subset_of (const pred_info &pred1, const pred_info &pred2)
{
  if (pred_equal_p (pred1, pred2))
    return true;

  if ((TREE_CODE (pred1.pred_rhs) != INTEGER_CST)
      || (TREE_CODE (pred2.pred_rhs) != INTEGER_CST))
    return false;

  if (!operand_equal_p (pred1.pred_lhs, pred2.pred_lhs, 0))
    return false;

  tree_code code1 = pred1.cond_code;
  if (pred1.invert)
    code1 = invert_tree_comparison (code1, false);
  tree_code code2 = pred2.cond_code;
  if (pred2.invert)
    code2 = invert_tree_comparison (code2, false);

  if (code2 == NE_EXPR && code1 == NE_EXPR)
    return false;

  if (code2 == NE_EXPR)
    return !value_sat_pred_p (pred2.pred_rhs, pred1.pred_rhs, code1);

  if (code1 == EQ_EXPR)
    return value_sat_pred_p (pred1.pred_rhs, pred2.pred_rhs, code2);

  if (code1 == code2)
    return value_sat_pred_p (pred1.pred_rhs, pred2.pred_rhs, code2,
			     code1 == BIT_AND_EXPR);

  return false;
}

/* Return true if the domain of CHAIN1 is a subset of that of CHAIN2.
   Return false if it cannot be proven so.  */

static bool
subset_of (const pred_chain &chain1, const pred_chain &chain2)
{
  unsigned np1 = chain1.length ();
  unsigned np2 = chain2.length ();
  for (unsigned i2 = 0; i2 < np2; i2++)
    {
      bool found = false;
      const pred_info &info2 = chain2[i2];
      for (unsigned i1 = 0; i1 < np1; i1++)
	{
	  const pred_info &info1 = chain1[i1];
	  if (subset_of (info1, info2))
	    {
	      found = true;
	      break;
	    }
	}
      if (!found)
	return false;
    }
  return true;
}

/* Return true if the domain defined by the predicate chain PREDS is
   a subset of the domain of *THIS.  Return false if PREDS's domain
   is not a subset of any of the sub-domains of *THIS (corresponding
   to each individual chains in it), even though it may be still be
   a subset of whole domain of *THIS which is the union (ORed) of all
   its subdomains.  In other words, the result is conservative.  */

bool
predicate::includes (const pred_chain &chain) const
{
  for (unsigned i = 0; i < m_preds.length (); i++)
    if (subset_of (chain, m_preds[i]))
      return true;

  return false;
}

/* Return true if the domain defined by *THIS is a superset of PREDS's
   domain.
   Avoid building generic trees (and rely on the folding capability
   of the compiler), and instead perform brute force comparison of
   individual predicate chains (this won't be a computationally costly
   since the chains are pretty short).  Returning false does not
   necessarily mean *THIS is not a superset of *PREDS, only that
   it need not be since the analysis cannot prove it.  */

bool
predicate::superset_of (const predicate &preds) const
{
  for (unsigned i = 0; i < preds.m_preds.length (); i++)
    if (!includes (preds.m_preds[i]))
      return false;

  return true;
}

/* Create a predicate of the form OP != 0 and push it the work list CHAIN.  */

static void
push_to_worklist (tree op, pred_chain *chain, hash_set<tree> *mark_set)
{
  if (mark_set->contains (op))
    return;
  mark_set->add (op);

  pred_info arg_pred;
  arg_pred.pred_lhs = op;
  arg_pred.pred_rhs = integer_zero_node;
  arg_pred.cond_code = NE_EXPR;
  arg_pred.invert = false;
  chain->safe_push (arg_pred);
}

/* Return a pred_info for a gimple assignment CMP_ASSIGN with comparison
   rhs.  */

static pred_info
get_pred_info_from_cmp (const gimple *cmp_assign)
{
  pred_info pred;
  pred.pred_lhs = gimple_assign_rhs1 (cmp_assign);
  pred.pred_rhs = gimple_assign_rhs2 (cmp_assign);
  pred.cond_code = gimple_assign_rhs_code (cmp_assign);
  pred.invert = false;
  return pred;
}

/* If PHI is a degenerate phi with all operands having the same value (relop)
   update *PRED to that value and return true.  Otherwise return false.  */

static bool
is_degenerate_phi (gimple *phi, pred_info *pred)
{
  tree op0 = gimple_phi_arg_def (phi, 0);

  if (TREE_CODE (op0) != SSA_NAME)
    return false;

  gimple *def0 = SSA_NAME_DEF_STMT (op0);
  if (gimple_code (def0) != GIMPLE_ASSIGN)
    return false;

  if (TREE_CODE_CLASS (gimple_assign_rhs_code (def0)) != tcc_comparison)
    return false;

  pred_info pred0 = get_pred_info_from_cmp (def0);

  unsigned n = gimple_phi_num_args (phi);
  for (unsigned i = 1; i < n; ++i)
    {
      tree op = gimple_phi_arg_def (phi, i);
      if (TREE_CODE (op) != SSA_NAME)
	return false;

      gimple *def = SSA_NAME_DEF_STMT (op);
      if (gimple_code (def) != GIMPLE_ASSIGN)
	return false;

      if (TREE_CODE_CLASS (gimple_assign_rhs_code (def)) != tcc_comparison)
	return false;

      pred_info pred = get_pred_info_from_cmp (def);
      if (!pred_equal_p (pred, pred0))
	return false;
    }

  *pred = pred0;
  return true;
}

/* If compute_control_dep_chain bailed out due to limits this routine
   tries to build a partial sparse path using dominators.  Returns
   path edges whose predicates are always true when reaching E.  */

static void
simple_control_dep_chain (vec<edge>& chain, basic_block from, basic_block to)
{
  if (!dominated_by_p (CDI_DOMINATORS, to, from))
    return;

  basic_block src = to;
  while (src != from
	 && chain.length () <= MAX_CHAIN_LEN)
    {
      basic_block dest = src;
      src = get_immediate_dominator (CDI_DOMINATORS, src);
      if (single_pred_p (dest))
	{
	  edge pred_e = single_pred_edge (dest);
	  gcc_assert (pred_e->src == src);
	  if (!(pred_e->flags & ((EDGE_FAKE | EDGE_ABNORMAL | EDGE_DFS_BACK)))
	      && !single_succ_p (src))
	    chain.safe_push (pred_e);
	}
    }
}

/* Perform a DFS walk on predecessor edges to mark the region denoted
   by the EXIT_SRC block and DOM which dominates EXIT_SRC, including DOM.
   Blocks in the region are marked with FLAG and added to BBS.  BBS is
   filled up to its capacity only after which the walk is terminated
   and false is returned.  If the whole region was marked, true is returned.  */

static bool
dfs_mark_dominating_region (basic_block exit_src, basic_block dom, int flag,
			    vec<basic_block> &bbs)
{
  if (exit_src == dom || exit_src->flags & flag)
    return true;
  if (!bbs.space (1))
    return false;
  bbs.quick_push (exit_src);
  exit_src->flags |= flag;
  auto_vec<edge_iterator, 20> stack (bbs.allocated () - bbs.length () + 1);
  stack.quick_push (ei_start (exit_src->preds));
  while (!stack.is_empty ())
    {
      /* Look at the edge on the top of the stack.  */
      edge_iterator ei = stack.last ();
      basic_block src = ei_edge (ei)->src;

      /* Check if the edge source has been visited yet.  */
      if (!(src->flags & flag))
	{
	  /* Mark the source if there's still space.  If not, return early.  */
	  if (!bbs.space (1))
	    return false;
	  src->flags |= flag;
	  bbs.quick_push (src);

	  /* Queue its predecessors if we didn't reach DOM.  */
	  if (src != dom && EDGE_COUNT (src->preds) > 0)
	    stack.quick_push (ei_start (src->preds));
	}
      else
	{
	  if (!ei_one_before_end_p (ei))
	    ei_next (&stack.last ());
	  else
	    stack.pop ();
	}
    }
  return true;
}

static bool
compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb,
			   vec<edge> cd_chains[], unsigned *num_chains,
			   vec<edge> &cur_cd_chain, unsigned *num_calls,
			   unsigned in_region, unsigned depth,
			   bool *complete_p);

/* Helper for compute_control_dep_chain that walks the post-dominator
   chain from CD_BB up unto TARGET_BB looking for paths to DEP_BB.  */

static bool
compute_control_dep_chain_pdom (basic_block cd_bb, const_basic_block dep_bb,
				basic_block target_bb,
				vec<edge> cd_chains[], unsigned *num_chains,
				vec<edge> &cur_cd_chain, unsigned *num_calls,
				unsigned in_region, unsigned depth,
				bool *complete_p)
{
  bool found_cd_chain = false;
  while (cd_bb != target_bb)
    {
      if (cd_bb == dep_bb)
	{
	  /* Found a direct control dependence.  */
	  if (*num_chains < MAX_NUM_CHAINS)
	    {
	      if (DEBUG_PREDICATE_ANALYZER && dump_file)
		fprintf (dump_file, "%*s pushing { %s }\n",
			 depth, "", format_edge_vec (cur_cd_chain).c_str ());
	      cd_chains[*num_chains] = cur_cd_chain.copy ();
	      (*num_chains)++;
	    }
	  found_cd_chain = true;
	  /* Check path from next edge.  */
	  break;
	}

      /* If the dominating region has been marked avoid walking outside.  */
      if (in_region != 0 && !(cd_bb->flags & in_region))
	break;

      /* Count the number of steps we perform to limit compile-time.
	 This should cover both recursion and the post-dominator walk.  */
      if (*num_calls > (unsigned)param_uninit_control_dep_attempts)
	{
	  if (dump_file)
	    fprintf (dump_file, "param_uninit_control_dep_attempts "
		     "exceeded: %u\n", *num_calls);
	  *complete_p = false;
	  break;
	}
      ++*num_calls;

      /* Check if DEP_BB is indirectly control-dependent on DOM_BB.  */
      if (!single_succ_p (cd_bb)
	  && compute_control_dep_chain (cd_bb, dep_bb, cd_chains,
					num_chains, cur_cd_chain,
					num_calls, in_region, depth + 1,
					complete_p))
	{
	  found_cd_chain = true;
	  break;
	}

      /* The post-dominator walk will reach a backedge only
	 from a forwarder, otherwise it should choose to exit
	 the SCC.  */
      if (single_succ_p (cd_bb)
	  && single_succ_edge (cd_bb)->flags & EDGE_DFS_BACK)
	break;
      basic_block prev_cd_bb = cd_bb;
      cd_bb = get_immediate_dominator (CDI_POST_DOMINATORS, cd_bb);
      if (cd_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
	break;
      /* Pick up conditions toward the post dominator such like
	 loop exit conditions.  See gcc.dg/uninit-pred-11.c and
	 gcc.dg/unninit-pred-12.c and PR106754.  */
      if (single_pred_p (cd_bb))
	{
	  edge e2 = single_pred_edge (cd_bb);
	  gcc_assert (e2->src == prev_cd_bb);
	  /* But avoid adding fallthru or abnormal edges.  */
	  if (!(e2->flags & (EDGE_FAKE | EDGE_ABNORMAL | EDGE_DFS_BACK))
	      && !single_succ_p (prev_cd_bb))
	    cur_cd_chain.safe_push (e2);
	}
    }
  return found_cd_chain;
}


/* Recursively compute the control dependence chains (paths of edges)
   from the dependent basic block, DEP_BB, up to the dominating basic
   block, DOM_BB (the head node of a chain should be dominated by it),
   storing them in the CD_CHAINS array.
   CUR_CD_CHAIN is the current chain being computed.
   *NUM_CHAINS is total number of chains in the CD_CHAINS array.
   *NUM_CALLS is the number of recursive calls to control unbounded
   recursion.
   Return true if the information is successfully computed, false if
   there is no control dependence or not computed.
   *COMPLETE_P is set to false if we stopped walking due to limits.
   In this case there might be missing chains.  */

static bool
compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb,
			   vec<edge> cd_chains[], unsigned *num_chains,
			   vec<edge> &cur_cd_chain, unsigned *num_calls,
			   unsigned in_region, unsigned depth,
			   bool *complete_p)
{
  /* In our recursive calls this doesn't happen.  */
  if (single_succ_p (dom_bb))
    return false;

  /* FIXME: Use a set instead.  */
  unsigned cur_chain_len = cur_cd_chain.length ();
  if (cur_chain_len > MAX_CHAIN_LEN)
    {
      if (dump_file)
	fprintf (dump_file, "MAX_CHAIN_LEN exceeded: %u\n", cur_chain_len);

      *complete_p = false;
      return false;
    }

  if (cur_chain_len > 5)
    {
      if (dump_file)
	fprintf (dump_file, "chain length exceeds 5: %u\n", cur_chain_len);
    }

  if (DEBUG_PREDICATE_ANALYZER && dump_file)
    fprintf (dump_file,
	     "%*s%s (dom_bb = %u, dep_bb = %u, ..., "
	     "cur_cd_chain = { %s }, ...)\n",
	     depth, "", __func__, dom_bb->index, dep_bb->index,
	     format_edge_vec (cur_cd_chain).c_str ());

  bool found_cd_chain = false;

  /* Iterate over DOM_BB's successors.  */
  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, dom_bb->succs)
    {
      if (e->flags & (EDGE_FAKE | EDGE_ABNORMAL | EDGE_DFS_BACK))
	continue;

      basic_block cd_bb = e->dest;
      unsigned pop_mark = cur_cd_chain.length ();
      cur_cd_chain.safe_push (e);
      basic_block target_bb
	= get_immediate_dominator (CDI_POST_DOMINATORS, dom_bb);
      /* Walk the post-dominator chain up to the CFG merge.  */
      found_cd_chain
	  |= compute_control_dep_chain_pdom (cd_bb, dep_bb, target_bb,
					     cd_chains, num_chains,
					     cur_cd_chain, num_calls,
					     in_region, depth, complete_p);
      cur_cd_chain.truncate (pop_mark);
      gcc_assert (cur_cd_chain.length () == cur_chain_len);
    }

  gcc_assert (cur_cd_chain.length () == cur_chain_len);
  return found_cd_chain;
}

/* Wrapper around the compute_control_dep_chain worker above.  Returns
   true when the collected set of chains in CD_CHAINS is complete.  */

static bool
compute_control_dep_chain (basic_block dom_bb, const_basic_block dep_bb,
			   vec<edge> cd_chains[], unsigned *num_chains,
			   unsigned in_region = 0)
{
  auto_vec<edge, MAX_CHAIN_LEN + 1> cur_cd_chain;
  unsigned num_calls = 0;
  unsigned depth = 0;
  bool complete_p = true;
  /* Walk the post-dominator chain.  */
  compute_control_dep_chain_pdom (dom_bb, dep_bb, NULL, cd_chains,
				  num_chains, cur_cd_chain, &num_calls,
				  in_region, depth, &complete_p);
  return complete_p;
}

/* Implemented simplifications:

   1) ((x IOR y) != 0) AND (x != 0) is equivalent to (x != 0);
   2) (X AND Y) OR (!X AND Y) is equivalent to Y;
   3) X OR (!X AND Y) is equivalent to (X OR Y);
   4) ((x IAND y) != 0) || (x != 0 AND y != 0)) is equivalent to
      (x != 0 AND y != 0)
   5) (X AND Y) OR (!X AND Z) OR (!Y AND Z) is equivalent to
      (X AND Y) OR Z

   PREDS is the predicate chains, and N is the number of chains.  */

/* Implement rule 1 above.  PREDS is the AND predicate to simplify
   in place.  */

static void
simplify_1 (pred_chain &chain)
{
  bool simplified = false;
  pred_chain s_chain = vNULL;

  unsigned n = chain.length ();
  for (unsigned i = 0; i < n; i++)
    {
      pred_info &a_pred = chain[i];

      if (!a_pred.pred_lhs
	  || !is_neq_zero_form_p (a_pred))
	continue;

      gimple *def_stmt = SSA_NAME_DEF_STMT (a_pred.pred_lhs);
      if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
	continue;

      if (gimple_assign_rhs_code (def_stmt) != BIT_IOR_EXPR)
	continue;

      for (unsigned j = 0; j < n; j++)
	{
	  const pred_info &b_pred = chain[j];

	  if (!b_pred.pred_lhs
	      || !is_neq_zero_form_p (b_pred))
	    continue;

	  if (pred_expr_equal_p (b_pred, gimple_assign_rhs1 (def_stmt))
	      || pred_expr_equal_p (b_pred, gimple_assign_rhs2 (def_stmt)))
	    {
	      /* Mark A_PRED for removal from PREDS.  */
	      a_pred.pred_lhs = NULL;
	      a_pred.pred_rhs = NULL;
	      simplified = true;
	      break;
	    }
	}
    }

  if (!simplified)
    return;

  /* Remove predicates marked above.  */
  for (unsigned i = 0; i < n; i++)
    {
      pred_info &a_pred = chain[i];
      if (!a_pred.pred_lhs)
	continue;
      s_chain.safe_push (a_pred);
    }

  chain.release ();
  chain = s_chain;
}

/* Implements rule 2 for the OR predicate PREDS:

   2) (X AND Y) OR (!X AND Y) is equivalent to Y.  */

bool
predicate::simplify_2 ()
{
  bool simplified = false;

  /* (X AND Y) OR (!X AND Y) is equivalent to Y.
     (X AND Y) OR (X AND !Y) is equivalent to X.  */

  unsigned n = m_preds.length ();
  for (unsigned i = 0; i < n; i++)
    {
      pred_chain &a_chain = m_preds[i];
      if (a_chain.length () != 2)
	continue;

      /* Create copies since the chain may be released below before
	 the copy is added to the other chain.  */
      const pred_info x = a_chain[0];
      const pred_info y = a_chain[1];

      for (unsigned j = 0; j < n; j++)
	{
	  if (j == i)
	    continue;

	  pred_chain &b_chain = m_preds[j];
	  if (b_chain.length () != 2)
	    continue;

	  const pred_info &x2 = b_chain[0];
	  const pred_info &y2 = b_chain[1];

	  if (pred_equal_p (x, x2) && pred_neg_p (y, y2))
	    {
	      /* Kill a_chain.  */
	      b_chain.release ();
	      a_chain.release ();
	      b_chain.safe_push (x);
	      simplified = true;
	      break;
	    }
	  if (pred_neg_p (x, x2) && pred_equal_p (y, y2))
	    {
	      /* Kill a_chain.  */
	      a_chain.release ();
	      b_chain.release ();
	      b_chain.safe_push (y);
	      simplified = true;
	      break;
	    }
	}
    }
  /* Now clean up the chain.  */
  if (simplified)
    {
      pred_chain_union s_preds = vNULL;
      for (unsigned i = 0; i < n; i++)
	{
	  if (m_preds[i].is_empty ())
	    continue;
	  s_preds.safe_push (m_preds[i]);
	}
      m_preds.release ();
      m_preds = s_preds;
      s_preds = vNULL;
    }

  return simplified;
}

/* Implement rule 3 for the OR predicate PREDS:

   3) x OR (!x AND y) is equivalent to x OR y.  */

bool
predicate::simplify_3 ()
{
  /* Now iteratively simplify X OR (!X AND Z ..)
       into X OR (Z ...).  */

  unsigned n = m_preds.length ();
  if (n < 2)
    return false;

  bool simplified = false;
  for (unsigned i = 0; i < n; i++)
    {
      const pred_chain &a_chain = m_preds[i];

      if (a_chain.length () != 1)
	continue;

      const pred_info &x = a_chain[0];
      for (unsigned j = 0; j < n; j++)
	{
	  if (j == i)
	    continue;

	  pred_chain b_chain = m_preds[j];
	  if (b_chain.length () < 2)
	    continue;

	  for (unsigned k = 0; k < b_chain.length (); k++)
	    {
	      const pred_info &x2 = b_chain[k];
	      if (pred_neg_p (x, x2))
		{
		  b_chain.unordered_remove (k);
		  simplified = true;
		  break;
		}
	    }
	}
    }
  return simplified;
}

/* Implement rule 4 for the OR predicate PREDS:

   2) ((x AND y) != 0) OR (x != 0 AND y != 0) is equivalent to
       (x != 0 AND y != 0).   */

bool
predicate::simplify_4 ()
{
  bool simplified = false;
  pred_chain_union s_preds = vNULL;

  unsigned n = m_preds.length ();
  for (unsigned i = 0; i < n; i++)
    {
      pred_chain a_chain = m_preds[i];
      if (a_chain.length () != 1)
	continue;

      const pred_info &z = a_chain[0];
      if (!is_neq_zero_form_p (z))
	continue;

      gimple *def_stmt = SSA_NAME_DEF_STMT (z.pred_lhs);
      if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
	continue;

      if (gimple_assign_rhs_code (def_stmt) != BIT_AND_EXPR)
	continue;

      for (unsigned j = 0; j < n; j++)
	{
	  if (j == i)
	    continue;

	  pred_chain b_chain = m_preds[j];
	  if (b_chain.length () != 2)
	    continue;

	  const pred_info &x2 = b_chain[0];
	  const pred_info &y2 = b_chain[1];
	  if (!is_neq_zero_form_p (x2) || !is_neq_zero_form_p (y2))
	    continue;

	  if ((pred_expr_equal_p (x2, gimple_assign_rhs1 (def_stmt))
	       && pred_expr_equal_p (y2, gimple_assign_rhs2 (def_stmt)))
	      || (pred_expr_equal_p (x2, gimple_assign_rhs2 (def_stmt))
		  && pred_expr_equal_p (y2, gimple_assign_rhs1 (def_stmt))))
	    {
	      /* Kill a_chain.  */
	      a_chain.release ();
	      simplified = true;
	      break;
	    }
	}
    }
  /* Now clean up the chain.  */
  if (simplified)
    {
      for (unsigned i = 0; i < n; i++)
	{
	  if (m_preds[i].is_empty ())
	    continue;
	  s_preds.safe_push (m_preds[i]);
	}

      m_preds.release ();
      m_preds = s_preds;
      s_preds = vNULL;
    }

  return simplified;
}

/* Simplify predicates in *THIS.  */

void
predicate::simplify (gimple *use_or_def, bool is_use)
{
  if (dump_file && dump_flags & TDF_DETAILS)
    {
      fprintf (dump_file, "Before simplication ");
      dump (dump_file, use_or_def, is_use ? "[USE]:\n" : "[DEF]:\n");
    }

  unsigned n = m_preds.length ();
  for (unsigned i = 0; i < n; i++)
    ::simplify_1 (m_preds[i]);

  if (n < 2)
    return;

  bool changed;
  do
    {
      changed = false;
      if (simplify_2 ())
	changed = true;

      if (simplify_3 ())
	changed = true;

      if (simplify_4 ())
	changed = true;
    }
  while (changed);
}

/* Attempt to normalize predicate chains by following UD chains by
   building up a big tree of either IOR operations or AND operations,
   and converting the IOR tree into a pred_chain_union or the BIT_AND
   tree into a pred_chain.
   Example:

  _3 = _2 RELOP1 _1;
  _6 = _5 RELOP2 _4;
  _9 = _8 RELOP3 _7;
  _10 = _3 | _6;
  _12 = _9 | _0;
  _t = _10 | _12;

  then _t != 0 will be normalized into a pred_chain_union

   (_2 RELOP1 _1) OR (_5 RELOP2 _4) OR (_8 RELOP3 _7) OR (_0 != 0)

   Similarly given:

  _3 = _2 RELOP1 _1;
  _6 = _5 RELOP2 _4;
  _9 = _8 RELOP3 _7;
  _10 = _3 & _6;
  _12 = _9 & _0;

  then _t != 0 will be normalized into a pred_chain:
  (_2 RELOP1 _1) AND (_5 RELOP2 _4) AND (_8 RELOP3 _7) AND (_0 != 0)
  */

/* Normalize predicate PRED:
   1) if PRED can no longer be normalized, append it to *THIS.
   2) otherwise if PRED is of the form x != 0, follow x's definition
      and put normalized predicates into WORK_LIST.  */

void
predicate::normalize (pred_chain *norm_chain,
		      pred_info pred,
		      tree_code and_or_code,
		      pred_chain *work_list,
		      hash_set<tree> *mark_set)
{
  if (!is_neq_zero_form_p (pred))
    {
      if (and_or_code == BIT_IOR_EXPR)
	push_pred (pred);
      else
	norm_chain->safe_push (pred);
      return;
    }

  gimple *def_stmt = SSA_NAME_DEF_STMT (pred.pred_lhs);

  if (gimple_code (def_stmt) == GIMPLE_PHI
      && is_degenerate_phi (def_stmt, &pred))
    /* PRED has been modified above.  */
    work_list->safe_push (pred);
  else if (gimple_code (def_stmt) == GIMPLE_PHI && and_or_code == BIT_IOR_EXPR)
    {
      unsigned n = gimple_phi_num_args (def_stmt);

      /* Punt for a nonzero constant.  The predicate should be one guarding
	 the phi edge.  */
      for (unsigned i = 0; i < n; ++i)
	{
	  tree op = gimple_phi_arg_def (def_stmt, i);
	  if (TREE_CODE (op) == INTEGER_CST && !integer_zerop (op))
	    {
	      push_pred (pred);
	      return;
	    }
	}

      for (unsigned i = 0; i < n; ++i)
	{
	  tree op = gimple_phi_arg_def (def_stmt, i);
	  if (integer_zerop (op))
	    continue;

	  push_to_worklist (op, work_list, mark_set);
	}
    }
  else if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
    {
      if (and_or_code == BIT_IOR_EXPR)
	push_pred (pred);
      else
	norm_chain->safe_push (pred);
    }
  else if (gimple_assign_rhs_code (def_stmt) == and_or_code)
    {
      /* Avoid splitting up bit manipulations like x & 3 or y | 1.  */
      if (is_gimple_min_invariant (gimple_assign_rhs2 (def_stmt)))
	{
	  /* But treat x & 3 as a condition.  */
	  if (and_or_code == BIT_AND_EXPR)
	    {
	      pred_info n_pred;
	      n_pred.pred_lhs = gimple_assign_rhs1 (def_stmt);
	      n_pred.pred_rhs = gimple_assign_rhs2 (def_stmt);
	      n_pred.cond_code = and_or_code;
	      n_pred.invert = false;
	      norm_chain->safe_push (n_pred);
	    }
	}
      else
	{
	  push_to_worklist (gimple_assign_rhs1 (def_stmt), work_list, mark_set);
	  push_to_worklist (gimple_assign_rhs2 (def_stmt), work_list, mark_set);
	}
    }
  else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
	   == tcc_comparison)
    {
      pred_info n_pred = get_pred_info_from_cmp (def_stmt);
      if (and_or_code == BIT_IOR_EXPR)
	push_pred (n_pred);
      else
	norm_chain->safe_push (n_pred);
    }
  else
    {
      if (and_or_code == BIT_IOR_EXPR)
	push_pred (pred);
      else
	norm_chain->safe_push (pred);
    }
}

/* Normalize PRED and store the normalized predicates in THIS->M_PREDS.  */

void
predicate::normalize (const pred_info &pred)
{
  if (!is_neq_zero_form_p (pred))
    {
      push_pred (pred);
      return;
    }

  tree_code and_or_code = ERROR_MARK;

  gimple *def_stmt = SSA_NAME_DEF_STMT (pred.pred_lhs);
  if (gimple_code (def_stmt) == GIMPLE_ASSIGN)
    and_or_code = gimple_assign_rhs_code (def_stmt);
  if (and_or_code != BIT_IOR_EXPR && and_or_code != BIT_AND_EXPR)
    {
      if (TREE_CODE_CLASS (and_or_code) == tcc_comparison)
	{
	  pred_info n_pred = get_pred_info_from_cmp (def_stmt);
	  push_pred (n_pred);
	}
      else
	push_pred (pred);
      return;
    }


  pred_chain norm_chain = vNULL;
  pred_chain work_list = vNULL;
  work_list.safe_push (pred);
  hash_set<tree> mark_set;

  while (!work_list.is_empty ())
    {
      pred_info a_pred = work_list.pop ();
      normalize (&norm_chain, a_pred, and_or_code, &work_list, &mark_set);
    }

  if (and_or_code == BIT_AND_EXPR)
    m_preds.safe_push (norm_chain);

  work_list.release ();
}

/* Normalize a single predicate PRED_CHAIN and append it to *THIS.  */

void
predicate::normalize (const pred_chain &chain)
{
  pred_chain work_list = vNULL;
  hash_set<tree> mark_set;
  for (unsigned i = 0; i < chain.length (); i++)
    {
      work_list.safe_push (chain[i]);
      mark_set.add (chain[i].pred_lhs);
    }

  /* Normalized chain of predicates built up below.  */
  pred_chain norm_chain = vNULL;
  while (!work_list.is_empty ())
    {
      pred_info pi = work_list.pop ();
      predicate pred;
      /* The predicate object is not modified here, only NORM_CHAIN and
	 WORK_LIST are appended to.  */
      pred.normalize (&norm_chain, pi, BIT_AND_EXPR, &work_list, &mark_set);
    }

  m_preds.safe_push (norm_chain);
  work_list.release ();
}

/* Normalize predicate chains in THIS.  */

void
predicate::normalize (gimple *use_or_def, bool is_use)
{
  if (dump_file && dump_flags & TDF_DETAILS)
    {
      fprintf (dump_file, "Before normalization ");
      dump (dump_file, use_or_def, is_use ? "[USE]:\n" : "[DEF]:\n");
    }

  predicate norm_preds;
  for (unsigned i = 0; i < m_preds.length (); i++)
    {
      if (m_preds[i].length () != 1)
	norm_preds.normalize (m_preds[i]);
      else
	norm_preds.normalize (m_preds[i][0]);
    }

  *this = norm_preds;

  if (dump_file)
    {
      fprintf (dump_file, "After normalization ");
      dump (dump_file, use_or_def, is_use ? "[USE]:\n" : "[DEF]:\n");
    }
}

/* Convert the chains of control dependence edges into a set of predicates.
   A control dependence chain is represented by a vector edges.  DEP_CHAINS
   points to an array of NUM_CHAINS dependence chains. One edge in
   a dependence chain is mapped to predicate expression represented by
   pred_info type.  One dependence chain is converted to a composite
   predicate that is the result of AND operation of pred_info mapped to
   each edge.  A composite predicate is represented by a vector of
   pred_info.  Sets M_PREDS to the resulting composite predicates.  */

void
predicate::init_from_control_deps (const vec<edge> *dep_chains,
				   unsigned num_chains, bool is_use)
{
  gcc_assert (is_empty ());

  if (num_chains == 0)
    return;

  if (DEBUG_PREDICATE_ANALYZER && dump_file)
    fprintf (dump_file, "init_from_control_deps [%s] {%s}:\n",
	     is_use ? "USE" : "DEF",
	     format_edge_vecs (dep_chains, num_chains).c_str ());

  /* Convert the control dependency chain into a set of predicates.  */
  m_preds.reserve (num_chains);

  for (unsigned i = 0; i < num_chains; i++)
    {
      /* One path through the CFG represents a logical conjunction
	 of the predicates.  */
      const vec<edge> &path = dep_chains[i];

      bool has_valid_pred = false;
      /* The chain of predicates guarding the definition along this path.  */
      pred_chain t_chain{ };
      for (unsigned j = 0; j < path.length (); j++)
	{
	  edge e = path[j];
	  basic_block guard_bb = e->src;

	  gcc_assert (!empty_block_p (guard_bb) && !single_succ_p (guard_bb));

	  /* Skip this edge if it is bypassing an abort - when the
	     condition is not satisfied we are neither reaching the
	     definition nor the use so it isn't meaningful.  Note if
	     we are processing the use predicate the condition is
	     meaningful.  See PR65244.  */
	  if (!is_use && EDGE_COUNT (e->src->succs) == 2)
	    {
	      edge e1;
	      edge_iterator ei1;
	      bool skip = false;

	      FOR_EACH_EDGE (e1, ei1, e->src->succs)
		{
		  if (EDGE_COUNT (e1->dest->succs) == 0)
		    {
		      skip = true;
		      break;
		    }
		}
	      if (skip)
		{
		  has_valid_pred = true;
		  continue;
		}
	    }
	  /* Get the conditional controlling the bb exit edge.  */
	  gimple *cond_stmt = last_stmt (guard_bb);
	  if (gimple_code (cond_stmt) == GIMPLE_COND)
	    {
	      /* The true edge corresponds to the uninteresting condition.
		 Add the negated predicate(s) for the edge to record
		 the interesting condition.  */
	      pred_info one_pred;
	      one_pred.pred_lhs = gimple_cond_lhs (cond_stmt);
	      one_pred.pred_rhs = gimple_cond_rhs (cond_stmt);
	      one_pred.cond_code = gimple_cond_code (cond_stmt);
	      one_pred.invert = !!(e->flags & EDGE_FALSE_VALUE);

	      t_chain.safe_push (one_pred);

	      if (DEBUG_PREDICATE_ANALYZER && dump_file)
		{
		  fprintf (dump_file, "%d -> %d: one_pred = ",
			   e->src->index, e->dest->index);
		  dump_pred_info (dump_file, one_pred);
		  fputc ('\n', dump_file);
		}

	      has_valid_pred = true;
	    }
	  else if (gswitch *gs = dyn_cast<gswitch *> (cond_stmt))
	    {
	      /* Find the case label, but avoid quadratic behavior.  */
	      tree l = get_cases_for_edge (e, gs);
	      /* If more than one label reaches this block or the case
		 label doesn't have a contiguous range of values (like the
		 default one) fail.  */
	      if (!l || CASE_CHAIN (l) || !CASE_LOW (l))
		has_valid_pred = false;
	      else if (!CASE_HIGH (l)
		      || operand_equal_p (CASE_LOW (l), CASE_HIGH (l)))
		{
		  pred_info one_pred;
		  one_pred.pred_lhs = gimple_switch_index (gs);
		  one_pred.pred_rhs = CASE_LOW (l);
		  one_pred.cond_code = EQ_EXPR;
		  one_pred.invert = false;
		  t_chain.safe_push (one_pred);
		  has_valid_pred = true;
		}
	      else
		{
		  /* Support a case label with a range with
		     two predicates.  We're overcommitting on
		     the MAX_CHAIN_LEN budget by at most a factor
		     of two here.  */
		  pred_info one_pred;
		  one_pred.pred_lhs = gimple_switch_index (gs);
		  one_pred.pred_rhs = CASE_LOW (l);
		  one_pred.cond_code = GE_EXPR;
		  one_pred.invert = false;
		  t_chain.safe_push (one_pred);
		  one_pred.pred_rhs = CASE_HIGH (l);
		  one_pred.cond_code = LE_EXPR;
		  t_chain.safe_push (one_pred);
		  has_valid_pred = true;
		}
	    }
	  else if (stmt_can_throw_internal (cfun, cond_stmt)
		   && !(e->flags & EDGE_EH))
	    /* Ignore the exceptional control flow and proceed as if
	       E were a fallthru without a controlling predicate for
	       both the USE (valid) and DEF (questionable) case.  */
	    has_valid_pred = true;
	  else
	    has_valid_pred = false;

	  /* For USE predicates we can drop components of the
	     AND chain.  */
	  if (!has_valid_pred && !is_use)
	    break;
	}

      /* For DEF predicates we have to drop components of the OR chain
	 on failure.  */
      if (!has_valid_pred && !is_use)
	{
	  t_chain.release ();
	  continue;
	}

      /* When we add || 1 simply prune the chain and return.  */
      if (t_chain.is_empty ())
	{
	  t_chain.release ();
	  for (auto chain : m_preds)
	    chain.release ();
	  m_preds.truncate (0);
	  break;
	}

      m_preds.quick_push (t_chain);
    }

  if (DEBUG_PREDICATE_ANALYZER && dump_file)
    dump (dump_file);
}

/* Store a PRED in *THIS.  */

void
predicate::push_pred (const pred_info &pred)
{
  pred_chain chain = vNULL;
  chain.safe_push (pred);
  m_preds.safe_push (chain);
}

/* Dump predicates in *THIS to F.  */

void
predicate::dump (FILE *f) const
{
  unsigned np = m_preds.length ();
  if (np == 0)
    {
      fprintf (f, "\tTRUE (empty)\n");
      return;
    }

  for (unsigned i = 0; i < np; i++)
    {
      if (i > 0)
	fprintf (f, "\tOR (");
      else
	fprintf (f, "\t(");
      dump_pred_chain (f, m_preds[i]);
      fprintf (f, ")\n");
    }
}

/* Dump predicates in *THIS to stderr.  */

void
predicate::debug () const
{
  dump (stderr);
}

/* Dump predicates in *THIS for STMT prepended by MSG to F.  */

void
predicate::dump (FILE *f, gimple *stmt, const char *msg) const
{
  fprintf (f, "%s", msg);
  if (stmt)
    {
      fputc ('\t', f);
      print_gimple_stmt (f, stmt, 0);
      fprintf (f, "  is conditional on:\n");
    }

  dump (f);
}

/* Initialize USE_PREDS with the predicates of the control dependence chains
   between the basic block DEF_BB that defines a variable of interst and
   USE_BB that uses the variable, respectively.  */

bool
uninit_analysis::init_use_preds (predicate &use_preds, basic_block def_bb,
				 basic_block use_bb)
{
  if (DEBUG_PREDICATE_ANALYZER && dump_file)
    fprintf (dump_file, "init_use_preds (def_bb = %u, use_bb = %u)\n",
	     def_bb->index, use_bb->index);

  gcc_assert (use_preds.is_empty ()
	      && dominated_by_p (CDI_DOMINATORS, use_bb, def_bb));

  /* Set CD_ROOT to the basic block closest to USE_BB that is the control
     equivalent of (is guarded by the same predicate as) DEF_BB that also
     dominates USE_BB.  This mimics the inner loop in
     compute_control_dep_chain.  */
  basic_block cd_root = def_bb;
  do
    {
      basic_block pdom = get_immediate_dominator (CDI_POST_DOMINATORS, cd_root);

      /* Stop at a loop exit which is also postdominating cd_root.  */
      if (single_pred_p (pdom) && !single_succ_p (cd_root))
	break;

      if (!dominated_by_p (CDI_DOMINATORS, pdom, cd_root)
	  || !dominated_by_p (CDI_DOMINATORS, use_bb, pdom))
	break;

      cd_root = pdom;
    }
  while (1);

  auto_bb_flag in_region (cfun);
  auto_vec<basic_block, 20> region (MIN (n_basic_blocks_for_fn (cfun),
					 param_uninit_control_dep_attempts));

  /* Set DEP_CHAINS to the set of edges between CD_ROOT and USE_BB.
     Each DEP_CHAINS element is a series of edges whose conditions
     are logical conjunctions.  Together, the DEP_CHAINS vector is
     used below to initialize an OR expression of the conjunctions.  */
  unsigned num_chains = 0;
  auto_vec<edge> dep_chains[MAX_NUM_CHAINS];

  if (!dfs_mark_dominating_region (use_bb, cd_root, in_region, region)
      || !compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains,
				     in_region))
    {
      /* If the info in dep_chains is not complete we need to use a
	 conservative approximation for the use predicate.  */
      if (DEBUG_PREDICATE_ANALYZER && dump_file)
	fprintf (dump_file, "init_use_preds: dep_chain incomplete, using "
		 "conservative approximation\n");
      num_chains = 1;
      dep_chains[0].truncate (0);
      simple_control_dep_chain (dep_chains[0], cd_root, use_bb);
    }

  /* Unmark the region.  */
  for (auto bb : region)
    bb->flags &= ~in_region;

  /* From the set of edges computed above initialize *THIS as the OR
     condition under which the definition in DEF_BB is used in USE_BB.
     Each OR subexpression is represented by one element of DEP_CHAINS,
     where each element consists of a series of AND subexpressions.  */
  use_preds.init_from_control_deps (dep_chains, num_chains, true);
  return !use_preds.is_empty ();
}

/* Release resources in *THIS.  */

predicate::~predicate ()
{
  unsigned n = m_preds.length ();
  for (unsigned i = 0; i != n; ++i)
    m_preds[i].release ();
  m_preds.release ();
}

/* Copy-assign RHS to *THIS.  */

predicate&
predicate::operator= (const predicate &rhs)
{
  if (this == &rhs)
    return *this;

  unsigned n = m_preds.length ();
  for (unsigned i = 0; i != n; ++i)
    m_preds[i].release ();
  m_preds.release ();

  n = rhs.m_preds.length ();
  for (unsigned i = 0; i != n; ++i)
    {
      const pred_chain &chain = rhs.m_preds[i];
      m_preds.safe_push (chain.copy ());
    }

  return *this;
}

/* For each use edge of PHI, compute all control dependence chains
   and convert those to the composite predicates in M_PREDS.
   Return true if a nonempty predicate has been obtained.  */

bool
uninit_analysis::init_from_phi_def (gphi *phi)
{
  gcc_assert (m_phi_def_preds.is_empty ());

  basic_block phi_bb = gimple_bb (phi);
  /* Find the closest dominating bb to be the control dependence root.  */
  basic_block cd_root = get_immediate_dominator (CDI_DOMINATORS, phi_bb);
  if (!cd_root)
    return false;

  /* Set DEF_EDGES to the edges to the PHI from the bb's that provide
     definitions of each of the PHI operands for which M_EVAL is false.  */
  auto_vec<edge> def_edges;
  hash_set<gimple *> visited_phis;
  collect_phi_def_edges (phi, cd_root, &def_edges, &visited_phis);

  unsigned nedges = def_edges.length ();
  if (nedges == 0)
    return false;

  auto_bb_flag in_region (cfun);
  auto_vec<basic_block, 20> region (MIN (n_basic_blocks_for_fn (cfun),
					 param_uninit_control_dep_attempts));
  /* Pre-mark the PHI incoming edges PHI block to make sure we only walk
     interesting edges from there.  */
  for (unsigned i = 0; i < nedges; i++)
    {
      if (!(def_edges[i]->dest->flags & in_region))
	{
	  if (!region.space (1))
	    break;
	  def_edges[i]->dest->flags |= in_region;
	  region.quick_push (def_edges[i]->dest);
	}
    }
  for (unsigned i = 0; i < nedges; i++)
    if (!dfs_mark_dominating_region (def_edges[i]->src, cd_root,
				     in_region, region))
      break;

  unsigned num_chains = 0;
  auto_vec<edge> dep_chains[MAX_NUM_CHAINS];
  for (unsigned i = 0; i < nedges; i++)
    {
      edge e = def_edges[i];
      unsigned prev_nc = num_chains;
      bool complete_p = compute_control_dep_chain (cd_root, e->src, dep_chains,
						   &num_chains, in_region);

      /* Update the newly added chains with the phi operand edge.  */
      if (EDGE_COUNT (e->src->succs) > 1)
	{
	  if (complete_p
	      && prev_nc == num_chains
	      && num_chains < MAX_NUM_CHAINS)
	    /* We can only add a chain for the PHI operand edge when the
	       collected info was complete, otherwise the predicate may
	       not be conservative.  */
	    dep_chains[num_chains++] = vNULL;
	  for (unsigned j = prev_nc; j < num_chains; j++)
	    dep_chains[j].safe_push (e);
	}
    }

  /* Unmark the region.  */
  for (auto bb : region)
    bb->flags &= ~in_region;

  /* Convert control dependence chains to the predicate in *THIS under
     which the PHI operands are defined to values for which M_EVAL is
     false.  */
  m_phi_def_preds.init_from_control_deps (dep_chains, num_chains, false);
  return !m_phi_def_preds.is_empty ();
}

/* Compute the predicates that guard the use USE_STMT and check if
   the incoming paths that have an empty (or possibly empty) definition
   can be pruned.  Return true if it can be determined that the use of
   PHI's def in USE_STMT is guarded by a predicate set that does not
   overlap with the predicate sets of all runtime paths that do not
   have a definition.

   Return false if the use is not guarded or if it cannot be determined.
   USE_BB is the bb of the use (for phi operand use, the bb is not the bb
   of the phi stmt, but the source bb of the operand edge).

   OPNDS is a bitmap with a bit set for each PHI operand of interest.

   THIS->M_PREDS contains the (memoized) defining predicate chains of
   a PHI.  If THIS->M_PREDS is empty, the PHI's defining predicate
   chains are computed and stored into THIS->M_PREDS as needed.

   VISITED_PHIS is a pointer set of phis being visited.  */

bool
uninit_analysis::is_use_guarded (gimple *use_stmt, basic_block use_bb,
				 gphi *phi, unsigned opnds,
				 hash_set<gphi *> *visited)
{
  if (visited->add (phi))
    return false;

  /* The basic block where the PHI is defined.  */
  basic_block def_bb = gimple_bb (phi);

  /* Try to build the predicate expression under which the PHI flows
     into its use.  This will be empty if the PHI is defined and used
     in the same bb.  */
  predicate use_preds;
  if (!init_use_preds (use_preds, def_bb, use_bb))
    return false;

  use_preds.simplify (use_stmt, /*is_use=*/true);
  use_preds.normalize (use_stmt, /*is_use=*/true);

  /* Try to prune the dead incoming phi edges.  */
  if (!overlap (phi, opnds, visited, use_preds))
    {
      if (DEBUG_PREDICATE_ANALYZER && dump_file)
	fputs ("found predicate overlap\n", dump_file);

      return true;
    }

  if (m_phi_def_preds.is_empty ())
    {
      /* Lazily initialize *THIS from PHI.  */
      if (!init_from_phi_def (phi))
	return false;

      m_phi_def_preds.simplify (phi);
      m_phi_def_preds.normalize (phi);
    }

  /* Return true if the predicate guarding the valid definition (i.e.,
     *THIS) is a superset of the predicate guarding the use (i.e.,
     USE_PREDS).  */
  if (m_phi_def_preds.superset_of (use_preds))
    return true;

  return false;
}

/* Public interface to the above. */

bool
uninit_analysis::is_use_guarded (gimple *stmt, basic_block use_bb, gphi *phi,
				 unsigned opnds)
{
  hash_set<gphi *> visited;
  return is_use_guarded (stmt, use_bb, phi, opnds, &visited);
}

