Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCXX / microsoft-abi-thread-safe-statics.cpp
blob7f8288cf96d5a61265f65dfe082c1571153d3e0a
1 // RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fms-extensions -fms-compatibility -fms-compatibility-version=19 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
2 // REQUIRES: asserts
4 struct S {
5 S();
6 ~S();
7 };
9 // CHECK-DAG: @"?s@?1??f@@YAAAUS@@XZ@4U2@A" = linkonce_odr dso_local thread_local global %struct.S zeroinitializer
10 // CHECK-DAG: @"??__J?1??f@@YAAAUS@@XZ@51" = linkonce_odr thread_local global i32 0
11 // CHECK-DAG: @"?s@?1??g@@YAAAUS@@XZ@4U2@A" = linkonce_odr dso_local global %struct.S zeroinitializer
12 // CHECK-DAG: @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA" = linkonce_odr global i32 0
13 // CHECK-DAG: @_Init_thread_epoch = external thread_local global i32, align 4
14 // CHECK-DAG: @"?j@?1??h@@YAAAUS@@_N@Z@4U2@A" = linkonce_odr dso_local thread_local global %struct.S zeroinitializer
15 // CHECK-DAG: @"??__J?1??h@@YAAAUS@@_N@Z@51" = linkonce_odr thread_local global i32 0
16 // CHECK-DAG: @"?i@?1??h@@YAAAUS@@_N@Z@4U2@A" = linkonce_odr dso_local global %struct.S zeroinitializer
17 // CHECK-DAG: @"?$TSS0@?1??h@@YAAAUS@@_N@Z@4HA" = linkonce_odr global i32 0
18 // CHECK-DAG: @"?i@?1??g1@@YAHXZ@4HA" = internal global i32 0, align 4
19 // CHECK-DAG: @"?$TSS0@?1??g1@@YAHXZ@4HA" = internal global i32 0, align 4
21 // CHECK-LABEL: define {{.*}} @"?f@@YAAAUS@@XZ"()
22 // CHECK-SAME: personality ptr @__CxxFrameHandler3
23 extern inline S &f() {
24 static thread_local S s;
25 // CHECK: %[[guard:.*]] = load i32, ptr @"??__J?1??f@@YAAAUS@@XZ@51"
26 // CHECK-NEXT: %[[mask:.*]] = and i32 %[[guard]], 1
27 // CHECK-NEXT: %[[cmp:.*]] = icmp eq i32 %[[mask]], 0
28 // CHECK-NEXT: br i1 %[[cmp]], label %[[init:.*]], label %[[init_end:.*]], !prof ![[unlikely_threadlocal:.*]]
30 // CHECK: [[init]]:
31 // CHECK-NEXT: %[[or:.*]] = or i32 %[[guard]], 1
32 // CHECK-NEXT: store i32 %[[or]], ptr @"??__J?1??f@@YAAAUS@@XZ@51"
33 // CHECK-NEXT: invoke {{.*}} @"??0S@@QAE@XZ"(ptr {{[^,]*}} @"?s@?1??f@@YAAAUS@@XZ@4U2@A")
34 // CHECK-NEXT: to label %[[invoke_cont:.*]] unwind label %[[lpad:.*]]
36 // CHECK: [[invoke_cont]]:
37 // CHECK-NEXT: call i32 @__tlregdtor(ptr @"??__Fs@?1??f@@YAAAUS@@XZ@YAXXZ")
38 // CHECK-NEXT: br label %[[init_end:.*]]
40 // CHECK: [[init_end]]:
41 // CHECK: [[S_ADDR:%.+]] = call align 1 ptr @llvm.threadlocal.address.p0(ptr align 1 @"?s@?1??f@@YAAAUS@@XZ@4U2@A")
42 // CHECK-NEXT: ret ptr [[S_ADDR]]
44 // CHECK: [[lpad:.*]]:
45 // CHECK-NEXT: cleanuppad within none []
46 // CHECK: %[[guard:.*]] = load i32, ptr @"??__J?1??f@@YAAAUS@@XZ@51"
47 // CHECK-NEXT: %[[mask:.*]] = and i32 %[[guard]], -2
48 // CHECK-NEXT: store i32 %[[mask]], ptr @"??__J?1??f@@YAAAUS@@XZ@51"
49 // CHECK-NEXT: cleanupret {{.*}} unwind to caller
50 return s;
54 // CHECK-LABEL: define {{.*}} @"?g@@YAAAUS@@XZ"()
55 extern inline S &g() {
56 static S s;
57 // CHECK: %[[guard:.*]] = load atomic i32, ptr @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA" unordered, align 4
58 // CHECK-NEXT: %[[epoch:.*]] = load i32, ptr @_Init_thread_epoch
59 // CHECK-NEXT: %[[cmp:.*]] = icmp sgt i32 %[[guard]], %[[epoch]]
60 // CHECK-NEXT: br i1 %[[cmp]], label %[[init_attempt:.*]], label %[[init_end:.*]], !prof ![[unlikely_staticlocal:.*]]
62 // CHECK: [[init_attempt]]:
63 // CHECK-NEXT: call void @_Init_thread_header(ptr @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
64 // CHECK-NEXT: %[[guard2:.*]] = load atomic i32, ptr @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA" unordered, align 4
65 // CHECK-NEXT: %[[cmp2:.*]] = icmp eq i32 %[[guard2]], -1
66 // CHECK-NEXT: br i1 %[[cmp2]], label %[[init:.*]], label %[[init_end:.*]]
68 // CHECK: [[init]]:
69 // CHECK-NEXT: invoke {{.*}} @"??0S@@QAE@XZ"(ptr {{[^,]*}} @"?s@?1??g@@YAAAUS@@XZ@4U2@A")
70 // CHECK-NEXT: to label %[[invoke_cont:.*]] unwind label %[[lpad:.*]]
72 // CHECK: [[invoke_cont]]:
73 // CHECK-NEXT: call i32 @atexit(ptr @"??__Fs@?1??g@@YAAAUS@@XZ@YAXXZ")
74 // CHECK-NEXT: call void @_Init_thread_footer(ptr @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
75 // CHECK-NEXT: br label %init.end
77 // CHECK: [[init_end]]:
78 // CHECK-NEXT: ret ptr @"?s@?1??g@@YAAAUS@@XZ@4U2@A"
80 // CHECK: [[lpad]]:
81 // CHECK-NEXT: cleanuppad within none []
82 // CHECK: call void @_Init_thread_abort(ptr @"?$TSS0@?1??g@@YAAAUS@@XZ@4HA")
83 // CHECK-NEXT: cleanupret {{.*}} unwind to caller
84 return s;
87 extern inline S&h(bool b) {
88 static thread_local S j;
89 static S i;
90 return b ? j : i;
93 // CHECK-LABEL: define dso_local noundef i32 @"?g1@@YAHXZ"()
94 int f1();
95 int g1() {
96 static int i = f1();
97 return i;
100 // CHECK-DAG: ![[unlikely_threadlocal]] = !{!"branch_weights", i32 1, i32 1023}
101 // CHECK-DAG: ![[unlikely_staticlocal]] = !{!"branch_weights", i32 1, i32 1048575}