This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Breakage in flow with table jumps
- To: Andrew Haley <aph at cambridge dot redhat dot com>
- Subject: Re: Breakage in flow with table jumps
- From: Franz Sirl <Franz dot Sirl-kernel at lauterbach dot com>
- Date: Thu, 21 Jun 2001 10:42:41 +0200
- Cc: gcc-bugs at gcc dot gnu dot org
At 20:04 20.06.2001, Andrew Haley wrote:
>I've been trying to sort out a problem in ARM gcc, with a testcase
>that looks like this:
>
>int SQLSetConnectOption( void * hDrvDbc,
> unsigned nOption,
> unsigned long vParam)
>{
>
> if ( hDrvDbc == 0 )
> return (-2);
>
> switch ( nOption )
> {
> case 106:
> case 107:
>
> case 110:
> case 104:
> switch ( vParam )
> {
> case 1UL:
> case 0UL:
> default:
> ;
> }
> break;
>
> case 105:
> case 101:
> case 102:
> default:
> ;
> }
>
>
> printf( "SQLSetConnectOption.c", "SQLSetConnectOption.c", 49, 1, 1,
> "SQL_SUCCESS_WITH_INFO Function not fully implemented" );
> return 1;
>}
>
>When compiled with -fpic -O2, the compiler aborts in flow when trying
>to merge a block that ends like this:
>
>(jump_insn 52 51 53 (parallel[
> (set (pc)
> (if_then_else (leu (reg:SI 3 r3 [37])
> (const_int 9 [0x9]))
> (mem:SI (plus:SI (mult:SI (reg:SI 3 r3 [37])
> (const_int 4 [0x4]))
> (label_ref 53)) 0)
> (label_ref 56)))
> (clobber (reg:CC 24 cc))
> (use (label_ref 53))
> ] ) 263 {casesi_internal} (insn_list 51 (nil))
> (nil))
>
>and a table like this:
>
>(jump_insn 54 15 55 (addr_diff_vec:SI (label_ref:SI 53)
> [
> (label_ref:SI 56)
> (label_ref:SI 56)
> (label_ref:SI 56)
> (label_ref:SI 56)
> (label_ref:SI 56)
> (label_ref:SI 56)
> (label_ref:SI 56)
> (label_ref:SI 56)
> (label_ref:SI 56)
> (label_ref:SI 56)
> ]
> (const_int 0 [0x0])
> (const_int 0 [0x0])) -1 (nil)
> (nil))
>
>with a block that begins like this:
>
>(code_label 56 43 101 3 "" "" [11 uses])
>
>The compiler quite properly notices that the basic blocks have only a
>single edge; the jump table and the if-then-else in insn 52 all have
>label 56 as their destination. However, the merge fails when we get
>to merge_blocks_move_predecessor_nojumps:
>
> barrier = next_nonnote_insn (end);
> if (GET_CODE (barrier) != BARRIER)
> abort ();
>
>and the compiler aborts.
>
>I could just replace
>
> if (GET_CODE (barrier) != BARRIER)
> abort ();
>
>with
>
> if (GET_CODE (barrier) != BARRIER)
> return 0;
>
>which seems to work OK.
>
>Thoughts?
Is this code from the unixODBC package? It seems I stumbled over the same
failure yesterday on ppc-linux then.
Franz.