[llvm] eb148ae - [LoongArch][Codegen] Add support for TLSDESC
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 30 00:14:49 PDT 2024
Author: wanglei
Date: 2024-04-30T15:14:44+08:00
New Revision: eb148aecb3603c2ba6ecbdaebd3b8a87f44349bc
URL: https://github.com/llvm/llvm-project/commit/eb148aecb3603c2ba6ecbdaebd3b8a87f44349bc
DIFF: https://github.com/llvm/llvm-project/commit/eb148aecb3603c2ba6ecbdaebd3b8a87f44349bc.diff
LOG: [LoongArch][Codegen] Add support for TLSDESC
The implementation only enables when the `-enable-tlsdesc` option is
passed and the TLS model is `dynamic`.
LoongArch's GCC has the same option(-mtls-dialet=) as RISC-V.
Reviewers: heiher, MaskRay, SixWeining
Reviewed By: SixWeining, MaskRay
Pull Request: https://github.com/llvm/llvm-project/pull/90159
Added:
clang/test/CodeGen/LoongArch/tls-dialect.c
Modified:
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/test/Driver/tls-dialect.c
llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
llvm/lib/Target/LoongArch/LoongArchISelLowering.h
llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
llvm/test/CodeGen/LoongArch/tls-models.ll
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index fec11c7e716fdf..6796b43a155020 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -737,7 +737,7 @@ bool tools::isTLSDESCEnabled(const ToolChain &TC,
StringRef V = A->getValue();
bool SupportedArgument = false, EnableTLSDESC = false;
bool Unsupported = !Triple.isOSBinFormatELF();
- if (Triple.isRISCV()) {
+ if (Triple.isLoongArch() || Triple.isRISCV()) {
SupportedArgument = V == "desc" || V == "trad";
EnableTLSDESC = V == "desc";
} else if (Triple.isX86()) {
diff --git a/clang/test/CodeGen/LoongArch/tls-dialect.c b/clang/test/CodeGen/LoongArch/tls-dialect.c
new file mode 100644
index 00000000000000..03401ef8af03d4
--- /dev/null
+++ b/clang/test/CodeGen/LoongArch/tls-dialect.c
@@ -0,0 +1,14 @@
+// REQUIRES: loongarch-registered-target
+/// cc1 -enable-tlsdesc (due to -mtls-dialect=desc) enables TLSDESC.
+// RUN: %clang_cc1 -triple loongarch64 -S -mrelocation-model pic -pic-level 1 -enable-tlsdesc %s -o - | FileCheck %s --check-prefix=DESC
+// RUN: %clang_cc1 -triple loongarch64 -S -mrelocation-model pic -pic-level 1 %s -o - | FileCheck %s --check-prefix=NODESC
+
+__thread int x;
+
+// DESC: %desc_pc_hi20
+// DESC-NOT: %gd_pc_hi20
+// NODESC: %gd_pc_hi20
+// NODESC-NOT: %desc_pc_hi20
+int use() {
+ return x;
+}
diff --git a/clang/test/Driver/tls-dialect.c b/clang/test/Driver/tls-dialect.c
index a808dd81531ce7..3471b55b0ebae9 100644
--- a/clang/test/Driver/tls-dialect.c
+++ b/clang/test/Driver/tls-dialect.c
@@ -1,3 +1,5 @@
+// RUN: %clang -### --target=loongarch64-linux -mtls-dialect=trad %s 2>&1 | FileCheck --check-prefix=NODESC %s
+// RUN: %clang -### --target=loongarch64-linux %s 2>&1 | FileCheck --check-prefix=NODESC %s
// RUN: %clang -### --target=riscv64-freebsd -mtls-dialect=desc %s 2>&1 | FileCheck --check-prefix=DESC %s
// RUN: %clang -### --target=riscv64-linux -mtls-dialect=trad %s 2>&1 | FileCheck --check-prefix=NODESC %s
// RUN: %clang -### --target=riscv64-linux %s 2>&1 | FileCheck --check-prefix=NODESC %s
@@ -9,6 +11,8 @@
// RUN: %clang -### --target=riscv64-android %s 2>&1 | FileCheck --check-prefix=DESC %s
/// LTO
+// RUN: %clang -### --target=loongarch64-linux -flto -mtls-dialect=desc %s 2>&1 | FileCheck --check-prefix=LTO-DESC %s
+// RUN: %clang -### --target=loongarch64-linux -flto %s 2>&1 | FileCheck --check-prefix=LTO-NODESC %s
// RUN: %clang -### --target=riscv64-linux -flto -mtls-dialect=desc %s 2>&1 | FileCheck --check-prefix=LTO-DESC %s
// RUN: %clang -### --target=riscv64-linux -flto %s 2>&1 | FileCheck --check-prefix=LTO-NODESC %s
@@ -18,6 +22,7 @@
// RUN: not %clang --target=x86_64-apple-macos -mtls-dialect=desc -flto %s 2>&1 | FileCheck -check-prefix=UNSUPPORTED-TARGET %s
/// Unsupported argument
+// RUN: not %clang -### --target=loongarch64-linux -mtls-dialect=gnu2 %s 2>&1 | FileCheck --check-prefix=UNSUPPORTED-ARG %s
// RUN: not %clang -### --target=riscv64-linux -mtls-dialect=gnu2 %s 2>&1 | FileCheck --check-prefix=UNSUPPORTED-ARG %s
// DESC: "-cc1" {{.*}}"-enable-tlsdesc"
diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
index ad39658f698e7b..c136f5b3e515d7 100644
--- a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
@@ -80,6 +80,9 @@ class LoongArchPreRAExpandPseudo : public MachineFunctionPass {
bool expandLoadAddressTLSGD(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI);
+ bool expandLoadAddressTLSDesc(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI);
};
char LoongArchPreRAExpandPseudo::ID = 0;
@@ -122,6 +125,8 @@ bool LoongArchPreRAExpandPseudo::expandMI(
return expandLoadAddressTLSLD(MBB, MBBI, NextMBBI);
case LoongArch::PseudoLA_TLS_GD:
return expandLoadAddressTLSGD(MBB, MBBI, NextMBBI);
+ case LoongArch::PseudoLA_TLS_DESC_PC:
+ return expandLoadAddressTLSDesc(MBB, MBBI, NextMBBI);
}
return false;
}
@@ -267,6 +272,52 @@ bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD(
SecondOpcode, LoongArchII::MO_GOT_PC_LO);
}
+bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSDesc(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI) {
+ // Code Sequence:
+ // pcalau12i $a0, %desc_pc_hi20(sym)
+ // addi.w/d $a0, $a0, %desc_pc_lo12(sym)
+ // ld.w/d $ra, $a0, %desc_ld(sym)
+ // jirl $ra, $ra, %desc_ld(sym)
+ // add.d $dst, $a0, $tp
+ MachineFunction *MF = MBB.getParent();
+ MachineInstr &MI = *MBBI;
+ DebugLoc DL = MI.getDebugLoc();
+
+ const auto &STI = MF->getSubtarget<LoongArchSubtarget>();
+ unsigned ADD = STI.is64Bit() ? LoongArch::ADD_D : LoongArch::ADD_W;
+ unsigned ADDI = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W;
+ unsigned LD = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W;
+
+ Register DestReg = MI.getOperand(0).getReg();
+ Register ScratchReg =
+ MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass);
+ MachineOperand &Symbol = MI.getOperand(1);
+
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), ScratchReg)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC_PC_HI);
+
+ BuildMI(MBB, MBBI, DL, TII->get(ADDI), LoongArch::R4)
+ .addReg(ScratchReg)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC_PC_LO);
+
+ BuildMI(MBB, MBBI, DL, TII->get(LD), LoongArch::R1)
+ .addReg(LoongArch::R4)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC_LD);
+
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PseudoDESC_CALL), LoongArch::R1)
+ .addReg(LoongArch::R1)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC_CALL);
+
+ BuildMI(MBB, MBBI, DL, TII->get(ADD), DestReg)
+ .addReg(LoongArch::R4)
+ .addReg(LoongArch::R2);
+
+ MI.eraseFromParent();
+ return true;
+}
+
class LoongArchExpandPseudo : public MachineFunctionPass {
public:
const LoongArchInstrInfo *TII;
@@ -313,6 +364,9 @@ class LoongArchExpandPseudo : public MachineFunctionPass {
bool expandLoadAddressTLSGDLarge(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI);
+ bool expandLoadAddressTLSDescPcLarge(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI);
bool expandFunctionCALL(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI,
@@ -361,6 +415,8 @@ bool LoongArchExpandPseudo::expandMI(MachineBasicBlock &MBB,
return expandLoadAddressTLSLDLarge(MBB, MBBI, NextMBBI);
case LoongArch::PseudoLA_TLS_GD_LARGE:
return expandLoadAddressTLSGDLarge(MBB, MBBI, NextMBBI);
+ case LoongArch::PseudoLA_TLS_DESC_PC_LARGE:
+ return expandLoadAddressTLSDescPcLarge(MBB, MBBI, NextMBBI);
case LoongArch::PseudoCALL:
case LoongArch::PseudoCALL_MEDIUM:
case LoongArch::PseudoCALL_LARGE:
@@ -560,6 +616,58 @@ bool LoongArchExpandPseudo::expandLoadAddressTLSGDLarge(
LoongArchII::MO_GD_PC_HI);
}
+bool LoongArchExpandPseudo::expandLoadAddressTLSDescPcLarge(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI) {
+ // Code Sequence:
+ //
+ // pcalau12i $a0, %desc_pc_hi20(sym)
+ // addi.d $t8, $zero, %desc_pc_lo12(sym)
+ // lu32i.d $t8, %desc64_pc_lo20(sym)
+ // lu52i.d $t8, $t8, %desc64_pc_hi12(sym)
+ // add.d $a0, $a0, $t8
+ // ld.d $ra, $a0, %desc_ld(sym)
+ // jirl $ra, $ra, %desc_call(sym)
+ // add.d $dst, $a0, $tp
+
+ MachineInstr &MI = *MBBI;
+ DebugLoc DL = MI.getDebugLoc();
+ Register DestReg = MI.getOperand(0).getReg();
+ MachineOperand &Symbol = MI.getOperand(2);
+ Register ScratchReg = LoongArch::R20; // $t8
+
+ assert(MBB.getParent()->getSubtarget<LoongArchSubtarget>().is64Bit() &&
+ "Large code model requires LA64");
+
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), LoongArch::R4)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC_PC_HI);
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ADDI_D), ScratchReg)
+ .addReg(LoongArch::R0)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC_PC_LO);
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU32I_D), ScratchReg)
+ .addReg(ScratchReg)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC64_PC_LO);
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU52I_D), ScratchReg)
+ .addReg(ScratchReg)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC64_PC_HI);
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ADD_D), LoongArch::R4)
+ .addReg(ScratchReg)
+ .addReg(LoongArch::R4);
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LD_D), LoongArch::R1)
+ .addReg(LoongArch::R4)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC_LD);
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PseudoDESC_CALL), LoongArch::R1)
+ .addReg(LoongArch::R1)
+ .addDisp(Symbol, 0, LoongArchII::MO_DESC_CALL);
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ADD_D), DestReg)
+ .addReg(LoongArch::R4)
+ .addReg(LoongArch::R2);
+
+ MI.eraseFromParent();
+
+ return true;
+}
+
bool LoongArchExpandPseudo::expandFunctionCALL(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI, bool IsTailCall) {
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 285d5c2a63b2da..e5c80644d4a83e 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -903,6 +903,24 @@ SDValue LoongArchTargetLowering::getDynamicTLSAddr(GlobalAddressSDNode *N,
return LowerCallTo(CLI).first;
}
+SDValue LoongArchTargetLowering::getTLSDescAddr(GlobalAddressSDNode *N,
+ SelectionDAG &DAG, unsigned Opc,
+ bool Large) const {
+ SDLoc DL(N);
+ EVT Ty = getPointerTy(DAG.getDataLayout());
+ const GlobalValue *GV = N->getGlobal();
+
+ // This is not actually used, but is necessary for successfully matching the
+ // PseudoLA_*_LARGE nodes.
+ SDValue Tmp = DAG.getConstant(0, DL, Ty);
+
+ // Use a PC-relative addressing mode to access the global dynamic GOT address.
+ // This generates the pattern (PseudoLA_TLS_DESC_PC{,LARGE} sym).
+ SDValue Addr = DAG.getTargetGlobalAddress(GV, DL, Ty, 0, 0);
+ return Large ? SDValue(DAG.getMachineNode(Opc, DL, Ty, Tmp, Addr), 0)
+ : SDValue(DAG.getMachineNode(Opc, DL, Ty, Addr), 0);
+}
+
SDValue
LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op,
SelectionDAG &DAG) const {
@@ -916,42 +934,46 @@ LoongArchTargetLowering::lowerGlobalTLSAddress(SDValue Op,
GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);
assert(N->getOffset() == 0 && "unexpected offset in global node");
- SDValue Addr;
+ bool IsDesc = DAG.getTarget().useTLSDESC();
+
switch (getTargetMachine().getTLSModel(N->getGlobal())) {
case TLSModel::GeneralDynamic:
// In this model, application code calls the dynamic linker function
// __tls_get_addr to locate TLS offsets into the dynamic thread vector at
// runtime.
- Addr = getDynamicTLSAddr(N, DAG,
- Large ? LoongArch::PseudoLA_TLS_GD_LARGE
- : LoongArch::PseudoLA_TLS_GD,
- Large);
+ if (!IsDesc)
+ return getDynamicTLSAddr(N, DAG,
+ Large ? LoongArch::PseudoLA_TLS_GD_LARGE
+ : LoongArch::PseudoLA_TLS_GD,
+ Large);
break;
case TLSModel::LocalDynamic:
// Same as GeneralDynamic, except for assembly modifiers and relocation
// records.
- Addr = getDynamicTLSAddr(N, DAG,
- Large ? LoongArch::PseudoLA_TLS_LD_LARGE
- : LoongArch::PseudoLA_TLS_LD,
- Large);
+ if (!IsDesc)
+ return getDynamicTLSAddr(N, DAG,
+ Large ? LoongArch::PseudoLA_TLS_LD_LARGE
+ : LoongArch::PseudoLA_TLS_LD,
+ Large);
break;
case TLSModel::InitialExec:
// This model uses the GOT to resolve TLS offsets.
- Addr = getStaticTLSAddr(N, DAG,
+ return getStaticTLSAddr(N, DAG,
Large ? LoongArch::PseudoLA_TLS_IE_LARGE
: LoongArch::PseudoLA_TLS_IE,
Large);
- break;
case TLSModel::LocalExec:
// This model is used when static linking as the TLS offsets are resolved
// during program linking.
//
// This node doesn't need an extra argument for the large code model.
- Addr = getStaticTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_LE);
- break;
+ return getStaticTLSAddr(N, DAG, LoongArch::PseudoLA_TLS_LE);
}
- return Addr;
+ return getTLSDescAddr(N, DAG,
+ Large ? LoongArch::PseudoLA_TLS_DESC_PC_LARGE
+ : LoongArch::PseudoLA_TLS_DESC_PC,
+ Large);
}
template <unsigned N>
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index 4bb6c049f8d758..31b4d651956342 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -263,6 +263,8 @@ class LoongArchTargetLowering : public TargetLowering {
unsigned Opc, bool Large = false) const;
SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
unsigned Opc, bool Large = false) const;
+ SDValue getTLSDescAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
+ unsigned Opc, bool Large = false) const;
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
index 6576100d3b3218..babb6632471bbf 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
@@ -530,6 +530,12 @@ LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
{MO_IE_PC_LO, "loongarch-ie-pc-lo"},
{MO_IE_PC64_LO, "loongarch-ie-pc64-lo"},
{MO_IE_PC64_HI, "loongarch-ie-pc64-hi"},
+ {MO_DESC_PC_HI, "loongarch-desc-pc-hi"},
+ {MO_DESC_PC_LO, "loongarch-desc-pc-lo"},
+ {MO_DESC64_PC_LO, "loongarch-desc64-pc-lo"},
+ {MO_DESC64_PC_HI, "loongarch-desc64-pc-hi"},
+ {MO_DESC_LD, "loongarch-desc-ld"},
+ {MO_DESC_CALL, "loongarch-desc-call"},
{MO_LD_PC_HI, "loongarch-ld-pc-hi"},
{MO_GD_PC_HI, "loongarch-gd-pc-hi"}};
return ArrayRef(TargetFlags);
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index 958803b52d4ec8..a7f6eb9a79ebc0 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -1607,6 +1607,13 @@ def PseudoLA_TLS_GD_LARGE : Pseudo<(outs GPR:$dst),
} // Defs = [R20], Size = 20
}
+// Used for expand PseudoLA_TLS_DESC_* instructions.
+let isCall = 1, isBarrier = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0,
+ Defs = [R4], Uses = [R4] in
+def PseudoDESC_CALL : Pseudo<(outs GPR:$rd), (ins GPR:$rj, simm16_lsl2:$imm16)>,
+ PseudoInstExpansion<(JIRL GPR:$rd, GPR:$rj,
+ simm16_lsl2:$imm16)>;
+
// TLSDESC
let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
isAsmParserOnly = 1, Defs = [R1] in {
diff --git a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
index 98ad49f25e3f2f..d1d428241ebcc2 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp
@@ -98,6 +98,24 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
case LoongArchII::MO_CALL36:
Kind = LoongArchMCExpr::VK_LoongArch_CALL36;
break;
+ case LoongArchII::MO_DESC_PC_HI:
+ Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_PC_HI20;
+ break;
+ case LoongArchII::MO_DESC_PC_LO:
+ Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_PC_LO12;
+ break;
+ case LoongArchII::MO_DESC64_PC_LO:
+ Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC64_PC_LO20;
+ break;
+ case LoongArchII::MO_DESC64_PC_HI:
+ Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC64_PC_HI12;
+ break;
+ case LoongArchII::MO_DESC_LD:
+ Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_LD;
+ break;
+ case LoongArchII::MO_DESC_CALL:
+ Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_CALL;
+ break;
// TODO: Handle more target-flags.
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
index 0692cb92b69440..3c3fed7d43ed98 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.h
@@ -47,7 +47,13 @@ enum {
MO_IE_PC64_HI,
MO_LD_PC_HI,
MO_GD_PC_HI,
- MO_CALL36
+ MO_CALL36,
+ MO_DESC_PC_HI,
+ MO_DESC_PC_LO,
+ MO_DESC64_PC_HI,
+ MO_DESC64_PC_LO,
+ MO_DESC_LD,
+ MO_DESC_CALL,
// TODO: Add more flags.
};
} // end namespace LoongArchII
diff --git a/llvm/test/CodeGen/LoongArch/tls-models.ll b/llvm/test/CodeGen/LoongArch/tls-models.ll
index 3994df1da7163f..6b250ec021624a 100644
--- a/llvm/test/CodeGen/LoongArch/tls-models.ll
+++ b/llvm/test/CodeGen/LoongArch/tls-models.ll
@@ -5,6 +5,12 @@
; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefix=LA32NOPIC
; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefix=LA64NOPIC
; RUN: llc --mtriple=loongarch64 --code-model=large < %s | FileCheck %s --check-prefix=LA64LARGENOPIC
+; RUN: llc --mtriple=loongarch32 --relocation-model=pic --enable-tlsdesc < %s \
+; RUN: | FileCheck %s --check-prefix=LA32DESC
+; RUN: llc --mtriple=loongarch64 --relocation-model=pic --enable-tlsdesc < %s \
+; RUN: | FileCheck %s --check-prefix=LA64DESC
+; RUN: llc --mtriple=loongarch64 --relocation-model=pic --enable-tlsdesc \
+; RUN: --code-model=large < %s | FileCheck %s --check-prefix=DESC64
;; Check that TLS symbols are lowered correctly based on the specified
;; model. Make sure they're external to avoid them all being optimised to Local
@@ -82,6 +88,49 @@ define ptr @f1() nounwind {
; LA64LARGENOPIC-NEXT: ldx.d $a0, $t8, $a0
; LA64LARGENOPIC-NEXT: add.d $a0, $a0, $tp
; LA64LARGENOPIC-NEXT: ret
+;
+; LA32DESC-LABEL: f1:
+; LA32DESC: # %bb.0: # %entry
+; LA32DESC-NEXT: addi.w $sp, $sp, -16
+; LA32DESC-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32DESC-NEXT: pcalau12i $a0, %desc_pc_hi20(unspecified)
+; LA32DESC-NEXT: addi.w $a0, $a0, %desc_pc_lo12(unspecified)
+; LA32DESC-NEXT: ld.w $ra, $a0, %desc_ld(unspecified)
+; LA32DESC-NEXT: jirl $ra, $ra, %desc_call(unspecified)
+; LA32DESC-NEXT: add.w $a0, $a0, $tp
+; LA32DESC-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32DESC-NEXT: addi.w $sp, $sp, 16
+; LA32DESC-NEXT: ret
+;
+; LA64DESC-LABEL: f1:
+; LA64DESC: # %bb.0: # %entry
+; LA64DESC-NEXT: addi.d $sp, $sp, -16
+; LA64DESC-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64DESC-NEXT: pcalau12i $a0, %desc_pc_hi20(unspecified)
+; LA64DESC-NEXT: addi.d $a0, $a0, %desc_pc_lo12(unspecified)
+; LA64DESC-NEXT: ld.d $ra, $a0, %desc_ld(unspecified)
+; LA64DESC-NEXT: jirl $ra, $ra, %desc_call(unspecified)
+; LA64DESC-NEXT: add.d $a0, $a0, $tp
+; LA64DESC-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64DESC-NEXT: addi.d $sp, $sp, 16
+; LA64DESC-NEXT: ret
+;
+; DESC64-LABEL: f1:
+; DESC64: # %bb.0: # %entry
+; DESC64-NEXT: addi.d $sp, $sp, -16
+; DESC64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
+; DESC64-NEXT: pcalau12i $a0, %desc_pc_hi20(unspecified)
+; DESC64-NEXT: addi.d $t8, $zero, %desc_pc_lo12(unspecified)
+; DESC64-NEXT: lu32i.d $t8, %desc64_pc_lo20(unspecified)
+; DESC64-NEXT: lu52i.d $t8, $t8, %desc64_pc_hi12(unspecified)
+; DESC64-NEXT: add.d $a0, $t8, $a0
+; DESC64-NEXT: ld.d $ra, $a0, %desc_ld(unspecified)
+; DESC64-NEXT: jirl $ra, $ra, %desc_call(unspecified)
+; DESC64-NEXT: add.d $a1, $a0, $tp
+; DESC64-NEXT: move $a0, $a1
+; DESC64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; DESC64-NEXT: addi.d $sp, $sp, 16
+; DESC64-NEXT: ret
entry:
ret ptr @unspecified
}
@@ -153,6 +202,49 @@ define ptr @f2() nounwind {
; LA64LARGENOPIC-NEXT: ldx.d $a0, $t8, $a0
; LA64LARGENOPIC-NEXT: add.d $a0, $a0, $tp
; LA64LARGENOPIC-NEXT: ret
+;
+; LA32DESC-LABEL: f2:
+; LA32DESC: # %bb.0: # %entry
+; LA32DESC-NEXT: addi.w $sp, $sp, -16
+; LA32DESC-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
+; LA32DESC-NEXT: pcalau12i $a0, %desc_pc_hi20(ld)
+; LA32DESC-NEXT: addi.w $a0, $a0, %desc_pc_lo12(ld)
+; LA32DESC-NEXT: ld.w $ra, $a0, %desc_ld(ld)
+; LA32DESC-NEXT: jirl $ra, $ra, %desc_call(ld)
+; LA32DESC-NEXT: add.w $a0, $a0, $tp
+; LA32DESC-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
+; LA32DESC-NEXT: addi.w $sp, $sp, 16
+; LA32DESC-NEXT: ret
+;
+; LA64DESC-LABEL: f2:
+; LA64DESC: # %bb.0: # %entry
+; LA64DESC-NEXT: addi.d $sp, $sp, -16
+; LA64DESC-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
+; LA64DESC-NEXT: pcalau12i $a0, %desc_pc_hi20(ld)
+; LA64DESC-NEXT: addi.d $a0, $a0, %desc_pc_lo12(ld)
+; LA64DESC-NEXT: ld.d $ra, $a0, %desc_ld(ld)
+; LA64DESC-NEXT: jirl $ra, $ra, %desc_call(ld)
+; LA64DESC-NEXT: add.d $a0, $a0, $tp
+; LA64DESC-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; LA64DESC-NEXT: addi.d $sp, $sp, 16
+; LA64DESC-NEXT: ret
+;
+; DESC64-LABEL: f2:
+; DESC64: # %bb.0: # %entry
+; DESC64-NEXT: addi.d $sp, $sp, -16
+; DESC64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
+; DESC64-NEXT: pcalau12i $a0, %desc_pc_hi20(ld)
+; DESC64-NEXT: addi.d $t8, $zero, %desc_pc_lo12(ld)
+; DESC64-NEXT: lu32i.d $t8, %desc64_pc_lo20(ld)
+; DESC64-NEXT: lu52i.d $t8, $t8, %desc64_pc_hi12(ld)
+; DESC64-NEXT: add.d $a0, $t8, $a0
+; DESC64-NEXT: ld.d $ra, $a0, %desc_ld(ld)
+; DESC64-NEXT: jirl $ra, $ra, %desc_call(ld)
+; DESC64-NEXT: add.d $a1, $a0, $tp
+; DESC64-NEXT: move $a0, $a1
+; DESC64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; DESC64-NEXT: addi.d $sp, $sp, 16
+; DESC64-NEXT: ret
entry:
ret ptr @ld
}
@@ -207,6 +299,30 @@ define ptr @f3() nounwind {
; LA64LARGENOPIC-NEXT: ldx.d $a0, $t8, $a0
; LA64LARGENOPIC-NEXT: add.d $a0, $a0, $tp
; LA64LARGENOPIC-NEXT: ret
+;
+; LA32DESC-LABEL: f3:
+; LA32DESC: # %bb.0: # %entry
+; LA32DESC-NEXT: pcalau12i $a0, %ie_pc_hi20(ie)
+; LA32DESC-NEXT: ld.w $a0, $a0, %ie_pc_lo12(ie)
+; LA32DESC-NEXT: add.w $a0, $a0, $tp
+; LA32DESC-NEXT: ret
+;
+; LA64DESC-LABEL: f3:
+; LA64DESC: # %bb.0: # %entry
+; LA64DESC-NEXT: pcalau12i $a0, %ie_pc_hi20(ie)
+; LA64DESC-NEXT: ld.d $a0, $a0, %ie_pc_lo12(ie)
+; LA64DESC-NEXT: add.d $a0, $a0, $tp
+; LA64DESC-NEXT: ret
+;
+; DESC64-LABEL: f3:
+; DESC64: # %bb.0: # %entry
+; DESC64-NEXT: pcalau12i $a0, %ie_pc_hi20(ie)
+; DESC64-NEXT: addi.d $t8, $zero, %ie_pc_lo12(ie)
+; DESC64-NEXT: lu32i.d $t8, %ie64_pc_lo20(ie)
+; DESC64-NEXT: lu52i.d $t8, $t8, %ie64_pc_hi12(ie)
+; DESC64-NEXT: ldx.d $a0, $t8, $a0
+; DESC64-NEXT: add.d $a0, $a0, $tp
+; DESC64-NEXT: ret
entry:
ret ptr @ie
}
@@ -259,6 +375,29 @@ define ptr @f4() nounwind {
; LA64LARGENOPIC-NEXT: lu52i.d $a0, $a0, %le64_hi12(le)
; LA64LARGENOPIC-NEXT: add.d $a0, $a0, $tp
; LA64LARGENOPIC-NEXT: ret
+;
+; LA32DESC-LABEL: f4:
+; LA32DESC: # %bb.0: # %entry
+; LA32DESC-NEXT: lu12i.w $a0, %le_hi20(le)
+; LA32DESC-NEXT: ori $a0, $a0, %le_lo12(le)
+; LA32DESC-NEXT: add.w $a0, $a0, $tp
+; LA32DESC-NEXT: ret
+;
+; LA64DESC-LABEL: f4:
+; LA64DESC: # %bb.0: # %entry
+; LA64DESC-NEXT: lu12i.w $a0, %le_hi20(le)
+; LA64DESC-NEXT: ori $a0, $a0, %le_lo12(le)
+; LA64DESC-NEXT: add.d $a0, $a0, $tp
+; LA64DESC-NEXT: ret
+;
+; DESC64-LABEL: f4:
+; DESC64: # %bb.0: # %entry
+; DESC64-NEXT: lu12i.w $a0, %le_hi20(le)
+; DESC64-NEXT: ori $a0, $a0, %le_lo12(le)
+; DESC64-NEXT: lu32i.d $a0, %le64_lo20(le)
+; DESC64-NEXT: lu52i.d $a0, $a0, %le64_hi12(le)
+; DESC64-NEXT: add.d $a0, $a0, $tp
+; DESC64-NEXT: ret
entry:
ret ptr @le
}
More information about the llvm-commits
mailing list