/* If-conversion support.
   Copyright (C) 2000-2021 Free Software Foundation, Inc.

   This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "expmed.h"
#include "optabs.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"

#include "cfgrtl.h"
#include "cfganal.h"
#include "cfgcleanup.h"
#include "expr.h"
#include "output.h"
#include "cfgloop.h"
#include "tree-pass.h"
#include "dbgcnt.h"
#include "shrink-wrap.h"
#include "rtl-iter.h"
#include "ifcvt.h"

#ifndef MAX_CONDITIONAL_EXECUTE
#define MAX_CONDITIONAL_EXECUTE \
  (BRANCH_COST (optimize_function_for_speed_p (cfun), false) \
   + 1)
#endif

#define IFCVT_MULTIPLE_DUMPS 1

#define NULL_BLOCK	((basic_block) NULL)

/* True if after combine pass.  */
static bool ifcvt_after_combine;

/* True if the target has the cbranchcc4 optab.  */
static bool have_cbranchcc4;

/* # of IF-THEN or IF-THEN-ELSE blocks we looked at  */
static int num_possible_if_blocks;

/* # of IF-THEN or IF-THEN-ELSE blocks were converted to conditional
   execution.  */
static int num_updated_if_blocks;

/* # of changes made.  */
static int num_true_changes;

/* Whether conditional execution changes were made.  */
static int cond_exec_changed_p;

/* Forward references.  */
static int count_bb_insns (const_basic_block);
static bool cheap_bb_rtx_cost_p (const_basic_block, profile_probability, int);
static rtx_insn *first_active_insn (basic_block);
static rtx_insn *last_active_insn (basic_block, int);
static rtx_insn *find_active_insn_before (basic_block, rtx_insn *);
static rtx_insn *find_active_insn_after (basic_block, rtx_insn *);
static basic_block block_fallthru (basic_block);
static rtx cond_exec_get_condition (rtx_insn *);
static rtx noce_get_condition (rtx_insn *, rtx_insn **, bool);
static int noce_operand_ok (const_rtx);
static void merge_if_block (ce_if_block *);
static int find_cond_trap (basic_block, edge, edge);
static basic_block find_if_header (basic_block, int);
static int block_jumps_and_fallthru_p (basic_block, basic_block);
static int noce_find_if_block (basic_block, edge, edge, int);
static int cond_exec_find_if_block (ce_if_block *);
static int find_if_case_1 (basic_block, edge, edge);
static int find_if_case_2 (basic_block, edge, edge);
static int dead_or_predicable (basic_block, basic_block, basic_block,
			       edge, int);
static void noce_emit_move_insn (rtx, rtx);
static rtx_insn *block_has_only_trap (basic_block);

/* Count the number of non-jump active insns in BB.  */

static int
count_bb_insns (const_basic_block bb)
{
  int count = 0;
  rtx_insn *insn = BB_HEAD (bb);

  while (1)
    {
      if (active_insn_p (insn) && !JUMP_P (insn))
	count++;

      if (insn == BB_END (bb))
	break;
      insn = NEXT_INSN (insn);
    }

  return count;
}

/* Determine whether the total insn_cost on non-jump insns in
   basic block BB is less than MAX_COST.  This function returns
   false if the cost of any instruction could not be estimated. 

   The cost of the non-jump insns in BB is scaled by REG_BR_PROB_BASE
   as those insns are being speculated.  MAX_COST is scaled with SCALE
   plus a small fudge factor.  */

static bool
cheap_bb_rtx_cost_p (const_basic_block bb,
		     profile_probability prob, int max_cost)
{
  int count = 0;
  rtx_insn *insn = BB_HEAD (bb);
  bool speed = optimize_bb_for_speed_p (bb);
  int scale = prob.initialized_p () ? prob.to_reg_br_prob_base ()
	      : REG_BR_PROB_BASE;

  /* Set scale to REG_BR_PROB_BASE to void the identical scaling
     applied to insn_cost when optimizing for size.  Only do
     this after combine because if-conversion might interfere with
     passes before combine.

     Use optimize_function_for_speed_p instead of the pre-defined
     variable speed to make sure it is set to same value for all
     basic blocks in one if-conversion transformation.  */
  if (!optimize_function_for_speed_p (cfun) && ifcvt_after_combine)
    scale = REG_BR_PROB_BASE;
  /* Our branch probability/scaling factors are just estimates and don't
     account for cases where we can get speculation for free and other
     secondary benefits.  So we fudge the scale factor to make speculating
     appear a little more profitable when optimizing for performance.  */
  else
    scale += REG_BR_PROB_BASE / 8;


  max_cost *= scale;

  while (1)
    {
      if (NONJUMP_INSN_P (insn))
	{
	  int cost = insn_cost (insn, speed) * REG_BR_PROB_BASE;
	  if (cost == 0)
	    return false;

	  /* If this instruction is the load or set of a "stack" register,
	     such as a floating point register on x87, then the cost of
	     speculatively executing this insn may need to include
	     the additional cost of popping its result off of the
	     register stack.  Unfortunately, correctly recognizing and
	     accounting for this additional overhead is tricky, so for
	     now we simply prohibit such speculative execution.  */
#ifdef STACK_REGS
	  {
	    rtx set = single_set (insn);
	    if (set && STACK_REG_P (SET_DEST (set)))
	      return false;
	  }
#endif

	  count += cost;
	  if (count >= max_cost)
	    return false;
	}
      else if (CALL_P (insn))
	return false;

      if (insn == BB_END (bb))
	break;
      insn = NEXT_INSN (insn);
    }

  return true;
}

/* Return the first non-jump active insn in the basic block.  */

static rtx_insn *
first_active_insn (basic_block bb)
{
  rtx_insn *insn = BB_HEAD (bb);

  if (LABEL_P (insn))
    {
      if (insn == BB_END (bb))
	return NULL;
      insn = NEXT_INSN (insn);
    }

  while (NOTE_P (insn) || DEBUG_INSN_P (insn))
    {
      if (insn == BB_END (bb))
	return NULL;
      insn = NEXT_INSN (insn);
    }

  if (JUMP_P (insn))
    return NULL;

  return insn;
}

/* Return the last non-jump active (non-jump) insn in the basic block.  */

static rtx_insn *
last_active_insn (basic_block bb, int skip_use_p)
{
  rtx_insn *insn = BB_END (bb);
  rtx_insn *head = BB_HEAD (bb);

  while (NOTE_P (insn)
	 || JUMP_P (insn)
	 || DEBUG_INSN_P (insn)
	 || (skip_use_p
	     && NONJUMP_INSN_P (insn)
	     && GET_CODE (PATTERN (insn)) == USE))
    {
      if (insn == head)
	return NULL;
      insn = PREV_INSN (insn);
    }

  if (LABEL_P (insn))
    return NULL;

  return insn;
}

/* Return the active insn before INSN inside basic block CURR_BB. */

static rtx_insn *
find_active_insn_before (basic_block curr_bb, rtx_insn *insn)
{
  if (!insn || insn == BB_HEAD (curr_bb))
    return NULL;

  while ((insn = PREV_INSN (insn)) != NULL_RTX)
    {
      if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
        break;

      /* No other active insn all the way to the start of the basic block. */
      if (insn == BB_HEAD (curr_bb))
        return NULL;
    }

  return insn;
}

/* Return the active insn after INSN inside basic block CURR_BB. */

static rtx_insn *
find_active_insn_after (basic_block curr_bb, rtx_insn *insn)
{
  if (!insn || insn == BB_END (curr_bb))
    return NULL;

  while ((insn = NEXT_INSN (insn)) != NULL_RTX)
    {
      if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
        break;

      /* No other active insn all the way to the end of the basic block. */
      if (insn == BB_END (curr_bb))
        return NULL;
    }

  return insn;
}

/* Return the basic block reached by falling though the basic block BB.  */

static basic_block
block_fallthru (basic_block bb)
{
  edge e = find_fallthru_edge (bb->succs);

  return (e) ? e->dest : NULL_BLOCK;
}

/* Return true if RTXs A and B can be safely interchanged.  */

static bool
rtx_interchangeable_p (const_rtx a, const_rtx b)
{
  if (!rtx_equal_p (a, b))
    return false;

  if (GET_CODE (a) != MEM)
    return true;

  /* A dead type-unsafe memory reference is legal, but a live type-unsafe memory
     reference is not.  Interchanging a dead type-unsafe memory reference with
     a live type-safe one creates a live type-unsafe memory reference, in other
     words, it makes the program illegal.
     We check here conservatively whether the two memory references have equal
     memory attributes.  */

  return mem_attrs_eq_p (get_mem_attrs (a), get_mem_attrs (b));
}


/* Go through a bunch of insns, converting them to conditional
   execution format if possible.  Return TRUE if all of the non-note
   insns were processed.  */

static int
cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED,
			 /* if block information */rtx_insn *start,
			 /* first insn to look at */rtx end,
			 /* last insn to look at */rtx test,
			 /* conditional execution test */profile_probability
							    prob_val,
			 /* probability of branch taken. */int mod_ok)
{
  int must_be_last = FALSE;
  rtx_insn *insn;
  rtx xtest;
  rtx pattern;

  if (!start || !end)
    return FALSE;

  for (insn = start; ; insn = NEXT_INSN (insn))
    {
      /* dwarf2out can't cope with conditional prologues.  */
      if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END)
	return FALSE;

      if (NOTE_P (insn) || DEBUG_INSN_P (insn))
	goto insn_done;

      gcc_assert (NONJUMP_INSN_P (insn) || CALL_P (insn));

      /* dwarf2out can't cope with conditional unwind info.  */
      if (RTX_FRAME_RELATED_P (insn))
	return FALSE;

      /* Remove USE insns that get in the way.  */
      if (reload_completed && GET_CODE (PATTERN (insn)) == USE)
	{
	  /* ??? Ug.  Actually unlinking the thing is problematic,
	     given what we'd have to coordinate with our callers.  */
	  SET_INSN_DELETED (insn);
	  goto insn_done;
	}

      /* Last insn wasn't last?  */
      if (must_be_last)
	return FALSE;

      if (modified_in_p (test, insn))
	{
	  if (!mod_ok)
	    return FALSE;
	  must_be_last = TRUE;
	}

      /* Now build the conditional form of the instruction.  */
      pattern = PATTERN (insn);
      xtest = copy_rtx (test);

      /* If this is already a COND_EXEC, rewrite the test to be an AND of the
         two conditions.  */
      if (GET_CODE (pattern) == COND_EXEC)
	{
	  if (GET_MODE (xtest) != GET_MODE (COND_EXEC_TEST (pattern)))
	    return FALSE;

	  xtest = gen_rtx_AND (GET_MODE (xtest), xtest,
			       COND_EXEC_TEST (pattern));
	  pattern = COND_EXEC_CODE (pattern);
	}

      pattern = gen_rtx_COND_EXEC (VOIDmode, xtest, pattern);

      /* If the machine needs to modify the insn being conditionally executed,
         say for example to force a constant integer operand into a temp
         register, do so here.  */
#ifdef IFCVT_MODIFY_INSN
      IFCVT_MODIFY_INSN (ce_info, pattern, insn);
      if (! pattern)
	return FALSE;
#endif

      validate_change (insn, &PATTERN (insn), pattern, 1);

      if (CALL_P (insn) && prob_val.initialized_p ())
	validate_change (insn, &REG_NOTES (insn),
			 gen_rtx_INT_LIST ((machine_mode) REG_BR_PROB,
					   prob_val.to_reg_br_prob_note (),
					   REG_NOTES (insn)), 1);

    insn_done:
      if (insn == end)
	break;
    }

  return TRUE;
}

/* Return the condition for a jump.  Do not do any special processing.  */

static rtx
cond_exec_get_condition (rtx_insn *jump)
{
  rtx test_if, cond;

  if (any_condjump_p (jump))
    test_if = SET_SRC (pc_set (jump));
  else
    return NULL_RTX;
  cond = XEXP (test_if, 0);

  /* If this branches to JUMP_LABEL when the condition is false,
     reverse the condition.  */
  if (GET_CODE (XEXP (test_if, 2)) == LABEL_REF
      && label_ref_label (XEXP (test_if, 2)) == JUMP_LABEL (jump))
    {
      enum rtx_code rev = reversed_comparison_code (cond, jump);
      if (rev == UNKNOWN)
	return NULL_RTX;

      cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
			     XEXP (cond, 1));
    }

  return cond;
}

/* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
   to conditional execution.  Return TRUE if we were successful at
   converting the block.  */

static int
cond_exec_process_if_block (ce_if_block * ce_info,
			    /* if block information */int do_multiple_p)
{
  basic_block test_bb = ce_info->test_bb;	/* last test block */
  basic_block then_bb = ce_info->then_bb;	/* THEN */
  basic_block else_bb = ce_info->else_bb;	/* ELSE or NULL */
  rtx test_expr;		/* expression in IF_THEN_ELSE that is tested */
  rtx_insn *then_start;		/* first insn in THEN block */
  rtx_insn *then_end;		/* last insn + 1 in THEN block */
  rtx_insn *else_start = NULL;	/* first insn in ELSE block or NULL */
  rtx_insn *else_end = NULL;	/* last insn + 1 in ELSE block */
  int max;			/* max # of insns to convert.  */
  int then_mod_ok;		/* whether conditional mods are ok in THEN */
  rtx true_expr;		/* test for else block insns */
  rtx false_expr;		/* test for then block insns */
  profile_probability true_prob_val;/* probability of else block */
  profile_probability false_prob_val;/* probability of then block */
  rtx_insn *then_last_head = NULL;	/* Last match at the head of THEN */
  rtx_insn *else_last_head = NULL;	/* Last match at the head of ELSE */
  rtx_insn *then_first_tail = NULL;	/* First match at the tail of THEN */
  rtx_insn *else_first_tail = NULL;	/* First match at the tail of ELSE */
  int then_n_insns, else_n_insns, n_insns;
  enum rtx_code false_code;
  rtx note;

  /* If test is comprised of && or || elements, and we've failed at handling
     all of them together, just use the last test if it is the special case of
     && elements without an ELSE block.  */
  if (!do_multiple_p && ce_info->num_multiple_test_blocks)
    {
      if (else_bb || ! ce_info->and_and_p)
	return FALSE;

      ce_info->test_bb = test_bb = ce_info->last_test_bb;
      ce_info->num_multiple_test_blocks = 0;
      ce_info->num_and_and_blocks = 0;
      ce_info->num_or_or_blocks = 0;
    }

  /* Find the conditional jump to the ELSE or JOIN part, and isolate
     the test.  */
  test_expr = cond_exec_get_condition (BB_END (test_bb));
  if (! test_expr)
    return FALSE;

  /* If the conditional jump is more than just a conditional jump,
     then we cannot do conditional execution conversion on this block.  */
  if (! onlyjump_p (BB_END (test_bb)))
    return FALSE;

  /* Collect the bounds of where we're to search, skipping any labels, jumps
     and notes at the beginning and end of the block.  Then count the total
     number of insns and see if it is small enough to convert.  */
  then_start = first_active_insn (then_bb);
  then_end = last_active_insn (then_bb, TRUE);
  then_n_insns = ce_info->num_then_insns = count_bb_insns (then_bb);
  n_insns = then_n_insns;
  max = MAX_CONDITIONAL_EXECUTE;

  if (else_bb)
    {
      int n_matching;

      max *= 2;
      else_start = first_active_insn (else_bb);
      else_end = last_active_insn (else_bb, TRUE);
      else_n_insns = ce_info->num_else_insns = count_bb_insns (else_bb);
      n_insns += else_n_insns;

      /* Look for matching sequences at the head and tail of the two blocks,
	 and limit the range of insns to be converted if possible.  */
      n_matching = flow_find_cross_jump (then_bb, else_bb,
					 &then_first_tail, &else_first_tail,
					 NULL);
      if (then_first_tail == BB_HEAD (then_bb))
	then_start = then_end = NULL;
      if (else_first_tail == BB_HEAD (else_bb))
	else_start = else_end = NULL;

      if (n_matching > 0)
	{
	  if (then_end)
	    then_end = find_active_insn_before (then_bb, then_first_tail);
	  if (else_end)
	    else_end = find_active_insn_before (else_bb, else_first_tail);
	  n_insns -= 2 * n_matching;
	}

      if (then_start
	  && else_start
	  && then_n_insns > n_matching
	  && else_n_insns > n_matching)
	{
	  int longest_match = MIN (then_n_insns - n_matching,
				   else_n_insns - n_matching);
	  n_matching
	    = flow_find_head_matching_sequence (then_bb, else_bb,
						&then_last_head,
						&else_last_head,
						longest_match);

	  if (n_matching > 0)
	    {
	      rtx_insn *insn;

	      /* We won't pass the insns in the head sequence to
		 cond_exec_process_insns, so we need to test them here
		 to make sure that they don't clobber the condition.  */
	      for (insn = BB_HEAD (then_bb);
		   insn != NEXT_INSN (then_last_head);
		   insn = NEXT_INSN (insn))
		if (!LABEL_P (insn) && !NOTE_P (insn)
		    && !DEBUG_INSN_P (insn)
		    && modified_in_p (test_expr, insn))
		  return FALSE;
	    }

	  if (then_last_head == then_end)
	    then_start = then_end = NULL;
	  if (else_last_head == else_end)
	    else_start = else_end = NULL;

	  if (n_matching > 0)
	    {
	      if (then_start)
		then_start = find_active_insn_after (then_bb, then_last_head);
	      if (else_start)
		else_start = find_active_insn_after (else_bb, else_last_head);
	      n_insns -= 2 * n_matching;
	    }
	}
    }

  if (n_insns > max)
    return FALSE;

  /* Map test_expr/test_jump into the appropriate MD tests to use on
     the conditionally executed code.  */

  true_expr = test_expr;

  false_code = reversed_comparison_code (true_expr, BB_END (test_bb));
  if (false_code != UNKNOWN)
    false_expr = gen_rtx_fmt_ee (false_code, GET_MODE (true_expr),
				 XEXP (true_expr, 0), XEXP (true_expr, 1));
  else
    false_expr = NULL_RTX;

#ifdef IFCVT_MODIFY_TESTS
  /* If the machine description needs to modify the tests, such as setting a
     conditional execution register from a comparison, it can do so here.  */
  IFCVT_MODIFY_TESTS (ce_info, true_expr, false_expr);

  /* See if the conversion failed.  */
  if (!true_expr || !false_expr)
    goto fail;
#endif

  note = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
  if (note)
    {
      true_prob_val = profile_probability::from_reg_br_prob_note (XINT (note, 0));
      false_prob_val = true_prob_val.invert ();
    }
  else
    {
      true_prob_val = profile_probability::uninitialized ();
      false_prob_val = profile_probability::uninitialized ();
    }

  /* If we have && or || tests, do them here.  These tests are in the adjacent
     blocks after the first block containing the test.  */
  if (ce_info->num_multiple_test_blocks > 0)
    {
      basic_block bb = test_bb;
      basic_block last_test_bb = ce_info->last_test_bb;

      if (! false_expr)
	goto fail;

      do
	{
	  rtx_insn *start, *end;
	  rtx t, f;
	  enum rtx_code f_code;

	  bb = block_fallthru (bb);
	  start = first_active_insn (bb);
	  end = last_active_insn (bb, TRUE);
	  if (start
	      && ! cond_exec_process_insns (ce_info, start, end, false_expr,
					    false_prob_val, FALSE))
	    goto fail;

	  /* If the conditional jump is more than just a conditional jump, then
	     we cannot do conditional execution conversion on this block.  */
	  if (! onlyjump_p (BB_END (bb)))
	    goto fail;

	  /* Find the conditional jump and isolate the test.  */
	  t = cond_exec_get_condition (BB_END (bb));
	  if (! t)
	    goto fail;

	  f_code = reversed_comparison_code (t, BB_END (bb));
	  if (f_code == UNKNOWN)
	    goto fail;

	  f = gen_rtx_fmt_ee (f_code, GET_MODE (t), XEXP (t, 0), XEXP (t, 1));
	  if (ce_info->and_and_p)
	    {
	      t = gen_rtx_AND (GET_MODE (t), true_expr, t);
	      f = gen_rtx_IOR (GET_MODE (t), false_expr, f);
	    }
	  else
	    {
	      t = gen_rtx_IOR (GET_MODE (t), true_expr, t);
	      f = gen_rtx_AND (GET_MODE (t), false_expr, f);
	    }

	  /* If the machine description needs to modify the tests, such as
	     setting a conditional execution register from a comparison, it can
	     do so here.  */
#ifdef IFCVT_MODIFY_MULTIPLE_TESTS
	  IFCVT_MODIFY_MULTIPLE_TESTS (ce_info, bb, t, f);

	  /* See if the conversion failed.  */
	  if (!t || !f)
	    goto fail;
#endif

	  true_expr = t;
	  false_expr = f;
	}
      while (bb != last_test_bb);
    }

  /* For IF-THEN-ELSE blocks, we don't allow modifications of the test
     on then THEN block.  */
  then_mod_ok = (else_bb == NULL_BLOCK);

  /* Go through the THEN and ELSE blocks converting the insns if possible
     to conditional execution.  */

  if (then_end
      && (! false_expr
	  || ! cond_exec_process_insns (ce_info, then_start, then_end,
					false_expr, false_prob_val,
					then_mod_ok)))
    goto fail;

  if (else_bb && else_end
      && ! cond_exec_process_insns (ce_info, else_start, else_end,
				    true_expr, true_prob_val, TRUE))
    goto fail;

  /* If we cannot apply the changes, fail.  Do not go through the normal fail
     processing, since apply_change_group will call cancel_changes.  */
  if (! apply_change_group ())
    {
#ifdef IFCVT_MODIFY_CANCEL
      /* Cancel any machine dependent changes.  */
      IFCVT_MODIFY_CANCEL (ce_info);
#endif
      return FALSE;
    }

#ifdef IFCVT_MODIFY_FINAL
  /* Do any machine dependent final modifications.  */
  IFCVT_MODIFY_FINAL (ce_info);
#endif

  /* Conversion succeeded.  */
  if (dump_file)
    fprintf (dump_file, "%d insn%s converted to conditional execution.\n",
	     n_insns, (n_insns == 1) ? " was" : "s were");

  /* Merge the blocks!  If we had matching sequences, make sure to delete one
     copy at the appropriate location first: delete the copy in the THEN branch
     for a tail sequence so that the remaining one is executed last for both
     branches, and delete the copy in the ELSE branch for a head sequence so
     that the remaining one is executed first for both branches.  */
  if (then_first_tail)
    {
      rtx_insn *from = then_first_tail;
      if (!INSN_P (from))
	from = find_active_insn_after (then_bb, from);
      delete_insn_chain (from, get_last_bb_insn (then_bb), false);
    }
  if (else_last_head)
    delete_insn_chain (first_active_insn (else_bb), else_last_head, false);

  merge_if_block (ce_info);
  cond_exec_changed_p = TRUE;
  return TRUE;

 fail:
#ifdef IFCVT_MODIFY_CANCEL
  /* Cancel any machine dependent changes.  */
  IFCVT_MODIFY_CANCEL (ce_info);
#endif

  cancel_changes (0);
  return FALSE;
}

