From: Marcel Moolenaar <email@example.com>
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, firstname.lastname@example.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 email@example.com
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.
GCC 3.2.2 (FreeBSD embedded)
os: FreeBSD 5-current
gcc: (GCC) 3.2.2 [FreeBSD] 20030205 (release)
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
Diff taken from the FreeBSD vendor imported code (whitespace corrupted, no doubt):
RCS file: /home/ncvs/src/contrib/gcc/ifcvt.c,v
retrieving revision 22.214.171.124
diff -u -r126.96.36.199 ifcvt.c
--- ifcvt.c 1 Sep 2002 20:37:43 -0000 188.8.131.52
+++ 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. */
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
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?