Hi! GCC before r237607 used to mishandle TLS in -mcmodel=large - forcing TLS symbols in constant pool, which obviously doesn't work, because they aren't constant. For all other models aarch64_tls_symbol_p is checked first.
The following patch backports just the bug fix for this PR part to 6.x, the whole patch has not been declared as a bugfix, came with no testcases, so I have no idea on what it actually fixes. I want to roll GCC 6.3rc1 today, is this ok for 6.3 before that, or do you prefer to backport it yourself later (post 6.3)? Bootstrapped/regtested successfully on aarch64-linux on 6 branch. Is the testcase alone ok for trunk (additionally I've included it in my x86_64-linux and i686-linux bootstraps)? 2016-12-14 Wilco Dijkstra <wdijk...@arm.com> Jakub Jelinek <ja...@redhat.com> PR target/78796 * config/aarch64/aarch64.c (aarch64_classify_symbol): Merge large model checks into switch. * gcc.dg/tls/pr78796.c: New test. --- gcc/config/aarch64/aarch64.c.jj 2016-08-12 18:05:00.000000000 +0200 +++ gcc/config/aarch64/aarch64.c 2016-12-13 17:13:24.372394957 +0100 @@ -9280,18 +9280,6 @@ aarch64_classify_symbol (rtx x, rtx offs if (GET_CODE (x) == SYMBOL_REF) { - if (aarch64_cmodel == AARCH64_CMODEL_LARGE) - { - /* This is alright even in PIC code as the constant - pool reference is always PC relative and within - the same translation unit. */ - if (nopcrelative_literal_loads - && CONSTANT_POOL_ADDRESS_P (x)) - return SYMBOL_SMALL_ABSOLUTE; - else - return SYMBOL_FORCE_TO_MEM; - } - if (aarch64_tls_symbol_p (x)) return aarch64_classify_tls_symbol (x); @@ -9332,6 +9320,16 @@ aarch64_classify_symbol (rtx x, rtx offs ? SYMBOL_SMALL_GOT_28K : SYMBOL_SMALL_GOT_4G); return SYMBOL_SMALL_ABSOLUTE; + case AARCH64_CMODEL_LARGE: + /* This is alright even in PIC code as the constant + pool reference is always PC relative and within + the same translation unit. */ + if (nopcrelative_literal_loads + && CONSTANT_POOL_ADDRESS_P (x)) + return SYMBOL_SMALL_ABSOLUTE; + else + return SYMBOL_FORCE_TO_MEM; + default: gcc_unreachable (); } --- gcc/testsuite/gcc.dg/tls/pr78796.c.jj 2016-12-13 17:15:17.135966420 +0100 +++ gcc/testsuite/gcc.dg/tls/pr78796.c 2016-12-13 17:15:13.939006921 +0100 @@ -0,0 +1,32 @@ +/* PR target/78796 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-mcmodel=large" { target aarch64-*-* } } */ +/* { dg-require-effective-target tls } */ + +struct S { int a, b, c, d, e; }; +struct S t; +__thread struct S s; + +__attribute__((used, noinline, noclone)) void +foo (int *x, int *y) +{ + asm volatile ("" : : "g" (x), "g" (y) : "memory"); + if (*x != 1 || *y != 2) + __builtin_abort (); +} + +__attribute__((used, noinline, noclone)) void +bar (void) +{ + foo (&t.c, &s.c); +} + +int +main () +{ + t.c = 1; + s.c = 2; + bar (); + return 0; +} Jakub