1 // RUN: %clang_cc1 -no-opaque-pointers -emit-llvm -std=c++1z %s -o - -triple=x86_64-linux-gnu | FileCheck %s 2 3 struct S { S(); ~S(); }; 4 5 // CHECK-LABEL: define {{.*}}global_var_init 6 // CHECK-NOT: br 7 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @global) 8 S global; 9 10 // CHECK-LABEL: define {{.*}}global_var_init 11 // FIXME: Do we really need thread-safe initialization here? We don't run 12 // global ctors on multiple threads. (If we were to do so, we'd need thread-safe 13 // init for B<int>::member and B<int>::inline_member too.) 14 // CHECK: load atomic i8, i8* bitcast (i64* @_ZGV13inline_global to i8*) acquire, align 8 15 // CHECK: icmp eq i8 {{.*}}, 0 16 // CHECK: br i1 17 // CHECK-NOT: !prof 18 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @inline_global) 19 inline S inline_global; 20 21 // CHECK-LABEL: define {{.*}}global_var_init 22 // CHECK-NOT: br 23 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @thread_local_global) 24 thread_local S thread_local_global; 25 26 // CHECK-LABEL: define {{.*}}global_var_init 27 // CHECK: load i8, i8* bitcast (i64* @_ZGV26thread_local_inline_global to i8*) 28 // CHECK: icmp eq i8 {{.*}}, 0 29 // CHECK: br i1 30 // CHECK-NOT: !prof 31 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @thread_local_inline_global) 32 thread_local inline S thread_local_inline_global; 33 34 struct A { 35 static S member; 36 static thread_local S thread_local_member; 37 38 // CHECK-LABEL: define {{.*}}global_var_init 39 // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVN1A13inline_memberE to i8*) acquire, align 8 40 // CHECK: icmp eq i8 {{.*}}, 0 41 // CHECK: br i1 42 // CHECK-NOT: !prof 43 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @_ZN1A13inline_memberE) 44 static inline S inline_member; 45 46 // CHECK-LABEL: define {{.*}}global_var_init 47 // CHECK: load i8, i8* bitcast (i64* @_ZGVN1A26thread_local_inline_memberE to i8*) 48 // CHECK: icmp eq i8 {{.*}}, 0 49 // CHECK: br i1 50 // CHECK-NOT: !prof 51 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @_ZN1A26thread_local_inline_memberE) 52 static thread_local inline S thread_local_inline_member; 53 }; 54 55 // CHECK-LABEL: define{{.*}} void @_Z1fv() 56 void f() { 57 // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZ1fvE12static_local to i8*) acquire, align 8 58 // CHECK: icmp eq i8 {{.*}}, 0 59 // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_LOCAL:[0-9]*]] 60 static S static_local; 61 62 // CHECK: load i8, i8* @_ZGVZ1fvE19static_thread_local, 63 // CHECK: icmp eq i8 {{.*}}, 0 64 // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL:[0-9]*]] 65 static thread_local S static_thread_local; 66 } 67 68 // CHECK-LABEL: define {{.*}}global_var_init 69 // CHECK-NOT: br 70 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @_ZN1A6memberE) 71 S A::member; 72 73 // CHECK-LABEL: define {{.*}}global_var_init 74 // CHECK-NOT: br 75 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @_ZN1A19thread_local_memberE) 76 thread_local S A::thread_local_member; 77 78 template <typename T> struct B { 79 // CHECK-LABEL: define {{.*}}global_var_init 80 // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE6memberE to i8*) 81 // CHECK: icmp eq i8 {{.*}}, 0 82 // CHECK: br i1 83 // CHECK-NOT: !prof 84 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @_ZN1BIiE6memberE) 85 static S member; 86 87 // CHECK-LABEL: define {{.*}}global_var_init 88 // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE13inline_memberE to i8*) 89 // CHECK: icmp eq i8 {{.*}}, 0 90 // CHECK: br i1 91 // CHECK-NOT: !prof 92 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @_ZN1BIiE13inline_memberE) 93 static inline S inline_member; 94 95 // CHECK-LABEL: define {{.*}}global_var_init 96 // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE19thread_local_memberE to i8*) 97 // CHECK: icmp eq i8 {{.*}}, 0 98 // CHECK: br i1 99 // CHECK-NOT: !prof 100 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @_ZN1BIiE19thread_local_memberE) 101 static thread_local S thread_local_member; 102 103 // CHECK-LABEL: define {{.*}}global_var_init 104 // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE26thread_local_inline_memberE to i8*) 105 // CHECK: icmp eq i8 {{.*}}, 0 106 // CHECK: br i1 107 // CHECK-NOT: !prof 108 // CHECK: call void @_ZN1SC1Ev({{.*}}* {{[^,]*}} @_ZN1BIiE26thread_local_inline_memberE) 109 static thread_local inline S thread_local_inline_member; 110 }; 111 template<typename T> S B<T>::member; 112 template<typename T> thread_local S B<T>::thread_local_member; 113 114 template<typename ...T> void use(T &...); 115 void use_b() { 116 use(B<int>::member, B<int>::inline_member, B<int>::thread_local_member, 117 B<int>::thread_local_inline_member); 118 } 119 120 // CHECK-LABEL: define {{.*}}tls_init() 121 // CHECK: load i8, i8* @__tls_guard, align 1 122 // CHECK: icmp eq i8 {{.*}}, 0 123 // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL]] 124 125 // CHECK-DAG: ![[WEIGHTS_THREAD_LOCAL]] = !{!"branch_weights", i32 1, i32 1023} 126 // CHECK-DAG: ![[WEIGHTS_LOCAL]] = !{!"branch_weights", i32 1, i32 1048575} 127