re PR target/66334 (cleanup block fails to initialize EBX)
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 8 Jul 2015 15:04:54 +0000 (15:04 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 8 Jul 2015 15:04:54 +0000 (15:04 +0000)
2015-07-08  Vladimir Makarov  <vmakarov@redhat.com>

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  <vmakarov@redhat.com>

PR middle-end/66334
* gcc.target/i386/pr66334.c: New.

From-SVN: r225561

gcc/ChangeLog
gcc/ira-lives.c
gcc/lra-lives.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr66334.c [new file with mode: 0644]

index 4c837231db2f7ed5fa958795e16acf619fb343cc..9d19711adf6d3a481e9929238f1e1a6ef923c5cb 100644 (file)
@@ -1,3 +1,10 @@
+2015-07-08  Vladimir Makarov  <vmakarov@redhat.com>
+
+       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  <thomas@codesourcery.com>
 
        PR libgomp/65099
index 4f5f3cc47169a4bdf00bc5e153f4177a20f68b68..44f0cbf74ffab5e8fbb8851e3a8d1b773fb9e260 100644 (file)
@@ -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);
        }
 
index b270b0e6be6d214d95eb3fe0f72cafb2b99b0413..edf4a91028e3a1250cd49c11a0f860a504b885a9 100644 (file)
@@ -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);
     }
 
index d39b273a615e205572bbd108cd1276d73fa64724..b288f0d7490949047e471d827c9bc3a8e18d8ef4 100644 (file)
@@ -1,3 +1,8 @@
+2015-07-08  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR middle-end/66334
+       * gcc.target/i386/pr66334.c: New.
+
 2015-07-08  David Malcolm  <dmalcolm@redhat.com>
 
        * 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 (file)
index 0000000..97dfecc
--- /dev/null
@@ -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);
+}