[clang] [Clang] Enable AIX local-dynamic TLS mode (PR #66972)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Sep 20 19:46:35 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
<details>
<summary>Changes</summary>
We are going to support local-dynamic TLS mode on AIX targets.
This patch removes relevant guards in clang.
---
Patch is 137.79 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66972.diff
21 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (-1)
- (modified) clang/lib/Frontend/CompilerInvocation.cpp (-8)
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (-6)
- (modified) clang/test/CodeGen/PowerPC/aix-tls-model.cpp (+6-3)
- (modified) clang/test/Sema/aix-attr-tls_model.c (+1-1)
- (modified) llvm/include/llvm/MC/MCExpr.h (+2)
- (modified) llvm/lib/MC/MCExpr.cpp (+4)
- (modified) llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp (+6-3)
- (modified) llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp (+4)
- (modified) llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp (+72-19)
- (modified) llvm/lib/Target/PowerPC/PPCISelLowering.cpp (+21-7)
- (modified) llvm/lib/Target/PowerPC/PPCISelLowering.h (+13-1)
- (modified) llvm/lib/Target/PowerPC/PPCInstr64Bit.td (+12-1)
- (modified) llvm/lib/Target/PowerPC/PPCInstrInfo.td (+14-1)
- (modified) llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp (+63-12)
- (modified) llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll (+53-37)
- (modified) llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll (+56-40)
- (modified) llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll (+157-141)
- (added) llvm/test/CodeGen/PowerPC/aix-tls-local-dynamic.ll (+364)
- (modified) llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc-large.ll (+154-132)
- (modified) llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc.ll (+155-133)
``````````diff
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 9349ff85ca8a1d3..cb0b7b2355678b3 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -653,7 +653,6 @@ def err_drv_cannot_mix_options : Error<"cannot specify '%1' along with '%0'">;
def err_drv_invalid_object_mode : Error<
"OBJECT_MODE setting %0 is not recognized and is not a valid setting">;
-def err_aix_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">;
def err_roptr_requires_data_sections: Error<"-mxcoff-roptr is supported only with -fdata-sections">;
def err_roptr_cannot_build_shared: Error<"-mxcoff-roptr is not supported with -shared">;
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2dd299b5d10322d..e0d21305ea15ed7 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1967,14 +1967,6 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Opts.LinkBitcodeFiles.push_back(F);
}
- if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
- if (T.isOSAIX()) {
- StringRef Name = A->getValue();
- if (Name == "local-dynamic")
- Diags.Report(diag::err_aix_unsupported_tls_model) << Name;
- }
- }
-
if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
StringRef Val = A->getValue();
Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val);
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index cc98713241395ec..ec6d889b8db5c81 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2053,12 +2053,6 @@ static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
- if (S.Context.getTargetInfo().getTriple().isOSAIX() &&
- Model == "local-dynamic") {
- S.Diag(LiteralLoc, diag::err_aix_attr_unsupported_tls_model) << Model;
- return;
- }
-
D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
}
diff --git a/clang/test/CodeGen/PowerPC/aix-tls-model.cpp b/clang/test/CodeGen/PowerPC/aix-tls-model.cpp
index 9fdd6855a89ee93..cd0a08aa9a3b77b 100644
--- a/clang/test/CodeGen/PowerPC/aix-tls-model.cpp
+++ b/clang/test/CodeGen/PowerPC/aix-tls-model.cpp
@@ -1,11 +1,11 @@
// RUN: %clang_cc1 %s -triple powerpc-unknown-aix -target-cpu pwr8 -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-GD
// RUN: %clang_cc1 %s -triple powerpc-unknown-aix -target-cpu pwr8 -ftls-model=global-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-GD
-// RUN: not %clang_cc1 %s -triple powerpc-unknown-aix -target-cpu pwr8 -ftls-model=local-dynamic -emit-llvm 2>&1 | FileCheck %s -check-prefix=CHECK-LD-ERROR
+// RUN: %clang_cc1 %s -triple powerpc-unknown-aix -target-cpu pwr8 -ftls-model=local-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LD
// RUN: %clang_cc1 %s -triple powerpc-unknown-aix -target-cpu pwr8 -ftls-model=initial-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-IE
// RUN: %clang_cc1 %s -triple powerpc-unknown-aix -target-cpu pwr8 -ftls-model=local-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LE
// RUN: %clang_cc1 %s -triple powerpc64-unknown-aix -target-cpu pwr8 -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-GD
// RUN: %clang_cc1 %s -triple powerpc64-unknown-aix -target-cpu pwr8 -ftls-model=global-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-GD
-// RUN: not %clang_cc1 %s -triple powerpc64-unknown-aix -target-cpu pwr8 -ftls-model=local-dynamic -emit-llvm 2>&1 | FileCheck %s -check-prefix=CHECK-LD-ERROR
+// RUN: %clang_cc1 %s -triple powerpc64-unknown-aix -target-cpu pwr8 -ftls-model=local-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LD
// RUN: %clang_cc1 %s -triple powerpc64-unknown-aix -target-cpu pwr8 -ftls-model=initial-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-IE
// RUN: %clang_cc1 %s -triple powerpc64-unknown-aix -target-cpu pwr8 -ftls-model=local-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LE
@@ -21,7 +21,10 @@ int f() {
// CHECK-GD: @z2 ={{.*}} global i32 0
// CHECK-GD: @x ={{.*}} thread_local global i32 0
// CHECK-GD: @_ZZ1fvE1y = internal thread_local global i32 0
-// CHECK-LD-ERROR: error: TLS model 'local-dynamic' is not yet supported on AIX
+// CHECK-LD: @z1 ={{.*}} global i32 0
+// CHECK-LD: @z2 ={{.*}} global i32 0
+// CHECK-LD: @x ={{.*}} thread_local(localdynamic) global i32 0
+// CHECK-LD: @_ZZ1fvE1y = internal thread_local(localdynamic) global i32 0
// CHECK-IE: @z1 ={{.*}} global i32 0
// CHECK-IE: @z2 ={{.*}} global i32 0
// CHECK-IE: @x ={{.*}} thread_local(initialexec) global i32 0
diff --git a/clang/test/Sema/aix-attr-tls_model.c b/clang/test/Sema/aix-attr-tls_model.c
index 9c22d6cceed81c6..7c2047bced93917 100644
--- a/clang/test/Sema/aix-attr-tls_model.c
+++ b/clang/test/Sema/aix-attr-tls_model.c
@@ -6,6 +6,6 @@
#endif
static __thread int y __attribute((tls_model("global-dynamic"))); // no-warning
-static __thread int y __attribute((tls_model("local-dynamic"))); // expected-error {{TLS model 'local-dynamic' is not yet supported on AIX}}
+static __thread int y __attribute((tls_model("local-dynamic"))); // expected-no-diagnostics
static __thread int y __attribute((tls_model("initial-exec"))); // no-warning
static __thread int y __attribute((tls_model("local-exec"))); // no-warning
diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h
index 67836292874f5f7..f3bc0491fd2f193 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -301,6 +301,8 @@ class MCSymbolRefExpr : public MCExpr {
VK_PPC_AIX_TLSGDM, // symbol at m
VK_PPC_AIX_TLSIE, // symbol at ie
VK_PPC_AIX_TLSLE, // symbol at le
+ VK_PPC_AIX_TLSLD, // symbol at ld
+ VK_PPC_AIX_TLSML, // symbol at ml
VK_PPC_GOT_TLSLD, // symbol at got@tlsld
VK_PPC_GOT_TLSLD_LO, // symbol at got@tlsld at l
VK_PPC_GOT_TLSLD_HI, // symbol at got@tlsld at h
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index 73e6569f96e4630..bc1bb9b80630546 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -331,6 +331,10 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
return "ie";
case VK_PPC_AIX_TLSLE:
return "le";
+ case VK_PPC_AIX_TLSLD:
+ return "ld";
+ case VK_PPC_AIX_TLSML:
+ return "ml";
case VK_PPC_GOT_TLSLD: return "got at tlsld";
case VK_PPC_GOT_TLSLD_LO: return "got at tlsld@l";
case VK_PPC_GOT_TLSLD_HI: return "got at tlsld@h";
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index a804dd823daa4da..22cd2fc03ef7c39 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -231,12 +231,15 @@ class PPCTargetAsmStreamer : public PPCTargetStreamer {
MCSymbolXCOFF *TCSym =
cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly())
->getQualNameSymbol();
- // On AIX, we have a region handle (symbol at m) and the variable offset
- // (symbol@{gd|ie|le}) for TLS variables, depending on the TLS model.
+ // On AIX, we have a region handle (symbol at m), module handle
+ // (__TLSML[TC]@ml) and the variable offset (symbol@{gd|ie|le|ld}) for TLS
+ // variables, depending on the TLS model.
if (Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD ||
Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||
Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE ||
- Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE)
+ Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE ||
+ Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD ||
+ Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML)
OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
<< MCSymbolRefExpr::getVariantKindName(Kind) << '\n';
else
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
index 065daf42fe6eb0c..f4998e9b9dcba86 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
@@ -116,6 +116,10 @@ std::pair<uint8_t, uint8_t> PPCXCOFFObjectWriter::getRelocTypeAndSignSize(
return {XCOFF::RelocationType::R_TLS_IE, SignAndSizeForFKData};
case MCSymbolRefExpr::VK_PPC_AIX_TLSLE:
return {XCOFF::RelocationType::R_TLS_LE, SignAndSizeForFKData};
+ case MCSymbolRefExpr::VK_PPC_AIX_TLSLD:
+ return {XCOFF::RelocationType::R_TLS_LD, SignAndSizeForFKData};
+ case MCSymbolRefExpr::VK_PPC_AIX_TLSML:
+ return {XCOFF::RelocationType::R_TLSML, SignAndSizeForFKData};
case MCSymbolRefExpr::VK_None:
return {XCOFF::RelocationType::R_POS, SignAndSizeForFKData};
}
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 4b97e3e1a09152f..211a5290939b38d 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -613,12 +613,23 @@ void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
}
-/// This helper function creates the TlsGetAddr MCSymbol for AIX. We will
-/// create the csect and use the qual-name symbol instead of creating just the
-/// external symbol.
+/// This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX. We
+/// will create the csect and use the qual-name symbol instead of creating just
+/// the external symbol.
static MCSymbol *createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc) {
- StringRef SymName =
- MIOpc == PPC::GETtlsTpointer32AIX ? ".__get_tpointer" : ".__tls_get_addr";
+ StringRef SymName;
+ switch (MIOpc) {
+ default:
+ SymName = ".__tls_get_addr";
+ break;
+ case PPC::GETtlsTpointer32AIX:
+ SymName = ".__get_tpointer";
+ break;
+ case PPC::GETtlsMOD32AIX:
+ case PPC::GETtlsMOD64AIX:
+ SymName = ".__tls_get_mod";
+ break;
+ }
return Ctx
.getXCOFFSection(SymName, SectionKind::getText(),
XCOFF::CsectProperties(XCOFF::XMC_PR, XCOFF::XTY_ER))
@@ -660,14 +671,16 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
"GETtls[ld]ADDR[32] must read GPR3");
if (Subtarget->isAIXABI()) {
- // On AIX, the variable offset should already be in R4 and the region handle
- // should already be in R3.
- // For TLSGD, which currently is the only supported access model, we only
- // need to generate an absolute branch to .__tls_get_addr.
+ // For TLSGD, the variable offset should already be in R4 and the region
+ // handle should already be in R3, generate absolute branch to
+ // .__tls_get_addr. For TLSLD, the module handle should already be in R3,
+ // generate branch to .__tls_get_mod.
Register VarOffsetReg = Subtarget->isPPC64() ? PPC::X4 : PPC::R4;
(void)VarOffsetReg;
- assert(MI->getOperand(2).isReg() &&
- MI->getOperand(2).getReg() == VarOffsetReg &&
+ assert((MI->getOpcode() == PPC::GETtlsMOD32AIX ||
+ MI->getOpcode() == PPC::GETtlsMOD64AIX ||
+ (MI->getOperand(2).isReg() &&
+ MI->getOperand(2).getReg() == VarOffsetReg)) &&
"GETtls[ld]ADDR[32] must read GPR4");
EmitAIXTlsCallHelper(MI);
return;
@@ -710,6 +723,8 @@ static MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO,
return AP.GetJTISymbol(MO.getIndex());
case MachineOperand::MO_BlockAddress:
return AP.GetBlockAddressSymbol(MO.getBlockAddress());
+ case MachineOperand::MO_ExternalSymbol:
+ return AP.OutContext.getOrCreateSymbol(MO.getSymbolName());
default:
llvm_unreachable("Unexpected operand type to get symbol.");
}
@@ -757,6 +772,16 @@ getTOCEntryTypeForMO(const MachineOperand &MO) {
llvm_unreachable("Unexpected operand type to get TOC type.");
}
}
+
+// On AIX, TLS-local-dynamic requires that symbol for the module handle must
+// have the name "_$TLSML". This symbol is used as one TOC symbol reference
+// itself with ML relocation type, thus it has "[TC]" attached to its name.
+static inline bool isSpecialAIXSymbolTLSML(const MachineOperand &MO,
+ const bool IsAIX) {
+ return IsAIX && MO.isSymbol() &&
+ (std::strcmp(MO.getSymbolName(), "_$TLSML[TC]") == 0);
+}
+
/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
/// the current output stream.
///
@@ -846,6 +871,15 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM;
if (MO.getTargetFlags() & PPCII::MO_TLSGD_FLAG)
return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD;
+ if (MO.getTargetFlags() & PPCII::MO_TLSLD_FLAG) {
+ if (isSpecialAIXSymbolTLSML(MO, IsAIX))
+ // FIXME: On AIX the ML relocation type is only valid for a reference to
+ // a TOC symbol from the symbol itself, and right now its only user is
+ // symbol "_$TLSML". Use symbol name to decide that R_TLSML is expected.
+ return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML;
+ if (IsAIX)
+ return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD;
+ }
return MCSymbolRefExpr::VariantKind::VK_None;
};
@@ -964,7 +998,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
TmpInst.setOpcode(PPC::LWZ);
const MachineOperand &MO = MI->getOperand(1);
- assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
+ assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress() ||
+ isSpecialAIXSymbolTLSML(MO, IsAIX)) &&
"Invalid operand for LWZtoc.");
// Map the operand to its corresponding MCSymbol.
@@ -1053,7 +1088,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
TmpInst.setOpcode(PPC::LD);
const MachineOperand &MO = MI->getOperand(1);
- assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
+ assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress() ||
+ isSpecialAIXSymbolTLSML(MO, IsAIX)) &&
"Invalid operand!");
// Map the operand to its corresponding MCSymbol.
@@ -1091,7 +1127,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
TmpInst.setOpcode(PPC::ADDIS);
const MachineOperand &MO = MI->getOperand(2);
- assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
+ assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress() ||
+ isSpecialAIXSymbolTLSML(MO, IsAIX)) &&
"Invalid operand for ADDIStocHA.");
// Map the machine operand to its corresponding MCSymbol.
@@ -1124,7 +1161,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
TmpInst.setOpcode(PPC::LWZ);
const MachineOperand &MO = MI->getOperand(1);
- assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
+ assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress() ||
+ isSpecialAIXSymbolTLSML(MO, IsAIX)) &&
"Invalid operand for LWZtocL.");
// Map the machine operand to its corresponding MCSymbol.
@@ -1156,7 +1194,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
TmpInst.setOpcode(PPC::ADDIS8);
const MachineOperand &MO = MI->getOperand(2);
- assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
+ assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress() ||
+ isSpecialAIXSymbolTLSML(MO, IsAIX)) &&
"Invalid operand for ADDIStocHA8!");
const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
@@ -1166,7 +1205,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
const bool GlobalToc =
MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal());
if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
- (MO.isCPI() && TM.getCodeModel() == CodeModel::Large))
+ (MO.isCPI() && TM.getCodeModel() == CodeModel::Large) ||
+ isSpecialAIXSymbolTLSML(MO, IsAIX))
MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
VK = IsAIX ? MCSymbolRefExpr::VK_PPC_U : MCSymbolRefExpr::VK_PPC_TOC_HA;
@@ -1195,8 +1235,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
TmpInst.setOpcode(PPC::LD);
const MachineOperand &MO = MI->getOperand(1);
- assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
- MO.isBlockAddress()) &&
+ assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress() ||
+ isSpecialAIXSymbolTLSML(MO, IsAIX)) &&
"Invalid operand for LDtocL!");
LLVM_DEBUG(assert(
@@ -1362,6 +1402,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
case PPC::GETtlsADDRPCREL:
case PPC::GETtlsADDR32AIX:
case PPC::GETtlsADDR64AIX:
+ case PPC::GETtlsMOD32AIX:
+ case PPC::GETtlsMOD64AIX:
// Transform: %r3 = GETtlsADDRNNAIX %r3, %r4 (for NN == 32/64).
// Into: BLA .__tls_get_addr()
// Unlike on Linux, there is no symbol or relocation needed for this call.
@@ -2710,6 +2752,15 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
MCSymbol *S = OutContext.getOrCreateSymbol(Name);
TCEntry = cast<MCSectionXCOFF>(
getObjFileLowering().getSectionForTOCEntry(S, TM));
+ } else if (I.first.second ==
+ MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML) {
+ // AIX assembler expects TC storage-mapping class for the "_$TLSML"
+ // symbol.
+ MCSection *MCSect = getObjFileLowering().getContext().getXCOFFSection(
+ cast<MCSymbolXCOFF>(I.first.first)->getSymbolTableName(),
+ SectionKind::getData(),
+ XCOFF::CsectProperties(XCOFF::XMC_TC, XCOFF::XTY_SD));
+ TCEntry = cast<MCSectionXCOFF>(MCSect);
} else {
TCEntry = cast<MCSectionXCOFF>(
getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
@@ -2826,6 +2877,8 @@ void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
MMI->hasDebugInfo());
break;
}
+ case PPC::GETtlsMOD32AIX:
+ case PPC::GETtlsMOD64AIX:
case PPC::GETtlsTpointer32AIX:
case PPC::GETtlsADDR64AIX:
case PPC::GETtlsADDR32AIX: {
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 95f2243178c8a10..38d7aad6ec517fb 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1771,9 +1771,13 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
case PPCISD::ADDIS_TLSGD_HA: return "PPCISD::ADDIS_TLSGD_HA";
case PPCISD::ADDI_TLSGD_L: return "PPCISD::ADDI_TLSGD_L";
case PPCISD::GET_TLS_ADDR: return "PPCISD::GET_TLS_ADDR";
+ case PPCISD::GET_TLS_MOD_AIX:
+ return "PPCISD::GET_TLS_MOD_AIX";
case PPCISD::GET_TPOINTER: return "PPCISD::GET_TPOINTER";
case PPCISD::ADDI_TLSGD_L_ADDR: return "PPCISD::ADDI_TLSGD_L_ADDR";
case PPCISD::TLSGD_AIX: return "PPCISD::TLSGD_AIX";
+ case PPCISD::TLSLD_AIX:
+ return "PPCISD::TLSLD_AIX";
case PPCISD::ADDIS_TLSLD_HA: return "PPCISD::ADDIS_TLSLD_HA";
case PPCISD::ADDI_TLSLD_L: return "PPCISD::ADDI_TLSLD_L";
case PPCISD::GET_TLSLD_ADDR: return "PPCISD::GET_TLSLD_ADDR";
@@ -3412,13 +3416,23 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
}
- // Only Local-Exec, Initial-Exec and General-Dynamic TLS models are currently
- // supported models. If Local- or Initial-exec are not possible or specified,
- // all GlobalTLSAddress nodes are lowered using the general-dynamic model.
- // We need to generate two TOC entries, one for the variable offset, one for
- // the region handle. The global address for the TOC entry of the region
- // handle is created with the MO_TLSGDM_FLAG flag and the global address
- // for the TOC entry of th...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/66972
More information about the cfe-commits
mailing list