diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -2485,6 +2485,21 @@ CGF.EmitBlock(InitCheckBlock); } + // The semantics of dynamic initialization of variables with static or thread + // storage duration depends on whether they are declared at block-scope. The + // initialization of such variables at block-scope can be aborted with an + // exception and later retried (per C++20 [stmt.dcl]p4), and recursive entry + // to their initialization has undefined behavior (also per C++20 + // [stmt.dcl]p4). For such variables declared at non-block scope, exceptions + // lead to termination (per C++20 [except.terminate]p1), and recursive + // references to the variables are governed only by the lifetime rules (per + // C++20 [class.cdtor]p2), which means such references are perfectly fine as + // long as they avoid touching memory. As a result, block-scope variables must + // not be marked as initialized until after initialization completes (unless + // the mark is reverted following an exception), but non-block-scope variables + // must be marked prior to initialization so that recursive accesses during + // initialization do not restart initialization. + // Variables used when coping with thread-safe statics and exceptions. if (threadsafe) { // Call __cxa_guard_acquire. @@ -2500,6 +2515,12 @@ CGF.EHStack.pushCleanup(EHCleanup, guard); CGF.EmitBlock(InitBlock); + } else if (!D.isLocalVarDecl()) { + // For non-local variables, store 1 into the first byte of the guard + // variable before the object initialization begins so that references + // to the variable during initialization don't restart initialization. + Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1), + Builder.CreateElementBitCast(guardAddr, CGM.Int8Ty)); } // Emit the initializer and add a global destructor if appropriate. @@ -2512,9 +2533,10 @@ // Call __cxa_guard_release. This cannot throw. CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy), guardAddr.getPointer()); - } else { - // Store 1 into the first byte of the guard variable after initialization is - // complete. + } else if (D.isLocalVarDecl()) { + // For local variables, store 1 into the first byte of the guard variable + // after the object initialization completes so that initialization is + // retried if initialization is interrupted by an exception. Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1), Builder.CreateElementBitCast(guardAddr, CGM.Int8Ty)); } diff --git a/clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp b/clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp --- a/clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp +++ b/clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp @@ -127,9 +127,9 @@ // CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end // CHECK: init.check: +// CHECK: store i8 1, ptr @_ZGVN5test21AIvE8instanceE, align 8 // CHECK: call void @_ZN5test21AIvEC1Ev(ptr {{[^,]*}} @_ZN5test21AIvE8instanceE) // CHECK: %1 = call i32 @atexit(ptr @__dtor__ZN5test21AIvE8instanceE) -// CHECK: store i8 1, ptr @_ZGVN5test21AIvE8instanceE, align 8 // CHECK: br label %init.end // CHECK: init.end: @@ -190,10 +190,10 @@ // CHECK: br i1 %guard.uninitialized, label %init.check, label %init.end // CHECK: init.check: +// CHECK: store i8 1, ptr @_ZGVN5test12t1IiEE, align 8 // CHECK32: call void @_ZN5test15Test1C1Ei(ptr {{[^,]*}} @_ZN5test12t1IiEE, i32 noundef 2) // CHECK64: call void @_ZN5test15Test1C1Ei(ptr {{[^,]*}} @_ZN5test12t1IiEE, i32 noundef signext 2) // CHECK: %1 = call i32 @atexit(ptr @__dtor__ZN5test12t1IiEE) -// CHECK: store i8 1, ptr @_ZGVN5test12t1IiEE, align 8 // CHECK: br label %init.end // CHECK: init.end: diff --git a/clang/test/CodeGenCXX/cxx11-thread-local.cpp b/clang/test/CodeGenCXX/cxx11-thread-local.cpp --- a/clang/test/CodeGenCXX/cxx11-thread-local.cpp +++ b/clang/test/CodeGenCXX/cxx11-thread-local.cpp @@ -193,10 +193,10 @@ // CHECK: %[[VF_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0 // CHECK: br i1 %[[VF_M_INITIALIZED]], // need init: +// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1VIfE1mE to i8*) // CHECK: call{{.*}} i32 @_Z1gv() // CHECK: [[VFM_ADDR:%.+]] = call align 4 i32* @llvm.threadlocal.address.p0i32(i32* align 4 @_ZN1VIfE1mE) // CHECK: store i32 %{{.*}}, i32* [[VFM_ADDR]], align 4 -// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1VIfE1mE to i8*) // CHECK: br label // LINUX_AIX: define internal void @[[XF_M_INIT]]() @@ -206,11 +206,11 @@ // CHECK: %[[XF_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0 // CHECK: br i1 %[[XF_M_INITIALIZED]], // need init: +// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1XIfE1mE to i8*) // AIX-NOT: br // LINUX: call {{.*}}__cxa_thread_atexit // AIX: call {{.*}}__pt_atexit_np // DARWIN: call {{.*}}_tlv_atexit -// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1XIfE1mE to i8*) // CHECK: br label // LINUX: declare i32 @__cxa_thread_atexit(void (i8*)*, i8*, i8*) @@ -329,10 +329,10 @@ // CHECK: %[[V_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0 // CHECK: br i1 %[[V_M_INITIALIZED]], // need init: +// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*) // CHECK: call{{.*}} i32 @_Z1gv() // CHECK: [[VEM_ADDR:%.+]] = call align 4 i32* @llvm.threadlocal.address.p0i32(i32* align 4 @_ZN1VIiE1mE) // CHECK: store i32 %{{.*}}, i32* [[VEM_ADDR]], align 4 -// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*) // CHECK: br label // LINUX_AIX: define internal void @[[X_M_INIT]]() @@ -342,10 +342,10 @@ // CHECK: %[[X_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0 // CHECK: br i1 %[[X_M_INITIALIZED]], // need init: +// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1XIiE1mE to i8*) // LINUX: call {{.*}}__cxa_thread_atexit // AIX: call {{.*}}__pt_atexit_np // DARWIN: call {{.*}}_tlv_atexit -// CHECK: store i8 1, i8* bitcast (i64* @_ZGVN1XIiE1mE to i8*) // CHECK: br label // CHECK: define {{.*}}@[[GLOBAL_INIT:.*]]() diff --git a/clang/test/CodeGenCXX/cxx1y-variable-template.cpp b/clang/test/CodeGenCXX/cxx1y-variable-template.cpp --- a/clang/test/CodeGenCXX/cxx1y-variable-template.cpp +++ b/clang/test/CodeGenCXX/cxx1y-variable-template.cpp @@ -40,9 +40,9 @@ // CHECK: load {{.*}} @_ZGVN7PR4211112_GLOBAL__N_11nILi0EEE // CHECK: icmp eq i8 {{.*}}, 0 // CHECK: br i1 + // CHECK: store i8 1, ptr @_ZGVN7PR4211112_GLOBAL__N_11nILi0EEE // CHECK: call noundef i32 @_ZN7PR421111fEv( // CHECK: [[N_ADDR:%.+]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_ZN7PR4211112_GLOBAL__N_11nILi0EEE) // CHECK: store i32 {{.*}}, ptr [[N_ADDR]] - // CHECK: store i8 1, ptr @_ZGVN7PR4211112_GLOBAL__N_11nILi0EEE int g() { return n<> + n<>; } } diff --git a/clang/test/CodeGenCXX/global-init.cpp b/clang/test/CodeGenCXX/global-init.cpp --- a/clang/test/CodeGenCXX/global-init.cpp +++ b/clang/test/CodeGenCXX/global-init.cpp @@ -80,9 +80,9 @@ // This needs an initialization function and guard variables. // CHECK: load i8, i8* bitcast (i64* @_ZGVN5test41xE to i8*) - // CHECK: [[CALL:%.*]] = call noundef i32 @_ZN5test43fooEv + // CHECK: store i8 1, i8* bitcast (i64* @_ZGVN5test41xE to i8*) + // CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN5test43fooEv // CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test41xE - // CHECK-NEXT: store i8 1, i8* bitcast (i64* @_ZGVN5test41xE to i8*) __attribute__((weak)) int x = foo(); } diff --git a/clang/test/CodeGenCXX/static-data-member.cpp b/clang/test/CodeGenCXX/static-data-member.cpp --- a/clang/test/CodeGenCXX/static-data-member.cpp +++ b/clang/test/CodeGenCXX/static-data-member.cpp @@ -70,9 +70,9 @@ // CHECK: [[GUARDBYTE:%.*]] = load i8, ptr @_ZGVN5test31AIiE1xE // CHECK-NEXT: [[UNINITIALIZED:%.*]] = icmp eq i8 [[GUARDBYTE]], 0 // CHECK-NEXT: br i1 [[UNINITIALIZED]] - // CHECK: [[TMP:%.*]] = call noundef i32 @_ZN5test33fooEv() + // CHECK: store i8 1, ptr @_ZGVN5test31AIiE1xE + // CHECK-NEXT: [[TMP:%.*]] = call noundef i32 @_ZN5test33fooEv() // CHECK-NEXT: store i32 [[TMP]], ptr @_ZN5test31AIiE1xE, align 4 - // CHECK-NEXT: store i8 1, ptr @_ZGVN5test31AIiE1xE // CHECK-NEXT: br label // CHECK: ret void } diff --git a/clang/test/OpenMP/threadprivate_codegen.cpp b/clang/test/OpenMP/threadprivate_codegen.cpp --- a/clang/test/OpenMP/threadprivate_codegen.cpp +++ b/clang/test/OpenMP/threadprivate_codegen.cpp @@ -1585,11 +1585,11 @@ // CHECK1-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0 // CHECK1-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]] // CHECK1: init.check: +// CHECK1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // CHECK1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) // CHECK1-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB1]], ptr @_ZN2STI2S4E2stE, ptr @.__kmpc_global_ctor_..9, ptr null, ptr @.__kmpc_global_dtor_..10) // CHECK1-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23) // CHECK1-NEXT: [[TMP2:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]] -// CHECK1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // CHECK1-NEXT: br label [[INIT_END]] // CHECK1: init.end: // CHECK1-NEXT: ret void @@ -2214,11 +2214,11 @@ // CHECK2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0 // CHECK2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]] // CHECK2: init.check: +// CHECK2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // CHECK2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB1]]) // CHECK2-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB1]], ptr @_ZN2STI2S4E2stE, ptr @.__kmpc_global_ctor_..9, ptr null, ptr @.__kmpc_global_dtor_..10) // CHECK2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23) // CHECK2-NEXT: [[TMP2:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]] -// CHECK2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // CHECK2-NEXT: br label [[INIT_END]] // CHECK2: init.end: // CHECK2-NEXT: ret void @@ -2697,9 +2697,9 @@ // SIMD1-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0 // SIMD1-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]] // SIMD1: init.check: +// SIMD1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // SIMD1-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23) // SIMD1-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]] -// SIMD1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // SIMD1-NEXT: br label [[INIT_END]] // SIMD1: init.end: // SIMD1-NEXT: ret void @@ -3167,9 +3167,9 @@ // SIMD2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG234]] // SIMD2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG234]] // SIMD2: init.check: +// SIMD2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG234]] // SIMD2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG235:![0-9]+]] // SIMD2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG234]] -// SIMD2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG234]] // SIMD2-NEXT: br label [[INIT_END]], !dbg [[DBG234]] // SIMD2: init.end: // SIMD2-NEXT: ret void, !dbg [[DBG237:![0-9]+]] @@ -3767,9 +3767,9 @@ // CHECK-TLS1-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0 // CHECK-TLS1-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]] // CHECK-TLS1: init.check: +// CHECK-TLS1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // CHECK-TLS1-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23) // CHECK-TLS1-NEXT: [[TMP1:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]] -// CHECK-TLS1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // CHECK-TLS1-NEXT: br label [[INIT_END]] // CHECK-TLS1: init.end: // CHECK-TLS1-NEXT: ret void @@ -4302,9 +4302,9 @@ // CHECK-TLS2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0 // CHECK-TLS2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]] // CHECK-TLS2: init.check: +// CHECK-TLS2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // CHECK-TLS2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23) // CHECK-TLS2-NEXT: [[TMP1:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR4]] -// CHECK-TLS2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // CHECK-TLS2-NEXT: br label [[INIT_END]] // CHECK-TLS2: init.end: // CHECK-TLS2-NEXT: ret void @@ -4846,9 +4846,9 @@ // CHECK-TLS3-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG291]] // CHECK-TLS3-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG291]] // CHECK-TLS3: init.check: +// CHECK-TLS3-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG291]] // CHECK-TLS3-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG292:![0-9]+]] // CHECK-TLS3-NEXT: [[TMP1:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG291]] -// CHECK-TLS3-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG291]] // CHECK-TLS3-NEXT: br label [[INIT_END]], !dbg [[DBG291]] // CHECK-TLS3: init.end: // CHECK-TLS3-NEXT: ret void, !dbg [[DBG294:![0-9]+]] @@ -5408,9 +5408,9 @@ // CHECK-TLS4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG291]] // CHECK-TLS4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG291]] // CHECK-TLS4: init.check: +// CHECK-TLS4-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG291]] // CHECK-TLS4-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG292:![0-9]+]] // CHECK-TLS4-NEXT: [[TMP1:%.*]] = call i32 @__cxa_thread_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR5]], !dbg [[DBG291]] -// CHECK-TLS4-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG291]] // CHECK-TLS4-NEXT: br label [[INIT_END]], !dbg [[DBG291]] // CHECK-TLS4: init.end: // CHECK-TLS4-NEXT: ret void, !dbg [[DBG294:![0-9]+]] @@ -5810,9 +5810,9 @@ // SIMD3-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0 // SIMD3-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]] // SIMD3: init.check: +// SIMD3-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // SIMD3-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23) // SIMD3-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]] -// SIMD3-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8 // SIMD3-NEXT: br label [[INIT_END]] // SIMD3: init.end: // SIMD3-NEXT: ret void @@ -6280,9 +6280,9 @@ // SIMD4-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG234]] // SIMD4-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG234]] // SIMD4: init.check: +// SIMD4-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG234]] // SIMD4-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG235:![0-9]+]] // SIMD4-NEXT: [[TMP1:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR3]], !dbg [[DBG234]] -// SIMD4-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG234]] // SIMD4-NEXT: br label [[INIT_END]], !dbg [[DBG234]] // SIMD4: init.end: // SIMD4-NEXT: ret void, !dbg [[DBG237:![0-9]+]] @@ -7076,11 +7076,11 @@ // DEBUG1-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG334]] // DEBUG1-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG334]] // DEBUG1: init.check: +// DEBUG1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG334]] // DEBUG1-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB41:[0-9]+]]), !dbg [[DBG334]] // DEBUG1-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB41]], ptr @_ZN2STI2S4E2stE, ptr @.__kmpc_global_ctor_..9, ptr null, ptr @.__kmpc_global_dtor_..10), !dbg [[DBG334]] // DEBUG1-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG335:![0-9]+]] // DEBUG1-NEXT: [[TMP2:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG334]] -// DEBUG1-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG334]] // DEBUG1-NEXT: br label [[INIT_END]], !dbg [[DBG334]] // DEBUG1: init.end: // DEBUG1-NEXT: ret void, !dbg [[DBG337:![0-9]+]] @@ -7719,11 +7719,11 @@ // DEBUG2-NEXT: [[GUARD_UNINITIALIZED:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBG285]] // DEBUG2-NEXT: br i1 [[GUARD_UNINITIALIZED]], label [[INIT_CHECK:%.*]], label [[INIT_END:%.*]], !dbg [[DBG285]] // DEBUG2: init.check: +// DEBUG2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG285]] // DEBUG2-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(ptr @[[GLOB41:[0-9]+]]), !dbg [[DBG285]] // DEBUG2-NEXT: call void @__kmpc_threadprivate_register(ptr @[[GLOB41]], ptr @_ZN2STI2S4E2stE, ptr @.__kmpc_global_ctor_..8, ptr null, ptr @.__kmpc_global_dtor_..9), !dbg [[DBG285]] // DEBUG2-NEXT: call void @_ZN2S4C1Ei(ptr noundef nonnull align 4 dereferenceable(8) @_ZN2STI2S4E2stE, i32 noundef 23), !dbg [[DBG286:![0-9]+]] // DEBUG2-NEXT: [[TMP2:%.*]] = call i32 @__cxa_atexit(ptr @_ZN2S4D1Ev, ptr @_ZN2STI2S4E2stE, ptr @__dso_handle) #[[ATTR4]], !dbg [[DBG285]] -// DEBUG2-NEXT: store i8 1, ptr @_ZGVN2STI2S4E2stE, align 8, !dbg [[DBG285]] // DEBUG2-NEXT: br label [[INIT_END]], !dbg [[DBG285]] // DEBUG2: init.end: // DEBUG2-NEXT: ret void, !dbg [[DBG288:![0-9]+]]