diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h --- a/llvm/include/llvm/MC/MCExpr.h +++ b/llvm/include/llvm/MC/MCExpr.h @@ -299,6 +299,7 @@ VK_PPC_TLSGD, // symbol@tlsgd VK_PPC_AIX_TLSGD, // symbol@gd VK_PPC_AIX_TLSGDM, // symbol@m + VK_PPC_AIX_TLSLE, // symbol@le VK_PPC_GOT_TLSLD, // symbol@got@tlsld VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -327,6 +327,8 @@ return "gd"; case VK_PPC_AIX_TLSGDM: return "m"; + case VK_PPC_AIX_TLSLE: + return "le"; case VK_PPC_GOT_TLSLD: return "got@tlsld"; case VK_PPC_GOT_TLSLD_LO: return "got@tlsld@l"; case VK_PPC_GOT_TLSLD_HI: return "got@tlsld@h"; diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -151,8 +151,11 @@ // region handle for the symbol, we add the relocation specifier @m. // If the variant kind is VK_PPC_AIX_TLSGD the entry represents the // variable offset for the symbol, we add the relocation specifier @gd. + // If the variant kind is VK_PPC_AIX_TLSLE the entry represents the + // variable offset for the symbol, we add the relocation specifier @le. if (Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD || - Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM) + Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM || + Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE) 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 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp @@ -108,6 +108,8 @@ return {XCOFF::RelocationType::R_TLS, SignAndSizeForFKData}; case MCSymbolRefExpr::VK_PPC_AIX_TLSGDM: return {XCOFF::RelocationType::R_TLSM, SignAndSizeForFKData}; + case MCSymbolRefExpr::VK_PPC_AIX_TLSLE: + return {XCOFF::RelocationType::R_TLS_LE, SignAndSizeForFKData}; case MCSymbolRefExpr::VK_None: return {XCOFF::RelocationType::R_POS, SignAndSizeForFKData}; } diff --git a/llvm/lib/Target/PowerPC/PPC.h b/llvm/lib/Target/PowerPC/PPC.h --- a/llvm/lib/Target/PowerPC/PPC.h +++ b/llvm/lib/Target/PowerPC/PPC.h @@ -128,7 +128,8 @@ MO_TLSGD_FLAG = 32, /// MO_TPREL_FLAG - If this bit is set the symbol reference is relative to - /// TLS Initial Exec model. + /// TLS Initial Exec model, or for the TLS Local Exec or Initial Exec models + /// on AIX. MO_TPREL_FLAG = 64, /// MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -813,6 +813,18 @@ return Expr; }; auto GetVKForMO = [&](const MachineOperand &MO) { + // For LE TLS access on AIX, we have one TOC entry for the symbol (with the + // variable offset), which is differentiated by MO_TPREL_FLAG. + if (MO.getTargetFlags() & PPCII::MO_TPREL_FLAG) { + // TODO: Update the query and the comment above to add a check for initial + // exec when this TLS model is supported on AIX in the future, as both + // local-exec and initial-exec can use MO_TPREL_FLAG. + assert(MO.isGlobal() && "Only expecting a global MachineOperand here!\n"); + const GlobalValue *GV = MO.getGlobal(); + TLSModel::Model Model = TM.getTLSModel(GV); + if (Model == TLSModel::LocalExec) + return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE; + } // For GD TLS access on AIX, we have two TOC entries for the symbol (one for // the variable offset and the other for the region handle). They are // differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG. diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -3329,9 +3329,26 @@ SDLoc dl(GA); const GlobalValue *GV = GA->getGlobal(); EVT PtrVT = getPointerTy(DAG.getDataLayout()); + bool Is64Bit = Subtarget.isPPC64(); + const TargetMachine &TM = getTargetMachine(); + TLSModel::Model Model = TM.getTLSModel(GV); + + if (Model == TLSModel::LocalExec) { + assert(Is64Bit && + "The local-exec TLS model is only supported on PPC64 for now."); + if (Is64Bit) { + SDValue TLSReg = DAG.getRegister(PPC::X13, MVT::i64); + SDValue VariableOffsetTGA = + DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, PPCII::MO_TPREL_FLAG); + SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA); + return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset); + } + // TODO: Add an 'else' to account for generating the 32-bit access sequence. + } - // The general-dynamic model is the only access model supported for now, so - // all the GlobalTLSAddress nodes are lowered with this model. + // Aside from the local-exec model, the general-dynamic model is the only + // other access model supported for now, so all other GlobalTLSAddress nodes + // are lowered with this 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 diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td --- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -1913,6 +1913,17 @@ def : Pat<(i64 (PPCtoc_entry tglobaltlsaddr:$disp, i64:$reg)), (i64 (LDtoc tglobaltlsaddr:$disp, i64:$reg))>; +// The following pattern is needed to match a local-exec TLS access on AIX +// (64-bit) for both small and large code models. The typical AIX 64-bit access +// sequence is as follows: +// ld reg1,var[TC](2) +// add reg2, reg1, r13 // r13 contains the thread pointer +// The load from the TOC is matched by the AIX 64-bit small code model pattern +// defined above, while the add is matched by the below pattern for ADD8TLS. +// For the large code model, we match the load (addis+ld) in PPCISelDAGToDAG. +def : Pat<(PPCaddTls i64:$in, i64:$addr), + (ADD8TLS $in, $addr)>; + // 64-bits atomic loads and stores def : Pat<(atomic_load_64 DSForm:$src), (LD memrix:$src)>; def : Pat<(atomic_load_64 XForm:$src), (LDX memrr:$src)>; diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-double.ll b/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-double.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-double.ll @@ -0,0 +1,328 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s \ +; RUN: --check-prefix=SMALL64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large < %s \ +; RUN: | FileCheck %s --check-prefix=LARGE64 + +@ThreadLocalVarInit = thread_local(localexec) global double 0x4021947AE147AE14, align 8 +@VarInit = global double 8.787000e+01, align 8 +@IThreadLocalVarUninit = internal thread_local(localexec) global double 0.000000e+00, align 8 +@IThreadLocalVarInit = internal thread_local(localexec) global double 5.870000e+00, align 8 +@ThreadLocalVarUninit = thread_local(localexec) global double 0.000000e+00, align 8 +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #1 + +define void @storeITLUninit(double noundef %x) { +; SMALL64-LABEL: storeITLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: stfd f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeITLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: stfd f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit) + store double %x, ptr %0, align 8 + ret void +} + +define void @storeITLInit(double noundef %x) { +; SMALL64-LABEL: storeITLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: stfd f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeITLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: stfd f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarInit) + store double %x, ptr %0, align 8 + ret void +} + +define void @storeTLUninit(double noundef %x) { +; SMALL64-LABEL: storeTLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: stfd f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeTLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: stfd f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarUninit) + store double %x, ptr %0, align 8 + ret void +} + +define void @storeTLInit(double noundef %x) { +; SMALL64-LABEL: storeTLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: stfd f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeTLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: stfd f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit) + store double %x, ptr %0, align 8 + ret void +} + +define double @loadITLUninit() { +; SMALL64-LABEL: loadITLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfd f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfd f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit) + %1 = load double, ptr %0, align 8 + ret double %1 +} + +define double @loadITLUninit2() { +; SMALL64-LABEL: loadITLUninit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfd f1, 0(r4) +; SMALL64-NEXT: lfd f0, 0(r3) +; SMALL64-NEXT: xsadddp f1, f0, f1 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLUninit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfd f1, 0(r4) +; LARGE64-NEXT: lfd f0, 0(r3) +; LARGE64-NEXT: xsadddp f1, f0, f1 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit) + %1 = load double, ptr %0, align 8 + %2 = load double, ptr @VarInit, align 8 + %add = fadd double %1, %2 + ret double %add +} + +define double @loadITLInit() { +; SMALL64-LABEL: loadITLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfd f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfd f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarInit) + %1 = load double, ptr %0, align 8 + ret double %1 +} + +define double @loadITLInit2() { +; SMALL64-LABEL: loadITLInit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfd f1, 0(r4) +; SMALL64-NEXT: lfd f0, 0(r3) +; SMALL64-NEXT: xsadddp f1, f0, f1 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLInit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfd f1, 0(r4) +; LARGE64-NEXT: lfd f0, 0(r3) +; LARGE64-NEXT: xsadddp f1, f0, f1 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarInit) + %1 = load double, ptr %0, align 8 + %2 = load double, ptr @VarInit, align 8 + %add = fadd double %1, %2 + ret double %add +} + +define double @loadTLUninit() { +; SMALL64-LABEL: loadTLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfd f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfd f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarUninit) + %1 = load double, ptr %0, align 8 + ret double %1 +} + +define double @loadTLUninit2() { +; SMALL64-LABEL: loadTLUninit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfd f1, 0(r4) +; SMALL64-NEXT: lfd f0, 0(r3) +; SMALL64-NEXT: xsadddp f1, f0, f1 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLUninit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfd f1, 0(r4) +; LARGE64-NEXT: lfd f0, 0(r3) +; LARGE64-NEXT: xsadddp f1, f0, f1 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarUninit) + %1 = load double, ptr %0, align 8 + %2 = load double, ptr @VarInit, align 8 + %add = fadd double %1, %2 + ret double %add +} + +define double @loadTLInit() { +; SMALL64-LABEL: loadTLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfd f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfd f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit) + %1 = load double, ptr %0, align 8 + ret double %1 +} + +define double @loadTLInit2() { +; SMALL64-LABEL: loadTLInit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfd f1, 0(r4) +; SMALL64-NEXT: lfd f0, 0(r3) +; SMALL64-NEXT: xsadddp f1, f0, f1 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLInit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfd f1, 0(r4) +; LARGE64-NEXT: lfd f0, 0(r3) +; LARGE64-NEXT: xsadddp f1, f0, f1 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit) + %1 = load double, ptr %0, align 8 + %2 = load double, ptr @VarInit, align 8 + %add = fadd double %1, %2 + ret double %add +} + +; TOC Entry Checks. + +; SMALL64-LABEL: .toc +; SMALL64-LABEL: L..C0: +; SMALL64-NEXT: .tc IThreadLocalVarUninit[TC],IThreadLocalVarUninit[UL]@le +; SMALL64-LABEL: L..C1: +; SMALL64-NEXT: .tc IThreadLocalVarInit[TC],IThreadLocalVarInit[TL]@le +; SMALL64-LABEL: L..C2: +; SMALL64-NEXT: .tc ThreadLocalVarUninit[TC],ThreadLocalVarUninit[TL]@le +; SMALL64-LABEL: L..C3: +; SMALL64-NEXT: .tc ThreadLocalVarInit[TC],ThreadLocalVarInit[TL]@le +; SMALL64-LABEL: L..C4: +; SMALL64-NEXT: .tc VarInit[TC],VarInit[RW] + +; LARGE64-LABEL: .toc +; LARGE64-LABEL: L..C0: +; LARGE64-NEXT: .tc IThreadLocalVarUninit[TE],IThreadLocalVarUninit[UL]@le +; LARGE64-LABEL: L..C1: +; LARGE64-NEXT: .tc IThreadLocalVarInit[TE],IThreadLocalVarInit[TL]@le +; LARGE64-LABEL: L..C2: +; LARGE64-NEXT: .tc ThreadLocalVarUninit[TE],ThreadLocalVarUninit[TL]@le +; LARGE64-LABEL: L..C3: +; LARGE64-NEXT: .tc ThreadLocalVarInit[TE],ThreadLocalVarInit[TL]@le +; LARGE64-LABEL: L..C4: +; LARGE64-NEXT: .tc VarInit[TE],VarInit[RW] diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-float.ll b/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-float.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-float.ll @@ -0,0 +1,328 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s \ +; RUN: --check-prefix=SMALL64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large < %s \ +; RUN: | FileCheck %s --check-prefix=LARGE64 + +@ThreadLocalVarInit = thread_local(localexec) global float 0x401D333340000000, align 4 +@VarInit = global float 0x4021666660000000, align 4 +@IThreadLocalVarUninit = internal thread_local(localexec) global float 0.000000e+00, align 4 +@IThreadLocalVarInit = internal thread_local(localexec) global float 0x4018CCCCC0000000, align 4 +@ThreadLocalVarUninit = thread_local(localexec) global float 0.000000e+00, align 4 +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #1 + +define void @storeITLUninit(float noundef %x) { +; SMALL64-LABEL: storeITLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: stfs f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeITLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: stfs f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarUninit) + store float %x, ptr %0, align 4 + ret void +} + +define void @storeITLInit(float noundef %x) { +; SMALL64-LABEL: storeITLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: stfs f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeITLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: stfs f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarInit) + store float %x, ptr %0, align 4 + ret void +} + +define void @storeTLUninit(float noundef %x) { +; SMALL64-LABEL: storeTLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: stfs f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeTLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: stfs f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarUninit) + store float %x, ptr %0, align 4 + ret void +} + +define void @storeTLInit(float noundef %x) { +; SMALL64-LABEL: storeTLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: stfs f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeTLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: stfs f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarInit) + store float %x, ptr %0, align 4 + ret void +} + +define float @loadITLUninit() { +; SMALL64-LABEL: loadITLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfs f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfs f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarUninit) + %1 = load float, ptr %0, align 4 + ret float %1 +} + +define float @loadITLUninit2() { +; SMALL64-LABEL: loadITLUninit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfs f1, 0(r4) +; SMALL64-NEXT: lfs f0, 0(r3) +; SMALL64-NEXT: fadds f1, f0, f1 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLUninit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfs f1, 0(r4) +; LARGE64-NEXT: lfs f0, 0(r3) +; LARGE64-NEXT: fadds f1, f0, f1 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarUninit) + %1 = load float, ptr %0, align 4 + %2 = load float, ptr @VarInit, align 4 + %add = fadd float %1, %2 + ret float %add +} + +define float @loadITLInit() { +; SMALL64-LABEL: loadITLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfs f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfs f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarInit) + %1 = load float, ptr %0, align 4 + ret float %1 +} + +define float @loadITLInit2() { +; SMALL64-LABEL: loadITLInit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfs f1, 0(r4) +; SMALL64-NEXT: lfs f0, 0(r3) +; SMALL64-NEXT: fadds f1, f0, f1 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLInit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfs f1, 0(r4) +; LARGE64-NEXT: lfs f0, 0(r3) +; LARGE64-NEXT: fadds f1, f0, f1 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarInit) + %1 = load float, ptr %0, align 4 + %2 = load float, ptr @VarInit, align 4 + %add = fadd float %1, %2 + ret float %add +} + +define float @loadTLUninit() { +; SMALL64-LABEL: loadTLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfs f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfs f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarUninit) + %1 = load float, ptr %0, align 4 + ret float %1 +} + +define float @loadTLUninit2() { +; SMALL64-LABEL: loadTLUninit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfs f1, 0(r4) +; SMALL64-NEXT: lfs f0, 0(r3) +; SMALL64-NEXT: fadds f1, f0, f1 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLUninit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfs f1, 0(r4) +; LARGE64-NEXT: lfs f0, 0(r3) +; LARGE64-NEXT: fadds f1, f0, f1 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarUninit) + %1 = load float, ptr %0, align 4 + %2 = load float, ptr @VarInit, align 4 + %add = fadd float %1, %2 + ret float %add +} + +define float @loadTLInit() { +; SMALL64-LABEL: loadTLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfs f1, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfs f1, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarInit) + %1 = load float, ptr %0, align 4 + ret float %1 +} + +define float @loadTLInit2() { +; SMALL64-LABEL: loadTLInit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lfs f1, 0(r4) +; SMALL64-NEXT: lfs f0, 0(r3) +; SMALL64-NEXT: fadds f1, f0, f1 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLInit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lfs f1, 0(r4) +; LARGE64-NEXT: lfs f0, 0(r3) +; LARGE64-NEXT: fadds f1, f0, f1 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarInit) + %1 = load float, ptr %0, align 4 + %2 = load float, ptr @VarInit, align 4 + %add = fadd float %1, %2 + ret float %add +} + +; TOC Entry Checks. + +; SMALL64-LABEL: .toc +; SMALL64-LABEL: L..C0: +; SMALL64-NEXT: .tc IThreadLocalVarUninit[TC],IThreadLocalVarUninit[UL]@le +; SMALL64-LABEL: L..C1: +; SMALL64-NEXT: .tc IThreadLocalVarInit[TC],IThreadLocalVarInit[TL]@le +; SMALL64-LABEL: L..C2: +; SMALL64-NEXT: .tc ThreadLocalVarUninit[TC],ThreadLocalVarUninit[TL]@le +; SMALL64-LABEL: L..C3: +; SMALL64-NEXT: .tc ThreadLocalVarInit[TC],ThreadLocalVarInit[TL]@le +; SMALL64-LABEL: L..C4: +; SMALL64-NEXT: .tc VarInit[TC],VarInit[RW] + +; LARGE64-LABEL: .toc +; LARGE64-LABEL: L..C0: +; LARGE64-NEXT: .tc IThreadLocalVarUninit[TE],IThreadLocalVarUninit[UL]@le +; LARGE64-LABEL: L..C1: +; LARGE64-NEXT: .tc IThreadLocalVarInit[TE],IThreadLocalVarInit[TL]@le +; LARGE64-LABEL: L..C2: +; LARGE64-NEXT: .tc ThreadLocalVarUninit[TE],ThreadLocalVarUninit[TL]@le +; LARGE64-LABEL: L..C3: +; LARGE64-NEXT: .tc ThreadLocalVarInit[TE],ThreadLocalVarInit[TL]@le +; LARGE64-LABEL: L..C4: +; LARGE64-NEXT: .tc VarInit[TE],VarInit[RW] diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-int.ll b/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-int.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-int.ll @@ -0,0 +1,336 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s \ +; RUN: --check-prefix=SMALL64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large < %s \ +; RUN: | FileCheck %s --check-prefix=LARGE64 + +@ThreadLocalVarInit = thread_local(localexec) global i32 1, align 4 +@VarInit = global i32 87, align 4 +@IThreadLocalVarUninit = internal thread_local(localexec) global i32 0, align 4 +@IThreadLocalVarInit = internal thread_local(localexec) global i32 1, align 4 +@ThreadLocalVarUninit = thread_local(localexec) global i32 0, align 4 +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #1 + +define void @storeITLUninit(i32 noundef signext %x) { +; SMALL64-LABEL: storeITLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r4, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: add r4, r13, r4 +; SMALL64-NEXT: stw r3, 0(r4) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeITLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r4, L..C0@u(r2) +; LARGE64-NEXT: ld r4, L..C0@l(r4) +; LARGE64-NEXT: add r4, r13, r4 +; LARGE64-NEXT: stw r3, 0(r4) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarUninit) + store i32 %x, ptr %0, align 4 + ret void +} + +define void @storeITLInit(i32 noundef signext %x) { +; SMALL64-LABEL: storeITLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r4, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: add r4, r13, r4 +; SMALL64-NEXT: stw r3, 0(r4) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeITLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r4, L..C1@u(r2) +; LARGE64-NEXT: ld r4, L..C1@l(r4) +; LARGE64-NEXT: add r4, r13, r4 +; LARGE64-NEXT: stw r3, 0(r4) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarInit) + store i32 %x, ptr %0, align 4 + ret void +} + +define void @storeTLUninit(i32 noundef signext %x) { +; SMALL64-LABEL: storeTLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r4, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: add r4, r13, r4 +; SMALL64-NEXT: stw r3, 0(r4) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeTLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r4, L..C2@u(r2) +; LARGE64-NEXT: ld r4, L..C2@l(r4) +; LARGE64-NEXT: add r4, r13, r4 +; LARGE64-NEXT: stw r3, 0(r4) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarUninit) + store i32 %x, ptr %0, align 4 + ret void +} + +define void @storeTLInit(i32 noundef signext %x) { +; SMALL64-LABEL: storeTLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r4, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: add r4, r13, r4 +; SMALL64-NEXT: stw r3, 0(r4) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeTLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r4, L..C3@u(r2) +; LARGE64-NEXT: ld r4, L..C3@l(r4) +; LARGE64-NEXT: add r4, r13, r4 +; LARGE64-NEXT: stw r3, 0(r4) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarInit) + store i32 %x, ptr %0, align 4 + ret void +} + +define signext i32 @loadITLUninit() { +; SMALL64-LABEL: loadITLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lwa r3, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lwa r3, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarUninit) + %1 = load i32, ptr %0, align 4 + ret i32 %1 +} + +define signext i32 @loadITLUninit2() { +; SMALL64-LABEL: loadITLUninit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lwz r4, 0(r4) +; SMALL64-NEXT: lwz r3, 0(r3) +; SMALL64-NEXT: add r3, r4, r3 +; SMALL64-NEXT: extsw r3, r3 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLUninit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lwz r4, 0(r4) +; LARGE64-NEXT: lwz r3, 0(r3) +; LARGE64-NEXT: add r3, r4, r3 +; LARGE64-NEXT: extsw r3, r3 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarUninit) + %1 = load i32, ptr %0, align 4 + %2 = load i32, ptr @VarInit, align 4 + %add = add nsw i32 %2, %1 + ret i32 %add +} + +define signext i32 @loadITLInit() { +; SMALL64-LABEL: loadITLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lwa r3, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lwa r3, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarInit) + %1 = load i32, ptr %0, align 4 + ret i32 %1 +} + +define signext i32 @loadITLInit2() { +; SMALL64-LABEL: loadITLInit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lwz r4, 0(r4) +; SMALL64-NEXT: lwz r3, 0(r3) +; SMALL64-NEXT: add r3, r4, r3 +; SMALL64-NEXT: extsw r3, r3 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLInit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lwz r4, 0(r4) +; LARGE64-NEXT: lwz r3, 0(r3) +; LARGE64-NEXT: add r3, r4, r3 +; LARGE64-NEXT: extsw r3, r3 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarInit) + %1 = load i32, ptr %0, align 4 + %2 = load i32, ptr @VarInit, align 4 + %add = add nsw i32 %2, %1 + ret i32 %add +} + +define signext i32 @loadTLUninit() { +; SMALL64-LABEL: loadTLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lwa r3, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lwa r3, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarUninit) + %1 = load i32, ptr %0, align 4 + ret i32 %1 +} + +define signext i32 @loadTLUninit2() { +; SMALL64-LABEL: loadTLUninit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lwz r4, 0(r4) +; SMALL64-NEXT: lwz r3, 0(r3) +; SMALL64-NEXT: add r3, r4, r3 +; SMALL64-NEXT: extsw r3, r3 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLUninit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lwz r4, 0(r4) +; LARGE64-NEXT: lwz r3, 0(r3) +; LARGE64-NEXT: add r3, r4, r3 +; LARGE64-NEXT: extsw r3, r3 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarUninit) + %1 = load i32, ptr %0, align 4 + %2 = load i32, ptr @VarInit, align 4 + %add = add nsw i32 %2, %1 + ret i32 %add +} + +define signext i32 @loadTLInit() { +; SMALL64-LABEL: loadTLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lwa r3, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lwa r3, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarInit) + %1 = load i32, ptr %0, align 4 + ret i32 %1 +} + +define signext i32 @loadTLInit2() { +; SMALL64-LABEL: loadTLInit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: lwz r4, 0(r4) +; SMALL64-NEXT: lwz r3, 0(r3) +; SMALL64-NEXT: add r3, r4, r3 +; SMALL64-NEXT: extsw r3, r3 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLInit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: lwz r4, 0(r4) +; LARGE64-NEXT: lwz r3, 0(r3) +; LARGE64-NEXT: add r3, r4, r3 +; LARGE64-NEXT: extsw r3, r3 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarInit) + %1 = load i32, ptr %0, align 4 + %2 = load i32, ptr @VarInit, align 4 + %add = add nsw i32 %2, %1 + ret i32 %add +} + +; TOC Entry Checks. + +; SMALL64-LABEL: .toc +; SMALL64-LABEL: L..C0: +; SMALL64-NEXT: .tc IThreadLocalVarUninit[TC],IThreadLocalVarUninit[UL]@le +; SMALL64-LABEL: L..C1: +; SMALL64-NEXT: .tc IThreadLocalVarInit[TC],IThreadLocalVarInit[TL]@le +; SMALL64-LABEL: L..C2: +; SMALL64-NEXT: .tc ThreadLocalVarUninit[TC],ThreadLocalVarUninit[TL]@le +; SMALL64-LABEL: L..C3: +; SMALL64-NEXT: .tc ThreadLocalVarInit[TC],ThreadLocalVarInit[TL]@le +; SMALL64-LABEL: L..C4: +; SMALL64-NEXT: .tc VarInit[TC],VarInit[RW] + +; LARGE64-LABEL: .toc +; LARGE64-LABEL: L..C0: +; LARGE64-NEXT: .tc IThreadLocalVarUninit[TE],IThreadLocalVarUninit[UL]@le +; LARGE64-LABEL: L..C1: +; LARGE64-NEXT: .tc IThreadLocalVarInit[TE],IThreadLocalVarInit[TL]@le +; LARGE64-LABEL: L..C2: +; LARGE64-NEXT: .tc ThreadLocalVarUninit[TE],ThreadLocalVarUninit[TL]@le +; LARGE64-LABEL: L..C3: +; LARGE64-NEXT: .tc ThreadLocalVarInit[TE],ThreadLocalVarInit[TL]@le +; LARGE64-LABEL: L..C4: +; LARGE64-NEXT: .tc VarInit[TE],VarInit[RW] diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-longlong.ll b/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-longlong.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-longlong.ll @@ -0,0 +1,328 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s \ +; RUN: --check-prefix=SMALL64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large < %s \ +; RUN: | FileCheck %s --check-prefix=LARGE64 + +@ThreadLocalVarInit = thread_local(localexec) global i64 1, align 8 +@VarInit = global i64 87, align 8 +@IThreadLocalVarUninit = internal thread_local(localexec) global i64 0, align 8 +@IThreadLocalVarInit = internal thread_local(localexec) global i64 1, align 8 +@ThreadLocalVarUninit = thread_local(localexec) global i64 0, align 8 +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #1 + +define void @storeITLUninit(i64 noundef %x) { +; SMALL64-LABEL: storeITLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r4, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: add r4, r13, r4 +; SMALL64-NEXT: std r3, 0(r4) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeITLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r4, L..C0@u(r2) +; LARGE64-NEXT: ld r4, L..C0@l(r4) +; LARGE64-NEXT: add r4, r13, r4 +; LARGE64-NEXT: std r3, 0(r4) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit) + store i64 %x, ptr %0, align 8 + ret void +} + +define void @storeITLInit(i64 noundef %x) { +; SMALL64-LABEL: storeITLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r4, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: add r4, r13, r4 +; SMALL64-NEXT: std r3, 0(r4) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeITLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r4, L..C1@u(r2) +; LARGE64-NEXT: ld r4, L..C1@l(r4) +; LARGE64-NEXT: add r4, r13, r4 +; LARGE64-NEXT: std r3, 0(r4) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarInit) + store i64 %x, ptr %0, align 8 + ret void +} + +define void @storeTLUninit(i64 noundef %x) { +; SMALL64-LABEL: storeTLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r4, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: add r4, r13, r4 +; SMALL64-NEXT: std r3, 0(r4) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeTLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r4, L..C2@u(r2) +; LARGE64-NEXT: ld r4, L..C2@l(r4) +; LARGE64-NEXT: add r4, r13, r4 +; LARGE64-NEXT: std r3, 0(r4) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarUninit) + store i64 %x, ptr %0, align 8 + ret void +} + +define void @storeTLInit(i64 noundef %x) { +; SMALL64-LABEL: storeTLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r4, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: add r4, r13, r4 +; SMALL64-NEXT: std r3, 0(r4) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storeTLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r4, L..C3@u(r2) +; LARGE64-NEXT: ld r4, L..C3@l(r4) +; LARGE64-NEXT: add r4, r13, r4 +; LARGE64-NEXT: std r3, 0(r4) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit) + store i64 %x, ptr %0, align 8 + ret void +} + +define i64 @loadITLUninit() { +; SMALL64-LABEL: loadITLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: ld r3, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: ld r3, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit) + %1 = load i64, ptr %0, align 8 + ret i64 %1 +} + +define i64 @loadITLUninit2() { +; SMALL64-LABEL: loadITLUninit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @IThreadLocalVarUninit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: ld r4, 0(r4) +; SMALL64-NEXT: ld r3, 0(r3) +; SMALL64-NEXT: add r3, r4, r3 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLUninit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C0@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C0@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: ld r4, 0(r4) +; LARGE64-NEXT: ld r3, 0(r3) +; LARGE64-NEXT: add r3, r4, r3 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit) + %1 = load i64, ptr %0, align 8 + %2 = load i64, ptr @VarInit, align 8 + %add = add nsw i64 %2, %1 + ret i64 %add +} + +define i64 @loadITLInit() { +; SMALL64-LABEL: loadITLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: ld r3, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: ld r3, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarInit) + %1 = load i64, ptr %0, align 8 + ret i64 %1 +} + +define i64 @loadITLInit2() { +; SMALL64-LABEL: loadITLInit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @IThreadLocalVarInit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: ld r4, 0(r4) +; SMALL64-NEXT: ld r3, 0(r3) +; SMALL64-NEXT: add r3, r4, r3 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadITLInit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C1@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C1@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: ld r4, 0(r4) +; LARGE64-NEXT: ld r3, 0(r3) +; LARGE64-NEXT: add r3, r4, r3 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarInit) + %1 = load i64, ptr %0, align 8 + %2 = load i64, ptr @VarInit, align 8 + %add = add nsw i64 %2, %1 + ret i64 %add +} + +define i64 @loadTLUninit() { +; SMALL64-LABEL: loadTLUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: ld r3, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: ld r3, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarUninit) + %1 = load i64, ptr %0, align 8 + ret i64 %1 +} + +define i64 @loadTLUninit2() { +; SMALL64-LABEL: loadTLUninit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @ThreadLocalVarUninit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: ld r4, 0(r4) +; SMALL64-NEXT: ld r3, 0(r3) +; SMALL64-NEXT: add r3, r4, r3 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLUninit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C2@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C2@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: ld r4, 0(r4) +; LARGE64-NEXT: ld r3, 0(r3) +; LARGE64-NEXT: add r3, r4, r3 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarUninit) + %1 = load i64, ptr %0, align 8 + %2 = load i64, ptr @VarInit, align 8 + %add = add nsw i64 %2, %1 + ret i64 %add +} + +define i64 @loadTLInit() { +; SMALL64-LABEL: loadTLInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: ld r3, 0(r3) +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: ld r3, 0(r3) +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit) + %1 = load i64, ptr %0, align 8 + ret i64 %1 +} + +define i64 @loadTLInit2() { +; SMALL64-LABEL: loadTLInit2: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @ThreadLocalVarInit +; SMALL64-NEXT: ld r4, L..C4(r2) # @VarInit +; SMALL64-NEXT: add r3, r13, r3 +; SMALL64-NEXT: ld r4, 0(r4) +; SMALL64-NEXT: ld r3, 0(r3) +; SMALL64-NEXT: add r3, r4, r3 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadTLInit2: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: addis r3, L..C3@u(r2) +; LARGE64-NEXT: addis r4, L..C4@u(r2) +; LARGE64-NEXT: ld r3, L..C3@l(r3) +; LARGE64-NEXT: ld r4, L..C4@l(r4) +; LARGE64-NEXT: add r3, r13, r3 +; LARGE64-NEXT: ld r4, 0(r4) +; LARGE64-NEXT: ld r3, 0(r3) +; LARGE64-NEXT: add r3, r4, r3 +; LARGE64-NEXT: blr +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit) + %1 = load i64, ptr %0, align 8 + %2 = load i64, ptr @VarInit, align 8 + %add = add nsw i64 %2, %1 + ret i64 %add +} + +; TOC Entry Checks. + +; SMALL64-LABEL: .toc +; SMALL64-LABEL: L..C0: +; SMALL64-NEXT: .tc IThreadLocalVarUninit[TC],IThreadLocalVarUninit[UL]@le +; SMALL64-LABEL: L..C1: +; SMALL64-NEXT: .tc IThreadLocalVarInit[TC],IThreadLocalVarInit[TL]@le +; SMALL64-LABEL: L..C2: +; SMALL64-NEXT: .tc ThreadLocalVarUninit[TC],ThreadLocalVarUninit[TL]@le +; SMALL64-LABEL: L..C3: +; SMALL64-NEXT: .tc ThreadLocalVarInit[TC],ThreadLocalVarInit[TL]@le +; SMALL64-LABEL: L..C4: +; SMALL64-NEXT: .tc VarInit[TC],VarInit[RW] + +; LARGE64-LABEL: .toc +; LARGE64-LABEL: L..C0: +; LARGE64-NEXT: .tc IThreadLocalVarUninit[TE],IThreadLocalVarUninit[UL]@le +; LARGE64-LABEL: L..C1: +; LARGE64-NEXT: .tc IThreadLocalVarInit[TE],IThreadLocalVarInit[TL]@le +; LARGE64-LABEL: L..C2: +; LARGE64-NEXT: .tc ThreadLocalVarUninit[TE],ThreadLocalVarUninit[TL]@le +; LARGE64-LABEL: L..C3: +; LARGE64-NEXT: .tc ThreadLocalVarInit[TE],ThreadLocalVarInit[TL]@le +; LARGE64-LABEL: L..C4: +; LARGE64-NEXT: .tc VarInit[TE],VarInit[RW] diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-le-xcoff-reloc-large.ll b/llvm/test/CodeGen/PowerPC/aix-tls-le-xcoff-reloc-large.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-tls-le-xcoff-reloc-large.ll @@ -0,0 +1,452 @@ +; RUN: llc -verify-machineinstrs -mcpu=pwr4 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -xcoff-traceback-table=false --code-model=large -filetype=obj -o %t.o < %s +; RUN: llvm-readobj --relocs --expand-relocs %t.o | FileCheck --check-prefix=RELOC %s +; RUN: llvm-readobj --syms %t.o | FileCheck --check-prefix=SYM %s +; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck --check-prefix=DIS %s + +@ThreadLocalVarInit = thread_local(localexec) global i64 1, align 8 +@VarInit = global i64 87, align 8 +@IThreadLocalVarUninit = internal thread_local(localexec) global i64 0, align 8 +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) + +define void @storeITLUninit(i64 noundef %x) { +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @IThreadLocalVarUninit) + store i64 %x, ptr %0, align 8 + ret void +} + +define i64 @loadTLInit() { +entry: + %0 = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @ThreadLocalVarInit) + %1 = load i64, ptr %0, align 8 + %2 = load i64, ptr @VarInit, align 8 + %add = add nsw i64 %2, %1 + ret i64 %add +} + +; RELOC: File: {{.*}}aix-tls-le-xcoff-reloc-large.ll.tmp.o +; RELOC-NEXT: Format: aix5coff64-rs6000 +; RELOC-NEXT: Arch: powerpc64 +; RELOC-NEXT: AddressSize: 64bit +; RELOC-NEXT: Relocations [ +; RELOC-NEXT: Section (index: 1) .text { +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x2 +; RELOC-NEXT: Symbol: IThreadLocalVarUninit (15) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOCU (0x30) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x6 +; RELOC-NEXT: Symbol: IThreadLocalVarUninit (15) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOCL (0x31) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x22 +; RELOC-NEXT: Symbol: ThreadLocalVarInit (17) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOCU (0x30) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x26 +; RELOC-NEXT: Symbol: VarInit (19) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOCU (0x30) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x2A +; RELOC-NEXT: Symbol: ThreadLocalVarInit (17) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOCL (0x31) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x2E +; RELOC-NEXT: Symbol: VarInit (19) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOCL (0x31) +; RELOC-NEXT: } +; RELOC-NEXT: } +; RELOC-NEXT: Section (index: 2) .data { +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x50 +; RELOC-NEXT: Symbol: .storeITLUninit (3) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x58 +; RELOC-NEXT: Symbol: TOC (13) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x68 +; RELOC-NEXT: Symbol: .loadTLInit (5) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x70 +; RELOC-NEXT: Symbol: TOC (13) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x80 +; RELOC-NEXT: Symbol: IThreadLocalVarUninit (23) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_TLS_LE (0x23) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x88 +; RELOC-NEXT: Symbol: ThreadLocalVarInit (21) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_TLS_LE (0x23) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x90 +; RELOC-NEXT: Symbol: VarInit (7) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: } +; RELOC-NEXT: ] + +; SYM: File: {{.*}}aix-tls-le-xcoff-reloc-large.ll.tmp.o +; SYM-NEXT: Format: aix5coff64-rs6000 +; SYM-NEXT: Arch: powerpc64 +; SYM-NEXT: AddressSize: 64bit +; SYM-NEXT: Symbols [ +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 0 +; SYM-NEXT: Name: +; SYM-NEXT: Value (SymbolTableIndex): 0x0 +; SYM-NEXT: Section: N_DEBUG +; SYM-NEXT: Source Language ID: TB_C (0x0) +; SYM-NEXT: CPU Version ID: 0x0 +; SYM-NEXT: StorageClass: C_FILE (0x67) +; SYM-NEXT: NumberOfAuxEntries: 0 +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 1 +; SYM-NEXT: Name: .text +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: .text +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 2 +; SYM-NEXT: SectionLen: 68 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 5 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 3 +; SYM-NEXT: Name: .storeITLUninit +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: .text +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 4 +; SYM-NEXT: ContainingCsectSymbolIndex: 1 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 5 +; SYM-NEXT: Name: .loadTLInit +; SYM-NEXT: Value (RelocatableAddress): 0x20 +; SYM-NEXT: Section: .text +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 6 +; SYM-NEXT: ContainingCsectSymbolIndex: 1 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 7 +; SYM-NEXT: Name: VarInit +; SYM-NEXT: Value (RelocatableAddress): 0x48 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 8 +; SYM-NEXT: SectionLen: 8 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_RW (0x5) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 9 +; SYM-NEXT: Name: storeITLUninit +; SYM-NEXT: Value (RelocatableAddress): 0x50 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 10 +; SYM-NEXT: SectionLen: 24 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_DS (0xA) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 11 +; SYM-NEXT: Name: loadTLInit +; SYM-NEXT: Value (RelocatableAddress): 0x68 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 12 +; SYM-NEXT: SectionLen: 24 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_DS (0xA) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 13 +; SYM-NEXT: Name: TOC +; SYM-NEXT: Value (RelocatableAddress): 0x80 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 14 +; SYM-NEXT: SectionLen: 0 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 2 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TC0 (0xF) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 15 +; SYM-NEXT: Name: IThreadLocalVarUninit +; SYM-NEXT: Value (RelocatableAddress): 0x80 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 16 +; SYM-NEXT: SectionLen: 8 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TE (0x16) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 17 +; SYM-NEXT: Name: ThreadLocalVarInit +; SYM-NEXT: Value (RelocatableAddress): 0x88 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 18 +; SYM-NEXT: SectionLen: 8 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TE (0x16) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 19 +; SYM-NEXT: Name: VarInit +; SYM-NEXT: Value (RelocatableAddress): 0x90 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 20 +; SYM-NEXT: SectionLen: 8 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TE (0x16) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 21 +; SYM-NEXT: Name: ThreadLocalVarInit +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: .tdata +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 22 +; SYM-NEXT: SectionLen: 8 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TL (0x14) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 23 +; SYM-NEXT: Name: IThreadLocalVarUninit +; SYM-NEXT: Value (RelocatableAddress): 0x8 +; SYM-NEXT: Section: .tbss +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 24 +; SYM-NEXT: SectionLen: 8 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_CM (0x3) +; SYM-NEXT: StorageMappingClass: XMC_UL (0x15) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: ] + +; DIS: {{.*}}aix-tls-le-xcoff-reloc-large.ll.tmp.o: file format aix5coff64-rs6000 +; DIS: Disassembly of section .text: +; DIS: 0000000000000000 (idx: 3) .storeITLUninit: +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} addis 4, 2, 0 +; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOCU (idx: 15) IThreadLocalVarUninit[TE] +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} ld 4, 0(4) +; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOCL (idx: 15) IThreadLocalVarUninit[TE] +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 4, 13, 4 +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} std 3, 0(4) +; DIS-NEXT: blr +; DIS: 0000000000000020 (idx: 5) .loadTLInit: +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} addis 3, 2, 0 +; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOCU (idx: 17) ThreadLocalVarInit[TE] +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} addis 4, 2, 0 +; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOCU (idx: 19) VarInit[TE] +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} ld 3, 8(3) +; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOCL (idx: 17) ThreadLocalVarInit[TE] +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} ld 4, 16(4) +; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOCL (idx: 19) VarInit[TE] +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 3, 13, 3 +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} ld 4, 0(4) +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} ld 3, 0(3) +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 3, 4, 3 +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} blr + +; DIS: Disassembly of section .data: +; DIS: 0000000000000048 (idx: 7) VarInit[RW]: +; DIS-NEXT: 48: 00 00 00 00 +; DIS-NEXT: 4c: 00 00 00 57 +; DIS: 0000000000000050 (idx: 9) storeITLUninit[DS]: +; DIS-NEXT: 50: 00 00 00 00 +; DIS-NEXT: 0000000000000050: R_POS (idx: 3) .storeITLUninit +; DIS-NEXT: 54: 00 00 00 00 +; DIS-NEXT: 58: 00 00 00 00 +; DIS-NEXT: 0000000000000058: R_POS (idx: 13) TOC[TC0] +; DIS-NEXT: 5c: 00 00 00 80 +; DIS: 0000000000000068 (idx: 11) loadTLInit[DS]: +; DIS-NEXT: 68: 00 00 00 00 +; DIS-NEXT: 0000000000000068: R_POS (idx: 5) .loadTLInit +; DIS-NEXT: 6c: 00 00 00 20 +; DIS-NEXT: 70: 00 00 00 00 +; DIS-NEXT: 0000000000000070: R_POS (idx: 13) TOC[TC0] +; DIS-NEXT: 74: 00 00 00 80 +; DIS: 0000000000000080 (idx: 15) IThreadLocalVarUninit[TE]: +; DIS-NEXT: 80: 00 00 00 00 +; DIS-NEXT: 0000000000000080: R_TLS_LE (idx: 23) IThreadLocalVarUninit[UL] +; DIS-NEXT: 84: 00 00 00 00 +; DIS: 0000000000000088 (idx: 17) ThreadLocalVarInit[TE]: +; DIS-NEXT: 88: 00 00 00 00 +; DIS-NEXT: 0000000000000088: R_TLS_LE (idx: 21) ThreadLocalVarInit[TL] +; DIS-NEXT: 8c: 00 00 00 00 +; DIS: 0000000000000090 (idx: 19) VarInit[TE]: +; DIS-NEXT: 90: 00 00 00 00 +; DIS-NEXT: 0000000000000090: R_POS (idx: 7) VarInit[RW] +; DIS-NEXT: 94: 00 00 00 48 + +; DIS: Disassembly of section .tdata: +; DIS: 0000000000000000 (idx: 21) ThreadLocalVarInit[TL]: +; DIS-NEXT: 0: 00 00 00 00 +; DIS-NEXT: 4: 00 00 00 01 + +; DIS: Disassembly of section .tbss: +; DIS: 0000000000000008 (idx: 23) IThreadLocalVarUninit[UL]: +; DIS-NEXT: ... + diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-le-xcoff-reloc.ll b/llvm/test/CodeGen/PowerPC/aix-tls-le-xcoff-reloc.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-tls-le-xcoff-reloc.ll @@ -0,0 +1,456 @@ +; RUN: llc -verify-machineinstrs -mcpu=pwr4 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \ +; RUN: -xcoff-traceback-table=false -data-sections=false -filetype=obj -o %t.o < %s +; RUN: llvm-readobj --relocs --expand-relocs %t.o | FileCheck --check-prefix=RELOC %s +; RUN: llvm-readobj --syms %t.o | FileCheck --check-prefix=SYM %s +; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck --check-prefix=DIS %s + +@ThreadLocalVarInit = thread_local(localexec) global i32 1, align 4 +@VarInit = global i32 87, align 4 +@IThreadLocalVarUninit = internal thread_local(localexec) global i32 0, align 4 +declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) + +define void @storeITLUninit(i32 noundef signext %x) { +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @IThreadLocalVarUninit) + store i32 %x, ptr %0, align 4 + ret void +} + +define signext i32 @loadTLInit() { +entry: + %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @ThreadLocalVarInit) + %1 = load i32, ptr %0, align 4 + %2 = load i32, ptr @VarInit, align 4 + %add = add nsw i32 %2, %1 + ret i32 %add +} + +; RELOC: File: {{.*}}aix-tls-le-xcoff-reloc.ll.tmp.o +; RELOC-NEXT: Format: aix5coff64-rs6000 +; RELOC-NEXT: Arch: powerpc64 +; RELOC-NEXT: AddressSize: 64bit +; RELOC-NEXT: Relocations [ +; RELOC-NEXT: Section (index: 1) .text { +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x2 +; RELOC-NEXT: Symbol: IThreadLocalVarUninit (17) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOC (0x3) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x12 +; RELOC-NEXT: Symbol: ThreadLocalVarInit (19) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOC (0x3) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x16 +; RELOC-NEXT: Symbol: VarInit (21) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 16 +; RELOC-NEXT: Type: R_TOC (0x3) +; RELOC-NEXT: } +; RELOC-NEXT: } +; RELOC-NEXT: Section (index: 2) .data { +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x38 +; RELOC-NEXT: Symbol: .storeITLUninit (3) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x40 +; RELOC-NEXT: Symbol: TOC (15) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x50 +; RELOC-NEXT: Symbol: .loadTLInit (5) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x58 +; RELOC-NEXT: Symbol: TOC (15) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x68 +; RELOC-NEXT: Symbol: IThreadLocalVarUninit (27) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_TLS_LE (0x23) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x70 +; RELOC-NEXT: Symbol: ThreadLocalVarInit (25) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_TLS_LE (0x23) +; RELOC-NEXT: } +; RELOC-NEXT: Relocation { +; RELOC-NEXT: Virtual Address: 0x78 +; RELOC-NEXT: Symbol: VarInit (9) +; RELOC-NEXT: IsSigned: No +; RELOC-NEXT: FixupBitValue: 0 +; RELOC-NEXT: Length: 64 +; RELOC-NEXT: Type: R_POS (0x0) +; RELOC-NEXT: } +; RELOC-NEXT: } +; RELOC-NEXT: ] + +; SYM: File: {{.*}}aix-tls-le-xcoff-reloc.ll.tmp.o +; SYM-NEXT: Format: aix5coff64-rs6000 +; SYM-NEXT: Arch: powerpc64 +; SYM-NEXT: AddressSize: 64bit +; SYM-NEXT: Symbols [ +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 0 +; SYM-NEXT: Name: +; SYM-NEXT: Value (SymbolTableIndex): 0x0 +; SYM-NEXT: Section: N_DEBUG +; SYM-NEXT: Source Language ID: TB_C (0x0) +; SYM-NEXT: CPU Version ID: 0x0 +; SYM-NEXT: StorageClass: C_FILE (0x67) +; SYM-NEXT: NumberOfAuxEntries: 0 +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 1 +; SYM-NEXT: Name: .text +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: .text +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 2 +; SYM-NEXT: SectionLen: 48 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 5 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 3 +; SYM-NEXT: Name: .storeITLUninit +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: .text +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 4 +; SYM-NEXT: ContainingCsectSymbolIndex: 1 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 5 +; SYM-NEXT: Name: .loadTLInit +; SYM-NEXT: Value (RelocatableAddress): 0x10 +; SYM-NEXT: Section: .text +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 6 +; SYM-NEXT: ContainingCsectSymbolIndex: 1 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_PR (0x0) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 7 +; SYM-NEXT: Name: .data +; SYM-NEXT: Value (RelocatableAddress): 0x30 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 8 +; SYM-NEXT: SectionLen: 4 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 2 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_RW (0x5) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 9 +; SYM-NEXT: Name: VarInit +; SYM-NEXT: Value (RelocatableAddress): 0x30 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 10 +; SYM-NEXT: ContainingCsectSymbolIndex: 7 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_RW (0x5) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 11 +; SYM-NEXT: Name: storeITLUninit +; SYM-NEXT: Value (RelocatableAddress): 0x38 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 12 +; SYM-NEXT: SectionLen: 24 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_DS (0xA) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 13 +; SYM-NEXT: Name: loadTLInit +; SYM-NEXT: Value (RelocatableAddress): 0x50 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 14 +; SYM-NEXT: SectionLen: 24 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_DS (0xA) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 15 +; SYM-NEXT: Name: TOC +; SYM-NEXT: Value (RelocatableAddress): 0x68 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 16 +; SYM-NEXT: SectionLen: 0 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 2 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TC0 (0xF) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 17 +; SYM-NEXT: Name: IThreadLocalVarUninit +; SYM-NEXT: Value (RelocatableAddress): 0x68 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 18 +; SYM-NEXT: SectionLen: 8 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TC (0x3) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 19 +; SYM-NEXT: Name: ThreadLocalVarInit +; SYM-NEXT: Value (RelocatableAddress): 0x70 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 20 +; SYM-NEXT: SectionLen: 8 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TC (0x3) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 21 +; SYM-NEXT: Name: VarInit +; SYM-NEXT: Value (RelocatableAddress): 0x78 +; SYM-NEXT: Section: .data +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 22 +; SYM-NEXT: SectionLen: 8 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 3 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TC (0x3) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 23 +; SYM-NEXT: Name: .tdata +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: .tdata +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 24 +; SYM-NEXT: SectionLen: 4 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 2 +; SYM-NEXT: SymbolType: XTY_SD (0x1) +; SYM-NEXT: StorageMappingClass: XMC_TL (0x14) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 25 +; SYM-NEXT: Name: ThreadLocalVarInit +; SYM-NEXT: Value (RelocatableAddress): 0x0 +; SYM-NEXT: Section: .tdata +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_EXT (0x2) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 26 +; SYM-NEXT: ContainingCsectSymbolIndex: 23 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 0 +; SYM-NEXT: SymbolType: XTY_LD (0x2) +; SYM-NEXT: StorageMappingClass: XMC_TL (0x14) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: Symbol { +; SYM-NEXT: Index: 27 +; SYM-NEXT: Name: IThreadLocalVarUninit +; SYM-NEXT: Value (RelocatableAddress): 0x4 +; SYM-NEXT: Section: .tbss +; SYM-NEXT: Type: 0x0 +; SYM-NEXT: StorageClass: C_HIDEXT (0x6B) +; SYM-NEXT: NumberOfAuxEntries: 1 +; SYM-NEXT: CSECT Auxiliary Entry { +; SYM-NEXT: Index: 28 +; SYM-NEXT: SectionLen: 4 +; SYM-NEXT: ParameterHashIndex: 0x0 +; SYM-NEXT: TypeChkSectNum: 0x0 +; SYM-NEXT: SymbolAlignmentLog2: 2 +; SYM-NEXT: SymbolType: XTY_CM (0x3) +; SYM-NEXT: StorageMappingClass: XMC_UL (0x15) +; SYM-NEXT: Auxiliary Type: AUX_CSECT (0xFB) +; SYM-NEXT: } +; SYM-NEXT: } +; SYM-NEXT: ] + +; DIS: {{.*}}aix-tls-le-xcoff-reloc.ll.tmp.o: file format aix5coff64-rs6000 +; DIS: Disassembly of section .text: +; DIS: 0000000000000000 (idx: 3) .storeITLUninit: +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} ld 4, 0(2) +; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOC (idx: 17) IThreadLocalVarUninit[TC] +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 4, 13, 4 +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} stw 3, 0(4) +; DIS-NEXT: blr +; DIS: 0000000000000010 (idx: 5) .loadTLInit: +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} ld 3, 8(2) +; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOC (idx: 19) ThreadLocalVarInit[TC] +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} ld 4, 16(2) +; DIS-NEXT: {{0*}}[[#ADDR + 2]]: R_TOC (idx: 21) VarInit[TC] +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 3, 13, 3 +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} lwz 4, 0(4) +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} lwz 3, 0(3) +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} add 3, 4, 3 +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} extsw 3, 3 +; DIS-NEXT: [[#%x, ADDR:]]: {{.*}} blr + +; DIS: Disassembly of section .data: +; DIS: 0000000000000030 (idx: 9) VarInit: +; DIS-NEXT: 30: 00 00 00 57 +; DIS: 0000000000000038 (idx: 11) storeITLUninit[DS]: +; DIS-NEXT: 8: 00 00 00 00 +; DIS-NEXT: 0000000000000038: R_POS (idx: 3) .storeITLUninit +; DIS-NEXT: 3c: 00 00 00 00 +; DIS-NEXT: 40: 00 00 00 00 +; DIS-NEXT: 0000000000000040: R_POS (idx: 15) TOC[TC0] +; DIS-NEXT: 44: 00 00 00 68 +; DIS: 0000000000000050 (idx: 13) loadTLInit[DS]: +; DIS-NEXT: 50: 00 00 00 00 +; DIS-NEXT: 0000000000000050: R_POS (idx: 5) .loadTLInit +; DIS-NEXT: 54: 00 00 00 10 +; DIS-NEXT: 58: 00 00 00 00 +; DIS-NEXT: 0000000000000058: R_POS (idx: 15) TOC[TC0] +; DIS-NEXT: 5c: 00 00 00 68 +; DIS: 0000000000000068 (idx: 17) IThreadLocalVarUninit[TC]: +; DIS-NEXT: 68: 00 00 00 00 +; DIS-NEXT: 0000000000000068: R_TLS_LE (idx: 27) IThreadLocalVarUninit[UL] +; DIS: 0000000000000070 (idx: 19) ThreadLocalVarInit[TC]: +; DIS-NEXT: 70: 00 00 00 00 +; DIS-NEXT: 0000000000000070: R_TLS_LE (idx: 25) ThreadLocalVarInit +; DIS: 0000000000000078 (idx: 21) VarInit[TC]: +; DIS-NEXT: 78: 00 00 00 00 +; DIS-NEXT: 0000000000000078: R_POS (idx: 9) VarInit + +; DIS: Disassembly of section .tdata: +; DIS: 0000000000000000 (idx: 25) ThreadLocalVarInit: +; DIS-NEXT: 0: 00 00 00 01 + +; DIS: Disassembly of section .tbss: +; DIS: 0000000000000004 (idx: 27) IThreadLocalVarUninit[UL]: +; DIS-NEXT: ... +