diff options
-rw-r--r-- | gcc/ifcvt.cc | 31 | ||||
-rw-r--r-- | gcc/ifcvt.h | 8 |
2 files changed, 27 insertions, 12 deletions
diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc index 0087968..e4168d9 100644 --- a/gcc/ifcvt.cc +++ b/gcc/ifcvt.cc @@ -4253,6 +4253,9 @@ cond_move_convert_if_block (struct noce_if_info *if_infop, e = dest; } + if (if_infop->cond_inverted) + std::swap (t, e); + target = noce_emit_cmove (if_infop, dest, code, cond_arg0, cond_arg1, t, e); if (!target) @@ -4405,7 +4408,6 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, 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); @@ -4481,25 +4483,28 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, 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; + if_info.cond = noce_get_condition (jump, &cond_earliest, + then_else_reversed); rtx_insn *rev_cond_earliest; if_info.rev_cond = noce_get_condition (jump, &rev_cond_earliest, !then_else_reversed); + if (!if_info.cond && !if_info.rev_cond) + return FALSE; + if (!if_info.cond) + { + std::swap (if_info.cond, if_info.rev_cond); + std::swap (cond_earliest, rev_cond_earliest); + if_info.cond_inverted = true; + } + /* We must be comparing objects whose modes imply the size. */ + if (GET_MODE (XEXP (if_info.cond, 0)) == BLKmode) + return FALSE; gcc_assert (if_info.rev_cond == NULL_RTX || rev_cond_earliest == cond_earliest); if_info.cond_earliest = cond_earliest; @@ -4518,7 +4523,9 @@ noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge, /* Do the real work. */ - if (noce_process_if_block (&if_info)) + /* ??? noce_process_if_block has not yet been updated to handle + inverted conditions. */ + if (!if_info.cond_inverted && noce_process_if_block (&if_info)) return TRUE; if (HAVE_conditional_move diff --git a/gcc/ifcvt.h b/gcc/ifcvt.h index c6ea244..be1385a 100644 --- a/gcc/ifcvt.h +++ b/gcc/ifcvt.h @@ -86,6 +86,14 @@ struct noce_if_info form as well. */ bool then_else_reversed; + /* True if THEN_BB is conditional on !COND rather than COND. + This is used if: + + - JUMP branches to THEN_BB on COND + - JUMP falls through to JOIN_BB on !COND + - COND cannot be reversed. */ + bool cond_inverted; + /* True if the contents of then_bb and else_bb are a simple single set instruction. */ bool then_simple; |