diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -557,6 +557,9 @@ GlobalAddressSDNode *N = cast(Op); assert(N->getOffset() == 0 && "unexpected offset in global node"); + if (DAG.getTarget().useEmulatedTLS()) + return LowerToTLSEmulatedModel(N, DAG); + SDValue Addr; switch (getTargetMachine().getTLSModel(N->getGlobal())) { case TLSModel::GeneralDynamic: diff --git a/llvm/test/CodeGen/LoongArch/emutls_generic.ll b/llvm/test/CodeGen/LoongArch/emutls_generic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/emutls_generic.ll @@ -0,0 +1,43 @@ +; RUN: llc < %s --emulated-tls --mtriple=loongarch64 --relocation-model=pic \ +; RUN: | FileCheck %s + +; RUN: llc < %s --mtriple=loongarch64 --relocation-model=pic \ +; RUN: | FileCheck --check-prefix=NoEMU %s + +;; NoEMU-NOT: __emutls + +;; Make sure that TLS symbols are emitted in expected order. + +@external_x = external thread_local global i32, align 8 +@external_y = thread_local global i8 7, align 2 +@internal_y = internal thread_local global i64 9, align 16 + +define ptr @get_external_x() { +; CHECK-LABEL: get_external_x: +; CHECK-NOT: _tls_get_address +; CHECK: __emutls_get_address +entry: + ret ptr @external_x +} + +define ptr @get_external_y() { +; CHECK-LABEL: get_external_y: +; CHECK: __emutls_get_address +; CHECK-NOT: _tls_get_address +entry: + ret ptr @external_y +} + +define ptr @get_internal_y() { +; CHECK-LABEL: get_internal_y: +; CHECK-NOT: __emutls_t.external_x: +; CHECK-NOT: __emutls_v.external_x: +; CHECK-LABEL: __emutls_v.external_y: +; CHECK-LABEL: __emutls_t.external_y: +; CHECK: __emutls_t.external_y +; CHECK-LABEL: __emutls_v.internal_y: +; CHECK-LABEL: __emutls_t.internal_y: +; CHECK: __emutls_t.internal_y +entry: + ret ptr @internal_y +}