diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 65b1b2b6284..51778ecb9cf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-12-03 Kyrylo Tkachov + + PR rtl-optimization/68624 + * ifcvt.c (noce_try_cmove_arith): Check clobbers of temp regs in both + blocks if they exist and simplify the logic choosing the order to emit + them in. + 2015-12-03 Richard Biener PR tree-optimization/66051 diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 8ece8734338..d474b3ba493 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -2172,10 +2172,6 @@ noce_try_cmove_arith (struct noce_if_info *if_info) } } - /* 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. */ - modified_in_a = emit_a != NULL_RTX && modified_in_p (orig_b, emit_a); if (tmp_b && then_bb) { @@ -2190,38 +2186,42 @@ 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); - if (tmp_b && 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 (modified_in_b) - goto end_seq_and_fail; + 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 - { - 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; - } + goto end_seq_and_fail; target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0), XEXP (if_info->cond, 1), a, b); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 55529e05720..3417f36f6ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-12-03 Kyrylo Tkachov + + PR rtl-optimization/68624 + * gcc.c-torture/execute/pr68624.c: New test. + 2015-12-03 Richard Biener PR tree-optimization/66051 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr68624.c b/gcc/testsuite/gcc.c-torture/execute/pr68624.c new file mode 100644 index 00000000000..abb716b1550 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr68624.c @@ -0,0 +1,30 @@ +int b, c, d, e = 1, f, g, h, j; + +static int +fn1 () +{ + int a = c; + if (h) + return 9; + g = (c || b) % e; + if ((g || f) && b) + return 9; + e = d; + for (c = 0; c > -4; c--) + ; + if (d) + c--; + j = c; + return d; +} + +int +main () +{ + fn1 (); + + if (c != -4) + __builtin_abort (); + + return 0; +}