static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int);
static int noce_try_move (struct noce_if_info *);
static int noce_try_ifelse_collapse (struct noce_if_info *);
static int noce_try_store_flag (struct noce_if_info *);
static int noce_try_addcc (struct noce_if_info *);
static int noce_try_store_flag_constants (struct noce_if_info *);
static int noce_try_store_flag_mask (struct noce_if_info *);
static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx,
			    rtx, rtx, rtx);
static int noce_try_cmove (struct noce_if_info *);
static int noce_try_cmove_arith (struct noce_if_info *);
static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **);
static int noce_try_minmax (struct noce_if_info *);
static int noce_try_abs (struct noce_if_info *);
static int noce_try_sign_mask (struct noce_if_info *);

/* Return the comparison code for reversed condition for IF_INFO,
   or UNKNOWN if reversing the condition is not possible.  */

static inline enum rtx_code
noce_reversed_cond_code (struct noce_if_info *if_info)
{
  if (if_info->rev_cond)
    return GET_CODE (if_info->rev_cond);
  return reversed_comparison_code (if_info->cond, if_info->jump);
}

/* Return true if SEQ is a good candidate as a replacement for the
   if-convertible sequence described in IF_INFO.
   This is the default implementation that targets can override
   through a target hook.  */

bool
default_noce_conversion_profitable_p (rtx_insn *seq,
				      struct noce_if_info *if_info)
{
  bool speed_p = if_info->speed_p;

  /* Cost up the new sequence.  */
  unsigned int cost = seq_cost (seq, speed_p);

  if (cost <= if_info->original_cost)
    return true;

  /* When compiling for size, we can make a reasonably accurately guess
     at the size growth.  When compiling for speed, use the maximum.  */
  return speed_p && cost <= if_info->max_seq_cost;
}

/* Helper function for noce_try_store_flag*.  */

static rtx
noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
		      int normalize)
{
  rtx cond = if_info->cond;
  int cond_complex;
  enum rtx_code code;

  cond_complex = (! general_operand (XEXP (cond, 0), VOIDmode)
		  || ! general_operand (XEXP (cond, 1), VOIDmode));

  /* If earliest == jump, or when the condition is complex, try to
     build the store_flag insn directly.  */

  if (cond_complex)
    {
      rtx set = pc_set (if_info->jump);
      cond = XEXP (SET_SRC (set), 0);
      if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
	  && label_ref_label (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (if_info->jump))
	reversep = !reversep;
      if (if_info->then_else_reversed)
	reversep = !reversep;
    }
  else if (reversep
	   && if_info->rev_cond
	   && general_operand (XEXP (if_info->rev_cond, 0), VOIDmode)
	   && general_operand (XEXP (if_info->rev_cond, 1), VOIDmode))
    {
      cond = if_info->rev_cond;
      reversep = false;
    }

  if (reversep)
    code = reversed_comparison_code (cond, if_info->jump);
  else
    code = GET_CODE (cond);

  if ((if_info->cond_earliest == if_info->jump || cond_complex)
      && (normalize == 0 || STORE_FLAG_VALUE == normalize))
    {
      rtx src = gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (cond, 0),
				XEXP (cond, 1));
      rtx set = gen_rtx_SET (x, src);

      start_sequence ();
      rtx_insn *insn = emit_insn (set);

      if (recog_memoized (insn) >= 0)
	{
	  rtx_insn *seq = get_insns ();
	  end_sequence ();
	  emit_insn (seq);

	  if_info->cond_earliest = if_info->jump;

	  return x;
	}

      end_sequence ();
    }

  /* Don't even try if the comparison operands or the mode of X are weird.  */
  if (cond_complex || !SCALAR_INT_MODE_P (GET_MODE (x)))
    return NULL_RTX;

  return emit_store_flag (x, code, XEXP (cond, 0),
			  XEXP (cond, 1), VOIDmode,
			  (code == LTU || code == LEU
			   || code == GEU || code == GTU), normalize);
}

/* Return true if X can be safely forced into a register by copy_to_mode_reg
   / force_operand.  */

static bool
noce_can_force_operand (rtx x)
{
  if (general_operand (x, VOIDmode))
    return true;
  if (SUBREG_P (x))
    {
      if (!noce_can_force_operand (SUBREG_REG (x)))
	return false;
      return true;
    }
  if (ARITHMETIC_P (x))
    {
      if (!noce_can_force_operand (XEXP (x, 0))
	  || !noce_can_force_operand (XEXP (x, 1)))
	return false;
      switch (GET_CODE (x))
	{
	case MULT:
	case DIV:
	case MOD:
	case UDIV:
	case UMOD:
	  return true;
	default:
	  return code_to_optab (GET_CODE (x));
	}
    }
  if (UNARY_P (x))
    {
      if (!noce_can_force_operand (XEXP (x, 0)))
	return false;
      switch (GET_CODE (x))
	{
	case ZERO_EXTEND:
	case SIGN_EXTEND:
	case TRUNCATE:
	case FLOAT_EXTEND:
	case FLOAT_TRUNCATE:
	case FIX:
	case UNSIGNED_FIX:
	case FLOAT:
	case UNSIGNED_FLOAT:
	  return true;
	default:
	  return code_to_optab (GET_CODE (x));
	}
    }
  return false;
}

/* Emit instruction to move an rtx, possibly into STRICT_LOW_PART.
   X is the destination/target and Y is the value to copy.  */

static void
noce_emit_move_insn (rtx x, rtx y)
{
  machine_mode outmode;
  rtx outer, inner;
  poly_int64 bitpos;

  if (GET_CODE (x) != STRICT_LOW_PART)
    {
      rtx_insn *seq, *insn;
      rtx target;
      optab ot;

      start_sequence ();
      /* Check that the SET_SRC is reasonable before calling emit_move_insn,
	 otherwise construct a suitable SET pattern ourselves.  */
      insn = (OBJECT_P (y) || CONSTANT_P (y) || GET_CODE (y) == SUBREG)
	     ? emit_move_insn (x, y)
	     : emit_insn (gen_rtx_SET (x, y));
      seq = get_insns ();
      end_sequence ();

      if (recog_memoized (insn) <= 0)
	{
	  if (GET_CODE (x) == ZERO_EXTRACT)
	    {
	      rtx op = XEXP (x, 0);
	      unsigned HOST_WIDE_INT size = INTVAL (XEXP (x, 1));
	      unsigned HOST_WIDE_INT start = INTVAL (XEXP (x, 2));

	      /* store_bit_field expects START to be relative to
		 BYTES_BIG_ENDIAN and adjusts this value for machines with
		 BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN.  In order to be able to
		 invoke store_bit_field again it is necessary to have the START
		 value from the first call.  */
	      if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
		{
		  if (MEM_P (op))
		    start = BITS_PER_UNIT - start - size;
		  else
		    {
		      gcc_assert (REG_P (op));
		      start = BITS_PER_WORD - start - size;
		    }
		}

	      gcc_assert (start < (MEM_P (op) ? BITS_PER_UNIT : BITS_PER_WORD));
	      store_bit_field (op, size, start, 0, 0, GET_MODE (x), y, false);
	      return;
	    }

	  switch (GET_RTX_CLASS (GET_CODE (y)))
	    {
	    case RTX_UNARY:
	      ot = code_to_optab (GET_CODE (y));
	      if (ot && noce_can_force_operand (XEXP (y, 0)))
		{
		  start_sequence ();
		  target = expand_unop (GET_MODE (y), ot, XEXP (y, 0), x, 0);
		  if (target != NULL_RTX)
		    {
		      if (target != x)
			emit_move_insn (x, target);
		      seq = get_insns ();
		    }
		  end_sequence ();
		}
	      break;

	    case RTX_BIN_ARITH:
	    case RTX_COMM_ARITH:
	      ot = code_to_optab (GET_CODE (y));
	      if (ot
		  && noce_can_force_operand (XEXP (y, 0))
		  && noce_can_force_operand (XEXP (y, 1)))
		{
		  start_sequence ();
		  target = expand_binop (GET_MODE (y), ot,
					 XEXP (y, 0), XEXP (y, 1),
					 x, 0, OPTAB_DIRECT);
		  if (target != NULL_RTX)
		    {
		      if (target != x)
			  emit_move_insn (x, target);
		      seq = get_insns ();
		    }
		  end_sequence ();
		}
	      break;

	    default:
	      break;
	    }
	}

      emit_insn (seq);
      return;
    }

  outer = XEXP (x, 0);
  inner = XEXP (outer, 0);
  outmode = GET_MODE (outer);
  bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
  store_bit_field (inner, GET_MODE_BITSIZE (outmode), bitpos,
		   0, 0, outmode, y, false);
}

/* Return the CC reg if it is used in COND.  */

static rtx
cc_in_cond (rtx cond)
{
  if (have_cbranchcc4 && cond
      && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_CC)
    return XEXP (cond, 0);

  return NULL_RTX;
}

/* Return sequence of instructions generated by if conversion.  This
   function calls end_sequence() to end the current stream, ensures
   that the instructions are unshared, recognizable non-jump insns.
   On failure, this function returns a NULL_RTX.  */

static rtx_insn *
end_ifcvt_sequence (struct noce_if_info *if_info)
{
  rtx_insn *insn;
  rtx_insn *seq = get_insns ();
  rtx cc = cc_in_cond (if_info->cond);

  set_used_flags (if_info->x);
  set_used_flags (if_info->cond);
  set_used_flags (if_info->a);
  set_used_flags (if_info->b);

  for (insn = seq; insn; insn = NEXT_INSN (insn))
    set_used_flags (insn);

  unshare_all_rtl_in_chain (seq);
  end_sequence ();

  /* Make sure that all of the instructions emitted are recognizable,
     and that we haven't introduced a new jump instruction.
     As an exercise for the reader, build a general mechanism that
     allows proper placement of required clobbers.  */
  for (insn = seq; insn; insn = NEXT_INSN (insn))
    if (JUMP_P (insn)
	|| recog_memoized (insn) == -1
	   /* Make sure new generated code does not clobber CC.  */
	|| (cc && set_of (cc, insn)))
      return NULL;

  return seq;
}

/* Return true iff the then and else basic block (if it exists)
   consist of a single simple set instruction.  */

static bool
noce_simple_bbs (struct noce_if_info *if_info)
{
  if (!if_info->then_simple)
    return false;

  if (if_info->else_bb)
    return if_info->else_simple;

  return true;
}

/* Convert "if (a != b) x = a; else x = b" into "x = a" and
   "if (a == b) x = a; else x = b" into "x = b".  */

static int
noce_try_move (struct noce_if_info *if_info)
{
  rtx cond = if_info->cond;
  enum rtx_code code = GET_CODE (cond);
  rtx y;
  rtx_insn *seq;

  if (code != NE && code != EQ)
    return FALSE;

  if (!noce_simple_bbs (if_info))
    return FALSE;

  /* This optimization isn't valid if either A or B could be a NaN
     or a signed zero.  */
  if (HONOR_NANS (if_info->x)
      || HONOR_SIGNED_ZEROS (if_info->x))
    return FALSE;

  /* Check whether the operands of the comparison are A and in
     either order.  */
  if ((rtx_equal_p (if_info->a, XEXP (cond, 0))
       && rtx_equal_p (if_info->b, XEXP (cond, 1)))
      || (rtx_equal_p (if_info->a, XEXP (cond, 1))
	  && rtx_equal_p (if_info->b, XEXP (cond, 0))))
    {
      if (!rtx_interchangeable_p (if_info->a, if_info->b))
	return FALSE;

      y = (code == EQ) ? if_info->a : if_info->b;

      /* Avoid generating the move if the source is the destination.  */
      if (! rtx_equal_p (if_info->x, y))
	{
	  start_sequence ();
	  noce_emit_move_insn (if_info->x, y);
	  seq = end_ifcvt_sequence (if_info);
	  if (!seq)
	    return FALSE;

	  emit_insn_before_setloc (seq, if_info->jump,
				   INSN_LOCATION (if_info->insn_a));
	}
      if_info->transform_name = "noce_try_move";
      return TRUE;
    }
  return FALSE;
}

/* Try forming an IF_THEN_ELSE (cond, b, a) and collapsing that
   through simplify_rtx.  Sometimes that can eliminate the IF_THEN_ELSE.
   If that is the case, emit the result into x.  */

static int
noce_try_ifelse_collapse (struct noce_if_info * if_info)
{
  if (!noce_simple_bbs (if_info))
    return FALSE;

  machine_mode mode = GET_MODE (if_info->x);
  rtx if_then_else = simplify_gen_ternary (IF_THEN_ELSE, mode, mode,
					    if_info->cond, if_info->b,
					    if_info->a);

  if (GET_CODE (if_then_else) == IF_THEN_ELSE)
    return FALSE;

  rtx_insn *seq;
  start_sequence ();
  noce_emit_move_insn (if_info->x, if_then_else);
  seq = end_ifcvt_sequence (if_info);
  if (!seq)
    return FALSE;

  emit_insn_before_setloc (seq, if_info->jump,
			  INSN_LOCATION (if_info->insn_a));

  if_info->transform_name = "noce_try_ifelse_collapse";
  return TRUE;
}


/* Convert "if (test) x = 1; else x = 0".

   Only try 0 and STORE_FLAG_VALUE here.  Other combinations will be
   tried in noce_try_store_flag_constants after noce_try_cmove has had
   a go at the conversion.  */

static int
noce_try_store_flag (struct noce_if_info *if_info)
{
  int reversep;
  rtx target;
  rtx_insn *seq;

  if (!noce_simple_bbs (if_info))
    return FALSE;

  if (CONST_INT_P (if_info->b)
      && INTVAL (if_info->b) == STORE_FLAG_VALUE
      && if_info->a == const0_rtx)
    reversep = 0;
  else if (if_info->b == const0_rtx
	   && CONST_INT_P (if_info->a)
	   && INTVAL (if_info->a) == STORE_FLAG_VALUE
	   && noce_reversed_cond_code (if_info) != UNKNOWN)
    reversep = 1;
  else
    return FALSE;

  start_sequence ();

  target = noce_emit_store_flag (if_info, if_info->x, reversep, 0);
  if (target)
    {
      if (target != if_info->x)
	noce_emit_move_insn (if_info->x, target);

      seq = end_ifcvt_sequence (if_info);
      if (! seq)
	return FALSE;

      emit_insn_before_setloc (seq, if_info->jump,
			       INSN_LOCATION (if_info->insn_a));
      if_info->transform_name = "noce_try_store_flag";
      return TRUE;
    }
  else
    {
      end_sequence ();
      return FALSE;
    }
}


/* Convert "if (test) x = -A; else x = A" into
   x = A; if (test) x = -x if the machine can do the
   conditional negate form of this cheaply.
   Try this before noce_try_cmove that will just load the
   immediates into two registers and do a conditional select
   between them.  If the target has a conditional negate or
   conditional invert operation we can save a potentially
   expensive constant synthesis.  */

static bool
noce_try_inverse_constants (struct noce_if_info *if_info)
{
  if (!noce_simple_bbs (if_info))
    return false;

  if (!CONST_INT_P (if_info->a)
      || !CONST_INT_P (if_info->b)
      || !REG_P (if_info->x))
    return false;

  machine_mode mode = GET_MODE (if_info->x);

  HOST_WIDE_INT val_a = INTVAL (if_info->a);
  HOST_WIDE_INT val_b = INTVAL (if_info->b);

  rtx cond = if_info->cond;

  rtx x = if_info->x;
  rtx target;

  start_sequence ();

  rtx_code code;
  if (val_b != HOST_WIDE_INT_MIN && val_a == -val_b)
    code = NEG;
  else if (val_a == ~val_b)
    code = NOT;
  else
    {
      end_sequence ();
      return false;
    }

  rtx tmp = gen_reg_rtx (mode);
  noce_emit_move_insn (tmp, if_info->a);

  target = emit_conditional_neg_or_complement (x, code, mode, cond, tmp, tmp);

  if (target)
    {
      rtx_insn *seq = get_insns ();

      if (!seq)
	{
	  end_sequence ();
	  return false;
	}

      if (target != if_info->x)
	noce_emit_move_insn (if_info->x, target);

      seq = end_ifcvt_sequence (if_info);

      if (!seq)
	return false;

      emit_insn_before_setloc (seq, if_info->jump,
			       INSN_LOCATION (if_info->insn_a));
      if_info->transform_name = "noce_try_inverse_constants";
      return true;
    }

  end_sequence ();
  return false;
}


/* Convert "if (test) x = a; else x = b", for A and B constant.
   Also allow A = y + c1, B = y + c2, with a common y between A
   and B.  */

static int
noce_try_store_flag_constants (struct noce_if_info *if_info)
{
  rtx target;
  rtx_insn *seq;
  bool reversep;
  HOST_WIDE_INT itrue, ifalse, diff, tmp;
  int normalize;
  bool can_reverse;
  machine_mode mode = GET_MODE (if_info->x);
  rtx common = NULL_RTX;

  rtx a = if_info->a;
  rtx b = if_info->b;

  /* Handle cases like x := test ? y + 3 : y + 4.  */
  if (GET_CODE (a) == PLUS
      && GET_CODE (b) == PLUS
      && CONST_INT_P (XEXP (a, 1))
      && CONST_INT_P (XEXP (b, 1))
      && rtx_equal_p (XEXP (a, 0), XEXP (b, 0))
      /* Allow expressions that are not using the result or plain
         registers where we handle overlap below.  */
      && (REG_P (XEXP (a, 0))
	  || (noce_operand_ok (XEXP (a, 0))
	      && ! reg_overlap_mentioned_p (if_info->x, XEXP (a, 0)))))
    {
      common = XEXP (a, 0);
      a = XEXP (a, 1);
      b = XEXP (b, 1);
    }

  if (!noce_simple_bbs (if_info))
    return FALSE;

  if (CONST_INT_P (a)
      && CONST_INT_P (b))
    {
      ifalse = INTVAL (a);
      itrue = INTVAL (b);
      bool subtract_flag_p = false;

      diff = (unsigned HOST_WIDE_INT) itrue - ifalse;
      /* Make sure we can represent the difference between the two values.  */
      if ((diff > 0)
	  != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue))
	return FALSE;

      diff = trunc_int_for_mode (diff, mode);

      can_reverse = noce_reversed_cond_code (if_info) != UNKNOWN;
      reversep = false;
      if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
	{
	  normalize = 0;
	  /* We could collapse these cases but it is easier to follow the
	     diff/STORE_FLAG_VALUE combinations when they are listed
	     explicitly.  */

	  /* test ? 3 : 4
	     => 4 + (test != 0).  */
	  if (diff < 0 && STORE_FLAG_VALUE < 0)
	      reversep = false;
	  /* test ? 4 : 3
	     => can_reverse  | 4 + (test == 0)
		!can_reverse | 3 - (test != 0).  */
	  else if (diff > 0 && STORE_FLAG_VALUE < 0)
	    {
	      reversep = can_reverse;
	      subtract_flag_p = !can_reverse;
	      /* If we need to subtract the flag and we have PLUS-immediate
		 A and B then it is unlikely to be beneficial to play tricks
		 here.  */
	      if (subtract_flag_p && common)
		return FALSE;
	    }
	  /* test ? 3 : 4
	     => can_reverse  | 3 + (test == 0)
		!can_reverse | 4 - (test != 0).  */
	  else if (diff < 0 && STORE_FLAG_VALUE > 0)
	    {
	      reversep = can_reverse;
	      subtract_flag_p = !can_reverse;
	      /* If we need to subtract the flag and we have PLUS-immediate
		 A and B then it is unlikely to be beneficial to play tricks
		 here.  */
	      if (subtract_flag_p && common)
		return FALSE;
	    }
	  /* test ? 4 : 3
	     => 4 + (test != 0).  */
	  else if (diff > 0 && STORE_FLAG_VALUE > 0)
	    reversep = false;
	  else
	    gcc_unreachable ();
	}
      /* Is this (cond) ? 2^n : 0?  */
      else if (ifalse == 0 && pow2p_hwi (itrue)
	       && STORE_FLAG_VALUE == 1)
	normalize = 1;
      /* Is this (cond) ? 0 : 2^n?  */
      else if (itrue == 0 && pow2p_hwi (ifalse) && can_reverse
	       && STORE_FLAG_VALUE == 1)
	{
	  normalize = 1;
	  reversep = true;
	}
      /* Is this (cond) ? -1 : x?  */
      else if (itrue == -1
	       && STORE_FLAG_VALUE == -1)
	normalize = -1;
      /* Is this (cond) ? x : -1?  */
      else if (ifalse == -1 && can_reverse
	       && STORE_FLAG_VALUE == -1)
	{
	  normalize = -1;
	  reversep = true;
	}
      else
	return FALSE;

      if (reversep)
	{
	  std::swap (itrue, ifalse);
	  diff = trunc_int_for_mode (-(unsigned HOST_WIDE_INT) diff, mode);
	}

      start_sequence ();

      /* If we have x := test ? x + 3 : x + 4 then move the original
	 x out of the way while we store flags.  */
      if (common && rtx_equal_p (common, if_info->x))
	{
	  common = gen_reg_rtx (mode);
	  noce_emit_move_insn (common, if_info->x);
	}

      target = noce_emit_store_flag (if_info, if_info->x, reversep, normalize);
      if (! target)
	{
	  end_sequence ();
	  return FALSE;
	}

      /* if (test) x = 3; else x = 4;
	 =>   x = 3 + (test == 0);  */
      if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
	{
	  /* Add the common part now.  This may allow combine to merge this
	     with the store flag operation earlier into some sort of conditional
	     increment/decrement if the target allows it.  */
	  if (common)
	    target = expand_simple_binop (mode, PLUS,
					   target, common,
					   target, 0, OPTAB_WIDEN);

	  /* Always use ifalse here.  It should have been swapped with itrue
	     when appropriate when reversep is true.  */
	  target = expand_simple_binop (mode, subtract_flag_p ? MINUS : PLUS,
					gen_int_mode (ifalse, mode), target,
					if_info->x, 0, OPTAB_WIDEN);
	}
      /* Other cases are not beneficial when the original A and B are PLUS
	 expressions.  */
      else if (common)
	{
	  end_sequence ();
	  return FALSE;
	}
      /* if (test) x = 8; else x = 0;
	 =>   x = (test != 0) << 3;  */
      else if (ifalse == 0 && (tmp = exact_log2 (itrue)) >= 0)
	{
	  target = expand_simple_binop (mode, ASHIFT,
					target, GEN_INT (tmp), if_info->x, 0,
					OPTAB_WIDEN);
	}

      /* if (test) x = -1; else x = b;
	 =>   x = -(test != 0) | b;  */
      else if (itrue == -1)
	{
	  target = expand_simple_binop (mode, IOR,
					target, gen_int_mode (ifalse, mode),
					if_info->x, 0, OPTAB_WIDEN);
	}
      else
	{
	  end_sequence ();
	  return FALSE;
	}

      if (! target)
	{
	  end_sequence ();
	  return FALSE;
	}

      if (target != if_info->x)
	noce_emit_move_insn (if_info->x, target);

      seq = end_ifcvt_sequence (if_info);
      if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
	return FALSE;

      emit_insn_before_setloc (seq, if_info->jump,
			       INSN_LOCATION (if_info->insn_a));
      if_info->transform_name = "noce_try_store_flag_constants";

      return TRUE;
    }

  return FALSE;
}

/* Convert "if (test) foo++" into "foo += (test != 0)", and
   similarly for "foo--".  */

static int
noce_try_addcc (struct noce_if_info *if_info)
{
  rtx target;
  rtx_insn *seq;
  int subtract, normalize;

  if (!noce_simple_bbs (if_info))
    return FALSE;

  if (GET_CODE (if_info->a) == PLUS
      && rtx_equal_p (XEXP (if_info->a, 0), if_info->b)
      && noce_reversed_cond_code (if_info) != UNKNOWN)
    {
      rtx cond = if_info->rev_cond;
      enum rtx_code code;

      if (cond == NULL_RTX)
	{
	  cond = if_info->cond;
	  code = reversed_comparison_code (cond, if_info->jump);
	}
      else
	code = GET_CODE (cond);

      /* First try to use addcc pattern.  */
      if (general_operand (XEXP (cond, 0), VOIDmode)
	  && general_operand (XEXP (cond, 1), VOIDmode))
	{
	  start_sequence ();
	  target = emit_conditional_add (if_info->x, code,
					 XEXP (cond, 0),
					 XEXP (cond, 1),
					 VOIDmode,
					 if_info->b,
					 XEXP (if_info->a, 1),
					 GET_MODE (if_info->x),
					 (code == LTU || code == GEU
					  || code == LEU || code == GTU));
	  if (target)
	    {
	      if (target != if_info->x)
		noce_emit_move_insn (if_info->x, target);

	      seq = end_ifcvt_sequence (if_info);
	      if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
		return FALSE;

	      emit_insn_before_setloc (seq, if_info->jump,
				       INSN_LOCATION (if_info->insn_a));
	      if_info->transform_name = "noce_try_addcc";

	      return TRUE;
	    }
	  end_sequence ();
	}

      /* If that fails, construct conditional increment or decrement using
	 setcc.  We're changing a branch and an increment to a comparison and
	 an ADD/SUB.  */
      if (XEXP (if_info->a, 1) == const1_rtx
	  || XEXP (if_info->a, 1) == constm1_rtx)
        {
	  start_sequence ();
	  if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
	    subtract = 0, normalize = 0;
	  else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
	    subtract = 1, normalize = 0;
	  else
	    subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));


	  target = noce_emit_store_flag (if_info,
					 gen_reg_rtx (GET_MODE (if_info->x)),
					 1, normalize);

	  if (target)
	    target = expand_simple_binop (GET_MODE (if_info->x),
					  subtract ? MINUS : PLUS,
					  if_info->b, target, if_info->x,
					  0, OPTAB_WIDEN);
	  if (target)
	    {
	      if (target != if_info->x)
		noce_emit_move_insn (if_info->x, target);

	      seq = end_ifcvt_sequence (if_info);
	      if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
		return FALSE;

	      emit_insn_before_setloc (seq, if_info->jump,
				       INSN_LOCATION (if_info->insn_a));
	      if_info->transform_name = "noce_try_addcc";
	      return TRUE;
	    }
	  end_sequence ();
	}
    }

  return FALSE;
}

/* Convert "if (test) x = 0;" to "x &= -(test == 0);"  */

static int
noce_try_store_flag_mask (struct noce_if_info *if_info)
{
  rtx target;
  rtx_insn *seq;
  int reversep;

  if (!noce_simple_bbs (if_info))
    return FALSE;

  reversep = 0;

  if ((if_info->a == const0_rtx
       && rtx_equal_p (if_info->b, if_info->x))
      || ((reversep = (noce_reversed_cond_code (if_info) != UNKNOWN))
	  && if_info->b == const0_rtx
	  && rtx_equal_p (if_info->a, if_info->x)))
    {
      start_sequence ();
      target = noce_emit_store_flag (if_info,
				     gen_reg_rtx (GET_MODE (if_info->x)),
				     reversep, -1);
      if (target)
        target = expand_simple_binop (GET_MODE (if_info->x), AND,
				      if_info->x,
				      target, if_info->x, 0,
				      OPTAB_WIDEN);

      if (target)
	{
	  if (target != if_info->x)
	    noce_emit_move_insn (if_info->x, target);

	  seq = end_ifcvt_sequence (if_info);
	  if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
	    return FALSE;

	  emit_insn_before_setloc (seq, if_info->jump,
				   INSN_LOCATION (if_info->insn_a));
	  if_info->transform_name = "noce_try_store_flag_mask";

	  return TRUE;
	}

      end_sequence ();
    }

  return FALSE;
}

/* Helper function for noce_try_cmove and noce_try_cmove_arith.  */

static rtx
noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
		 rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue)
{
  rtx target ATTRIBUTE_UNUSED;
  int unsignedp ATTRIBUTE_UNUSED;

  /* If earliest == jump, try to build the cmove insn directly.
     This is helpful when combine has created some complex condition
     (like for alpha's cmovlbs) that we can't hope to regenerate
     through the normal interface.  */

  if (if_info->cond_earliest == if_info->jump)
    {
      rtx cond = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
      rtx if_then_else = gen_rtx_IF_THEN_ELSE (GET_MODE (x),
					       cond, vtrue, vfalse);
      rtx set = gen_rtx_SET (x, if_then_else);

      start_sequence ();
      rtx_insn *insn = emit_insn (set);

      if (recog_memoized (insn) >= 0)
	{
	  rtx_insn *seq = get_insns ();
	  end_sequence ();
	  emit_insn (seq);

	  return x;
	}

      end_sequence ();
    }

  /* Don't even try if the comparison operands are weird
     except that the target supports cbranchcc4.  */
  if (! general_operand (cmp_a, GET_MODE (cmp_a))
      || ! general_operand (cmp_b, GET_MODE (cmp_b)))
    {
      if (!have_cbranchcc4
	  || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
	  || cmp_b != const0_rtx)
	return NULL_RTX;
    }

  unsignedp = (code == LTU || code == GEU
	       || code == LEU || code == GTU);

  target = emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode,
				  vtrue, vfalse, GET_MODE (x),
				  unsignedp);
  if (target)
    return target;

  /* We might be faced with a situation like:

     x = (reg:M TARGET)
     vtrue = (subreg:M (reg:N VTRUE) BYTE)
     vfalse = (subreg:M (reg:N VFALSE) BYTE)

     We can't do a conditional move in mode M, but it's possible that we
     could do a conditional move in mode N instead and take a subreg of
     the result.

     If we can't create new pseudos, though, don't bother.  */
  if (reload_completed)
    return NULL_RTX;

  if (GET_CODE (vtrue) == SUBREG && GET_CODE (vfalse) == SUBREG)
    {
      rtx reg_vtrue = SUBREG_REG (vtrue);
      rtx reg_vfalse = SUBREG_REG (vfalse);
      poly_uint64 byte_vtrue = SUBREG_BYTE (vtrue);
      poly_uint64 byte_vfalse = SUBREG_BYTE (vfalse);
      rtx promoted_target;

      if (GET_MODE (reg_vtrue) != GET_MODE (reg_vfalse)
	  || maybe_ne (byte_vtrue, byte_vfalse)
	  || (SUBREG_PROMOTED_VAR_P (vtrue)
	      != SUBREG_PROMOTED_VAR_P (vfalse))
	  || (SUBREG_PROMOTED_GET (vtrue)
	      != SUBREG_PROMOTED_GET (vfalse)))
	return NULL_RTX;

      promoted_target = gen_reg_rtx (GET_MODE (reg_vtrue));

      target = emit_conditional_move (promoted_target, code, cmp_a, cmp_b,
				      VOIDmode, reg_vtrue, reg_vfalse,
				      GET_MODE (reg_vtrue), unsignedp);
      /* Nope, couldn't do it in that mode either.  */
      if (!target)
	return NULL_RTX;

      target = gen_rtx_SUBREG (GET_MODE (vtrue), promoted_target, byte_vtrue);
      SUBREG_PROMOTED_VAR_P (target) = SUBREG_PROMOTED_VAR_P (vtrue);
      SUBREG_PROMOTED_SET (target, SUBREG_PROMOTED_GET (vtrue));
      emit_move_insn (x, target);
      return x;
    }
  else
    return NULL_RTX;
}

/* Try only simple constants and registers here.  More complex cases
   are handled in noce_try_cmove_arith after noce_try_store_flag_arith
   has had a go at it.  */

static int
noce_try_cmove (struct noce_if_info *if_info)
{
  enum rtx_code code;
  rtx target;
  rtx_insn *seq;

  if (!noce_simple_bbs (if_info))
    return FALSE;

  if ((CONSTANT_P (if_info->a) || register_operand (if_info->a, VOIDmode))
      && (CONSTANT_P (if_info->b) || register_operand (if_info->b, VOIDmode)))
    {
      start_sequence ();

      code = GET_CODE (if_info->cond);
      target = noce_emit_cmove (if_info, if_info->x, code,
				XEXP (if_info->cond, 0),
				XEXP (if_info->cond, 1),
				if_info->a, if_info->b);

      if (target)
	{
	  if (target != if_info->x)
	    noce_emit_move_insn (if_info->x, target);

	  seq = end_ifcvt_sequence (if_info);
	  if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
	    return FALSE;

	  emit_insn_before_setloc (seq, if_info->jump,
				   INSN_LOCATION (if_info->insn_a));
	  if_info->transform_name = "noce_try_cmove";

	  return TRUE;
	}
      /* If both a and b are constants try a last-ditch transformation:
	 if (test) x = a; else x = b;
	 =>   x = (-(test != 0) & (b - a)) + a;
	 Try this only if the target-specific expansion above has failed.
	 The target-specific expander may want to generate sequences that
	 we don't know about, so give them a chance before trying this
	 approach.  */
      else if (!targetm.have_conditional_execution ()
		&& CONST_INT_P (if_info->a) && CONST_INT_P (if_info->b))
	{
	  machine_mode mode = GET_MODE (if_info->x);
	  HOST_WIDE_INT ifalse = INTVAL (if_info->a);
	  HOST_WIDE_INT itrue = INTVAL (if_info->b);
	  rtx target = noce_emit_store_flag (if_info, if_info->x, false, -1);
	  if (!target)
	    {
	      end_sequence ();
	      return FALSE;
	    }

	  HOST_WIDE_INT diff = (unsigned HOST_WIDE_INT) itrue - ifalse;
	  /* Make sure we can represent the difference
	     between the two values.  */
	  if ((diff > 0)
	      != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue))
	    {
	      end_sequence ();
	      return FALSE;
	    }

	  diff = trunc_int_for_mode (diff, mode);
	  target = expand_simple_binop (mode, AND,
					target, gen_int_mode (diff, mode),
					if_info->x, 0, OPTAB_WIDEN);
	  if (target)
	    target = expand_simple_binop (mode, PLUS,
					  target, gen_int_mode (ifalse, mode),
					  if_info->x, 0, OPTAB_WIDEN);
	  if (target)
	    {
	      if (target != if_info->x)
		noce_emit_move_insn (if_info->x, target);

	      seq = end_ifcvt_sequence (if_info);
	      if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
		return FALSE;

	      emit_insn_before_setloc (seq, if_info->jump,
				   INSN_LOCATION (if_info->insn_a));
	      if_info->transform_name = "noce_try_cmove";
	      return TRUE;
	    }
	  else
	    {
	      end_sequence ();
	      return FALSE;
	    }
	}
      else
	end_sequence ();
    }

  return FALSE;
}

/* Return true if X contains a conditional code mode rtx.  */

static bool
contains_ccmode_rtx_p (rtx x)
{
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, x, ALL)
    if (GET_MODE_CLASS (GET_MODE (*iter)) == MODE_CC)
      return true;

  return false;
}

/* Helper for bb_valid_for_noce_process_p.  Validate that
   the rtx insn INSN is a single set that does not set
   the conditional register CC and is in general valid for
   if-conversion.  */

static bool
insn_valid_noce_process_p (rtx_insn *insn, rtx cc)
{
  if (!insn
      || !NONJUMP_INSN_P (insn)
      || (cc && set_of (cc, insn)))
      return false;

  rtx sset = single_set (insn);

  /* Currently support only simple single sets in test_bb.  */
  if (!sset
      || !noce_operand_ok (SET_DEST (sset))
      || contains_ccmode_rtx_p (SET_DEST (sset))
      || !noce_operand_ok (SET_SRC (sset)))
    return false;

  return true;
}


/* Return true iff the registers that the insns in BB_A set do not get
   used in BB_B.  If TO_RENAME is non-NULL then it is a location that will be
   renamed later by the caller and so conflicts on it should be ignored
   in this function.  */

static bool
bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b, rtx to_rename)
{
  rtx_insn *a_insn;
  bitmap bba_sets = BITMAP_ALLOC (&reg_obstack);

  df_ref def;
  df_ref use;

  FOR_BB_INSNS (bb_a, a_insn)
    {
      if (!active_insn_p (a_insn))
	continue;

      rtx sset_a = single_set (a_insn);

      if (!sset_a)
	{
	  BITMAP_FREE (bba_sets);
	  return false;
	}
      /* Record all registers that BB_A sets.  */
      FOR_EACH_INSN_DEF (def, a_insn)
	if (!(to_rename && DF_REF_REG (def) == to_rename))
	  bitmap_set_bit (bba_sets, DF_REF_REGNO (def));
    }

  rtx_insn *b_insn;

  FOR_BB_INSNS (bb_b, b_insn)
    {
      if (!active_insn_p (b_insn))
	continue;

      rtx sset_b = single_set (b_insn);

      if (!sset_b)
	{
	  BITMAP_FREE (bba_sets);
	  return false;
	}

      /* Make sure this is a REG and not some instance
	 of ZERO_EXTRACT or SUBREG or other dangerous stuff.
	 If we have a memory destination then we have a pair of simple
	 basic blocks performing an operation of the form [addr] = c ? a : b.
	 bb_valid_for_noce_process_p will have ensured that these are
	 the only stores present.  In that case [addr] should be the location
	 to be renamed.  Assert that the callers set this up properly.  */
      if (MEM_P (SET_DEST (sset_b)))
	gcc_assert (rtx_equal_p (SET_DEST (sset_b), to_rename));
      else if (!REG_P (SET_DEST (sset_b)))
	{
	  BITMAP_FREE (bba_sets);
	  return false;
	}

      /* If the insn uses a reg set in BB_A return false.  */
      FOR_EACH_INSN_USE (use, b_insn)
	{
	  if (bitmap_bit_p (bba_sets, DF_REF_REGNO (use)))
	    {
	      BITMAP_FREE (bba_sets);
	      return false;
	    }
	}

    }

  BITMAP_FREE (bba_sets);
  return true;
}

/* Emit copies of all the active instructions in BB except the last.
   This is a helper for noce_try_cmove_arith.  */

static void
noce_emit_all_but_last (basic_block bb)
{
  rtx_insn *last = last_active_insn (bb, FALSE);
  rtx_insn *insn;
  FOR_BB_INSNS (bb, insn)
    {
      if (insn != last && active_insn_p (insn))
	{
	  rtx_insn *to_emit = as_a <rtx_insn *> (copy_rtx (insn));

	  emit_insn (PATTERN (to_emit));
	}
    }
}

/* Helper for noce_try_cmove_arith.  Emit the pattern TO_EMIT and return
   the resulting insn or NULL if it's not a valid insn.  */

static rtx_insn *
noce_emit_insn (rtx to_emit)
{
  gcc_assert (to_emit);
  rtx_insn *insn = emit_insn (to_emit);

  if (recog_memoized (insn) < 0)
    return NULL;

  return insn;
}

/* Helper for noce_try_cmove_arith.  Emit a copy of the insns up to
   and including the penultimate one in BB if it is not simple
   (as indicated by SIMPLE).  Then emit LAST_INSN as the last
   insn in the block.  The reason for that is that LAST_INSN may
   have been modified by the preparation in noce_try_cmove_arith.  */

static bool
noce_emit_bb (rtx last_insn, basic_block bb, bool simple)
{
  if (bb && !simple)
    noce_emit_all_but_last (bb);

  if (last_insn && !noce_emit_insn (last_insn))
    return false;

  return true;
}

/* Try more complex cases involving conditional_move.  */

static int
noce_try_cmove_arith (struct noce_if_info *if_info)
{
  rtx a = if_info->a;
  rtx b = if_info->b;
  rtx x = if_info->x;
  rtx orig_a, orig_b;
  rtx_insn *insn_a, *insn_b;
  bool a_simple = if_info->then_simple;
  bool b_simple = if_info->else_simple;
  basic_block then_bb = if_info->then_bb;
  basic_block else_bb = if_info->else_bb;
  rtx target;
  int is_mem = 0;
  enum rtx_code code;
  rtx cond = if_info->cond;
  rtx_insn *ifcvt_seq;

  /* A conditional move from two memory sources is equivalent to a
     conditional on their addresses followed by a load.  Don't do this
     early because it'll screw alias analysis.  Note that we've
     already checked for no side effects.  */
  if (cse_not_expected
      && MEM_P (a) && MEM_P (b)
      && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b))
    {
      machine_mode address_mode = get_address_mode (a);

      a = XEXP (a, 0);
      b = XEXP (b, 0);
      x = gen_reg_rtx (address_mode);
      is_mem = 1;
    }

  /* ??? We could handle this if we knew that a load from A or B could
     not trap or fault.  This is also true if we've already loaded
     from the address along the path from ENTRY.  */
  else if (may_trap_or_fault_p (a) || may_trap_or_fault_p (b))
    return FALSE;

  /* if (test) x = a + b; else x = c - d;
     => y = a + b;
        x = c - d;
	if (test)
	  x = y;
  */

  code = GET_CODE (cond);
  insn_a = if_info->insn_a;
  insn_b = if_info->insn_b;

  machine_mode x_mode = GET_MODE (x);

  if (!can_conditionally_move_p (x_mode))
    return FALSE;

  /* Possibly rearrange operands to make things come out more natural.  */
  if (noce_reversed_cond_code (if_info) != UNKNOWN)
    {
      int reversep = 0;
      if (rtx_equal_p (b, x))
	reversep = 1;
      else if (general_operand (b, GET_MODE (b)))
	reversep = 1;

      if (reversep)
	{
	  if (if_info->rev_cond)
	    {
	      cond = if_info->rev_cond;
	      code = GET_CODE (cond);
	    }
	  else
	    code = reversed_comparison_code (cond, if_info->jump);
	  std::swap (a, b);
	  std::swap (insn_a, insn_b);
	  std::swap (a_simple, b_simple);
	  std::swap (then_bb, else_bb);
	}
    }

  if (then_bb && else_bb
      && (!bbs_ok_for_cmove_arith (then_bb, else_bb,  if_info->orig_x)
	  || !bbs_ok_for_cmove_arith (else_bb, then_bb,  if_info->orig_x)))
    return FALSE;

  start_sequence ();

  /* If one of the blocks is empty then the corresponding B or A value
     came from the test block.  The non-empty complex block that we will
     emit might clobber the register used by B or A, so move it to a pseudo
     first.  */

  rtx tmp_a = NULL_RTX;
  rtx tmp_b = NULL_RTX;

  if (b_simple || !else_bb)
    tmp_b = gen_reg_rtx (x_mode);

  if (a_simple || !then_bb)
    tmp_a = gen_reg_rtx (x_mode);

  orig_a = a;
  orig_b = b;

  rtx emit_a = NULL_RTX;
  rtx emit_b = NULL_RTX;
  rtx_insn *tmp_insn = NULL;
  bool modified_in_a = false;
  bool modified_in_b = false;
  /* If either operand is complex, load it into a register first.
     The best way to do this is to copy the original insn.  In this
     way we preserve any clobbers etc that the insn may have had.
     This is of course not possible in the IS_MEM case.  */

  if (! general_operand (a, GET_MODE (a)) || tmp_a)
    {

      if (is_mem)
	{
	  rtx reg = gen_reg_rtx (GET_MODE (a));
	  emit_a = gen_rtx_SET (reg, a);
	}
      else
	{
	  if (insn_a)
	    {
	      a = tmp_a ? tmp_a : gen_reg_rtx (GET_MODE (a));

	      rtx_insn *copy_of_a = as_a <rtx_insn *> (copy_rtx (insn_a));
	      rtx set = single_set (copy_of_a);
	      SET_DEST (set) = a;

	      emit_a = PATTERN (copy_of_a);
	    }
	  else
	    {
	      rtx tmp_reg = tmp_a ? tmp_a : gen_reg_rtx (GET_MODE (a));
	      emit_a = gen_rtx_SET (tmp_reg, a);
	      a = tmp_reg;
	    }
	}
    }

  if (! general_operand (b, GET_MODE (b)) || tmp_b)
    {
      if (is_mem)
	{
          rtx reg = gen_reg_rtx (GET_MODE (b));
	  emit_b = gen_rtx_SET (reg, b);
	}
      else
	{
	  if (insn_b)
	    {
	      b = tmp_b ? tmp_b : gen_reg_rtx (GET_MODE (b));
	      rtx_insn *copy_of_b = as_a <rtx_insn *> (copy_rtx (insn_b));
	      rtx set = single_set (copy_of_b);

	      SET_DEST (set) = b;
	      emit_b = PATTERN (copy_of_b);
	    }
	  else
	    {
	      rtx tmp_reg = tmp_b ? tmp_b : gen_reg_rtx (GET_MODE (b));
	      emit_b = gen_rtx_SET (tmp_reg, b);
	      b = tmp_reg;
	    }
	}
    }

  modified_in_a = emit_a != NULL_RTX && modified_in_p (orig_b, emit_a);
  if (tmp_b && then_bb)
    {
      FOR_BB_INSNS (then_bb, tmp_insn)
	/* Don't check inside insn_a.  We will have changed it to emit_a
	   with a destination that doesn't conflict.  */
	if (!(insn_a && tmp_insn == insn_a)
	    && modified_in_p (orig_b, tmp_insn))
	  {
	    modified_in_a = true;
	    break;
	  }

    }

  modified_in_b = emit_b != NULL_RTX && modified_in_p (orig_a, emit_b);
  if (tmp_a && else_bb)
    {
      FOR_BB_INSNS (else_bb, tmp_insn)
      /* Don't check inside insn_b.  We will have changed it to emit_b
	 with a destination that doesn't conflict.  */
      if (!(insn_b && tmp_insn == insn_b)
	  && modified_in_p (orig_a, tmp_insn))
	{
	  modified_in_b = true;
	  break;
	}
    }

  /* If insn to set up A clobbers any registers B depends on, try to
     swap insn that sets up A with the one that sets up B.  If even
     that doesn't help, punt.  */
  if (modified_in_a && !modified_in_b)
    {
      if (!noce_emit_bb (emit_b, else_bb, b_simple))
	goto end_seq_and_fail;

      if (!noce_emit_bb (emit_a, then_bb, a_simple))
	goto end_seq_and_fail;
    }
  else if (!modified_in_a)
    {
      if (!noce_emit_bb (emit_a, then_bb, a_simple))
	goto end_seq_and_fail;

      if (!noce_emit_bb (emit_b, else_bb, b_simple))
	goto end_seq_and_fail;
    }
  else
    goto end_seq_and_fail;

  target = noce_emit_cmove (if_info, x, code, XEXP (cond, 0), XEXP (cond, 1),
			    a, b);

  if (! target)
    goto end_seq_and_fail;

  /* If we're handling a memory for above, emit the load now.  */
  if (is_mem)
    {
      rtx mem = gen_rtx_MEM (GET_MODE (if_info->x), target);

      /* Copy over flags as appropriate.  */
      if (MEM_VOLATILE_P (if_info->a) || MEM_VOLATILE_P (if_info->b))
	MEM_VOLATILE_P (mem) = 1;
      if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b))
	set_mem_alias_set (mem, MEM_ALIAS_SET (if_info->a));
      set_mem_align (mem,
		     MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b)));

      gcc_assert (MEM_ADDR_SPACE (if_info->a) == MEM_ADDR_SPACE (if_info->b));
      set_mem_addr_space (mem, MEM_ADDR_SPACE (if_info->a));

      noce_emit_move_insn (if_info->x, mem);
    }
  else if (target != x)
    noce_emit_move_insn (x, target);

  ifcvt_seq = end_ifcvt_sequence (if_info);
  if (!ifcvt_seq || !targetm.noce_conversion_profitable_p (ifcvt_seq, if_info))
    return FALSE;

  emit_insn_before_setloc (ifcvt_seq, if_info->jump,
			   INSN_LOCATION (if_info->insn_a));
  if_info->transform_name = "noce_try_cmove_arith";
  return TRUE;

 end_seq_and_fail:
  end_sequence ();
  return FALSE;
}

/* For most cases, the simplified condition we found is the best
   choice, but this is not the case for the min/max/abs transforms.
   For these we wish to know that it is A or B in the condition.  */

static rtx
noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
			rtx_insn **earliest)
{
  rtx cond, set;
  rtx_insn *insn;
  int reverse;

  /* If target is already mentioned in the known condition, return it.  */
  if (reg_mentioned_p (target, if_info->cond))
    {
      *earliest = if_info->cond_earliest;
      return if_info->cond;
    }

  set = pc_set (if_info->jump);
  cond = XEXP (SET_SRC (set), 0);
  reverse
    = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
      && label_ref_label (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (if_info->jump);
  if (if_info->then_else_reversed)
    reverse = !reverse;

  /* If we're looking for a constant, try to make the conditional
     have that constant in it.  There are two reasons why it may
     not have the constant we want:

     1. GCC may have needed to put the constant in a register, because
        the target can't compare directly against that constant.  For
        this case, we look for a SET immediately before the comparison
        that puts a constant in that register.

     2. GCC may have canonicalized the conditional, for example
	replacing "if x < 4" with "if x <= 3".  We can undo that (or
	make equivalent types of changes) to get the constants we need
	if they're off by one in the right direction.  */

  if (CONST_INT_P (target))
    {
      enum rtx_code code = GET_CODE (if_info->cond);
      rtx op_a = XEXP (if_info->cond, 0);
      rtx op_b = XEXP (if_info->cond, 1);
      rtx_insn *prev_insn;

      /* First, look to see if we put a constant in a register.  */
      prev_insn = prev_nonnote_nondebug_insn (if_info->cond_earliest);
      if (prev_insn
	  && BLOCK_FOR_INSN (prev_insn)
	     == BLOCK_FOR_INSN (if_info->cond_earliest)
	  && INSN_P (prev_insn)
	  && GET_CODE (PATTERN (prev_insn)) == SET)
	{
	  rtx src = find_reg_equal_equiv_note (prev_insn);
	  if (!src)
	    src = SET_SRC (PATTERN (prev_insn));
	  if (CONST_INT_P (src))
	    {
	      if (rtx_equal_p (op_a, SET_DEST (PATTERN (prev_insn))))
		op_a = src;
	      else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn))))
		op_b = src;

	      if (CONST_INT_P (op_a))
		{
		  std::swap (op_a, op_b);
		  code = swap_condition (code);
		}
	    }
	}

      /* Now, look to see if we can get the right constant by
	 adjusting the conditional.  */
      if (CONST_INT_P (op_b))
	{
	  HOST_WIDE_INT desired_val = INTVAL (target);
	  HOST_WIDE_INT actual_val = INTVAL (op_b);

	  switch (code)
	    {
	    case LT:
	      if (desired_val != HOST_WIDE_INT_MAX
		  && actual_val == desired_val + 1)
		{
		  code = LE;
		  op_b = GEN_INT (desired_val);
		}
	      break;
	    case LE:
	      if (desired_val != HOST_WIDE_INT_MIN
		  && actual_val == desired_val - 1)
		{
		  code = LT;
		  op_b = GEN_INT (desired_val);
		}
	      break;
	    case GT:
	      if (desired_val != HOST_WIDE_INT_MIN
		  && actual_val == desired_val - 1)
		{
		  code = GE;
		  op_b = GEN_INT (desired_val);
		}
	      break;
	    case GE:
	      if (desired_val != HOST_WIDE_INT_MAX
		  && actual_val == desired_val + 1)
		{
		  code = GT;
		  op_b = GEN_INT (desired_val);
		}
	      break;
	    default:
	      break;
	    }
	}

      /* If we made any changes, generate a new conditional that is
	 equivalent to what we started with, but has the right
	 constants in it.  */
      if (code != GET_CODE (if_info->cond)
	  || op_a != XEXP (if_info->cond, 0)
	  || op_b != XEXP (if_info->cond, 1))
	{
	  cond = gen_rtx_fmt_ee (code, GET_MODE (cond), op_a, op_b);
	  *earliest = if_info->cond_earliest;
	  return cond;
	}
    }

  cond = canonicalize_condition (if_info->jump, cond, reverse,
				 earliest, target, have_cbranchcc4, true);
  if (! cond || ! reg_mentioned_p (target, cond))
    return NULL;

  /* We almost certainly searched back to a different place.
     Need to re-verify correct lifetimes.  */

  /* X may not be mentioned in the range (cond_earliest, jump].  */
  for (insn = if_info->jump; insn != *earliest; insn = PREV_INSN (insn))
    if (INSN_P (insn) && reg_overlap_mentioned_p (if_info->x, PATTERN (insn)))
      return NULL;

  /* A and B may not be modified in the range [cond_earliest, jump).  */
  for (insn = *earliest; insn != if_info->jump; insn = NEXT_INSN (insn))
    if (INSN_P (insn)
	&& (modified_in_p (if_info->a, insn)
	    || modified_in_p (if_info->b, insn)))
      return NULL;

  return cond;
}

/* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc.  */

static int
noce_try_minmax (struct noce_if_info *if_info)
{
  rtx cond, target;
  rtx_insn *earliest, *seq;
  enum rtx_code code, op;
  int unsignedp;

  if (!noce_simple_bbs (if_info))
    return FALSE;

  /* ??? Reject modes with NaNs or signed zeros since we don't know how
     they will be resolved with an SMIN/SMAX.  It wouldn't be too hard
     to get the target to tell us...  */
  if (HONOR_SIGNED_ZEROS (if_info->x)
      || HONOR_NANS (if_info->x))
    return FALSE;

  cond = noce_get_alt_condition (if_info, if_info->a, &earliest);
  if (!cond)
    return FALSE;

  /* Verify the condition is of the form we expect, and canonicalize
     the comparison code.  */
  code = GET_CODE (cond);
  if (rtx_equal_p (XEXP (cond, 0), if_info->a))
    {
      if (! rtx_equal_p (XEXP (cond, 1), if_info->b))
	return FALSE;
    }
  else if (rtx_equal_p (XEXP (cond, 1), if_info->a))
    {
      if (! rtx_equal_p (XEXP (cond, 0), if_info->b))
	return FALSE;
      code = swap_condition (code);
    }
  else
    return FALSE;

  /* Determine what sort of operation this is.  Note that the code is for
     a taken branch, so the code->operation mapping appears backwards.  */
  switch (code)
    {
    case LT:
    case LE:
    case UNLT:
    case UNLE:
      op = SMAX;
      unsignedp = 0;
      break;
    case GT:
    case GE:
    case UNGT:
    case UNGE:
      op = SMIN;
      unsignedp = 0;
      break;
    case LTU:
    case LEU:
      op = UMAX;
      unsignedp = 1;
      break;
    case GTU:
    case GEU:
      op = UMIN;
      unsignedp = 1;
      break;
    default:
      return FALSE;
    }

  start_sequence ();

  target = expand_simple_binop (GET_MODE (if_info->x), op,
				if_info->a, if_info->b,
				if_info->x, unsignedp, OPTAB_WIDEN);
  if (! target)
    {
      end_sequence ();
      return FALSE;
    }
  if (target != if_info->x)
    noce_emit_move_insn (if_info->x, target);

  seq = end_ifcvt_sequence (if_info);
  if (!seq)
    return FALSE;

  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
  if_info->cond = cond;
  if_info->cond_earliest = earliest;
  if_info->rev_cond = NULL_RTX;
  if_info->transform_name = "noce_try_minmax";

  return TRUE;
}

/* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);",
   "if (a < 0) x = ~a; else x = a;" to "x = one_cmpl_abs(a);",
   etc.  */

static int
noce_try_abs (struct noce_if_info *if_info)
{
  rtx cond, target, a, b, c;
  rtx_insn *earliest, *seq;
  int negate;
  bool one_cmpl = false;

  if (!noce_simple_bbs (if_info))
    return FALSE;

  /* Reject modes with signed zeros.  */
  if (HONOR_SIGNED_ZEROS (if_info->x))
    return FALSE;

  /* Recognize A and B as constituting an ABS or NABS.  The canonical
     form is a branch around the negation, taken when the object is the
     first operand of a comparison against 0 that evaluates to true.  */
  a = if_info->a;
  b = if_info->b;
  if (GET_CODE (a) == NEG && rtx_equal_p (XEXP (a, 0), b))
    negate = 0;
  else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a))
    {
      std::swap (a, b);
      negate = 1;
    }
  else if (GET_CODE (a) == NOT && rtx_equal_p (XEXP (a, 0), b))
    {
      negate = 0;
      one_cmpl = true;
    }
  else if (GET_CODE (b) == NOT && rtx_equal_p (XEXP (b, 0), a))
    {
      std::swap (a, b);
      negate = 1;
      one_cmpl = true;
    }
  else
    return FALSE;

  cond = noce_get_alt_condition (if_info, b, &earliest);
  if (!cond)
    return FALSE;

  /* Verify the condition is of the form we expect.  */
  if (rtx_equal_p (XEXP (cond, 0), b))
    c = XEXP (cond, 1);
  else if (rtx_equal_p (XEXP (cond, 1), b))
    {
      c = XEXP (cond, 0);
      negate = !negate;
    }
  else
    return FALSE;

  /* Verify that C is zero.  Search one step backward for a
     REG_EQUAL note or a simple source if necessary.  */
  if (REG_P (c))
    {
      rtx set;
      rtx_insn *insn = prev_nonnote_nondebug_insn (earliest);
      if (insn
	  && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (earliest)
	  && (set = single_set (insn))
	  && rtx_equal_p (SET_DEST (set), c))
	{
	  rtx note = find_reg_equal_equiv_note (insn);
	  if (note)
	    c = XEXP (note, 0);
	  else
	    c = SET_SRC (set);
	}
      else
	return FALSE;
    }
  if (MEM_P (c)
      && GET_CODE (XEXP (c, 0)) == SYMBOL_REF
      && CONSTANT_POOL_ADDRESS_P (XEXP (c, 0)))
    c = get_pool_constant (XEXP (c, 0));

  /* Work around funny ideas get_condition has wrt canonicalization.
     Note that these rtx constants are known to be CONST_INT, and
     therefore imply integer comparisons.
     The one_cmpl case is more complicated, as we want to handle
     only x < 0 ? ~x : x or x >= 0 ? x : ~x to one_cmpl_abs (x)
     and x < 0 ? x : ~x or x >= 0 ? ~x : x to ~one_cmpl_abs (x),
     but not other cases (x > -1 is equivalent of x >= 0).  */
  if (c == constm1_rtx && GET_CODE (cond) == GT)
    ;
  else if (c == const1_rtx && GET_CODE (cond) == LT)
    {
      if (one_cmpl)
	return FALSE;
    }
  else if (c == CONST0_RTX (GET_MODE (b)))
    {
      if (one_cmpl
	  && GET_CODE (cond) != GE
	  && GET_CODE (cond) != LT)
	return FALSE;
    }
  else
    return FALSE;

  /* Determine what sort of operation this is.  */
  switch (GET_CODE (cond))
    {
    case LT:
    case LE:
    case UNLT:
    case UNLE:
      negate = !negate;
      break;
    case GT:
    case GE:
    case UNGT:
    case UNGE:
      break;
    default:
      return FALSE;
    }

  start_sequence ();
  if (one_cmpl)
    target = expand_one_cmpl_abs_nojump (GET_MODE (if_info->x), b,
                                         if_info->x);
  else
    target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1);

  /* ??? It's a quandary whether cmove would be better here, especially
     for integers.  Perhaps combine will clean things up.  */
  if (target && negate)
    {
      if (one_cmpl)
        target = expand_simple_unop (GET_MODE (target), NOT, target,
                                     if_info->x, 0);
      else
        target = expand_simple_unop (GET_MODE (target), NEG, target,
                                     if_info->x, 0);
    }

  if (! target)
    {
      end_sequence ();
      return FALSE;
    }

  if (target != if_info->x)
    noce_emit_move_insn (if_info->x, target);

  seq = end_ifcvt_sequence (if_info);
  if (!seq)
    return FALSE;

  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
  if_info->cond = cond;
  if_info->cond_earliest = earliest;
  if_info->rev_cond = NULL_RTX;
  if_info->transform_name = "noce_try_abs";

  return TRUE;
}

/* Convert "if (m < 0) x = b; else x = 0;" to "x = (m >> C) & b;".  */

static int
noce_try_sign_mask (struct noce_if_info *if_info)
{
  rtx cond, t, m, c;
  rtx_insn *seq;
  machine_mode mode;
  enum rtx_code code;
  bool t_unconditional;

  if (!noce_simple_bbs (if_info))
    return FALSE;

  cond = if_info->cond;
  code = GET_CODE (cond);
  m = XEXP (cond, 0);
  c = XEXP (cond, 1);

  t = NULL_RTX;
  if (if_info->a == const0_rtx)
    {
      if ((code == LT && c == const0_rtx)
	  || (code == LE && c == constm1_rtx))
	t = if_info->b;
    }
  else if (if_info->b == const0_rtx)
    {
      if ((code == GE && c == const0_rtx)
	  || (code == GT && c == constm1_rtx))
	t = if_info->a;
    }

  if (! t || side_effects_p (t))
    return FALSE;

  /* We currently don't handle different modes.  */
  mode = GET_MODE (t);
  if (GET_MODE (m) != mode)
    return FALSE;

  /* This is only profitable if T is unconditionally executed/evaluated in the
     original insn sequence or T is cheap.  The former happens if B is the
     non-zero (T) value and if INSN_B was taken from TEST_BB, or there was no
     INSN_B which can happen for e.g. conditional stores to memory.  For the
     cost computation use the block TEST_BB where the evaluation will end up
     after the transformation.  */
  t_unconditional
    = (t == if_info->b
       && (if_info->insn_b == NULL_RTX
	   || BLOCK_FOR_INSN (if_info->insn_b) == if_info->test_bb));
  if (!(t_unconditional
	|| (set_src_cost (t, mode, if_info->speed_p)
	    < COSTS_N_INSNS (2))))
    return FALSE;

  if (!noce_can_force_operand (t))
    return FALSE;

  start_sequence ();
  /* Use emit_store_flag to generate "m < 0 ? -1 : 0" instead of expanding
     "(signed) m >> 31" directly.  This benefits targets with specialized
     insns to obtain the signmask, but still uses ashr_optab otherwise.  */
  m = emit_store_flag (gen_reg_rtx (mode), LT, m, const0_rtx, mode, 0, -1);
  t = m ? expand_binop (mode, and_optab, m, t, NULL_RTX, 0, OPTAB_DIRECT)
	: NULL_RTX;

  if (!t)
    {
      end_sequence ();
      return FALSE;
    }

  noce_emit_move_insn (if_info->x, t);

  seq = end_ifcvt_sequence (if_info);
  if (!seq)
    return FALSE;

  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
  if_info->transform_name = "noce_try_sign_mask";

  return TRUE;
}


/* Optimize away "if (x & C) x |= C" and similar bit manipulation
   transformations.  */

static int
noce_try_bitop (struct noce_if_info *if_info)
{
  rtx cond, x, a, result;
  rtx_insn *seq;
  scalar_int_mode mode;
  enum rtx_code code;
  int bitnum;

  x = if_info->x;
  cond = if_info->cond;
  code = GET_CODE (cond);

  /* Check for an integer operation.  */
  if (!is_a <scalar_int_mode> (GET_MODE (x), &mode))
    return FALSE;

  if (!noce_simple_bbs (if_info))
    return FALSE;

  /* Check for no else condition.  */
  if (! rtx_equal_p (x, if_info->b))
    return FALSE;

  /* Check for a suitable condition.  */
  if (code != NE && code != EQ)
    return FALSE;
  if (XEXP (cond, 1) != const0_rtx)
    return FALSE;
  cond = XEXP (cond, 0);

  /* ??? We could also handle AND here.  */
  if (GET_CODE (cond) == ZERO_EXTRACT)
    {
      if (XEXP (cond, 1) != const1_rtx
	  || !CONST_INT_P (XEXP (cond, 2))
	  || ! rtx_equal_p (x, XEXP (cond, 0)))
	return FALSE;
      bitnum = INTVAL (XEXP (cond, 2));
      if (BITS_BIG_ENDIAN)
	bitnum = GET_MODE_BITSIZE (mode) - 1 - bitnum;
      if (bitnum < 0 || bitnum >= HOST_BITS_PER_WIDE_INT)
	return FALSE;
    }
  else
    return FALSE;

  a = if_info->a;
  if (GET_CODE (a) == IOR || GET_CODE (a) == XOR)
    {
      /* Check for "if (X & C) x = x op C".  */
      if (! rtx_equal_p (x, XEXP (a, 0))
          || !CONST_INT_P (XEXP (a, 1))
	  || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode))
	     != HOST_WIDE_INT_1U << bitnum)
        return FALSE;

      /* if ((x & C) == 0) x |= C; is transformed to x |= C.   */
      /* if ((x & C) != 0) x |= C; is transformed to nothing.  */
      if (GET_CODE (a) == IOR)
	result = (code == NE) ? a : NULL_RTX;
      else if (code == NE)
	{
	  /* if ((x & C) == 0) x ^= C; is transformed to x |= C.   */
	  result = gen_int_mode (HOST_WIDE_INT_1 << bitnum, mode);
	  result = simplify_gen_binary (IOR, mode, x, result);
	}
      else
	{
	  /* if ((x & C) != 0) x ^= C; is transformed to x &= ~C.  */
	  result = gen_int_mode (~(HOST_WIDE_INT_1 << bitnum), mode);
	  result = simplify_gen_binary (AND, mode, x, result);
	}
    }
  else if (GET_CODE (a) == AND)
    {
      /* Check for "if (X & C) x &= ~C".  */
      if (! rtx_equal_p (x, XEXP (a, 0))
	  || !CONST_INT_P (XEXP (a, 1))
	  || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode))
	     != (~(HOST_WIDE_INT_1 << bitnum) & GET_MODE_MASK (mode)))
        return FALSE;

      /* if ((x & C) == 0) x &= ~C; is transformed to nothing.  */
      /* if ((x & C) != 0) x &= ~C; is transformed to x &= ~C.  */
      result = (code == EQ) ? a : NULL_RTX;
    }
  else
    return FALSE;

  if (result)
    {
      start_sequence ();
      noce_emit_move_insn (x, result);
      seq = end_ifcvt_sequence (if_info);
      if (!seq)
	return FALSE;

      emit_insn_before_setloc (seq, if_info->jump,
			       INSN_LOCATION (if_info->insn_a));
    }
  if_info->transform_name = "noce_try_bitop";
  return TRUE;
}


/* Similar to get_condition, only the resulting condition must be
   valid at JUMP, instead of at EARLIEST.

   If THEN_ELSE_REVERSED is true, the fallthrough does not go to the
   THEN block of the caller, and we have to reverse the condition.  */

static rtx
noce_get_condition (rtx_insn *jump, rtx_insn **earliest, bool then_else_reversed)
{
  rtx cond, set, tmp;
  bool reverse;

  if (! any_condjump_p (jump))
    return NULL_RTX;

  set = pc_set (jump);

  /* If this branches to JUMP_LABEL when the condition is false,
     reverse the condition.  */
  reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
	     && label_ref_label (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (jump));

  /* We may have to reverse because the caller's if block is not canonical,
     i.e. the THEN block isn't the fallthrough block for the TEST block
     (see find_if_header).  */
  if (then_else_reversed)
    reverse = !reverse;

  /* If the condition variable is a register and is MODE_INT, accept it.  */

  cond = XEXP (SET_SRC (set), 0);
  tmp = XEXP (cond, 0);
  if (REG_P (tmp) && GET_MODE_CLASS (GET_MODE (tmp)) == MODE_INT
      && (GET_MODE (tmp) != BImode
          || !targetm.small_register_classes_for_mode_p (BImode)))
    {
      *earliest = jump;

      if (reverse)
	cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
			       GET_MODE (cond), tmp, XEXP (cond, 1));
      return cond;
    }

  /* Otherwise, fall back on canonicalize_condition to do the dirty
     work of manipulating MODE_CC values and COMPARE rtx codes.  */
  tmp = canonicalize_condition (jump, cond, reverse, earliest,
				NULL_RTX, have_cbranchcc4, true);

  /* We don't handle side-effects in the condition, like handling
     REG_INC notes and making sure no duplicate conditions are emitted.  */
  if (tmp != NULL_RTX && side_effects_p (tmp))
    return NULL_RTX;

  return tmp;
}

/* Return true if OP is ok for if-then-else processing.  */

static int
noce_operand_ok (const_rtx op)
{
  if (side_effects_p (op))
    return FALSE;

  /* We special-case memories, so handle any of them with
     no address side effects.  */
  if (MEM_P (op))
    return ! side_effects_p (XEXP (op, 0));

  return ! may_trap_p (op);
}

/* Return true iff basic block TEST_BB is valid for noce if-conversion.
   The condition used in this if-conversion is in COND.
   In practice, check that TEST_BB ends with a single set
   x := a and all previous computations
   in TEST_BB don't produce any values that are live after TEST_BB.
   In other words, all the insns in TEST_BB are there only
   to compute a value for x.  Add the rtx cost of the insns
   in TEST_BB to COST.  Record whether TEST_BB is a single simple
   set instruction in SIMPLE_P.  */

static bool
bb_valid_for_noce_process_p (basic_block test_bb, rtx cond,
			      unsigned int *cost, bool *simple_p)
{
  if (!test_bb)
    return false;

  rtx_insn *last_insn = last_active_insn (test_bb, FALSE);
  rtx last_set = NULL_RTX;

  rtx cc = cc_in_cond (cond);

  if (!insn_valid_noce_process_p (last_insn, cc))
    return false;
  last_set = single_set (last_insn);

  rtx x = SET_DEST (last_set);
  rtx_insn *first_insn = first_active_insn (test_bb);
  rtx first_set = single_set (first_insn);

  if (!first_set)
    return false;

  /* We have a single simple set, that's okay.  */
  bool speed_p = optimize_bb_for_speed_p (test_bb);

  if (first_insn == last_insn)
    {
      *simple_p = noce_operand_ok (SET_DEST (first_set));
      *cost += pattern_cost (first_set, speed_p);
      return *simple_p;
    }

  rtx_insn *prev_last_insn = PREV_INSN (last_insn);
  gcc_assert (prev_last_insn);

  /* For now, disallow setting x multiple times in test_bb.  */
  if (REG_P (x) && reg_set_between_p (x, first_insn, prev_last_insn))
    return false;

  bitmap test_bb_temps = BITMAP_ALLOC (&reg_obstack);

  /* The regs that are live out of test_bb.  */
  bitmap test_bb_live_out = df_get_live_out (test_bb);

  int potential_cost = pattern_cost (last_set, speed_p);
  rtx_insn *insn;
  FOR_BB_INSNS (test_bb, insn)
    {
      if (insn != last_insn)
	{
	  if (!active_insn_p (insn))
	    continue;

	  if (!insn_valid_noce_process_p (insn, cc))
	    goto free_bitmap_and_fail;

	  rtx sset = single_set (insn);
	  gcc_assert (sset);

	  if (contains_mem_rtx_p (SET_SRC (sset))
	      || !REG_P (SET_DEST (sset))
	      || reg_overlap_mentioned_p (SET_DEST (sset), cond))
	    goto free_bitmap_and_fail;

	  potential_cost += pattern_cost (sset, speed_p);
	  bitmap_set_bit (test_bb_temps, REGNO (SET_DEST (sset)));
	}
    }

  /* If any of the intermediate results in test_bb are live after test_bb
     then fail.  */
  if (bitmap_intersect_p (test_bb_live_out, test_bb_temps))
    goto free_bitmap_and_fail;

  BITMAP_FREE (test_bb_temps);
  *cost += potential_cost;
  *simple_p = false;
  return true;

 free_bitmap_and_fail:
  BITMAP_FREE (test_bb_temps);
  return false;
}

/* We have something like:

     if (x > y)
       { i = a; j = b; k = c; }

   Make it:

     tmp_i = (x > y) ? a : i;
     tmp_j = (x > y) ? b : j;
     tmp_k = (x > y) ? c : k;
     i = tmp_i;
     j = tmp_j;
     k = tmp_k;

   Subsequent passes are expected to clean up the extra moves.

   Look for special cases such as writes to one register which are
   read back in another SET, as might occur in a swap idiom or
   similar.

   These look like:

   if (x > y)
     i = a;
     j = i;

   Which we want to rewrite to:

     tmp_i = (x > y) ? a : i;
     tmp_j = (x > y) ? tmp_i : j;
     i = tmp_i;
     j = tmp_j;

   We can catch these when looking at (SET x y) by keeping a list of the
   registers we would have targeted before if-conversion and looking back
   through it for an overlap with Y.  If we find one, we rewire the
   conditional set to use the temporary we introduced earlier.

   IF_INFO contains the useful information about the block structure and
   jump instructions.  */

static int
noce_convert_multiple_sets (struct noce_if_info *if_info)
{
  basic_block test_bb = if_info->test_bb;
  basic_block then_bb = if_info->then_bb;
  basic_block join_bb = if_info->join_bb;
  rtx_insn *jump = if_info->jump;
  rtx_insn *cond_earliest;
  rtx_insn *insn;

  start_sequence ();

  /* Decompose the condition attached to the jump.  */
  rtx cond = noce_get_condition (jump, &cond_earliest, false);
  rtx x = XEXP (cond, 0);
  rtx y = XEXP (cond, 1);
  rtx_code cond_code = GET_CODE (cond);

  /* The true targets for a conditional move.  */
  auto_vec<rtx> targets;
  /* The temporaries introduced to allow us to not consider register
     overlap.  */
  auto_vec<rtx> temporaries;
  /* The insns we've emitted.  */
  auto_vec<rtx_insn *> unmodified_insns;
  int count = 0;

  FOR_BB_INSNS (then_bb, insn)
    {
      /* Skip over non-insns.  */
      if (!active_insn_p (insn))
	continue;

      rtx set = single_set (insn);
      gcc_checking_assert (set);

      rtx target = SET_DEST (set);
      rtx temp = gen_reg_rtx (GET_MODE (target));
      rtx new_val = SET_SRC (set);
      rtx old_val = target;

      /* If we were supposed to read from an earlier write in this block,
	 we've changed the register allocation.  Rewire the read.  While
	 we are looking, also try to catch a swap idiom.  */
      for (int i = count - 1; i >= 0; --i)
	if (reg_overlap_mentioned_p (new_val, targets[i]))
	  {
	    /* Catch a "swap" style idiom.  */
	    if (find_reg_note (insn, REG_DEAD, new_val) != NULL_RTX)
	      /* The write to targets[i] is only live until the read
		 here.  As the condition codes match, we can propagate
		 the set to here.  */
	      new_val = SET_SRC (single_set (unmodified_insns[i]));
	    else
	      new_val = temporaries[i];
	    break;
	  }

      /* If we had a non-canonical conditional jump (i.e. one where
	 the fallthrough is to the "else" case) we need to reverse
	 the conditional select.  */
      if (if_info->then_else_reversed)
	std::swap (old_val, new_val);


      /* We allow simple lowpart register subreg SET sources in
	 bb_ok_for_noce_convert_multiple_sets.  Be careful when processing
	 sequences like:
	 (set (reg:SI r1) (reg:SI r2))
	 (set (reg:HI r3) (subreg:HI (r1)))
	 For the second insn new_val or old_val (r1 in this example) will be
	 taken from the temporaries and have the wider mode which will not
	 match with the mode of the other source of the conditional move, so
	 we'll end up trying to emit r4:HI = cond ? (r1:SI) : (r3:HI).
	 Wrap the two cmove operands into subregs if appropriate to prevent
	 that.  */
      if (GET_MODE (new_val) != GET_MODE (temp))
	{
	  machine_mode src_mode = GET_MODE (new_val);
	  machine_mode dst_mode = GET_MODE (temp);
	  if (!partial_subreg_p (dst_mode, src_mode))
	    {
	      end_sequence ();
	      return FALSE;
	    }
	  new_val = lowpart_subreg (dst_mode, new_val, src_mode);
	}
      if (GET_MODE (old_val) != GET_MODE (temp))
	{
	  machine_mode src_mode = GET_MODE (old_val);
	  machine_mode dst_mode = GET_MODE (temp);
	  if (!partial_subreg_p (dst_mode, src_mode))
	    {
	      end_sequence ();
	      return FALSE;
	    }
	  old_val = lowpart_subreg (dst_mode, old_val, src_mode);
	}

      /* Actually emit the conditional move.  */
      rtx temp_dest = noce_emit_cmove (if_info, temp, cond_code,
				       x, y, new_val, old_val);

      /* If we failed to expand the conditional move, drop out and don't
	 try to continue.  */
      if (temp_dest == NULL_RTX)
	{
	  end_sequence ();
	  return FALSE;
	}

      /* Bookkeeping.  */
      count++;
      targets.safe_push (target);
      temporaries.safe_push (temp_dest);
      unmodified_insns.safe_push (insn);
    }

  /* We must have seen some sort of insn to insert, otherwise we were
     given an empty BB to convert, and we can't handle that.  */
  gcc_assert (!unmodified_insns.is_empty ());

  /* Now fixup the assignments.  */
  for (int i = 0; i < count; i++)
    noce_emit_move_insn (targets[i], temporaries[i]);

  /* Actually emit the sequence if it isn't too expensive.  */
  rtx_insn *seq = get_insns ();

  if (!targetm.noce_conversion_profitable_p (seq, if_info))
    {
      end_sequence ();
      return FALSE;
    }

  for (insn = seq; insn; insn = NEXT_INSN (insn))
    set_used_flags (insn);

  /* Mark all our temporaries and targets as used.  */
  for (int i = 0; i < count; i++)
    {
      set_used_flags (temporaries[i]);
      set_used_flags (targets[i]);
    }

  set_used_flags (cond);
  set_used_flags (x);
  set_used_flags (y);

  unshare_all_rtl_in_chain (seq);
  end_sequence ();

  if (!seq)
    return FALSE;

  for (insn = seq; insn; insn = NEXT_INSN (insn))
    if (JUMP_P (insn)
	|| recog_memoized (insn) == -1)
      return FALSE;

  emit_insn_before_setloc (seq, if_info->jump,
			   INSN_LOCATION (unmodified_insns.last ()));

  /* Clean up THEN_BB and the edges in and out of it.  */
  remove_edge (find_edge (test_bb, join_bb));
  remove_edge (find_edge (then_bb, join_bb));
  redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb);
  delete_basic_block (then_bb);
  num_true_changes++;

  /* Maybe merge blocks now the jump is simple enough.  */
  if (can_merge_blocks_p (test_bb, join_bb))
    {
      merge_blocks (test_bb, join_bb);
      num_true_changes++;
    }

  num_updated_if_blocks++;
  if_info->transform_name = "noce_convert_multiple_sets";
  return TRUE;
}

/* Return true iff basic block TEST_BB is comprised of only
   (SET (REG) (REG)) insns suitable for conversion to a series
   of conditional moves.  Also check that we have more than one set
   (other routines can handle a single set better than we would), and
   fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets.  */

static bool
bb_ok_for_noce_convert_multiple_sets (basic_block test_bb)
{
  rtx_insn *insn;
  unsigned count = 0;
  unsigned param = param_max_rtl_if_conversion_insns;

  FOR_BB_INSNS (test_bb, insn)
    {
      /* Skip over notes etc.  */
      if (!active_insn_p (insn))
	continue;

      /* We only handle SET insns.  */
      rtx set = single_set (insn);
      if (set == NULL_RTX)
	return false;

      rtx dest = SET_DEST (set);
      rtx src = SET_SRC (set);

      /* We can possibly relax this, but for now only handle REG to REG
	 (including subreg) moves.  This avoids any issues that might come
	 from introducing loads/stores that might violate data-race-freedom
	 guarantees.  */
      if (!REG_P (dest))
	return false;

      if (!(REG_P (src)
	   || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
	       && subreg_lowpart_p (src))))
	return false;

      /* Destination must be appropriate for a conditional write.  */
      if (!noce_operand_ok (dest))
	return false;

      /* We must be able to conditionally move in this mode.  */
      if (!can_conditionally_move_p (GET_MODE (dest)))
	return false;

      count++;
    }

  /* If we would only put out one conditional move, the other strategies
     this pass tries are better optimized and will be more appropriate.
     Some targets want to strictly limit the number of conditional moves
     that are emitted, they set this through PARAM, we need to respect
     that.  */
  return count > 1 && count <= param;
}

/* Compute average of two given costs weighted by relative probabilities
   of respective basic blocks in an IF-THEN-ELSE.  E is the IF-THEN edge.
   With P as the probability to take the IF-THEN branch, return
   P * THEN_COST + (1 - P) * ELSE_COST.  */
static unsigned
average_cost (unsigned then_cost, unsigned else_cost, edge e)
{
  return else_cost + e->probability.apply ((signed) (then_cost - else_cost));
}

/* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
   it without using conditional execution.  Return TRUE if we were successful
   at converting the block.  */

