rtx cond, earliest, target, seq, a, b, c;
int negate;
+ /* Reject modes with signed zeros. */
+ if (HONOR_SIGNED_ZEROS (GET_MODE (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. */
unconditionally before the barrier. */
if (INSN_P (insn)
&& (volatile_insn_p (PATTERN (insn))
- || (CALL_P (insn)
- && (!CONST_OR_PURE_CALL_P (insn)
- || pure_call_p (insn)))))
+ || (CALL_P (insn) && (!RTL_CONST_CALL_P (insn)))))
return false;
if (memory_modified_in_insn_p (mem, insn))
|| !NONJUMP_INSN_P (insn_b)
|| (set_b = single_set (insn_b)) == NULL_RTX
|| ! rtx_equal_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),
PREV_INSN (if_info->cond_earliest), jump)
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;
goto success;
}
+ if (!else_bb && set_b)
+ {
+ insn_b = set_b = NULL_RTX;
+ b = orig_x;
+ goto retry;
+ }
+
return FALSE;
success:
/* 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)))
- return FALSE;
+ {
+ VEC_free (int, heap, then_regs);
+ VEC_free (int, heap, else_regs);
+ return FALSE;
+ }
/* 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
if (!CONSTANT_P (then_vals[reg])
&& !CONSTANT_P (else_vals[reg])
&& !rtx_equal_p (then_vals[reg], else_vals[reg]))
- return FALSE;
+ {
+ VEC_free (int, heap, then_regs);
+ VEC_free (int, heap, else_regs);
+ return FALSE;
+ }
}
}
branches, since if we convert we are going to always execute
them. */
if (c > MAX_CONDITIONAL_EXECUTE)
- return FALSE;
+ {
+ VEC_free (int, heap, then_regs);
+ VEC_free (int, heap, else_regs);
+ return FALSE;
+ }
/* Try to emit the conditional moves. First do the then block,
then do anything left in the else blocks. */
then_vals, else_vals, true)))
{
end_sequence ();
+ VEC_free (int, heap, then_regs);
+ VEC_free (int, heap, else_regs);
return FALSE;
}
seq = end_ifcvt_sequence (if_info);
if (!seq)
- return FALSE;
+ {
+ VEC_free (int, heap, then_regs);
+ VEC_free (int, heap, else_regs);
+ return FALSE;
+ }
loc_insn = first_active_insn (then_bb);
if (!loc_insn)
VEC_free (int, heap, then_regs);
VEC_free (int, heap, else_regs);
-
return TRUE;
}
if (INSN_P (insn))
{
df_simulate_find_defs (insn, test_set);
- df_simulate_one_insn_backwards (test_bb, insn, test_live);
+ df_simulate_one_insn (test_bb, insn, test_live);
}
prev = PREV_INSN (insn);
if (insn == earliest)
return 0;
}
-struct tree_opt_pass pass_rtl_ifcvt =
+struct rtl_opt_pass pass_rtl_ifcvt =
{
+ {
+ RTL_PASS,
"ce1", /* name */
gate_handle_if_conversion, /* gate */
rest_of_handle_if_conversion, /* execute */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_dump_func, /* todo_flags_finish */
- 'C' /* letter */
+ TODO_dump_func /* todo_flags_finish */
+ }
};
static bool
return 0;
}
-struct tree_opt_pass pass_if_after_combine =
+struct rtl_opt_pass pass_if_after_combine =
{
+ {
+ RTL_PASS,
"ce2", /* name */
gate_handle_if_after_combine, /* gate */
rest_of_handle_if_after_combine, /* execute */
0, /* todo_flags_start */
TODO_df_finish | TODO_verify_rtl_sharing |
TODO_dump_func |
- TODO_ggc_collect, /* todo_flags_finish */
- 'C' /* letter */
+ TODO_ggc_collect /* todo_flags_finish */
+ }
};
}
-struct tree_opt_pass pass_if_after_reload =
+struct rtl_opt_pass pass_if_after_reload =
{
+ {
+ RTL_PASS,
"ce3", /* name */
gate_handle_if_after_reload, /* gate */
rest_of_handle_if_after_reload, /* execute */
0, /* todo_flags_start */
TODO_df_finish | TODO_verify_rtl_sharing |
TODO_dump_func |
- TODO_ggc_collect, /* todo_flags_finish */
- 'E' /* letter */
+ TODO_ggc_collect /* todo_flags_finish */
+ }
};