1 // RUN: %clang_cc1 -triple x86_64-pc-win32 -emit-llvm %s -o - | FileCheck --check-prefix=COFF %s
2 // COFF:      @baz = dso_local global i32 42
3 // COFF-NEXT: @import_var = external dllimport global i32
4 // COFF-NEXT: @weak_bar = extern_weak global i32
5 // COFF-NEXT: @bar = external dso_local global i32
6 // COFF-NEXT: @local_thread_var = dso_local thread_local global i32 42
7 // COFF-NEXT: @thread_var = external dso_local thread_local global i32
8 // COFF-DAG: declare dso_local void @foo()
9 // COFF-DAG: define dso_local i32* @zed()
10 // COFF-DAG: declare dllimport void @import_func()
11 
12 // RUN: %clang_cc1 -triple x86_64-w64-mingw32 -emit-llvm %s -o - | FileCheck --check-prefix=MINGW %s
13 // MINGW:      @baz = dso_local global i32 42
14 // MINGW-NEXT: @import_var = external dllimport global i32
15 // MINGW-NEXT: @weak_bar = extern_weak global i32
16 // MINGW-NEXT: @bar = external global i32
17 // MINGW-NEXT: @local_thread_var = dso_local thread_local global i32 42
18 // MINGW-NEXT: @thread_var = external dso_local thread_local global i32
19 // MINGW-DAG: declare dso_local void @foo()
20 // MINGW-DAG: define dso_local i32* @zed()
21 // MINGW-DAG: declare dllimport void @import_func()
22 
23 /// Static relocation model defaults to -fdirect-access-external-data and sets
24 /// dso_local on most global objects.
25 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -mrelocation-model static %s -o - | FileCheck --check-prefix=STATIC %s
26 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -mrelocation-model static -fdirect-access-external-data %s -o - | FileCheck --check-prefix=STATIC %s
27 // STATIC:      @baz = dso_local global i32 42
28 // STATIC-NEXT: @import_var = external dso_local global i32
29 // STATIC-NEXT: @weak_bar = extern_weak dso_local global i32
30 // STATIC-NEXT: @bar = external dso_local global i32
31 // STATIC-NEXT: @local_thread_var = dso_local thread_local global i32 42
32 // STATIC-NEXT: @thread_var = external thread_local global i32
33 // STATIC-DAG: declare dso_local void @foo()
34 // STATIC-DAG: define dso_local i32* @zed()
35 // STATIC-DAG: declare dso_local void @import_func()
36 
37 /// If -fno-direct-access-external-data is set, drop dso_local from global variable
38 /// declarations.
39 // RUN: %clang_cc1 -triple x86_64 -emit-llvm %s -mrelocation-model static -fno-direct-access-external-data -o - | FileCheck --check-prefix=STATIC-INDIRECT %s
40 // STATIC-INDIRECT:      @baz = dso_local global i32 42
41 // STATIC-INDIRECT-NEXT: @import_var = external global i32
42 // STATIC-INDIRECT-NEXT: @weak_bar = extern_weak global i32
43 // STATIC-INDIRECT-NEXT: @bar = external global i32
44 // STATIC-INDIRECT-NEXT: @local_thread_var = dso_local thread_local global i32 42
45 // STATIC-INDIRECT-NEXT: @thread_var = external thread_local global i32
46 // STATIC-INDIRECT-DAG:  declare void @import_func()
47 // STATIC-INDIRECT-DAG:  define dso_local i32* @zed()
48 // STATIC-INDIRECT-DAG:  declare void @foo()
49 
50 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 1 -pic-is-pie %s -o - | FileCheck --check-prefix=PIE %s
51 // PIE:      @baz = dso_local global i32 42
52 // PIE-NEXT: @import_var = external global i32
53 // PIE-NEXT: @weak_bar = extern_weak global i32
54 // PIE-NEXT: @bar = external global i32
55 // PIE-NEXT: @local_thread_var = dso_local thread_local global i32 42
56 // PIE-NEXT: @thread_var = external thread_local global i32
57 // PIE-DAG: declare void @foo()
58 // PIE-DAG: define dso_local i32* @zed()
59 // PIE-DAG: declare void @import_func()
60 
61 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 1 -pic-is-pie -fdirect-access-external-data %s -o - | FileCheck --check-prefix=PIE-DIRECT %s
62 // PIE-DIRECT:      @baz = dso_local global i32 42
63 // PIE-DIRECT-NEXT: @import_var = external dso_local global i32
64 // PIE-DIRECT-NEXT: @weak_bar = extern_weak global i32
65 // PIE-DIRECT-NEXT: @bar = external dso_local global i32
66 // PIE-DIRECT-NEXT: @local_thread_var = dso_local thread_local global i32 42
67 // PIE-DIRECT-NEXT: @thread_var = external thread_local global i32
68 // PIE-DIRECT-DAG: declare void @foo()
69 // PIE-DIRECT-DAG: define dso_local i32* @zed()
70 // PIE-DIRECT-DAG: declare void @import_func()
71 
72 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -mrelocation-model static -fno-plt %s -o - | FileCheck --check-prefix=NOPLT %s
73 // NOPLT:      @baz = dso_local global i32 42
74 // NOPLT-NEXT: @import_var = external dso_local global i32
75 // NOPLT-NEXT: @weak_bar = extern_weak dso_local global i32
76 // NOPLT-NEXT: @bar = external dso_local global i32
77 // NOPLT-NEXT: @local_thread_var = dso_local thread_local global i32 42
78 // NOPLT-NEXT: @thread_var = external thread_local global i32
79 // NOPLT-DAG: declare void @foo()
80 // NOPLT-DAG: define dso_local i32* @zed()
81 // NOPLT-DAG: declare void @import_func()
82 
83 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -fno-plt -pic-level 1 -pic-is-pie -fdirect-access-external-data %s -o - | FileCheck --check-prefix=PIE-DIRECT-NOPLT %s
84 // PIE-DIRECT-NOPLT:      @baz = dso_local global i32 42
85 // PIE-DIRECT-NOPLT-NEXT: @import_var = external dso_local global i32
86 // PIE-DIRECT-NOPLT-NEXT: @weak_bar = extern_weak global i32
87 // PIE-DIRECT-NOPLT-NEXT: @bar = external dso_local global i32
88 // PIE-DIRECT-NOPLT-NEXT: @local_thread_var = dso_local thread_local global i32 42
89 // PIE-DIRECT-NOPLT-NEXT: @thread_var = external thread_local global i32
90 // PIE-DIRECT-NOPLT-DAG: declare void @foo()
91 // PIE-DIRECT-NOPLT-DAG: define dso_local i32* @zed()
92 // PIE-DIRECT-NOPLT-DAG: declare void @import_func()
93 
94 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 1 -pic-is-pie -fno-plt %s -o - | FileCheck --check-prefix=PIE-NO-PLT %s
95 // RUN: %clang_cc1 -triple powerpc64le -emit-llvm -mrelocation-model static %s -o - | FileCheck --check-prefix=PIE-NO-PLT %s
96 // PIE-NO-PLT:      @baz = dso_local global i32 42
97 // PIE-NO-PLT-NEXT: @import_var = external global i32
98 // PIE-NO-PLT-NEXT: @weak_bar = extern_weak global i32
99 // PIE-NO-PLT-NEXT: @bar = external global i32
100 // PIE-NO-PLT-NEXT: @local_thread_var = dso_local thread_local global i32 42
101 // PIE-NO-PLT-NEXT: @thread_var = external thread_local global i32
102 // PIE-NO-PLT-DAG:  declare void @import_func()
103 // PIE-NO-PLT-DAG:  define dso_local i32* @zed()
104 // PIE-NO-PLT-DAG:  declare void @foo()
105 
106 /// -fdirect-access-external-data is currently ignored for -fPIC.
107 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 2 %s -o - | FileCheck --check-prefix=SHARED %s
108 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -pic-level 2 -fdirect-access-external-data %s -o - | FileCheck --check-prefix=SHARED %s
109 // SHARED-DAG: @bar = external global i32
110 // SHARED-DAG: @weak_bar = extern_weak global i32
111 // SHARED-DAG: declare void @foo()
112 // SHARED-DAG: @baz ={{.*}} global i32 42
113 // SHARED-DAG: define{{.*}} i32* @zed()
114 // SHARED-DAG: @thread_var = external thread_local global i32
115 // SHARED-DAG: @local_thread_var ={{.*}} thread_local global i32 42
116 
117 int baz = 42;
118 __attribute__((dllimport)) extern int import_var;
119 __attribute__((weak)) extern int weak_bar;
120 extern int bar;
121 __attribute__((dllimport)) void import_func(void);
122 
123 int *use_import() {
124   import_func();
125   return &import_var;
126 }
127 
128 void foo(void);
129 
130 int *zed() {
131   foo();
132   return baz ? &weak_bar : &bar;
133 }
134 
135 __thread int local_thread_var = 42;
136 extern __thread int thread_var;
137 int *get_thread_var(int a) {
138   return a ? &thread_var : &local_thread_var;
139 }
140