static int
noce_process_if_block (struct noce_if_info *if_info)
{
  basic_block test_bb = if_info->test_bb;	/* test block */
  basic_block then_bb = if_info->then_bb;	/* THEN */
  basic_block else_bb = if_info->else_bb;	/* ELSE or NULL */
  basic_block join_bb = if_info->join_bb;	/* JOIN */
  rtx_insn *jump = if_info->jump;
  rtx cond = if_info->cond;
  rtx_insn *insn_a, *insn_b;
  rtx set_a, set_b;
  rtx orig_x, x, a, b;

  /* We're looking for patterns of the form

     (1) if (...) x = a; else x = b;
     (2) x = b; if (...) x = a;
     (3) if (...) x = a;   // as if with an initial x = x.
     (4) if (...) { x = a; y = b; z = c; }  // Like 3, for multiple SETS.
     The later patterns require jumps to be more expensive.
     For the if (...) x = a; else x = b; case we allow multiple insns
     inside the then and else blocks as long as their only effect is
     to calculate a value for x.
     ??? For future expansion, further expand the "multiple X" rules.  */

  /* First look for multiple SETS.  */
  if (!else_bb
      && HAVE_conditional_move
      && bb_ok_for_noce_convert_multiple_sets (then_bb))
    {
      if (noce_convert_multiple_sets (if_info))
	{
	  if (dump_file && if_info->transform_name)
	    fprintf (dump_file, "if-conversion succeeded through %s\n",
		     if_info->transform_name);
	  return TRUE;
	}
    }

  bool speed_p = optimize_bb_for_speed_p (test_bb);
  unsigned int then_cost = 0, else_cost = 0;
  if (!bb_valid_for_noce_process_p (then_bb, cond, &then_cost,
				    &if_info->then_simple))
    return false;

  if (else_bb
      && !bb_valid_for_noce_process_p (else_bb, cond, &else_cost,
				       &if_info->else_simple))
    return false;

  if (speed_p)
    if_info->original_cost += average_cost (then_cost, else_cost,
					    find_edge (test_bb, then_bb));
  else
    if_info->original_cost += then_cost + else_cost;

  insn_a = last_active_insn (then_bb, FALSE);
  set_a = single_set (insn_a);
  gcc_assert (set_a);

  x = SET_DEST (set_a);
  a = SET_SRC (set_a);

  /* Look for the other potential set.  Make sure we've got equivalent
     destinations.  */
  /* ??? This is overconservative.  Storing to two different mems is
     as easy as conditionally computing the address.  Storing to a
     single mem merely requires a scratch memory to use as one of the
     destination addresses; often the memory immediately below the
     stack pointer is available for this.  */
  set_b = NULL_RTX;
  if (else_bb)
    {
      insn_b = last_active_insn (else_bb, FALSE);
      set_b = single_set (insn_b);
      gcc_assert (set_b);

      if (!rtx_interchangeable_p (x, SET_DEST (set_b)))
	return FALSE;
    }
  else
    {
      insn_b = if_info->cond_earliest;
      do
	insn_b = prev_nonnote_nondebug_insn (insn_b);
      while (insn_b
	     && (BLOCK_FOR_INSN (insn_b)
		 == BLOCK_FOR_INSN (if_info->cond_earliest))
	     && !modified_in_p (x, insn_b));

      /* We're going to be moving the evaluation of B down from above
	 COND_EARLIEST to JUMP.  Make sure the relevant data is still
	 intact.  */
      if (! insn_b
	  || BLOCK_FOR_INSN (insn_b) != BLOCK_FOR_INSN (if_info->cond_earliest)
	  || !NONJUMP_INSN_P (insn_b)
	  || (set_b = single_set (insn_b)) == NULL_RTX
	  || ! rtx_interchangeable_p (x, SET_DEST (set_b))
	  || ! noce_operand_ok (SET_SRC (set_b))
	  || reg_overlap_mentioned_p (x, SET_SRC (set_b))
	  || modified_between_p (SET_SRC (set_b), insn_b, jump)
	  /* Avoid extending the lifetime of hard registers on small
	     register class machines.  */
	  || (REG_P (SET_SRC (set_b))
	      && HARD_REGISTER_P (SET_SRC (set_b))
	      && targetm.small_register_classes_for_mode_p
		   (GET_MODE (SET_SRC (set_b))))
	  /* Likewise with X.  In particular this can happen when
	     noce_get_condition looks farther back in the instruction
	     stream than one might expect.  */
	  || reg_overlap_mentioned_p (x, cond)
	  || reg_overlap_mentioned_p (x, a)
	  || modified_between_p (x, insn_b, jump))
	{
	  insn_b = NULL;
	  set_b = NULL_RTX;
	}
    }

  /* If x has side effects then only the if-then-else form is safe to
     convert.  But even in that case we would need to restore any notes
     (such as REG_INC) at then end.  That can be tricky if
     noce_emit_move_insn expands to more than one insn, so disable the
     optimization entirely for now if there are side effects.  */
  if (side_effects_p (x))
    return FALSE;

  b = (set_b ? SET_SRC (set_b) : x);

  /* Only operate on register destinations, and even then avoid extending
     the lifetime of hard registers on small register class machines.  */
  orig_x = x;
  if_info->orig_x = orig_x;
  if (!REG_P (x)
      || (HARD_REGISTER_P (x)
	  && targetm.small_register_classes_for_mode_p (GET_MODE (x))))
    {
      if (GET_MODE (x) == BLKmode)
	return FALSE;

      if (GET_CODE (x) == ZERO_EXTRACT
	  && (!CONST_INT_P (XEXP (x, 1))
	      || !CONST_INT_P (XEXP (x, 2))))
	return FALSE;

      x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART
				 ? XEXP (x, 0) : x));
    }

  /* Don't operate on sources that may trap or are volatile.  */
  if (! noce_operand_ok (a) || ! noce_operand_ok (b))
    return FALSE;

 retry:
  /* Set up the info block for our subroutines.  */
  if_info->insn_a = insn_a;
  if_info->insn_b = insn_b;
  if_info->x = x;
  if_info->a = a;
  if_info->b = b;

  /* Try optimizations in some approximation of a useful order.  */
  /* ??? Should first look to see if X is live incoming at all.  If it
     isn't, we don't need anything but an unconditional set.  */

  /* Look and see if A and B are really the same.  Avoid creating silly
     cmove constructs that no one will fix up later.  */
  if (noce_simple_bbs (if_info)
      && rtx_interchangeable_p (a, b))
    {
      /* If we have an INSN_B, we don't have to create any new rtl.  Just
	 move the instruction that we already have.  If we don't have an
	 INSN_B, that means that A == X, and we've got a noop move.  In
	 that case don't do anything and let the code below delete INSN_A.  */
      if (insn_b && else_bb)
	{
	  rtx note;

	  if (else_bb && insn_b == BB_END (else_bb))
	    BB_END (else_bb) = PREV_INSN (insn_b);
	  reorder_insns (insn_b, insn_b, PREV_INSN (jump));

	  /* If there was a REG_EQUAL note, delete it since it may have been
	     true due to this insn being after a jump.  */
	  if ((note = find_reg_note (insn_b, REG_EQUAL, NULL_RTX)) != 0)
	    remove_note (insn_b, note);

	  insn_b = NULL;
	}
      /* If we have "x = b; if (...) x = a;", and x has side-effects, then
	 x must be executed twice.  */
      else if (insn_b && side_effects_p (orig_x))
	return FALSE;

      x = orig_x;
      goto success;
    }

  if (!set_b && MEM_P (orig_x))
    /* We want to avoid store speculation to avoid cases like
	 if (pthread_mutex_trylock(mutex))
	   ++global_variable;
       Rather than go to much effort here, we rely on the SSA optimizers,
       which do a good enough job these days.  */
    return FALSE;

  if (noce_try_move (if_info))
    goto success;
  if (noce_try_ifelse_collapse (if_info))
    goto success;
  if (noce_try_store_flag (if_info))
    goto success;
  if (noce_try_bitop (if_info))
    goto success;
  if (noce_try_minmax (if_info))
    goto success;
  if (noce_try_abs (if_info))
    goto success;
  if (noce_try_inverse_constants (if_info))
    goto success;
  if (!targetm.have_conditional_execution ()
      && noce_try_store_flag_constants (if_info))
    goto success;
  if (HAVE_conditional_move
      && noce_try_cmove (if_info))
    goto success;
  if (! targetm.have_conditional_execution ())
    {
      if (noce_try_addcc (if_info))
	goto success;
      if (noce_try_store_flag_mask (if_info))
	goto success;
      if (HAVE_conditional_move
	  && noce_try_cmove_arith (if_info))
	goto success;
      if (noce_try_sign_mask (if_info))
	goto success;
    }

  if (!else_bb && set_b)
    {
      insn_b = NULL;
      set_b = NULL_RTX;
      b = orig_x;
      goto retry;
    }

  return FALSE;

 success:
  if (dump_file && if_info->transform_name)
    fprintf (dump_file, "if-conversion succeeded through %s\n",
	     if_info->transform_name);

  /* If we used a temporary, fix it up now.  */
  if (orig_x != x)
    {
      rtx_insn *seq;

      start_sequence ();
      noce_emit_move_insn (orig_x, x);
      seq = get_insns ();
      set_used_flags (orig_x);
      unshare_all_rtl_in_chain (seq);
      end_sequence ();

      emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATION (insn_a));
    }

  /* The original THEN and ELSE blocks may now be removed.  The test block
     must now jump to the join block.  If the test block and the join block
     can be merged, do so.  */
  if (else_bb)
    {
      delete_basic_block (else_bb);
      num_true_changes++;
    }
  else
    remove_edge (find_edge (test_bb, join_bb));

  remove_edge (find_edge (then_bb, join_bb));
  redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb);
  delete_basic_block (then_bb);
  num_true_changes++;

  if (can_merge_blocks_p (test_bb, join_bb))
    {
      merge_blocks (test_bb, join_bb);
      num_true_changes++;
    }

  num_updated_if_blocks++;
  return TRUE;
}

/* Check whether a block is suitable for conditional move conversion.
   Every insn must be a simple set of a register to a constant or a
   register.  For each assignment, store the value in the pointer map
   VALS, keyed indexed by register pointer, then store the register
   pointer in REGS.  COND is the condition we will test.  */

static int
check_cond_move_block (basic_block bb,
		       hash_map<rtx, rtx> *vals,
		       vec<rtx> *regs,
		       rtx cond)
{
  rtx_insn *insn;
  rtx cc = cc_in_cond (cond);

   /* We can only handle simple jumps at the end of the basic block.
      It is almost impossible to update the CFG otherwise.  */
  insn = BB_END (bb);
  if (JUMP_P (insn) && !onlyjump_p (insn))
    return FALSE;

  FOR_BB_INSNS (bb, insn)
    {
      rtx set, dest, src;

      if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
	continue;
      set = single_set (insn);
      if (!set)
	return FALSE;

      dest = SET_DEST (set);
      src = SET_SRC (set);
      if (!REG_P (dest)
	  || (HARD_REGISTER_P (dest)
	      && targetm.small_register_classes_for_mode_p (GET_MODE (dest))))
	return FALSE;

      if (!CONSTANT_P (src) && !register_operand (src, VOIDmode))
	return FALSE;

      if (side_effects_p (src) || side_effects_p (dest))
	return FALSE;

      if (may_trap_p (src) || may_trap_p (dest))
	return FALSE;

      /* Don't try to handle this if the source register was
	 modified earlier in the block.  */
      if ((REG_P (src)
	   && vals->get (src))
	  || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
	      && vals->get (SUBREG_REG (src))))
	return FALSE;

      /* Don't try to handle this if the destination register was
	 modified earlier in the block.  */
      if (vals->get (dest))
	return FALSE;

      /* Don't try to handle this if the condition uses the
	 destination register.  */
      if (reg_overlap_mentioned_p (dest, cond))
	return FALSE;

      /* Don't try to handle this if the source register is modified
	 later in the block.  */
      if (!CONSTANT_P (src)
	  && modified_between_p (src, insn, NEXT_INSN (BB_END (bb))))
	return FALSE;

      /* Skip it if the instruction to be moved might clobber CC.  */
      if (cc && set_of (cc, insn))
	return FALSE;

      vals->put (dest, src);

      regs->safe_push (dest);
    }

  return TRUE;
}

/* Given a basic block BB suitable for conditional move conversion,
   a condition COND, and pointer maps THEN_VALS and ELSE_VALS containing
   the register values depending on COND, emit the insns in the block as
   conditional moves.  If ELSE_BLOCK is true, THEN_BB was already
   processed.  The caller has started a sequence for the conversion.
   Return true if successful, false if something goes wrong.  */

static bool
cond_move_convert_if_block (struct noce_if_info *if_infop,
			    basic_block bb, rtx cond,
			    hash_map<rtx, rtx> *then_vals,
			    hash_map<rtx, rtx> *else_vals,
			    bool else_block_p)
{
  enum rtx_code code;
  rtx_insn *insn;
  rtx cond_arg0, cond_arg1;

  code = GET_CODE (cond);
  cond_arg0 = XEXP (cond, 0);
  cond_arg1 = XEXP (cond, 1);

  FOR_BB_INSNS (bb, insn)
    {
      rtx set, target, dest, t, e;

      /* ??? Maybe emit conditional debug insn?  */
      if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
	continue;
      set = single_set (insn);
      gcc_assert (set && REG_P (SET_DEST (set)));

      dest = SET_DEST (set);

      rtx *then_slot = then_vals->get (dest);
      rtx *else_slot = else_vals->get (dest);
      t = then_slot ? *then_slot : NULL_RTX;
      e = else_slot ? *else_slot : NULL_RTX;

      if (else_block_p)
	{
	  /* If this register was set in the then block, we already
	     handled this case there.  */
	  if (t)
	    continue;
	  t = dest;
	  gcc_assert (e);
	}
      else
	{
	  gcc_assert (t);
	  if (!e)
	    e = dest;
	}

      target = noce_emit_cmove (if_infop, dest, code, cond_arg0, cond_arg1,
				t, e);
      if (!target)
	return false;

      if (target != dest)
	noce_emit_move_insn (dest, target);
    }

  return true;
}

/* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
   it using only conditional moves.  Return TRUE if we were successful at
   converting the block.  */

static int
cond_move_process_if_block (struct noce_if_info *if_info)
{
  basic_block test_bb = if_info->test_bb;
  basic_block then_bb = if_info->then_bb;
  basic_block else_bb = if_info->else_bb;
  basic_block join_bb = if_info->join_bb;
  rtx_insn *jump = if_info->jump;
  rtx cond = if_info->cond;
  rtx_insn *seq, *loc_insn;
  int c;
  vec<rtx> then_regs = vNULL;
  vec<rtx> else_regs = vNULL;
  int success_p = FALSE;
  int limit = param_max_rtl_if_conversion_insns;

  /* Build a mapping for each block to the value used for each
     register.  */
  hash_map<rtx, rtx> then_vals;
  hash_map<rtx, rtx> else_vals;

  /* Make sure the blocks are suitable.  */
  if (!check_cond_move_block (then_bb, &then_vals, &then_regs, cond)
      || (else_bb
	  && !check_cond_move_block (else_bb, &else_vals, &else_regs, cond)))
    goto done;

  /* Make sure the blocks can be used together.  If the same register
     is set in both blocks, and is not set to a constant in both
     cases, then both blocks must set it to the same register.  We
     have already verified that if it is set to a register, that the
     source register does not change after the assignment.  Also count
     the number of registers set in only one of the blocks.  */
  c = 0;
  for (rtx reg : then_regs)
    {
      rtx *then_slot = then_vals.get (reg);
      rtx *else_slot = else_vals.get (reg);

      gcc_checking_assert (then_slot);
      if (!else_slot)
	++c;
      else
	{
	  rtx then_val = *then_slot;
	  rtx else_val = *else_slot;
	  if (!CONSTANT_P (then_val) && !CONSTANT_P (else_val)
	      && !rtx_equal_p (then_val, else_val))
	    goto done;
	}
    }

  /* Finish off c for MAX_CONDITIONAL_EXECUTE.  */
  for (rtx reg : else_regs)
    {
      gcc_checking_assert (else_vals.get (reg));
      if (!then_vals.get (reg))
	++c;
    }

  /* Make sure it is reasonable to convert this block.  What matters
     is the number of assignments currently made in only one of the
     branches, since if we convert we are going to always execute
     them.  */
  if (c > MAX_CONDITIONAL_EXECUTE
      || c > limit)
    goto done;

  /* Try to emit the conditional moves.  First do the then block,
     then do anything left in the else blocks.  */
  start_sequence ();
  if (!cond_move_convert_if_block (if_info, then_bb, cond,
				   &then_vals, &else_vals, false)
      || (else_bb
	  && !cond_move_convert_if_block (if_info, else_bb, cond,
					  &then_vals, &else_vals, true)))
    {
      end_sequence ();
      goto done;
    }
  seq = end_ifcvt_sequence (if_info);
  if (!seq)
    goto done;

  loc_insn = first_active_insn (then_bb);
  if (!loc_insn)
    {
      loc_insn = first_active_insn (else_bb);
      gcc_assert (loc_insn);
    }
  emit_insn_before_setloc (seq, jump, INSN_LOCATION (loc_insn));

  if (else_bb)
    {
      delete_basic_block (else_bb);
      num_true_changes++;
    }
  else
    remove_edge (find_edge (test_bb, join_bb));

  remove_edge (find_edge (then_bb, join_bb));
  redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb);
  delete_basic_block (then_bb);
  num_true_changes++;

  if (can_merge_blocks_p (test_bb, join_bb))
    {
      merge_blocks (test_bb, join_bb);
      num_true_changes++;
    }

  num_updated_if_blocks++;
  success_p = TRUE;

done:
  then_regs.release ();
  else_regs.release ();
  return success_p;
}


/* Determine if a given basic block heads a simple IF-THEN-JOIN or an
   IF-THEN-ELSE-JOIN block.

   If so, we'll try to convert the insns to not require the branch,
   using only transformations that do not require conditional execution.

   Return TRUE if we were successful at converting the block.  */

static int
noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge,
		    int pass)
{
  basic_block then_bb, else_bb, join_bb;
  bool then_else_reversed = false;
  rtx_insn *jump;
  rtx cond;
  rtx_insn *cond_earliest;
  struct noce_if_info if_info;
  bool speed_p = optimize_bb_for_speed_p (test_bb);

  /* We only ever should get here before reload.  */
  gcc_assert (!reload_completed);

  /* Recognize an IF-THEN-ELSE-JOIN block.  */
  if (single_pred_p (then_edge->dest)
      && single_succ_p (then_edge->dest)
      && single_pred_p (else_edge->dest)
      && single_succ_p (else_edge->dest)
      && single_succ (then_edge->dest) == single_succ (else_edge->dest))
    {
      then_bb = then_edge->dest;
      else_bb = else_edge->dest;
      join_bb = single_succ (then_bb);
    }
  /* Recognize an IF-THEN-JOIN block.  */
  else if (single_pred_p (then_edge->dest)
	   && single_succ_p (then_edge->dest)
	   && single_succ (then_edge->dest) == else_edge->dest)
    {
      then_bb = then_edge->dest;
      else_bb = NULL_BLOCK;
      join_bb = else_edge->dest;
    }
  /* Recognize an IF-ELSE-JOIN block.  We can have those because the order
     of basic blocks in cfglayout mode does not matter, so the fallthrough
     edge can go to any basic block (and not just to bb->next_bb, like in
     cfgrtl mode).  */
  else if (single_pred_p (else_edge->dest)
	   && single_succ_p (else_edge->dest)
	   && single_succ (else_edge->dest) == then_edge->dest)
    {
      /* The noce transformations do not apply to IF-ELSE-JOIN blocks.
	 To make this work, we have to invert the THEN and ELSE blocks
	 and reverse the jump condition.  */
      then_bb = else_edge->dest;
      else_bb = NULL_BLOCK;
      join_bb = single_succ (then_bb);
      then_else_reversed = true;
    }
  else
    /* Not a form we can handle.  */
    return FALSE;

  /* The edges of the THEN and ELSE blocks cannot have complex edges.  */
  if (single_succ_edge (then_bb)->flags & EDGE_COMPLEX)
    return FALSE;
  if (else_bb
      && single_succ_edge (else_bb)->flags & EDGE_COMPLEX)
    return FALSE;

  num_possible_if_blocks++;

  if (dump_file)
    {
      fprintf (dump_file,
	       "\nIF-THEN%s-JOIN block found, pass %d, test %d, then %d",
	       (else_bb) ? "-ELSE" : "",
	       pass, test_bb->index, then_bb->index);

      if (else_bb)
	fprintf (dump_file, ", else %d", else_bb->index);

      fprintf (dump_file, ", join %d\n", join_bb->index);
    }

  /* If the conditional jump is more than just a conditional
     jump, then we cannot do if-conversion on this block.  */
  jump = BB_END (test_bb);
  if (! onlyjump_p (jump))
    return FALSE;

  /* If this is not a standard conditional jump, we can't parse it.  */
  cond = noce_get_condition (jump, &cond_earliest, then_else_reversed);
  if (!cond)
    return FALSE;

  /* We must be comparing objects whose modes imply the size.  */
  if (GET_MODE (XEXP (cond, 0)) == BLKmode)
    return FALSE;

  /* Initialize an IF_INFO struct to pass around.  */
  memset (&if_info, 0, sizeof if_info);
  if_info.test_bb = test_bb;
  if_info.then_bb = then_bb;
  if_info.else_bb = else_bb;
  if_info.join_bb = join_bb;
  if_info.cond = cond;
  rtx_insn *rev_cond_earliest;
  if_info.rev_cond = noce_get_condition (jump, &rev_cond_earliest,
					 !then_else_reversed);
  gcc_assert (if_info.rev_cond == NULL_RTX
	      || rev_cond_earliest == cond_earliest);
  if_info.cond_earliest = cond_earliest;
  if_info.jump = jump;
  if_info.then_else_reversed = then_else_reversed;
  if_info.speed_p = speed_p;
  if_info.max_seq_cost
    = targetm.max_noce_ifcvt_seq_cost (then_edge);
  /* We'll add in the cost of THEN_BB and ELSE_BB later, when we check
     that they are valid to transform.  We can't easily get back to the insn
     for COND (and it may not exist if we had to canonicalize to get COND),
     and jump_insns are always given a cost of 1 by seq_cost, so treat
     both instructions as having cost COSTS_N_INSNS (1).  */
  if_info.original_cost = COSTS_N_INSNS (2);


  /* Do the real work.  */

  if (noce_process_if_block (&if_info))
    return TRUE;

  if (HAVE_conditional_move
      && cond_move_process_if_block (&if_info))
    return TRUE;

  return FALSE;
}


/* Merge the blocks and mark for local life update.  */

