1 // Test that the use of thread local variables would be wrapped by @llvm.threadlocal.address intrinsics.
2 // RUN: %clang_cc1 -std=c++11 -emit-llvm -triple x86_64 -o - %s -disable-llvm-passes | FileCheck %s
3 // RUN: %clang_cc1 -std=c++11 -emit-llvm -triple aarch64 -o - -O1 %s | FileCheck %s -check-prefix=CHECK-O1
9 // CHECK: @i = {{.*}}thread_local global i32 0
10 // CHECK: @_ZZ1fvE1j = internal thread_local global i32 0
14 // CHECK-NEXT: %[[IA:.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @i)
15 // CHECK-NEXT: %[[VA:.+]] = load i32, ptr %[[IA]]
16 // CHECK-NEXT: %[[INC:.+]] = add nsw i32 %[[VA]], 1
17 // CHECK-NEXT: store i32 %[[INC]], ptr %[[IA]], align 4
18 // CHECK-NEXT: %[[IA2:.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @i)
19 // CHECK-NEXT: %[[RET:.+]] = load i32, ptr %[[IA2]], align 4
20 // CHECK-NEXT: ret i32 %[[RET]]
22 // CHECK: declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #[[ATTR_NUM:.+]]
24 // CHECK-O1-LABEL: @_Z1gv
25 // CHECK-O1-NEXT: entry:
26 // CHECK-O1-NEXT: %[[I_ADDR:.+]] = {{.*}}call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @i)
27 // CHECK-O1-NEXT: %[[VAL:.+]] = load i32, ptr %[[I_ADDR]]
28 // CHECK-O1-NEXT: %[[INC:.+]] = add nsw i32 %[[VAL]], 1
29 // CHECK-O1-NEXT: store i32 %[[INC]], ptr %[[I_ADDR]]
30 // CHECK-O1-NEXT: ret i32 %[[INC]]
32 thread_local
int j
= 0;
38 // CHECK-NEXT: %[[JA:.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZZ1fvE1j)
39 // CHECK-NEXT: %[[VA:.+]] = load i32, ptr %[[JA]]
40 // CHECK-NEXT: %[[INC:.+]] = add nsw i32 %[[VA]], 1
41 // CHECK-NEXT: store i32 %[[INC]], ptr %[[JA]], align 4
42 // CHECK-NEXT: %[[JA2:.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZZ1fvE1j)
43 // CHECK-NEXT: %[[RET:.+]] = load i32, ptr %[[JA2]], align 4
44 // CHECK-NEXT: ret i32 %[[RET]]
46 // CHECK-O1-LABEL: @_Z1fv
47 // CHECK-O1-NEXT: entry:
48 // CHECK-O1-NEXT: %[[J_ADDR:.+]] = {{.*}}call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZZ1fvE1j)
49 // CHECK-O1-NEXT: %[[VAL:.+]] = load i32, ptr %[[J_ADDR]]
50 // CHECK-O1-NEXT: %[[INC:.+]] = add nsw i32 %[[VAL]], 1
51 // CHECK-O1-NEXT: store i32 %[[INC]], ptr %[[J_ADDR]]
52 // CHECK-O1-NEXT: ret i32 %[[INC]]
54 // CHECK: attributes #[[ATTR_NUM]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }