https://github.com/xerpi updated https://github.com/llvm/llvm-project/pull/130932
From 0836ddbda0f00117ebbd82b13f3a1ba12cbdbfa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergi=20=28=E3=82=BB=E3=83=AB=E3=82=B8=29?= <sergi-granell-escal...@arkedgespace.com> Date: Wed, 12 Mar 2025 16:20:07 +0900 Subject: [PATCH] [AArch64] Add an option to get the TLS pointer from software This patch adds an option to get the TLS pointer via a call to __aarch64_read_tp() (similar to __aeabi_read_tp on ARM). This mode is enabled when -mtp=soft is passed to clang. Necessary on Nintendo Horizon OS, which puts the TLS pointer at a calculated offset from TPIDR_EL0. Co-authored-by: Mary Guillemard <m...@mary.zone> Signed-off-by: Sergi Granell Escalfet <xerpi.g...@gmail.com> --- clang/include/clang/Driver/Options.td | 2 +- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 56 ++++++++++++++----- clang/lib/Driver/ToolChains/Arch/AArch64.h | 15 ++++- clang/test/Driver/aarch64-thread-pointer.c | 15 +++++ .../AArch64/AArch64ExpandPseudoInsts.cpp | 11 ++++ llvm/lib/Target/AArch64/AArch64Features.td | 4 ++ llvm/lib/Target/AArch64/AArch64InstrInfo.td | 15 ++++- .../CodeGen/AArch64/arm64-builtins-linux.ll | 3 + .../CodeGen/AArch64/arm64-tls-dynamics.ll | 39 +++++++++++++ 9 files changed, 144 insertions(+), 16 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index e69cd6b833c3a..01ffaa9d8f8f4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4732,7 +4732,7 @@ let Flags = [TargetSpecific] in { def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft,cp15,tpidrurw,tpidruro,tpidrprw,el0,el1,el2,el3,tpidr_el0,tpidr_el1,tpidr_el2,tpidr_el3,tpidrro_el0,auto">, HelpText<"Thread pointer access method. " "For AArch32: 'soft' uses a function call, or 'tpidrurw', 'tpidruro' or 'tpidrprw' use the three CP15 registers. 'cp15' is an alias for 'tpidruro'. " - "For AArch64: 'tpidr_el0', 'tpidr_el1', 'tpidr_el2', 'tpidr_el3' or 'tpidrro_el0' use the five system registers. 'elN' is an alias for 'tpidr_elN'.">; + "For AArch64: 'soft' uses a function call, 'tpidr_el0', 'tpidr_el1', 'tpidr_el2', 'tpidr_el3' or 'tpidrro_el0' use the five system registers. 'elN' is an alias for 'tpidr_elN'.">; def mpure_code : Flag<["-"], "mpure-code">, Alias<mexecute_only>; // Alias for GCC compatibility def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias<mno_execute_only>; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>; diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index 6e70effe9e325..4bab0c6f1d37f 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -192,6 +192,35 @@ getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features); } +// Select mode for reading thread pointer (-mtp=). +aarch64::ReadTPMode aarch64::getReadTPMode(const Driver &D, const ArgList &Args, + const llvm::Triple &Triple, + bool ForAS) { + Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ); + if (A) { + aarch64::ReadTPMode ThreadPointer = + llvm::StringSwitch<aarch64::ReadTPMode>(A->getValue()) + .Case("soft", aarch64::ReadTPMode::Soft) + .Case("tpidr_el0", aarch64::ReadTPMode::TPIDR_EL0) + .Case("tpidr_el1", aarch64::ReadTPMode::TPIDR_EL1) + .Case("tpidr_el2", aarch64::ReadTPMode::TPIDR_EL2) + .Case("tpidr_el3", aarch64::ReadTPMode::TPIDR_EL3) + .Case("tpidrro_el0", aarch64::ReadTPMode::TPIDRRO_EL0) + .Case("el0", aarch64::ReadTPMode::TPIDR_EL0) + .Case("el1", aarch64::ReadTPMode::TPIDR_EL1) + .Case("el2", aarch64::ReadTPMode::TPIDR_EL2) + .Case("el3", aarch64::ReadTPMode::TPIDR_EL3) + .Default(ReadTPMode::Invalid); + if (ThreadPointer != ReadTPMode::Invalid) + return ThreadPointer; + if (StringRef(A->getValue()).empty()) + D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args); + else + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); + } + return ReadTPMode::Invalid; +} + void aarch64::getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, @@ -262,19 +291,20 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, // set to a feature list. Extensions.toLLVMFeatureList(Features); - if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) { - StringRef Mtp = A->getValue(); - if (Mtp == "el3" || Mtp == "tpidr_el3") - Features.push_back("+tpidr-el3"); - else if (Mtp == "el2" || Mtp == "tpidr_el2") - Features.push_back("+tpidr-el2"); - else if (Mtp == "el1" || Mtp == "tpidr_el1") - Features.push_back("+tpidr-el1"); - else if (Mtp == "tpidrro_el0") - Features.push_back("+tpidrro-el0"); - else if (Mtp != "el0" && Mtp != "tpidr_el0") - D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); - } + aarch64::ReadTPMode TPMode = getReadTPMode(D, Args, Triple, ForAS); + + if (TPMode == Soft) + Features.push_back("+read-tp-soft"); + else if (TPMode == TPIDR_EL1) + Features.push_back("+tpidr-el1"); + else if (TPMode == TPIDR_EL2) + Features.push_back("+tpidr-el2"); + else if (TPMode == TPIDR_EL3) + Features.push_back("+tpidr-el3"); + else if (TPMode == TPIDRRO_EL0) + Features.push_back("+tpidrro-el0"); + else if (TPMode != TPIDR_EL0 && TPMode != Soft) + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); // Enable/disable straight line speculation hardening. if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) { diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.h b/clang/lib/Driver/ToolChains/Arch/AArch64.h index 2057272867a17..d4eaa0c6a64e4 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.h +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.h @@ -20,6 +20,16 @@ namespace driver { namespace tools { namespace aarch64 { +enum class ReadTPMode { + Invalid, + Soft, + TPIDR_EL0, + TPIDR_EL1, + TPIDR_EL2, + TPIDR_EL3, + TPIDRRO_EL0, +}; + void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector<llvm::StringRef> &Features, @@ -28,11 +38,14 @@ void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, llvm::opt::Arg *&A); +ReadTPMode getReadTPMode(const Driver &D, const llvm::opt::ArgList &Args, + const llvm::Triple &Triple, bool ForAS); + void setPAuthABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, llvm::Triple &triple); } // end namespace aarch64 -} // end namespace target +} // end namespace tools } // end namespace driver } // end namespace clang diff --git a/clang/test/Driver/aarch64-thread-pointer.c b/clang/test/Driver/aarch64-thread-pointer.c index b1c6df4ac5e5d..6186a53bf3954 100644 --- a/clang/test/Driver/aarch64-thread-pointer.c +++ b/clang/test/Driver/aarch64-thread-pointer.c @@ -7,10 +7,13 @@ // RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL0 %s // RUN: %clang --target=aarch64-linux -### -S %s -mtp=tpidr_el0 2>&1 | \ // RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL0 %s +// RUN: %clang --target=aarch64-linux -### -S %s -mtp=soft 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL0 %s // ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidrro-el0" // ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el1" // ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el2" // ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el3" +// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+read-tp-soft" // RUN: %clang --target=aarch64-linux -### -S %s -mtp=tpidrro_el0 2>&1 | \ // RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_ROEL0 %s @@ -18,6 +21,7 @@ // ARMv8_THREAD_POINTER_ROEL0-NOT: "-target-feature" "+tpidr-el1" // ARMv8_THREAD_POINTER_ROEL0-NOT: "-target-feature" "+tpidr-el2" // ARMv8_THREAD_POINTER_ROEL0-NOT: "-target-feature" "+tpidr-el3" +// ARMv8_THREAD_POINTER_ROEL0-NOT: "-target-feature" "+read-tp-soft" // RUN: %clang --target=aarch64-linux -### -S %s -mtp=el1 2>&1 | \ // RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL1 %s @@ -27,6 +31,7 @@ // ARMv8_THREAD_POINTER_EL1: "-target-feature" "+tpidr-el1" // ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+tpidr-el2" // ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+tpidr-el3" +// ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+read-tp-soft" // RUN: %clang --target=aarch64-linux -### -S %s -mtp=el2 2>&1 | \ // RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL2 %s @@ -36,6 +41,7 @@ // ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+tpidr-el1" // ARMv8_THREAD_POINTER_EL2: "-target-feature" "+tpidr-el2" // ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+tpidr-el3" +// ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+read-tp-soft" // RUN: %clang --target=aarch64-linux -### -S %s -mtp=el3 2>&1 | \ // RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL3 %s @@ -45,3 +51,12 @@ // ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+tpidr-el1" // ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+tpidr-el2" // ARMv8_THREAD_POINTER_EL3: "-target-feature" "+tpidr-el3" +// ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+read-tp-soft" + +// RUN: %clang --target=aarch64-linux -### -S %s -mtp=soft 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_SOFT %s +// ARMv8_THREAD_POINTER_SOFT-NOT: "-target-feature" "+tpidrro-el0" +// ARMv8_THREAD_POINTER_SOFT-NOT: "-target-feature" "+tpidr-el1" +// ARMv8_THREAD_POINTER_SOFT-NOT: "-target-feature" "+tpidr-el2" +// ARMv8_THREAD_POINTER_SOFT-NOT: "-target-feature" "+tpidr-el3" +// ARMv8_THREAD_POINTER_SOFT: "-target-feature" "+read-tp-soft" diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp index 55a441b7d22b6..09ced5298cf61 100644 --- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp +++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp @@ -1487,6 +1487,17 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB, return true; } + case AArch64::GETbaseTLSsoft: { + Register DstReg = MI.getOperand(0).getReg(); + MachineInstrBuilder MIB = + BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::BL)) + .addExternalSymbol("__aarch64_read_tp") + .cloneMemRefs(MI); + transferImpOps(MI, MIB, MIB); + MI.eraseFromParent(); + return true; + } + case AArch64::MOVi32imm: return expandMOVImm(MBB, MBBI, 32); case AArch64::MOVi64imm: diff --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td index 357f526d5e308..42069e6dc5c17 100644 --- a/llvm/lib/Target/AArch64/AArch64Features.td +++ b/llvm/lib/Target/AArch64/AArch64Features.td @@ -818,6 +818,10 @@ def FeatureUseFixedOverScalableIfEqualCost : SubtargetFeature<"use-fixed-over-sc def FeatureAvoidLDAPUR : SubtargetFeature<"avoid-ldapur", "AvoidLDAPUR", "true", "Prefer add+ldapr to offset ldapur">; +// Read the TLS by calling __aarch64_read_tp +def FeatureReadTpSoft : SubtargetFeature<"read-tp-soft", "ReadTpSoft", + "true", "Read thread pointer from __aarch64_read_tp" >; + //===----------------------------------------------------------------------===// // Architectures. // diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 6c61e3a613f6f..7a6ee0ab2bad8 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -395,6 +395,8 @@ def AArch64LocalRecover : SDNode<"ISD::LOCAL_RECOVER", def AllowMisalignedMemAccesses : Predicate<"!Subtarget->requiresStrictAlign()">; +def IsReadTPHard : Predicate<"!Subtarget->readTpSoft()">; +def IsReadTPSoft : Predicate<"Subtarget->readTpSoft()">; //===----------------------------------------------------------------------===// // AArch64-specific DAG Nodes. @@ -2121,7 +2123,18 @@ def : Pat<(AArch64mrs imm:$id), // The thread pointer (on Linux, at least, where this has been implemented) is // TPIDR_EL0. def MOVbaseTLS : Pseudo<(outs GPR64:$dst), (ins), - [(set GPR64:$dst, AArch64threadpointer)]>, Sched<[WriteSys]>; + [(set GPR64:$dst, AArch64threadpointer)]>, Sched<[WriteSys]>, + Requires<[IsReadTPHard]>; + +// __aarch64_read_tp preserves the registers x1-x7. +// This is a pseudo inst so that we can get the encoding right, +// complete with fixup for the aarch64_read_tp function. +let isCall = 1, + Defs = [X0, X16, X17, LR], Uses = [SP] in { + def GETbaseTLSsoft : Pseudo<(outs), (ins), + [(set X0, AArch64threadpointer)]>, Sched<[WriteBr]>, + Requires<[IsReadTPSoft]>; +} // This gets lowered into a 24-byte instruction sequence let Defs = [ X9, X16, X17, NZCV ], Size = 24 in { diff --git a/llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll b/llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll index 679e4ac0bd27c..b796f59a54171 100644 --- a/llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll +++ b/llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll @@ -4,6 +4,7 @@ ; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+tpidr-el1 | FileCheck --check-prefix=USEEL1 %s ; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+tpidr-el2 | FileCheck --check-prefix=USEEL2 %s ; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+tpidr-el3 | FileCheck --check-prefix=USEEL3 %s +; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+read-tp-soft | FileCheck --check-prefix=SOFT %s ; Function Attrs: nounwind readnone declare ptr @llvm.thread.pointer() #1 @@ -19,6 +20,8 @@ define ptr @thread_pointer() { ; USEEL2: mrs {{x[0-9]+}}, TPIDR_EL2 ; USEEL3: thread_pointer: ; USEEL3: mrs {{x[0-9]+}}, TPIDR_EL3 +; SOFT: thread_pointer: +; SOFT: bl __aarch64_read_tp %1 = tail call ptr @llvm.thread.pointer() ret ptr %1 } diff --git a/llvm/test/CodeGen/AArch64/arm64-tls-dynamics.ll b/llvm/test/CodeGen/AArch64/arm64-tls-dynamics.ll index c12730bd3b0d7..ccca5d7ff01a1 100644 --- a/llvm/test/CodeGen/AArch64/arm64-tls-dynamics.ll +++ b/llvm/test/CodeGen/AArch64/arm64-tls-dynamics.ll @@ -3,6 +3,7 @@ ; RUN: llc < %s -debug-entry-values -mtriple=arm64-none-linux-gnu -stop-after=machineverifier -relocation-model=pic -aarch64-elf-ldtls-generation=1 < %s ; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -verify-machineinstrs -mattr=+read-tp-soft < %s | FileCheck --check-prefix=CHECK-TP-SOFT %s ; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -aarch64-elf-ldtls-generation=1 -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s ; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK-NOLD %s ; RUN: llc -mtriple=arm64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-NOLD-RELOC %s @@ -27,6 +28,12 @@ define i32 @test_generaldynamic() { ; CHECK-NEXT: .tlsdesccall general_dynamic_var ; CHECK-NEXT: blr [[CALLEE]] +; CHECK-TP-SOFT: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var +; CHECK-TP-SOFT-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var] +; CHECK-TP-SOFT-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var +; CHECK-TP-SOFT-NEXT: .tlsdesccall general_dynamic_var +; CHECK-TP-SOFT-NEXT: blr [[CALLEE]] + ; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var ; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var] ; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var @@ -36,6 +43,9 @@ define i32 @test_generaldynamic() { ; CHECK: mrs x[[TP:[0-9]+]], TPIDR_EL0 ; CHECK: ldr w0, [x[[TP]], x0] +; CHECK-TP-SOFT: mov x[[TMP:[0-9]+]], x0 +; CHECK-TP-SOFT: bl __aarch64_read_tp +; CHECK-TP-SOFT: ldr w0, [x0, x[[TMP]]] ; CHECK-NOLD: mrs x[[TP:[0-9]+]], TPIDR_EL0 ; CHECK-NOLD: ldr w0, [x[[TP]], x0] @@ -62,8 +72,17 @@ define ptr @test_generaldynamic_addr() { ; CHECK-NEXT: .tlsdesccall general_dynamic_var ; CHECK-NEXT: blr [[CALLEE]] +; CHECK-TP-SOFT: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var +; CHECK-TP-SOFT-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var] +; CHECK-TP-SOFT-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:general_dynamic_var +; CHECK-TP-SOFT-NEXT: .tlsdesccall general_dynamic_var +; CHECK-TP-SOFT-NEXT: blr [[CALLEE]] + ; CHECK: mrs [[TP:x[0-9]+]], TPIDR_EL0 ; CHECK: add x0, [[TP]], x0 +; CHECK-TP-SOFT: mov x[[TMP:[0-9]+]], x0 +; CHECK-TP-SOFT: bl __aarch64_read_tp +; CHECK-TP-SOFT: add x0, x0, x[[TMP]] ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE21 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12 @@ -95,6 +114,16 @@ define i32 @test_localdynamic() { ; CHECK-DAG: add x[[TPOFF]], x[[TPOFF]], :dtprel_lo12_nc:local_dynamic_var ; CHECK: ldr w0, [x[[TPIDR]], x[[TPOFF]]] +; CHECK-TP-SOFT: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ +; CHECK-TP-SOFT-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_] +; CHECK-TP-SOFT-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_ +; CHECK-TP-SOFT-NEXT: .tlsdesccall _TLS_MODULE_BASE_ +; CHECK-TP-SOFT-NEXT: blr [[CALLEE]] +; CHECK-TP-SOFT-NEXT: add x[[TPOFF:[0-9]+]], x0, :dtprel_hi12:local_dynamic_var +; CHECK-TP-SOFT-DAG: bl __aarch64_read_tp +; CHECK-TP-SOFT-DAG: add x[[TPOFF]], x[[TPOFF]], :dtprel_lo12_nc:local_dynamic_var +; CHECK-TP-SOFT: ldr w0, [x0, x[[TPOFF]]] + ; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:local_dynamic_var ; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var] ; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var @@ -131,6 +160,16 @@ define ptr @test_localdynamic_addr() { ; CHECK-DAG: mrs x[[TPIDR:[0-9]+]], TPIDR_EL0 ; CHECK: add x0, x[[TPIDR]], x[[TPOFF]] +; CHECK-TP-SOFT: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_ +; CHECK-TP-SOFT-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_] +; CHECK-TP-SOFT-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:_TLS_MODULE_BASE_ +; CHECK-TP-SOFT-NEXT: .tlsdesccall _TLS_MODULE_BASE_ +; CHECK-TP-SOFT-NEXT: blr [[CALLEE]] +; CHECK-TP-SOFT-NEXT: add x[[TPOFF:[0-9]+]], x0, :dtprel_hi12:local_dynamic_var +; CHECK-TP-SOFT-DAG: add x[[TPOFF]], x[[TPOFF]], :dtprel_lo12_nc:local_dynamic_var +; CHECK-TP-SOFT-DAG: bl __aarch64_read_tp +; CHECK-TP-SOFT: add x0, x0, x[[TPOFF]] + ; CHECK-NOLD: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:local_dynamic_var ; CHECK-NOLD-NEXT: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var] ; CHECK-NOLD-NEXT: add x0, x[[TLSDESC_HI]], :tlsdesc_lo12:local_dynamic_var _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits