This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]