mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 06:26:06 +00:00

Performing a load before calling __cxa_guard_acquire is supposed to be an optimization, but it isn't much of one if we're just going to emit a call to __atomic_load_1 instead. Instead, just skip the load, and let __cxa_guard_acquire do whatever it wants. (In practice, on such targets, the C++ library is just built with threading turned off, so the result isn't actually threadsafe, but there's not really anything clang can do about that.) The alternative here is that we try to define some ABI for threadsafe init that allows the speculative load without full atomics. Almost any target without full atomics has a load that's s "atomic enough" for this purpose. But it's not clear how we emit an "atomic enough" load in LLVM IR, and there isn't any ABI document we can refer to. Or I guess we could turn off -fthreadsafe-statics by default on Cortex-M0, but that seems like it would be surprising. Fixes https://github.com/llvm/llvm-project/issues/58184 Differential Revision: https://reviews.llvm.org/D135628
22 lines
800 B
C++
22 lines
800 B
C++
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
|
|
// RUN: %clang_cc1 -emit-llvm -triple=thumbv6m-eabi -o - %s | FileCheck %s
|
|
|
|
int f();
|
|
|
|
// CHECK-LABEL: @_Z1gv(
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: [[TMP0:%.*]] = call i32 @__cxa_guard_acquire(ptr @_ZGVZ1gvE1a) #[[ATTR1:[0-9]+]]
|
|
// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
|
// CHECK-NEXT: br i1 [[TOBOOL]], label [[INIT:%.*]], label [[INIT_END:%.*]]
|
|
// CHECK: init:
|
|
// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_Z1fv()
|
|
// CHECK-NEXT: store i32 [[CALL]], ptr @_ZZ1gvE1a, align 4
|
|
// CHECK-NEXT: call void @__cxa_guard_release(ptr @_ZGVZ1gvE1a) #[[ATTR1]]
|
|
// CHECK-NEXT: br label [[INIT_END]]
|
|
// CHECK: init.end:
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void g() {
|
|
static int a = f();
|
|
}
|