Bug 10116 - ce2: invalid merge of "join_bb" in the context of switch statements
Summary: ce2: invalid merge of "join_bb" in the context of switch statements
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.2.2
: P3 normal
Target Milestone: ---
Assignee: Richard Henderson
Depends on:
Reported: 2003-03-16 23:46 UTC by marcel
Modified: 2003-07-25 17:33 UTC (History)
2 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:

bug.i (570 bytes, text/x-c)
2003-05-21 15:17 UTC, marcel

Note You need to log in before you can comment on or make changes to this bug.
Description marcel 2003-03-16 16:16:42 UTC
From: Marcel Moolenaar <marcel@xcllnt.net>
To: gcc-gnats@gcc.gnu.org
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
Comment 1 marcel 2003-03-16 23:46:00 UTC
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
platform: ia64
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
Comment 2 marcel 2003-03-16 23:46:00 UTC
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
diff -u -r1.1.1.4 ifcvt.c
--- ifcvt.c     1 Sep 2002 20:37:43 -0000
+++ 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)
Comment 3 Wolfgang Bangerth 2003-03-22 05:02:24 UTC
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?
Comment 4 Richard Henderson 2003-03-23 20:30:33 UTC
State-Changed-From-To: open->closed
State-Changed-Why: http://gcc.gnu.org/ml/gcc-patches/2003-03/msg02032.html