Breakage in flow with table jumps
Andrew Haley
aph@cambridge.redhat.com
Wed Jun 20 11:05:00 GMT 2001
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?
Andrew.
More information about the Gcc-bugs
mailing list