From: Vladimir Makarov Date: Wed, 8 Jul 2015 15:04:54 +0000 (+0000) Subject: re PR target/66334 (cleanup block fails to initialize EBX) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1d6cc2e47f85b52bdfa6c4bec142b9d6ac1ca738;p=gcc.git re PR target/66334 (cleanup block fails to initialize EBX) 2015-07-08 Vladimir Makarov PR middle-end/66334 * ira-lives.c (process_bb_node_lives): Make conflicts with PIC hard regno live at the start of BB with incoming abnormal edges. * lra-lives.c (process_bb_lives): Ditto. 2015-07-08 Vladimir Makarov PR middle-end/66334 * gcc.target/i386/pr66334.c: New. From-SVN: r225561 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4c837231db2..9d19711adf6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-07-08 Vladimir Makarov + + PR middle-end/66334 + * ira-lives.c (process_bb_node_lives): Make conflicts with PIC + hard regno live at the start of BB with incoming abnormal edges. + * lra-lives.c (process_bb_lives): Ditto. + 2015-07-08 Thomas Schwinge PR libgomp/65099 diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index 4f5f3cc4716..44f0cbf74ff 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -1344,7 +1344,21 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) allocate such regs in this case. */ if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb)) for (px = 0; px < FIRST_PSEUDO_REGISTER; px++) - if (call_used_regs[px]) + if (call_used_regs[px] +#ifdef REAL_PIC_OFFSET_TABLE_REGNUM + /* We should create a conflict of PIC pseudo with + PIC hard reg as PIC hard reg can have a wrong + value after jump described by the abnormal edge. + In this case we can not allocate PIC hard reg to + PIC pseudo as PIC pseudo will also have a wrong + value. This code is not critical as LRA can fix + it but it is better to have the right allocation + earlier. */ + || (px == REAL_PIC_OFFSET_TABLE_REGNUM + && pic_offset_table_rtx != NULL_RTX + && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) +#endif + ) make_hard_regno_born (px); } diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index b270b0e6be6..edf4a91028e 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -953,7 +953,18 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) allocate such regs in this case. */ if (!cfun->has_nonlocal_label && bb_has_abnormal_call_pred (bb)) for (px = 0; px < FIRST_PSEUDO_REGISTER; px++) - if (call_used_regs[px]) + if (call_used_regs[px] +#ifdef REAL_PIC_OFFSET_TABLE_REGNUM + /* We should create a conflict of PIC pseudo with PIC + hard reg as PIC hard reg can have a wrong value after + jump described by the abnormal edge. In this case we + can not allocate PIC hard reg to PIC pseudo as PIC + pseudo will also have a wrong value. */ + || (px == REAL_PIC_OFFSET_TABLE_REGNUM + && pic_offset_table_rtx != NULL_RTX + && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) +#endif + ) make_hard_regno_born (px, false); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d39b273a615..b288f0d7490 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-07-08 Vladimir Makarov + + PR middle-end/66334 + * gcc.target/i386/pr66334.c: New. + 2015-07-08 David Malcolm * jit.dg/test-error-gcc_jit_block_end_with_switch-NULL-case.c: Fix diff --git a/gcc/testsuite/gcc.target/i386/pr66334.c b/gcc/testsuite/gcc.target/i386/pr66334.c new file mode 100644 index 00000000000..97dfecc8725 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66334.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-O2 -fpic -fexceptions -fasynchronous-unwind-tables" } */ +/* { dg-final { scan-assembler "movl\[ \\t\].+, %ebx" } } */ +extern int foo (int); +extern void exit (int __status) __attribute__ ((__nothrow__ )) __attribute__ ((__noreturn__)); +struct __pthread_cleanup_frame +{ + void (*__cancel_routine) (void *); + void *__cancel_arg; + int __do_it; + int __cancel_type; +}; +extern __inline void +__pthread_cleanup_routine (struct __pthread_cleanup_frame *__frame) +{ + if (__frame->__do_it) + __frame->__cancel_routine (__frame->__cancel_arg); +} +static int cl_called; + +static void +cl (void *arg) +{ + ++cl_called; +} + + +void * +tf_usleep (void *arg) +{ + + do { struct __pthread_cleanup_frame __clframe __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) = { .__cancel_routine = (cl), .__cancel_arg = ( + ((void *)0)), .__do_it = 1 };; + + foo (arg == ((void *)0) ? (0x7fffffffL * 2UL + 1UL) : 0); + + __clframe.__do_it = (0); } while (0); + + exit (1); +}