static void
merge_if_block (struct ce_if_block * ce_info)
{
  basic_block test_bb = ce_info->test_bb;	/* last test block */
  basic_block then_bb = ce_info->then_bb;	/* THEN */
  basic_block else_bb = ce_info->else_bb;	/* ELSE or NULL */
  basic_block join_bb = ce_info->join_bb;	/* join block */
  basic_block combo_bb;

  /* All block merging is done into the lower block numbers.  */

  combo_bb = test_bb;
  df_set_bb_dirty (test_bb);

  /* Merge any basic blocks to handle && and || subtests.  Each of
     the blocks are on the fallthru path from the predecessor block.  */
  if (ce_info->num_multiple_test_blocks > 0)
    {
      basic_block bb = test_bb;
      basic_block last_test_bb = ce_info->last_test_bb;
      basic_block fallthru = block_fallthru (bb);

      do
	{
	  bb = fallthru;
	  fallthru = block_fallthru (bb);
	  merge_blocks (combo_bb, bb);
	  num_true_changes++;
	}
      while (bb != last_test_bb);
    }

  /* Merge TEST block into THEN block.  Normally the THEN block won't have a
     label, but it might if there were || tests.  That label's count should be
     zero, and it normally should be removed.  */

  if (then_bb)
    {
      /* If THEN_BB has no successors, then there's a BARRIER after it.
	 If COMBO_BB has more than one successor (THEN_BB), then that BARRIER
	 is no longer needed, and in fact it is incorrect to leave it in
	 the insn stream.  */
      if (EDGE_COUNT (then_bb->succs) == 0
	  && EDGE_COUNT (combo_bb->succs) > 1)
	{
	  rtx_insn *end = NEXT_INSN (BB_END (then_bb));
	  while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
	    end = NEXT_INSN (end);

	  if (end && BARRIER_P (end))
	    delete_insn (end);
	}
      merge_blocks (combo_bb, then_bb);
      num_true_changes++;
    }

  /* The ELSE block, if it existed, had a label.  That label count
     will almost always be zero, but odd things can happen when labels
     get their addresses taken.  */
  if (else_bb)
    {
      /* If ELSE_BB has no successors, then there's a BARRIER after it.
	 If COMBO_BB has more than one successor (ELSE_BB), then that BARRIER
	 is no longer needed, and in fact it is incorrect to leave it in
	 the insn stream.  */
      if (EDGE_COUNT (else_bb->succs) == 0
	  && EDGE_COUNT (combo_bb->succs) > 1)
	{
	  rtx_insn *end = NEXT_INSN (BB_END (else_bb));
	  while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
	    end = NEXT_INSN (end);

	  if (end && BARRIER_P (end))
	    delete_insn (end);
	}
      merge_blocks (combo_bb, else_bb);
      num_true_changes++;
    }

  /* If there was no join block reported, that means it was not adjacent
     to the others, and so we cannot merge them.  */

  if (! join_bb)
    {
      rtx_insn *last = BB_END (combo_bb);

      /* The outgoing edge for the current COMBO block should already
	 be correct.  Verify this.  */
      if (EDGE_COUNT (combo_bb->succs) == 0)
	gcc_assert (find_reg_note (last, REG_NORETURN, NULL)
		    || (NONJUMP_INSN_P (last)
			&& GET_CODE (PATTERN (last)) == TRAP_IF
			&& (TRAP_CONDITION (PATTERN (last))
			    == const_true_rtx)));

      else
      /* There should still be something at the end of the THEN or ELSE
         blocks taking us to our final destination.  */
	gcc_assert (JUMP_P (last)
		    || (EDGE_SUCC (combo_bb, 0)->dest
			== EXIT_BLOCK_PTR_FOR_FN (cfun)
			&& CALL_P (last)
			&& SIBLING_CALL_P (last))
		    || ((EDGE_SUCC (combo_bb, 0)->flags & EDGE_EH)
			&& can_throw_internal (last)));
    }

  /* The JOIN block may have had quite a number of other predecessors too.
     Since we've already merged the TEST, THEN and ELSE blocks, we should
     have only one remaining edge from our if-then-else diamond.  If there
     is more than one remaining edge, it must come from elsewhere.  There
     may be zero incoming edges if the THEN block didn't actually join
     back up (as with a call to a non-return function).  */
  else if (EDGE_COUNT (join_bb->preds) < 2
	   && join_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      /* We can merge the JOIN cleanly and update the dataflow try
	 again on this pass.*/
      merge_blocks (combo_bb, join_bb);
      num_true_changes++;
    }
  else
    {
      /* We cannot merge the JOIN.  */

      /* The outgoing edge for the current COMBO block should already
	 be correct.  Verify this.  */
      gcc_assert (single_succ_p (combo_bb)
		  && single_succ (combo_bb) == join_bb);

      /* Remove the jump and cruft from the end of the COMBO block.  */
      if (join_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
	tidy_fallthru_edge (single_succ_edge (combo_bb));
    }

  num_updated_if_blocks++;
}

/* Find a block ending in a simple IF condition and try to transform it
   in some way.  When converting a multi-block condition, put the new code
   in the first such block and delete the rest.  Return a pointer to this
   first block if some transformation was done.  Return NULL otherwise.  */

static basic_block
find_if_header (basic_block test_bb, int pass)
{
  ce_if_block ce_info;
  edge then_edge;
  edge else_edge;

  /* The kind of block we're looking for has exactly two successors.  */
  if (EDGE_COUNT (test_bb->succs) != 2)
    return NULL;

  then_edge = EDGE_SUCC (test_bb, 0);
  else_edge = EDGE_SUCC (test_bb, 1);

  if (df_get_bb_dirty (then_edge->dest))
    return NULL;
  if (df_get_bb_dirty (else_edge->dest))
    return NULL;

  /* Neither edge should be abnormal.  */
  if ((then_edge->flags & EDGE_COMPLEX)
      || (else_edge->flags & EDGE_COMPLEX))
    return NULL;

  /* Nor exit the loop.  */
  if ((then_edge->flags & EDGE_LOOP_EXIT)
      || (else_edge->flags & EDGE_LOOP_EXIT))
    return NULL;

  /* The THEN edge is canonically the one that falls through.  */
  if (then_edge->flags & EDGE_FALLTHRU)
    ;
  else if (else_edge->flags & EDGE_FALLTHRU)
    std::swap (then_edge, else_edge);
  else
    /* Otherwise this must be a multiway branch of some sort.  */
    return NULL;

  memset (&ce_info, 0, sizeof (ce_info));
  ce_info.test_bb = test_bb;
  ce_info.then_bb = then_edge->dest;
  ce_info.else_bb = else_edge->dest;
  ce_info.pass = pass;

#ifdef IFCVT_MACHDEP_INIT
  IFCVT_MACHDEP_INIT (&ce_info);
#endif

  if (!reload_completed
      && noce_find_if_block (test_bb, then_edge, else_edge, pass))
    goto success;

  if (reload_completed
      && targetm.have_conditional_execution ()
      && cond_exec_find_if_block (&ce_info))
    goto success;

  if (targetm.have_trap ()
      && optab_handler (ctrap_optab, word_mode) != CODE_FOR_nothing
      && find_cond_trap (test_bb, then_edge, else_edge))
    goto success;

  if (dom_info_state (CDI_POST_DOMINATORS) >= DOM_NO_FAST_QUERY
      && (reload_completed || !targetm.have_conditional_execution ()))
    {
      if (find_if_case_1 (test_bb, then_edge, else_edge))
	goto success;
      if (find_if_case_2 (test_bb, then_edge, else_edge))
	goto success;
    }

  return NULL;

 success:
  if (dump_file)
    fprintf (dump_file, "Conversion succeeded on pass %d.\n", pass);
  /* Set this so we continue looking.  */
  cond_exec_changed_p = TRUE;
  return ce_info.test_bb;
}

/* Return true if a block has two edges, one of which falls through to the next
   block, and the other jumps to a specific block, so that we can tell if the
   block is part of an && test or an || test.  Returns either -1 or the number
   of non-note, non-jump, non-USE/CLOBBER insns in the block.  */

static int
block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb)
{
  edge cur_edge;
  int fallthru_p = FALSE;
  int jump_p = FALSE;
  rtx_insn *insn;
  rtx_insn *end;
  int n_insns = 0;
  edge_iterator ei;

  if (!cur_bb || !target_bb)
    return -1;

  /* If no edges, obviously it doesn't jump or fallthru.  */
  if (EDGE_COUNT (cur_bb->succs) == 0)
    return FALSE;

  FOR_EACH_EDGE (cur_edge, ei, cur_bb->succs)
    {
      if (cur_edge->flags & EDGE_COMPLEX)
	/* Anything complex isn't what we want.  */
	return -1;

      else if (cur_edge->flags & EDGE_FALLTHRU)
	fallthru_p = TRUE;

      else if (cur_edge->dest == target_bb)
	jump_p = TRUE;

      else
	return -1;
    }

  if ((jump_p & fallthru_p) == 0)
    return -1;

  /* Don't allow calls in the block, since this is used to group && and ||
     together for conditional execution support.  ??? we should support
     conditional execution support across calls for IA-64 some day, but
     for now it makes the code simpler.  */
  end = BB_END (cur_bb);
  insn = BB_HEAD (cur_bb);

  while (insn != NULL_RTX)
    {
      if (CALL_P (insn))
	return -1;

      if (INSN_P (insn)
	  && !JUMP_P (insn)
	  && !DEBUG_INSN_P (insn)
	  && GET_CODE (PATTERN (insn)) != USE
	  && GET_CODE (PATTERN (insn)) != CLOBBER)
	n_insns++;

      if (insn == end)
	break;

      insn = NEXT_INSN (insn);
    }

  return n_insns;
}

/* Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE
   block.  If so, we'll try to convert the insns to not require the branch.
   Return TRUE if we were successful at converting the block.  */

static int
cond_exec_find_if_block (struct ce_if_block * ce_info)
{
  basic_block test_bb = ce_info->test_bb;
  basic_block then_bb = ce_info->then_bb;
  basic_block else_bb = ce_info->else_bb;
  basic_block join_bb = NULL_BLOCK;
  edge cur_edge;
  basic_block next;
  edge_iterator ei;

  ce_info->last_test_bb = test_bb;

  /* We only ever should get here after reload,
     and if we have conditional execution.  */
  gcc_assert (reload_completed && targetm.have_conditional_execution ());

  /* Discover if any fall through predecessors of the current test basic block
     were && tests (which jump to the else block) or || tests (which jump to
     the then block).  */
  if (single_pred_p (test_bb)
      && single_pred_edge (test_bb)->flags == EDGE_FALLTHRU)
    {
      basic_block bb = single_pred (test_bb);
      basic_block target_bb;
      int max_insns = MAX_CONDITIONAL_EXECUTE;
      int n_insns;

      /* Determine if the preceding block is an && or || block.  */
      if ((n_insns = block_jumps_and_fallthru_p (bb, else_bb)) >= 0)
	{
	  ce_info->and_and_p = TRUE;
	  target_bb = else_bb;
	}
      else if ((n_insns = block_jumps_and_fallthru_p (bb, then_bb)) >= 0)
	{
	  ce_info->and_and_p = FALSE;
	  target_bb = then_bb;
	}
      else
	target_bb = NULL_BLOCK;

      if (target_bb && n_insns <= max_insns)
	{
	  int total_insns = 0;
	  int blocks = 0;

	  ce_info->last_test_bb = test_bb;

	  /* Found at least one && or || block, look for more.  */
	  do
	    {
	      ce_info->test_bb = test_bb = bb;
	      total_insns += n_insns;
	      blocks++;

	      if (!single_pred_p (bb))
		break;

	      bb = single_pred (bb);
	      n_insns = block_jumps_and_fallthru_p (bb, target_bb);
	    }
	  while (n_insns >= 0 && (total_insns + n_insns) <= max_insns);

	  ce_info->num_multiple_test_blocks = blocks;
	  ce_info->num_multiple_test_insns = total_insns;

	  if (ce_info->and_and_p)
	    ce_info->num_and_and_blocks = blocks;
	  else
	    ce_info->num_or_or_blocks = blocks;
	}
    }

  /* The THEN block of an IF-THEN combo must have exactly one predecessor,
     other than any || blocks which jump to the THEN block.  */
  if ((EDGE_COUNT (then_bb->preds) - ce_info->num_or_or_blocks) != 1)
    return FALSE;

  /* The edges of the THEN and ELSE blocks cannot have complex edges.  */
  FOR_EACH_EDGE (cur_edge, ei, then_bb->preds)
    {
      if (cur_edge->flags & EDGE_COMPLEX)
	return FALSE;
    }

  FOR_EACH_EDGE (cur_edge, ei, else_bb->preds)
    {
      if (cur_edge->flags & EDGE_COMPLEX)
	return FALSE;
    }

  /* The THEN block of an IF-THEN combo must have zero or one successors.  */
  if (EDGE_COUNT (then_bb->succs) > 0
      && (!single_succ_p (then_bb)
          || (single_succ_edge (then_bb)->flags & EDGE_COMPLEX)
	  || (epilogue_completed
	      && tablejump_p (BB_END (then_bb), NULL, NULL))))
    return FALSE;

  /* If the THEN block has no successors, conditional execution can still
     make a conditional call.  Don't do this unless the ELSE block has
     only one incoming edge -- the CFG manipulation is too ugly otherwise.
     Check for the last insn of the THEN block being an indirect jump, which
     is listed as not having any successors, but confuses the rest of the CE
     code processing.  ??? we should fix this in the future.  */
  if (EDGE_COUNT (then_bb->succs) == 0)
    {
      if (single_pred_p (else_bb) && else_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
	{
	  rtx_insn *last_insn = BB_END (then_bb);

	  while (last_insn
		 && NOTE_P (last_insn)
		 && last_insn != BB_HEAD (then_bb))
	    last_insn = PREV_INSN (last_insn);

	  if (last_insn
	      && JUMP_P (last_insn)
	      && ! simplejump_p (last_insn))
	    return FALSE;

	  join_bb = else_bb;
	  else_bb = NULL_BLOCK;
	}
      else
	return FALSE;
    }

  /* If the THEN block's successor is the other edge out of the TEST block,
     then we have an IF-THEN combo without an ELSE.  */
  else if (single_succ (then_bb) == else_bb)
    {
      join_bb = else_bb;
      else_bb = NULL_BLOCK;
    }

  /* If the THEN and ELSE block meet in a subsequent block, and the ELSE
     has exactly one predecessor and one successor, and the outgoing edge
     is not complex, then we have an IF-THEN-ELSE combo.  */
  else if (single_succ_p (else_bb)
	   && single_succ (then_bb) == single_succ (else_bb)
	   && single_pred_p (else_bb)
	   && !(single_succ_edge (else_bb)->flags & EDGE_COMPLEX)
	   && !(epilogue_completed
		&& tablejump_p (BB_END (else_bb), NULL, NULL)))
    join_bb = single_succ (else_bb);

  /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination.  */
  else
    return FALSE;

  num_possible_if_blocks++;

  if (dump_file)
    {
      fprintf (dump_file,
	       "\nIF-THEN%s block found, pass %d, start block %d "
	       "[insn %d], then %d [%d]",
	       (else_bb) ? "-ELSE" : "",
	       ce_info->pass,
	       test_bb->index,
	       BB_HEAD (test_bb) ? (int)INSN_UID (BB_HEAD (test_bb)) : -1,
	       then_bb->index,
	       BB_HEAD (then_bb) ? (int)INSN_UID (BB_HEAD (then_bb)) : -1);

      if (else_bb)
	fprintf (dump_file, ", else %d [%d]",
		 else_bb->index,
		 BB_HEAD (else_bb) ? (int)INSN_UID (BB_HEAD (else_bb)) : -1);

      fprintf (dump_file, ", join %d [%d]",
	       join_bb->index,
	       BB_HEAD (join_bb) ? (int)INSN_UID (BB_HEAD (join_bb)) : -1);

      if (ce_info->num_multiple_test_blocks > 0)
	fprintf (dump_file, ", %d %s block%s last test %d [%d]",
		 ce_info->num_multiple_test_blocks,
		 (ce_info->and_and_p) ? "&&" : "||",
		 (ce_info->num_multiple_test_blocks == 1) ? "" : "s",
		 ce_info->last_test_bb->index,
		 ((BB_HEAD (ce_info->last_test_bb))
		  ? (int)INSN_UID (BB_HEAD (ce_info->last_test_bb))
		  : -1));

      fputc ('\n', dump_file);
    }

  /* Make sure IF, THEN, and ELSE, blocks are adjacent.  Actually, we get the
     first condition for free, since we've already asserted that there's a
     fallthru edge from IF to THEN.  Likewise for the && and || blocks, since
     we checked the FALLTHRU flag, those are already adjacent to the last IF
     block.  */
  /* ??? As an enhancement, move the ELSE block.  Have to deal with
     BLOCK notes, if by no other means than backing out the merge if they
     exist.  Sticky enough I don't want to think about it now.  */
  next = then_bb;
  if (else_bb && (next = next->next_bb) != else_bb)
    return FALSE;
  if ((next = next->next_bb) != join_bb
      && join_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      if (else_bb)
	join_bb = NULL;
      else
	return FALSE;
    }

  /* Do the real work.  */

  ce_info->else_bb = else_bb;
  ce_info->join_bb = join_bb;

  /* If we have && and || tests, try to first handle combining the && and ||
     tests into the conditional code, and if that fails, go back and handle
     it without the && and ||, which at present handles the && case if there
     was no ELSE block.  */
  if (cond_exec_process_if_block (ce_info, TRUE))
    return TRUE;

  if (ce_info->num_multiple_test_blocks)
    {
      cancel_changes (0);

      if (cond_exec_process_if_block (ce_info, FALSE))
	return TRUE;
    }

  return FALSE;
}

/* Convert a branch over a trap, or a branch
   to a trap, into a conditional trap.  */

static int
find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
{
  basic_block then_bb = then_edge->dest;
  basic_block else_bb = else_edge->dest;
  basic_block other_bb, trap_bb;
  rtx_insn *trap, *jump;
  rtx cond;
  rtx_insn *cond_earliest;

  /* Locate the block with the trap instruction.  */
  /* ??? While we look for no successors, we really ought to allow
     EH successors.  Need to fix merge_if_block for that to work.  */
  if ((trap = block_has_only_trap (then_bb)) != NULL)
    trap_bb = then_bb, other_bb = else_bb;
  else if ((trap = block_has_only_trap (else_bb)) != NULL)
    trap_bb = else_bb, other_bb = then_bb;
  else
    return FALSE;

  if (dump_file)
    {
      fprintf (dump_file, "\nTRAP-IF block found, start %d, trap %d\n",
	       test_bb->index, trap_bb->index);
    }

  /* If this is not a standard conditional jump, we can't parse it.  */
  jump = BB_END (test_bb);
  cond = noce_get_condition (jump, &cond_earliest, then_bb == trap_bb);
  if (! cond)
    return FALSE;

  /* If the conditional jump is more than just a conditional jump, then
     we cannot do if-conversion on this block.  Give up for returnjump_p,
     changing a conditional return followed by unconditional trap for
     conditional trap followed by unconditional return is likely not
     beneficial and harder to handle.  */
  if (! onlyjump_p (jump) || returnjump_p (jump))
    return FALSE;

  /* We must be comparing objects whose modes imply the size.  */
  if (GET_MODE (XEXP (cond, 0)) == BLKmode)
    return FALSE;

  /* Attempt to generate the conditional trap.  */
  rtx_insn *seq = gen_cond_trap (GET_CODE (cond), copy_rtx (XEXP (cond, 0)),
				 copy_rtx (XEXP (cond, 1)),
				 TRAP_CODE (PATTERN (trap)));
  if (seq == NULL)
    return FALSE;

  /* If that results in an invalid insn, back out.  */
  for (rtx_insn *x = seq; x; x = NEXT_INSN (x))
    if (recog_memoized (x) < 0)
      return FALSE;

  /* Emit the new insns before cond_earliest.  */
  emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATION (trap));

  /* Delete the trap block if possible.  */
  remove_edge (trap_bb == then_bb ? then_edge : else_edge);
  df_set_bb_dirty (test_bb);
  df_set_bb_dirty (then_bb);
  df_set_bb_dirty (else_bb);

  if (EDGE_COUNT (trap_bb->preds) == 0)
    {
      delete_basic_block (trap_bb);
      num_true_changes++;
    }

  /* Wire together the blocks again.  */
  if (current_ir_type () == IR_RTL_CFGLAYOUT)
    single_succ_edge (test_bb)->flags |= EDGE_FALLTHRU;
  else if (trap_bb == then_bb)
    {
      rtx lab = JUMP_LABEL (jump);
      rtx_insn *seq = targetm.gen_jump (lab);
      rtx_jump_insn *newjump = emit_jump_insn_after (seq, jump);
      LABEL_NUSES (lab) += 1;
      JUMP_LABEL (newjump) = lab;
      emit_barrier_after (newjump);
    }
  delete_insn (jump);

  if (can_merge_blocks_p (test_bb, other_bb))
    {
      merge_blocks (test_bb, other_bb);
      num_true_changes++;
    }

  num_updated_if_blocks++;
  return TRUE;
}

/* Subroutine of find_cond_trap: if BB contains only a trap insn,
   return it.  */

static rtx_insn *
block_has_only_trap (basic_block bb)
{
  rtx_insn *trap;

  /* We're not the exit block.  */
  if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    return NULL;

  /* The block must have no successors.  */
  if (EDGE_COUNT (bb->succs) > 0)
    return NULL;

  /* The only instruction in the THEN block must be the trap.  */
  trap = first_active_insn (bb);
  if (! (trap == BB_END (bb)
	 && GET_CODE (PATTERN (trap)) == TRAP_IF
         && TRAP_CONDITION (PATTERN (trap)) == const_true_rtx))
    return NULL;

  return trap;
}

/* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
   transformable, but not necessarily the other.  There need be no
   JOIN block.

   Return TRUE if we were successful at converting the block.

   Cases we'd like to look at:

   (1)
	if (test) goto over; // x not live
	x = a;
	goto label;
	over:

   becomes

	x = a;
	if (! test) goto label;

   (2)
	if (test) goto E; // x not live
	x = big();
	goto L;
	E:
	x = b;
	goto M;

   becomes

	x = b;
	if (test) goto M;
	x = big();
	goto L;

   (3) // This one's really only interesting for targets that can do
       // multiway branching, e.g. IA-64 BBB bundles.  For other targets
       // it results in multiple branches on a cache line, which often
       // does not sit well with predictors.

	if (test1) goto E; // predicted not taken
	x = a;
	if (test2) goto F;
	...
	E:
	x = b;
	J:

   becomes

	x = a;
	if (test1) goto E;
	if (test2) goto F;

   Notes:

   (A) Don't do (2) if the branch is predicted against the block we're
   eliminating.  Do it anyway if we can eliminate a branch; this requires
   that the sole successor of the eliminated block postdominate the other
   side of the if.

   (B) With CE, on (3) we can steal from both sides of the if, creating

	if (test1) x = a;
	if (!test1) x = b;
	if (test1) goto J;
	if (test2) goto F;
	...
	J:

   Again, this is most useful if J postdominates.

   (C) CE substitutes for helpful life information.

   (D) These heuristics need a lot of work.  */

/* Tests for case 1 above.  */

