Hi all, As discussed, I've added a check for multiple_sets to insn_valid_noce_process_p and replaced the modified_a and modified_b redundant definitions with checking asserts to catch cases if any unexpected multiple sets get through the net.
Bootstrapped and tested on arm, aarch64, x86_64. As expected, I didn't see any codegen difference as it should a pretty rare case for which we have no reported testcase. Ok for trunk? Thanks, Kyrill 2015-11-27 Kyrylo Tkachov <kyrylo.tkac...@arm.com> * ifcvt.c (insn_valid_noce_process_p): Reject insn if it satisfies multiple_sets. (noce_try_cmove_arith): Add checking asserts that orig_a and orig_b are not modified by the final modified insns in the basic blocks
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 3ce9fe6082069361504268788c009eec722ac89b..ef3ebe359a3ef80965f9827c67a7cb6b0dca1442 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1880,6 +1880,7 @@ insn_valid_noce_process_p (rtx_insn *insn, rtx cc) { if (!insn || !NONJUMP_INSN_P (insn) + || multiple_sets (insn) || (cc && set_of (cc, insn))) return false; @@ -2206,7 +2207,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) swap insn that sets up A with the one that sets up B. If even that doesn't help, punt. */ - modified_in_a = emit_a != NULL_RTX && modified_in_p (orig_b, emit_a); + gcc_checking_assert (!emit_a || !modified_in_p (orig_b, emit_a)); if (tmp_b && then_bb) { FOR_BB_INSNS (then_bb, tmp_insn) @@ -2222,7 +2223,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) } if (emit_a || modified_in_a) { - modified_in_b = emit_b != NULL_RTX && modified_in_p (orig_a, emit_b); + gcc_checking_assert (!emit_b || !modified_in_p (orig_a, emit_b)); if (tmp_b && else_bb) { FOR_BB_INSNS (else_bb, tmp_insn)