/* 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
      && !HAVE_cc0
      && 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;
  rtx reg;
  int c;
  vec<rtx> then_regs = vNULL;
  vec<rtx> else_regs = vNULL;
  unsigned int i;
  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_EACH_VEC_ELT (then_regs, i, reg)
    {
      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_EACH_VEC_ELT (else_regs, i, reg)
    {
      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)
	return FALSE;

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