static int
find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
{
  basic_block then_bb = then_edge->dest;
  basic_block else_bb = else_edge->dest;
  basic_block new_bb;
  int then_bb_index;
  profile_probability then_prob;
  rtx else_target = NULL_RTX;

  /* If we are partitioning hot/cold basic blocks, we don't want to
     mess up unconditional or indirect jumps that cross between hot
     and cold sections.

     Basic block partitioning may result in some jumps that appear to
     be optimizable (or blocks that appear to be mergeable), but which really
     must be left untouched (they are required to make it safely across
     partition boundaries).  See  the comments at the top of
     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */

  if ((BB_END (then_bb)
       && JUMP_P (BB_END (then_bb))
       && CROSSING_JUMP_P (BB_END (then_bb)))
      || (BB_END (test_bb)
	  && JUMP_P (BB_END (test_bb))
	  && CROSSING_JUMP_P (BB_END (test_bb)))
      || (BB_END (else_bb)
	  && JUMP_P (BB_END (else_bb))
	  && CROSSING_JUMP_P (BB_END (else_bb))))
    return FALSE;

  /* THEN has one successor.  */
  if (!single_succ_p (then_bb))
    return FALSE;

  /* THEN does not fall through, but is not strange either.  */
  if (single_succ_edge (then_bb)->flags & (EDGE_COMPLEX | EDGE_FALLTHRU))
    return FALSE;

  /* THEN has one predecessor.  */
  if (!single_pred_p (then_bb))
    return FALSE;

  /* THEN must do something.  */
  if (forwarder_block_p (then_bb))
    return FALSE;

  num_possible_if_blocks++;
  if (dump_file)
    fprintf (dump_file,
	     "\nIF-CASE-1 found, start %d, then %d\n",
	     test_bb->index, then_bb->index);

  then_prob = then_edge->probability.invert ();

  /* We're speculating from the THEN path, we want to make sure the cost
     of speculation is within reason.  */
  if (! cheap_bb_rtx_cost_p (then_bb, then_prob,
	COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (then_edge->src),
				    predictable_edge_p (then_edge)))))
    return FALSE;

  if (else_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      rtx_insn *jump = BB_END (else_edge->src);
      gcc_assert (JUMP_P (jump));
      else_target = JUMP_LABEL (jump);
    }

  /* Registers set are dead, or are predicable.  */
  if (! dead_or_predicable (test_bb, then_bb, else_bb,
			    single_succ_edge (then_bb), 1))
    return FALSE;

  /* Conversion went ok, including moving the insns and fixing up the
     jump.  Adjust the CFG to match.  */

  /* We can avoid creating a new basic block if then_bb is immediately
     followed by else_bb, i.e. deleting then_bb allows test_bb to fall
     through to else_bb.  */

  if (then_bb->next_bb == else_bb
      && then_bb->prev_bb == test_bb
      && else_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
    {
      redirect_edge_succ (FALLTHRU_EDGE (test_bb), else_bb);
      new_bb = 0;
    }
  else if (else_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
    new_bb = force_nonfallthru_and_redirect (FALLTHRU_EDGE (test_bb),
					     else_bb, else_target);
  else
    new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb),
					     else_bb);

  df_set_bb_dirty (test_bb);
  df_set_bb_dirty (else_bb);

  then_bb_index = then_bb->index;
  delete_basic_block (then_bb);

  /* Make rest of code believe that the newly created block is the THEN_BB
     block we removed.  */
  if (new_bb)
    {
      df_bb_replace (then_bb_index, new_bb);
      /* This should have been done above via force_nonfallthru_and_redirect
         (possibly called from redirect_edge_and_branch_force).  */
      gcc_checking_assert (BB_PARTITION (new_bb) == BB_PARTITION (test_bb));
    }

  num_true_changes++;
  num_updated_if_blocks++;
  return TRUE;
}

/* Test for case 2 above.  */

static int
find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
{
  basic_block then_bb = then_edge->dest;
  basic_block else_bb = else_edge->dest;
  edge else_succ;
  profile_probability then_prob, else_prob;

  /* We do not want to speculate (empty) loop latches.  */
  if (current_loops
      && else_bb->loop_father->latch == else_bb)
    return FALSE;

  /* If we are partitioning hot/cold basic blocks, we don't want to
     mess up unconditional or indirect jumps that cross between hot
     and cold sections.

     Basic block partitioning may result in some jumps that appear to
     be optimizable (or blocks that appear to be mergeable), but which really
     must be left untouched (they are required to make it safely across
     partition boundaries).  See  the comments at the top of
     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */

  if ((BB_END (then_bb)
       && JUMP_P (BB_END (then_bb))
       && CROSSING_JUMP_P (BB_END (then_bb)))
      || (BB_END (test_bb)
	  && JUMP_P (BB_END (test_bb))
	  && CROSSING_JUMP_P (BB_END (test_bb)))
      || (BB_END (else_bb)
	  && JUMP_P (BB_END (else_bb))
	  && CROSSING_JUMP_P (BB_END (else_bb))))
    return FALSE;

  /* ELSE has one successor.  */
  if (!single_succ_p (else_bb))
    return FALSE;
  else
    else_succ = single_succ_edge (else_bb);

  /* ELSE outgoing edge is not complex.  */
  if (else_succ->flags & EDGE_COMPLEX)
    return FALSE;

  /* ELSE has one predecessor.  */
  if (!single_pred_p (else_bb))
    return FALSE;

  /* THEN is not EXIT.  */
  if (then_bb->index < NUM_FIXED_BLOCKS)
    return FALSE;

  else_prob = else_edge->probability;
  then_prob = else_prob.invert ();

  /* ELSE is predicted or SUCC(ELSE) postdominates THEN.  */
  if (else_prob > then_prob)
    ;
  else if (else_succ->dest->index < NUM_FIXED_BLOCKS
	   || dominated_by_p (CDI_POST_DOMINATORS, then_bb,
			      else_succ->dest))
    ;
  else
    return FALSE;

  num_possible_if_blocks++;
  if (dump_file)
    fprintf (dump_file,
	     "\nIF-CASE-2 found, start %d, else %d\n",
	     test_bb->index, else_bb->index);

  /* We're speculating from the ELSE path, we want to make sure the cost
     of speculation is within reason.  */
  if (! cheap_bb_rtx_cost_p (else_bb, else_prob,
	COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (else_edge->src),
				    predictable_edge_p (else_edge)))))
    return FALSE;

  /* Registers set are dead, or are predicable.  */
  if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ, 0))
    return FALSE;

  /* Conversion went ok, including moving the insns and fixing up the
     jump.  Adjust the CFG to match.  */

  df_set_bb_dirty (test_bb);
  df_set_bb_dirty (then_bb);
  delete_basic_block (else_bb);

  num_true_changes++;
  num_updated_if_blocks++;

  /* ??? We may now fallthru from one of THEN's successors into a join
     block.  Rerun cleanup_cfg?  Examine things manually?  Wait?  */

  return TRUE;
}

/* Used by the code above to perform the actual rtl transformations.
   Return TRUE if successful.

   TEST_BB is the block containing the conditional branch.  MERGE_BB
   is the block containing the code to manipulate.  DEST_EDGE is an
   edge representing a jump to the join block; after the conversion,
   TEST_BB should be branching to its destination.
   REVERSEP is true if the sense of the branch should be reversed.  */

static int
dead_or_predicable (basic_block test_bb, basic_block merge_bb,
		    basic_block other_bb, edge dest_edge, int reversep)
{
  basic_block new_dest = dest_edge->dest;
  rtx_insn *head, *end, *jump;
  rtx_insn *earliest = NULL;
  rtx old_dest;
  bitmap merge_set = NULL;
  /* Number of pending changes.  */
  int n_validated_changes = 0;
  rtx new_dest_label = NULL_RTX;

  jump = BB_END (test_bb);

  /* Find the extent of the real code in the merge block.  */
  head = BB_HEAD (merge_bb);
  end = BB_END (merge_bb);

  while (DEBUG_INSN_P (end) && end != head)
    end = PREV_INSN (end);

  /* If merge_bb ends with a tablejump, predicating/moving insn's
     into test_bb and then deleting merge_bb will result in the jumptable
     that follows merge_bb being removed along with merge_bb and then we
     get an unresolved reference to the jumptable.  */
  if (tablejump_p (end, NULL, NULL))
    return FALSE;

  if (LABEL_P (head))
    head = NEXT_INSN (head);
  while (DEBUG_INSN_P (head) && head != end)
    head = NEXT_INSN (head);
  if (NOTE_P (head))
    {
      if (head == end)
	{
	  head = end = NULL;
	  goto no_body;
	}
      head = NEXT_INSN (head);
      while (DEBUG_INSN_P (head) && head != end)
	head = NEXT_INSN (head);
    }

  if (JUMP_P (end))
    {
      if (!onlyjump_p (end))
	return FALSE;
      if (head == end)
	{
	  head = end = NULL;
	  goto no_body;
	}
      end = PREV_INSN (end);
      while (DEBUG_INSN_P (end) && end != head)
	end = PREV_INSN (end);
    }

  /* Don't move frame-related insn across the conditional branch.  This
     can lead to one of the paths of the branch having wrong unwind info.  */
  if (epilogue_completed)
    {
      rtx_insn *insn = head;
      while (1)
	{
	  if (INSN_P (insn) && RTX_FRAME_RELATED_P (insn))
	    return FALSE;
	  if (insn == end)
	    break;
	  insn = NEXT_INSN (insn);
	}
    }

  /* Disable handling dead code by conditional execution if the machine needs
     to do anything funny with the tests, etc.  */
#ifndef IFCVT_MODIFY_TESTS
  if (targetm.have_conditional_execution ())
    {
      /* In the conditional execution case, we have things easy.  We know
	 the condition is reversible.  We don't have to check life info
	 because we're going to conditionally execute the code anyway.
	 All that's left is making sure the insns involved can actually
	 be predicated.  */

      rtx cond;

      /* If the conditional jump is more than just a conditional jump,
	 then we cannot do conditional execution conversion on this block.  */
      if (!onlyjump_p (jump))
	goto nce;

      cond = cond_exec_get_condition (jump);
      if (! cond)
	goto nce;

      rtx note = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
      profile_probability prob_val
	  = (note ? profile_probability::from_reg_br_prob_note (XINT (note, 0))
	     : profile_probability::uninitialized ());

      if (reversep)
	{
	  enum rtx_code rev = reversed_comparison_code (cond, jump);
	  if (rev == UNKNOWN)
	    return FALSE;
	  cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
			         XEXP (cond, 1));
	  prob_val = prob_val.invert ();
	}

      if (cond_exec_process_insns (NULL, head, end, cond, prob_val, 0)
	  && verify_changes (0))
	n_validated_changes = num_validated_changes ();
      else
	cancel_changes (0);

      earliest = jump;
    }
 nce:
#endif

  /* If we allocated new pseudos (e.g. in the conditional move
     expander called from noce_emit_cmove), we must resize the
     array first.  */
  if (max_regno < max_reg_num ())
    max_regno = max_reg_num ();

  /* Try the NCE path if the CE path did not result in any changes.  */
  if (n_validated_changes == 0)
    {
      rtx cond;
      rtx_insn *insn;
      regset live;
      bool success;

      /* In the non-conditional execution case, we have to verify that there
	 are no trapping operations, no calls, no references to memory, and
	 that any registers modified are dead at the branch site.  */

      if (!any_condjump_p (jump))
	return FALSE;

      /* Find the extent of the conditional.  */
      cond = noce_get_condition (jump, &earliest, false);
      if (!cond)
	return FALSE;

      live = BITMAP_ALLOC (&reg_obstack);
      simulate_backwards_to_point (merge_bb, live, end);
      success = can_move_insns_across (head, end, earliest, jump,
				       merge_bb, live,
				       df_get_live_in (other_bb), NULL);
      BITMAP_FREE (live);
      if (!success)
	return FALSE;

      /* Collect the set of registers set in MERGE_BB.  */
      merge_set = BITMAP_ALLOC (&reg_obstack);

      FOR_BB_INSNS (merge_bb, insn)
	if (NONDEBUG_INSN_P (insn))
	  df_simulate_find_defs (insn, merge_set);

      /* If shrink-wrapping, disable this optimization when test_bb is
	 the first basic block and merge_bb exits.  The idea is to not
	 move code setting up a return register as that may clobber a
	 register used to pass function parameters, which then must be
	 saved in caller-saved regs.  A caller-saved reg requires the
	 prologue, killing a shrink-wrap opportunity.  */
      if ((SHRINK_WRAPPING_ENABLED && !epilogue_completed)
	  && ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == test_bb
	  && single_succ_p (new_dest)
	  && single_succ (new_dest) == EXIT_BLOCK_PTR_FOR_FN (cfun)
	  && bitmap_intersect_p (df_get_live_in (new_dest), merge_set))
	{
	  regset return_regs;
	  unsigned int i;

	  return_regs = BITMAP_ALLOC (&reg_obstack);

	  /* Start off with the intersection of regs used to pass
	     params and regs used to return values.  */
	  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	    if (FUNCTION_ARG_REGNO_P (i)
		&& targetm.calls.function_value_regno_p (i))
	      bitmap_set_bit (return_regs, INCOMING_REGNO (i));

	  bitmap_and_into (return_regs,
			   df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
	  bitmap_and_into (return_regs,
			   df_get_live_in (EXIT_BLOCK_PTR_FOR_FN (cfun)));
	  if (!bitmap_empty_p (return_regs))
	    {
	      FOR_BB_INSNS_REVERSE (new_dest, insn)
		if (NONDEBUG_INSN_P (insn))
		  {
		    df_ref def;

		    /* If this insn sets any reg in return_regs, add all
		       reg uses to the set of regs we're interested in.  */
		    FOR_EACH_INSN_DEF (def, insn)
		      if (bitmap_bit_p (return_regs, DF_REF_REGNO (def)))
			{
			  df_simulate_uses (insn, return_regs);
			  break;
			}
		  }
	      if (bitmap_intersect_p (merge_set, return_regs))
		{
		  BITMAP_FREE (return_regs);
		  BITMAP_FREE (merge_set);
		  return FALSE;
		}
	    }
	  BITMAP_FREE (return_regs);
	}
    }

 no_body:
  /* We don't want to use normal invert_jump or redirect_jump because
     we don't want to delete_insn called.  Also, we want to do our own
     change group management.  */

  old_dest = JUMP_LABEL (jump);
  if (other_bb != new_dest)
    {
      if (!any_condjump_p (jump))
	goto cancel;

      if (JUMP_P (BB_END (dest_edge->src)))
	new_dest_label = JUMP_LABEL (BB_END (dest_edge->src));
      else if (new_dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
	new_dest_label = ret_rtx;
      else
	new_dest_label = block_label (new_dest);

      rtx_jump_insn *jump_insn = as_a <rtx_jump_insn *> (jump);
      if (reversep
	  ? ! invert_jump_1 (jump_insn, new_dest_label)
	  : ! redirect_jump_1 (jump_insn, new_dest_label))
	goto cancel;
    }

  if (verify_changes (n_validated_changes))
    confirm_change_group ();
  else
    goto cancel;

  if (other_bb != new_dest)
    {
      redirect_jump_2 (as_a <rtx_jump_insn *> (jump), old_dest, new_dest_label,
		       0, reversep);

      redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
      if (reversep)
	{
	  std::swap (BRANCH_EDGE (test_bb)->probability,
		     FALLTHRU_EDGE (test_bb)->probability);
	  update_br_prob_note (test_bb);
	}
    }

  /* Move the insns out of MERGE_BB to before the branch.  */
  if (head != NULL)
    {
      rtx_insn *insn;

      if (end == BB_END (merge_bb))
	BB_END (merge_bb) = PREV_INSN (head);

      /* PR 21767: when moving insns above a conditional branch, the REG_EQUAL
	 notes being moved might become invalid.  */
      insn = head;
      do
	{
	  rtx note;

	  if (! INSN_P (insn))
	    continue;
	  note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
	  if (! note)
	    continue;
	  remove_note (insn, note);
	} while (insn != end && (insn = NEXT_INSN (insn)));

      /* PR46315: when moving insns above a conditional branch, the REG_EQUAL
	 notes referring to the registers being set might become invalid.  */
      if (merge_set)
	{
	  unsigned i;
	  bitmap_iterator bi;

	  EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)
	    remove_reg_equal_equiv_notes_for_regno (i);

	  BITMAP_FREE (merge_set);
	}

      reorder_insns (head, end, PREV_INSN (earliest));
    }

  /* Remove the jump and edge if we can.  */
  if (other_bb == new_dest)
    {
      delete_insn (jump);
      remove_edge (BRANCH_EDGE (test_bb));
      /* ??? Can't merge blocks here, as then_bb is still in use.
	 At minimum, the merge will get done just before bb-reorder.  */
    }

  return TRUE;

 cancel:
  cancel_changes (0);

  if (merge_set)
    BITMAP_FREE (merge_set);

  return FALSE;
}

/* Main entry point for all if-conversion.  AFTER_COMBINE is true if
   we are after combine pass.  */

static void
if_convert (bool after_combine)
{
  basic_block bb;
  int pass;

  if (optimize == 1)
    {
      df_live_add_problem ();
      df_live_set_all_dirty ();
    }

  /* Record whether we are after combine pass.  */
  ifcvt_after_combine = after_combine;
  have_cbranchcc4 = (direct_optab_handler (cbranch_optab, CCmode)
		     != CODE_FOR_nothing);
  num_possible_if_blocks = 0;
  num_updated_if_blocks = 0;
  num_true_changes = 0;

  loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
  mark_loop_exit_edges ();
  loop_optimizer_finalize ();
  free_dominance_info (CDI_DOMINATORS);

  /* Compute postdominators.  */
  calculate_dominance_info (CDI_POST_DOMINATORS);

  df_set_flags (DF_LR_RUN_DCE);

  /* Go through each of the basic blocks looking for things to convert.  If we
     have conditional execution, we make multiple passes to allow us to handle
     IF-THEN{-ELSE} blocks within other IF-THEN{-ELSE} blocks.  */
  pass = 0;
  do
    {
      df_analyze ();
      /* Only need to do dce on the first pass.  */
      df_clear_flags (DF_LR_RUN_DCE);
      cond_exec_changed_p = FALSE;
      pass++;

#ifdef IFCVT_MULTIPLE_DUMPS
      if (dump_file && pass > 1)
	fprintf (dump_file, "\n\n========== Pass %d ==========\n", pass);
#endif

      FOR_EACH_BB_FN (bb, cfun)
	{
          basic_block new_bb;
          while (!df_get_bb_dirty (bb)
                 && (new_bb = find_if_header (bb, pass)) != NULL)
            bb = new_bb;
	}

#ifdef IFCVT_MULTIPLE_DUMPS
      if (dump_file && cond_exec_changed_p)
	print_rtl_with_bb (dump_file, get_insns (), dump_flags);
#endif
    }
  while (cond_exec_changed_p);

#ifdef IFCVT_MULTIPLE_DUMPS
  if (dump_file)
    fprintf (dump_file, "\n\n========== no more changes\n");
#endif

  free_dominance_info (CDI_POST_DOMINATORS);

  if (dump_file)
    fflush (dump_file);

  clear_aux_for_blocks ();

  /* If we allocated new pseudos, we must resize the array for sched1.  */
  if (max_regno < max_reg_num ())
    max_regno = max_reg_num ();

  /* Write the final stats.  */
  if (dump_file && num_possible_if_blocks > 0)
    {
      fprintf (dump_file,
	       "\n%d possible IF blocks searched.\n",
	       num_possible_if_blocks);
      fprintf (dump_file,
	       "%d IF blocks converted.\n",
	       num_updated_if_blocks);
      fprintf (dump_file,
	       "%d true changes made.\n\n\n",
	       num_true_changes);
    }

  if (optimize == 1)
    df_remove_problem (df_live);

  /* Some non-cold blocks may now be only reachable from cold blocks.
     Fix that up.  */
  fixup_partitions ();

  checking_verify_flow_info ();
}

/* If-conversion and CFG cleanup.  */
static unsigned int
rest_of_handle_if_conversion (void)
{
  int flags = 0;

  if (flag_if_conversion)
    {
      if (dump_file)
	{
	  dump_reg_info (dump_file);
	  dump_flow_info (dump_file, dump_flags);
	}
      cleanup_cfg (CLEANUP_EXPENSIVE);
      if_convert (false);
      if (num_updated_if_blocks)
	/* Get rid of any dead CC-related instructions.  */
	flags |= CLEANUP_FORCE_FAST_DCE;
    }

  cleanup_cfg (flags);
  return 0;
}

namespace {

const pass_data pass_data_rtl_ifcvt =
{
  RTL_PASS, /* type */
  "ce1", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_IFCVT, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_df_finish, /* todo_flags_finish */
};

class pass_rtl_ifcvt : public rtl_opt_pass
{
public:
  pass_rtl_ifcvt (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_rtl_ifcvt, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    {
      return (optimize > 0) && dbg_cnt (if_conversion);
    }

  virtual unsigned int execute (function *)
    {
      return rest_of_handle_if_conversion ();
    }

}; // class pass_rtl_ifcvt

} // anon namespace

rtl_opt_pass *
make_pass_rtl_ifcvt (gcc::context *ctxt)
{
  return new pass_rtl_ifcvt (ctxt);
}


/* Rerun if-conversion, as combine may have simplified things enough
   to now meet sequence length restrictions.  */

namespace {

const pass_data pass_data_if_after_combine =
{
  RTL_PASS, /* type */
  "ce2", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_IFCVT, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_df_finish, /* todo_flags_finish */
};

class pass_if_after_combine : public rtl_opt_pass
{
public:
  pass_if_after_combine (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_if_after_combine, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    {
      return optimize > 0 && flag_if_conversion
	&& dbg_cnt (if_after_combine);
    }

  virtual unsigned int execute (function *)
    {
      if_convert (true);
      return 0;
    }

}; // class pass_if_after_combine

} // anon namespace

rtl_opt_pass *
make_pass_if_after_combine (gcc::context *ctxt)
{
  return new pass_if_after_combine (ctxt);
}


namespace {

const pass_data pass_data_if_after_reload =
{
  RTL_PASS, /* type */
  "ce3", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_IFCVT2, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  TODO_df_finish, /* todo_flags_finish */
};

class pass_if_after_reload : public rtl_opt_pass
{
public:
  pass_if_after_reload (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_if_after_reload, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *)
    {
      return optimize > 0 && flag_if_conversion2
	&& dbg_cnt (if_after_reload);
    }

  virtual unsigned int execute (function *)
    {
      if_convert (true);
      return 0;
    }

}; // class pass_if_after_reload

} // anon namespace

rtl_opt_pass *
make_pass_if_after_reload (gcc::context *ctxt)
{
  return new pass_if_after_reload (ctxt);
}
