This is GCC Bugzilla
This is GCC Bugzilla Version 2.20+
View Bug Activity | Format For Printing | Clone This Bug
From: Marcel Moolenaar <marcel@xcllnt.net> To: gcc-gnats@gcc.gnu.org Cc: Subject: Re: optimization/10116: ce2: invalid merge of "join_bb" in the context of switch statements Date: Sun, 16 Mar 2003 16:16:42 -0800 On Sun, Mar 16, 2003 at 11:46:00PM -0000, gcc-gnats@gcc.gnu.org wrote: > > >Category: optimization > >Responsible: unassigned > >Synopsis: ce2: invalid merge of "join_bb" in the context of switch statements > >Arrival-Date: Sun Mar 16 23:46:00 UTC 2003 This bug is being tracked with FreeBSD PR ia64/50059. The FreeBSD sibling can be closed when a vendor import has occured and the upgraded compiler contains a fix for this PR. -- Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net
The if converter on ia64 may end up merging basic blocks that are not actually adjacent, even though merge_blocks_nomove() is used. The situation given by the trigger case has a jump table between "combo_bb' and 'join_bb'. As a result of the invalid merge, the jump table gets eliminated causing a stale reference to a label. Note that in this case the jump table can actually be eliminated, but that's a different story. The fix is based on the assumption that any instruction between 'combo_bb' and 'join_bb' cannot be a label as that would invalidate the requirement that both BBs are adjacent. Release: GCC 3.2.2 (FreeBSD embedded) Environment: os: FreeBSD 5-current platform: ia64 gcc: (GCC) 3.2.2 [FreeBSD] 20030205 (release) How-To-Repeat: Compile the trigger case with -O with an ia64 (cross) compiler and observe that the assembly output references a temporary label that is not defined. For example: % cc -O -S bug.i -o bug.s
Fix: Diff taken from the FreeBSD vendor imported code (whitespace corrupted, no doubt): Index: ifcvt.c =================================================================== RCS file: /home/ncvs/src/contrib/gcc/ifcvt.c,v retrieving revision 1.1.1.4 diff -u -r1.1.1.4 ifcvt.c --- ifcvt.c 1 Sep 2002 20:37:43 -0000 1.1.1.4 +++ ifcvt.c 16 Mar 2003 09:55:05 -0000 @@ -1934,9 +1934,10 @@ is more than one remaining edge, it must come from elsewhere. There may be zero incoming edges if the THEN block didn't actually join back up (as with a call to abort). */ - else if ((join_bb->pred == NULL - || join_bb->pred->pred_next == NULL) - && join_bb != EXIT_BLOCK_PTR) + else if ((join_bb->pred == NULL || join_bb->pred->pred_next == NULL) + && join_bb != EXIT_BLOCK_PTR + && (NEXT_INSN(combo_bb->end) == join_bb->head + || GET_CODE(NEXT_INSN(combo_bb->end)) != CODE_LABEL)) { /* We can merge the JOIN. */ if (life_data_ok)
Responsible-Changed-From-To: unassigned->rth Responsible-Changed-Why: Richard, this might be another simple one for you -- it contains a patch to ifcvt.c around some lines that you last changed with this patch revision 1.64 date: 2001/08/22 05:21:10; author: rth; state: Exp; lines: +6 -3 * ifcvt.c (find_if_block): Allow join_bb as EXIT. (merge_if_block): Handle fallout from same. The patch in the PR only affects 3 lines and has a testcase that should be simple to verify. Would you mind taking a brief look? Thanks Wolfgang
State-Changed-From-To: open->closed State-Changed-Why: http://gcc.gnu.org/ml/gcc-patches/2003-03/msg02032.html