https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102772

--- Comment #16 from ro at CeBiTec dot Uni-Bielefeld.DE <ro at CeBiTec dot 
Uni-Bielefeld.DE> ---
> --- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
> If the movaps that it fails on are:
>         movaps  %xmm1, thr.1@ntpoff(%ebx)
>         movdqu  16(%eax), %xmm2
>         movaps  %xmm2, thr.1@ntpoff+16(%ebx)
> then I'd say it must be some Solaris bug, because:
>         .section        .tbss,"awT",@nobits
>         .align 16
>         .type   thr.1, @object
>         .size   thr.1, 36
> thr.1:
>         .zero   36
> so thr.1 symbol should be 16-byte aligned and so movaps to that address should
> work.
> On pointer2.o, is the .tbss section properly 16-byte aligned?
> On i686-linux I see in readelf -Wa:
>   [ 8] .tbss             NOBITS          00000000 000360 000024 00 WAT  0   0
> 16

Same on Solaris:

  [ 8] .tbss             NOBITS          00000000 000330 000024 00 WAT  0   0
16

> What about the executable (in that case the PT_TLS segment is more important
> (whether it has 16-byte p_align).

Same here:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
[...]
  TLS            0x00c3d0 0x0806c3d0 0x00000000 0x00000 0x00024 RW  0x10

> If Solaris dynamic linker doesn't ensure proper alignment of TLS vars (or
> assembler or linker screw it up in the middle), it would be nice to find out 
> if
> it does for all alignments or just say higher than 8-byte, and perhaps add 
> some
> workaround on the GCC side somewhere.
> On the pointer2.f90 testcase it is symtab_node::can_increase_alignment_p that
> decides if the alignment of the var can be done, so perhaps we'd need a target
> hook that for Solaris would say that one can't increase alignment of TLS vars.

We could try that once we know for certain that's the case (and get it
fixed at the same time).

However, when gld is in use, the test fails in exactly the same way.

> But the question is if in
> struct __attribute__((aligned (32))) S { long long buf[4]; };
> __thread struct S s;
> S *foo (void) { return &s; }
> it won't return not properly 32-byte aligned pointer too (and is that in all
> threads or just some (initial vs. other threads)?

I've wrapped that in a small test programming, calling foo both from the
initial thread and a new one: in all cases, the return value from foo
was 32-byte aligned as expected.

One thing I wondered about: Solaris ld used to be very picky about
exactly following the use of registers in TLS sequences: the Linker and
Libraries guide documents %eax for TLS LE:

https://docs.oracle.com/cd/E37838_01/html/E36783/man-tlsam.html#scrolltoc

Maybe the use of %ebx in this code is the program?  At least the test
program above does use %eax, as expected.

We had issues like this both for amd64 and sparc in the past.

Reply via email to