On Wed, Jan 08, 2014 at 05:54:55PM +0100, Uros Bizjak wrote: > This caused PR59724 on alpha: > > 20021116-1.c: In function ‘foo’: > 20021116-1.c:31:1: error: NOTE_INSN_BASIC_BLOCK is missing for block 9 > } > ^ > 20021116-1.c:31:1: error: insn outside basic block > (jump_insn 94 52 93 9 (return) 20021116-1.c:31 -1 > (nil) > -> return)
Ugh, indeed. The problem is that try_head_merge_bb really wants flow_find_head_matching_sequence to count all (non-note) insns, not just active insns, because otherwise as in the above testcase we can have e.g. 2 active insns followed by one non-active, all matching (flow_find_head_matching_sequence returns 2) and on another edge just 2 active insns and nothing else matching. 2 == 2, so the caller thinks it doesn't matter which one is shorter, but we have the insn range of 3 insns together. So, this patch just reverts the try_head_merge_bb changes and makes flow_find_head_matching_sequence behave the old way when called from try_head_merge_bb, i.e. count all non-note insns, and only when called from ifcvt.c count just active insns. Plus the ifcvt.c change ensures we don't mistakenly call it with stop_after == 0 (which wouldn't actually stop). Bootstrapped/regtested on x86_64-linux and i686-linux, Uros is testing it on Alpha. Ok for trunk? 2014-01-08 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/59724 * ifcvt.c (cond_exec_process_if_block): Don't call flow_find_head_matching_sequence with 0 longest_match. * cfgcleanup.c (flow_find_head_matching_sequence): Count even non-active insns if !stop_after. (try_head_merge_bb): Revert 2014-01-07 changes. --- gcc/ifcvt.c.jj 2014-01-08 10:23:20.000000000 +0100 +++ gcc/ifcvt.c 2014-01-08 18:46:17.017715169 +0100 @@ -522,7 +522,10 @@ cond_exec_process_if_block (ce_if_block n_insns -= 2 * n_matching; } - if (then_start && else_start) + 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); --- gcc/cfgcleanup.c.jj 2014-01-07 08:54:05.772736321 +0100 +++ gcc/cfgcleanup.c 2014-01-08 18:41:14.433307914 +0100 @@ -1421,7 +1421,8 @@ flow_find_cross_jump (basic_block bb1, b /* Like flow_find_cross_jump, except start looking for a matching sequence from the head of the two blocks. Do not include jumps at the end. If STOP_AFTER is nonzero, stop after finding that many matching - instructions. */ + instructions. If STOP_AFTER is zero, count all INSN_P insns, if it is + non-zero, only count active insns. */ int flow_find_head_matching_sequence (basic_block bb1, basic_block bb2, rtx *f1, @@ -1493,7 +1494,7 @@ flow_find_head_matching_sequence (basic_ beforelast1 = last1, beforelast2 = last2; last1 = i1, last2 = i2; - if (active_insn_p (i1)) + if (!stop_after || active_insn_p (i1)) ninsns++; } @@ -2408,7 +2409,9 @@ try_head_merge_bb (basic_block bb) max_match--; if (max_match == 0) return false; - e0_last_head = prev_active_insn (e0_last_head); + do + e0_last_head = prev_real_insn (e0_last_head); + while (DEBUG_INSN_P (e0_last_head)); } if (max_match == 0) @@ -2428,14 +2431,16 @@ try_head_merge_bb (basic_block bb) basic_block merge_bb = EDGE_SUCC (bb, ix)->dest; rtx head = BB_HEAD (merge_bb); - if (!active_insn_p (head)) - head = next_active_insn (head); + while (!NONDEBUG_INSN_P (head)) + head = NEXT_INSN (head); headptr[ix] = head; currptr[ix] = head; /* Compute the end point and live information */ for (j = 1; j < max_match; j++) - head = next_active_insn (head); + do + head = NEXT_INSN (head); + while (!NONDEBUG_INSN_P (head)); simulate_backwards_to_point (merge_bb, live, head); IOR_REG_SET (live_union, live); } Jakub