Hi,

This patch is to fix the problem described here:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066

I follow Ian's suggestion and set
ix86_tls_descriptor_calls_expanded_in_cfun in
tls_global_dynamic_64_<mode> and tls_local_dynamic_base_64_<mode>.
Although 32bit doesn't have the problem,
ix86_tls_descriptor_calls_expanded_in_cfun is also set for
tls_global_dynamic_32 and tls_local_dynamic_base_32 to make
ix86_tls_descriptor_calls_expanded_in_cfun setting consistent across
32bits and 64bits.

If ix86_current_function_calls_tls_descriptor is set, we know that
there is tls expanded call in current function. Update
crtl->preferred_stack_boundary and crtl->stack_alignment_needed to be
no less than PREFERED_STACK_ALIGNMENT at the start of
ix86_compute_frame_layout. We don't do the update in
legitimize_tls_address in cfgexpand stage, which is too early because
according to the comments before
ix86_current_function_calls_tls_descriptor, tls call may be optimized
away. ix86_compute_frame_layout is the latest place to do the update.

bootstrap on x86_64-linux-gnu is ok. regression test is going on. Ok
for trunk if tests pass?

Thanks,
Wei.

gcc/ChangeLog:

2014-03-07  Wei Mi  <w...@google.com>

        * config/i386/i386.c (ix86_compute_frame_layout): Update
        preferred_stack_boundary when there is tls expanded call.
        * config/i386/i386.md: Set
        ix86_tls_descriptor_calls_expanded_in_cfun.

gcc/testsuite/ChangeLog:

2014-03-07  Wei Mi  <w...@google.com>

        * g++.dg/pr58066.C: New test.


Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c      (revision 208410)
+++ gcc/config/i386/i386.c      (working copy)
@@ -9504,6 +9504,19 @@ ix86_compute_frame_layout (struct ix86_f
       crtl->preferred_stack_boundary = 128;
       crtl->stack_alignment_needed = 128;
     }
+  /* For 64-bit target, preferred_stack_boundary is never updated for call
+     expanded from tls descriptor. Update it here. We don't update it in
+     expand stage because according to the comments before
+     ix86_current_function_calls_tls_descriptor, tls calls may be optimized
+     away.  */
+  else if (TARGET_64BIT
+          && ix86_current_function_calls_tls_descriptor
+          && crtl->preferred_stack_boundary < PREFERRED_STACK_BOUNDARY)
+    {
+      crtl->preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
+      if (crtl->stack_alignment_needed < PREFERRED_STACK_BOUNDARY)
+       crtl->stack_alignment_needed = PREFERRED_STACK_BOUNDARY;
+    }

   gcc_assert (!size || stack_alignment_needed);
   gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
Index: gcc/config/i386/i386.md
===================================================================
--- gcc/config/i386/i386.md     (revision 208410)
+++ gcc/config/i386/i386.md     (working copy)
@@ -12891,7 +12891,11 @@
                     UNSPEC_TLS_GD))
      (clobber (match_scratch:SI 4))
      (clobber (match_scratch:SI 5))
-     (clobber (reg:CC FLAGS_REG))])])
+     (clobber (reg:CC FLAGS_REG))])]
+  ""
+{
+  ix86_tls_descriptor_calls_expanded_in_cfun = true;
+})

 (define_insn "*tls_global_dynamic_64_<mode>"
   [(set (match_operand:P 0 "register_operand" "=a")
@@ -12946,7 +12950,10 @@
           (const_int 0)))
      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
               UNSPEC_TLS_GD)])]
-  "TARGET_64BIT")
+  "TARGET_64BIT"
+{
+  ix86_tls_descriptor_calls_expanded_in_cfun = true;
+})

 (define_insn "*tls_local_dynamic_base_32_gnu"
   [(set (match_operand:SI 0 "register_operand" "=a")
@@ -12982,7 +12989,11 @@
            UNSPEC_TLS_LD_BASE))
       (clobber (match_scratch:SI 3))
       (clobber (match_scratch:SI 4))
-      (clobber (reg:CC FLAGS_REG))])])
+      (clobber (reg:CC FLAGS_REG))])]
+  ""
+{
+  ix86_tls_descriptor_calls_expanded_in_cfun = true;
+})

 (define_insn "*tls_local_dynamic_base_64_<mode>"
   [(set (match_operand:P 0 "register_operand" "=a")
@@ -13029,7 +13040,10 @@
            (mem:QI (match_operand 1))
            (const_int 0)))
       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
-  "TARGET_64BIT")
+  "TARGET_64BIT"
+{
+  ix86_tls_descriptor_calls_expanded_in_cfun = true;
+})

 ;; Local dynamic of a single variable is a lose.  Show combine how
 ;; to convert that back to global dynamic.
Index: gcc/testsuite/g++.dg/pr58066.C
===================================================================
--- gcc/testsuite/g++.dg/pr58066.C      (revision 0)
+++ gcc/testsuite/g++.dg/pr58066.C      (revision 0)
@@ -0,0 +1,12 @@
+/* { dg-do compile { target {{ i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-fPIC -O2 -m64" } */
+
+/* Check whether the stack frame starting address of tls expanded call
+   in __cxa_get_globals() is 16bytes aligned.  */
+static __thread char ccc;
+extern "C" void* __cxa_get_globals() throw()
+{
+ return &ccc;
+}
+
+/* { dg-final { scan-assembler ".cfi_def_cfa_offset 16" } } */

Reply via email to