This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
condexec ifcvt failure
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 30 Jan 2002 23:16:35 -0800
- Subject: condexec ifcvt failure
Seen in an ia64 bootstrap with the loop rotation patch.
(1)
/ \
/ \
(2)<-(4)
/ \
(3) (5)
will match the IF_CASE_2 test and pull a predicated form
of the insns from block 4 into block 1. Except we'd flub
the cfg manipulations and have two edges from block 1 to
block 2. Which gets caught by verify_flow_info.
r~
* ifcvt.c (dead_or_predicable): Handling merging when other_bb
and new_dest are the same.
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.76
diff -c -p -d -r1.76 ifcvt.c
*** ifcvt.c 2002/01/10 20:37:42 1.76
--- ifcvt.c 2002/01/31 07:09:09
*************** dead_or_predicable (test_bb, merge_bb, o
*** 2629,2663 ****
change group management. */
old_dest = JUMP_LABEL (jump);
! new_label = block_label (new_dest);
! if (reversep
! ? ! invert_jump_1 (jump, new_label)
! : ! redirect_jump_1 (jump, new_label))
! goto cancel;
if (! apply_change_group ())
return FALSE;
-
- if (old_dest)
- LABEL_NUSES (old_dest) -= 1;
- if (new_label)
- LABEL_NUSES (new_label) += 1;
- JUMP_LABEL (jump) = new_label;
-
- if (reversep)
- invert_br_probabilities (jump);
! redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
! if (reversep)
{
! gcov_type count, probability;
! count = BRANCH_EDGE (test_bb)->count;
! BRANCH_EDGE (test_bb)->count = FALLTHRU_EDGE (test_bb)->count;
! FALLTHRU_EDGE (test_bb)->count = count;
! probability = BRANCH_EDGE (test_bb)->probability;
! BRANCH_EDGE (test_bb)->probability = FALLTHRU_EDGE (test_bb)->probability;
! FALLTHRU_EDGE (test_bb)->probability = probability;
! update_br_prob_note (test_bb);
}
/* Move the insns out of MERGE_BB to before the branch. */
--- 2629,2669 ----
change group management. */
old_dest = JUMP_LABEL (jump);
! if (other_bb != new_dest)
! {
! new_label = block_label (new_dest);
! if (reversep
! ? ! invert_jump_1 (jump, new_label)
! : ! redirect_jump_1 (jump, new_label))
! goto cancel;
! }
if (! apply_change_group ())
return FALSE;
! if (other_bb != new_dest)
{
! if (old_dest)
! LABEL_NUSES (old_dest) -= 1;
! if (new_label)
! LABEL_NUSES (new_label) += 1;
! JUMP_LABEL (jump) = new_label;
! if (reversep)
! invert_br_probabilities (jump);
!
! redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
! if (reversep)
! {
! gcov_type count, probability;
! count = BRANCH_EDGE (test_bb)->count;
! BRANCH_EDGE (test_bb)->count = FALLTHRU_EDGE (test_bb)->count;
! FALLTHRU_EDGE (test_bb)->count = count;
! probability = BRANCH_EDGE (test_bb)->probability;
! BRANCH_EDGE (test_bb)->probability
! = FALLTHRU_EDGE (test_bb)->probability;
! FALLTHRU_EDGE (test_bb)->probability = probability;
! update_br_prob_note (test_bb);
! }
}
/* Move the insns out of MERGE_BB to before the branch. */
*************** dead_or_predicable (test_bb, merge_bb, o
*** 2671,2676 ****
--- 2677,2692 ----
reorder_insns (head, end, PREV_INSN (earliest));
}
+
+ /* Remove the jump and edge if we can. */
+ if (other_bb == new_dest)
+ {
+ delete_insn (jump);
+ remove_edge (BRANCH_EDGE (test_bb));
+ /* ??? Can't merge blocks here, as then_bb is still in use.
+ At minimum, the merge will get done just before bb-reorder. */
+ }
+
return TRUE;
cancel: