[llvm] 21bea1a - [PowerPC] Support initial-exec TLS relocation on AIX
Qiu Chaofan via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 30 01:28:44 PDT 2023
Author: Qiu Chaofan
Date: 2023-08-30T16:22:16+08:00
New Revision: 21bea1a208692f26a7112b9f0f46edb21d706023
URL: https://github.com/llvm/llvm-project/commit/21bea1a208692f26a7112b9f0f46edb21d706023
DIFF: https://github.com/llvm/llvm-project/commit/21bea1a208692f26a7112b9f0f46edb21d706023.diff
LOG: [PowerPC] Support initial-exec TLS relocation on AIX
Add TLS_IE relocation type to XCOFF writer, and emit code sequence for
initial-exec TLS variables.
Reviewed By: lkail
Differential Revision: https://reviews.llvm.org/D156292
Added:
llvm/test/CodeGen/PowerPC/aix-tls-ie-ldst.ll
llvm/test/CodeGen/PowerPC/aix-tls-ie-xcoff-reloc.ll
Modified:
llvm/include/llvm/MC/MCExpr.h
llvm/lib/MC/MCExpr.cpp
llvm/lib/MC/XCOFFObjectWriter.cpp
llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
llvm/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/lib/Target/PowerPC/PPCISelLowering.h
llvm/lib/Target/PowerPC/PPCInstr64Bit.td
llvm/lib/Target/PowerPC/PPCInstrInfo.td
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h
index 5bc5e04f79ffc3..67836292874f5f 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -299,6 +299,7 @@ class MCSymbolRefExpr : public MCExpr {
VK_PPC_TLSGD, // symbol at tlsgd
VK_PPC_AIX_TLSGD, // symbol at gd
VK_PPC_AIX_TLSGDM, // symbol at m
+ VK_PPC_AIX_TLSIE, // symbol at ie
VK_PPC_AIX_TLSLE, // symbol at le
VK_PPC_GOT_TLSLD, // symbol at got@tlsld
VK_PPC_GOT_TLSLD_LO, // symbol at got@tlsld at l
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index 392bc200ef30b4..73e6569f96e463 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -327,6 +327,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
return "gd";
case VK_PPC_AIX_TLSGDM:
return "m";
+ case VK_PPC_AIX_TLSIE:
+ return "ie";
case VK_PPC_AIX_TLSLE:
return "le";
case VK_PPC_GOT_TLSLD: return "got at tlsld";
diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp
index 036210d6b0efa2..2e8898cb6c5b38 100644
--- a/llvm/lib/MC/XCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/XCOFFObjectWriter.cpp
@@ -697,7 +697,8 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
const uint32_t Index = getIndex(SymA, SymASec);
if (Type == XCOFF::RelocationType::R_POS ||
Type == XCOFF::RelocationType::R_TLS ||
- Type == XCOFF::RelocationType::R_TLS_LE)
+ Type == XCOFF::RelocationType::R_TLS_LE ||
+ Type == XCOFF::RelocationType::R_TLS_IE)
// The FixedValue should be symbol's virtual address in this object file
// plus any constant value that we might get.
FixedValue = getVirtualAddress(SymA, SymASec) + Target.getConstant();
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index 271f7ab757e164..3a1bda31282799 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -148,9 +148,10 @@ class PPCTargetAsmStreamer : public PPCTargetStreamer {
cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly())
->getQualNameSymbol();
// On AIX, we have a region handle (symbol at m) and the variable offset
- // (symbol@{gd|le}) for TLS variables, depending on the TLS model.
+ // (symbol@{gd|ie|le}) 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)
OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
<< MCSymbolRefExpr::getVariantKindName(Kind) << '\n';
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
index df671f53cbd8ce..ffdbfc4ddb0134 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFObjectWriter.cpp
@@ -108,6 +108,8 @@ std::pair<uint8_t, uint8_t> PPCXCOFFObjectWriter::getRelocTypeAndSignSize(
return {XCOFF::RelocationType::R_TLS, SignAndSizeForFKData};
case MCSymbolRefExpr::VK_PPC_AIX_TLSGDM:
return {XCOFF::RelocationType::R_TLSM, SignAndSizeForFKData};
+ case MCSymbolRefExpr::VK_PPC_AIX_TLSIE:
+ return {XCOFF::RelocationType::R_TLS_IE, SignAndSizeForFKData};
case MCSymbolRefExpr::VK_PPC_AIX_TLSLE:
return {XCOFF::RelocationType::R_TLS_LE, SignAndSizeForFKData};
case MCSymbolRefExpr::VK_None:
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 37eb38363838f3..0e1d5911294eac 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -826,17 +826,17 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
return Expr;
};
auto GetVKForMO = [&](const MachineOperand &MO) {
- // For TLS local-exec accesses on AIX, we have one TOC entry for the symbol
- // (with the variable offset), which is
diff erentiated by MO_TPREL_FLAG.
+ // For TLS initial-exec and local-exec accesses on AIX, we have one TOC
+ // entry for the symbol (with the variable offset), which is
diff erentiated
+ // 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");
TLSModel::Model Model = TM.getTLSModel(MO.getGlobal());
if (Model == TLSModel::LocalExec)
return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;
- llvm_unreachable("Only expecting local-exec accesses!");
+ if (Model == TLSModel::InitialExec)
+ return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
+ llvm_unreachable("Only expecting local-exec or initial-exec accesses!");
}
// 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
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 0f15ad12db19eb..384e437cf5d366 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3336,22 +3336,22 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
bool Is64Bit = Subtarget.isPPC64();
TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
- if (Model == TLSModel::LocalExec) {
+ if (Model == TLSModel::LocalExec || Model == TLSModel::InitialExec) {
SDValue VariableOffsetTGA =
DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, PPCII::MO_TPREL_FLAG);
SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
SDValue TLSReg;
if (Is64Bit)
- // For local-exec on AIX (64-bit), the sequence that is generated involves
- // a load of the variable offset (from the TOC), followed by an add of the
- // loaded variable offset to R13 (the thread pointer).
+ // For local-exec and initial-exec on AIX (64-bit), the sequence generated
+ // involves a load of the variable offset (from the TOC), followed by an
+ // add of the loaded variable offset to R13 (the thread pointer).
// This code sequence looks like:
// ld reg1,var[TC](2)
// add reg2, reg1, r13 // r13 contains the thread pointer
TLSReg = DAG.getRegister(PPC::X13, MVT::i64);
else
- // For local-exec on AIX (32-bit), the sequence that is generated involves
- // loading the variable offset from the TOC, generating a call to
+ // For local-exec and initial-exec on AIX (32-bit), the sequence generated
+ // involves loading the variable offset from the TOC, generating a call to
// .__get_tpointer to get the thread pointer (which will be in R3), and
// adding the two together:
// lwz reg1,var[TC](2)
@@ -3361,9 +3361,9 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
}
- // The Local-Exec and General-Dynamic TLS models are currently the only
- // supported access models. If Local-exec is not possible or specified, all
- // GlobalTLSAddress nodes are lowered using the general-dynamic model.
+ // 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
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index e6ebc68008fb7b..6ef2d607ff9d3b 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -356,9 +356,9 @@ namespace llvm {
/// ADDIS_TLSGD_L_ADDR until after register assignment.
GET_TLS_ADDR,
- /// %x3 = GET_TPOINTER - Used for the local-exec TLS model on 32-bit AIX,
- /// produces a call to .__get_tpointer to retrieve the thread pointer
- /// At the end of the call, the thread pointer is found in R3.
+ /// %x3 = GET_TPOINTER - Used for the local- and initial-exec TLS model on
+ /// 32-bit AIX, produces a call to .__get_tpointer to retrieve the thread
+ /// pointer. At the end of the call, the thread pointer is found in R3.
GET_TPOINTER,
/// G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that
diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index fd44efa1b3f4ec..7067239dd92802 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -1958,8 +1958,8 @@ def : Pat<(add i64:$in, (PPChi tblockaddress:$g, 0)),
def : Pat<(i64 (PPCtoc_entry tglobaltlsaddr:$disp, i64:$reg)),
(i64 (LDtoc tglobaltlsaddr:$disp, i64:$reg))>;
-// The following pattern matches 64-bit local-exec TLS accesses on AIX.
-// PPCaddTls is used in local-exec accesses in order to:
+// The following pattern matches 64-bit local- and initial-exec TLS accesses on AIX.
+// PPCaddTls is used in local- and initial-exec accesses in order to:
// - Get the address of a variable (adding the variable offset to the thread
// pointer in r13).
// - Create an opportunity to optimize the user of the loaded address.
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 2992f78aa38ad7..4a8e36e8d242fe 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -3251,8 +3251,8 @@ def GETtlsTpointer32AIX : PPCEmitTimePseudo<(outs gprc:$rD), (ins),
"GETtlsTpointer32AIX",
[(set i32:$rD, (PPCgetTpointer))]>;
-// The following pattern matches local-exec TLS accesses on 32-bit AIX.
-// PPCaddTls is used in local-exec accesses in order to:
+// The following pattern matches local- and initial-exec TLS accesses on 32-bit AIX.
+// PPCaddTls is used in local- and initial-exec accesses in order to:
// - Get the address of a variable (add the variable offset to the thread
// pointer, retrieved by calling .__get_tpointer).
// - Create an opportunity to optimize the user of the loaded address.
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-ie-ldst.ll b/llvm/test/CodeGen/PowerPC/aix-tls-ie-ldst.ll
new file mode 100644
index 00000000000000..adfdc94e764005
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-ie-ldst.ll
@@ -0,0 +1,1690 @@
+; 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 -code-model=large < %s | \
+; RUN: FileCheck %s -check-prefix=LARGE64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \
+; RUN: -mtriple powerpc64-ibm-aix-xcoff -code-model=small < %s | \
+; RUN: FileCheck %s -check-prefix=SMALL64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \
+; RUN: -mtriple powerpc-ibm-aix-xcoff -code-model=large < %s | \
+; RUN: FileCheck %s -check-prefix=LARGE32
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -ppc-asm-full-reg-names \
+; RUN: -mtriple powerpc-ibm-aix-xcoff -code-model=small < %s | \
+; RUN: FileCheck %s -check-prefix=SMALL32
+
+ at global_int_zero = thread_local(initialexec) global i32 0, align 4
+ at global_int_nonzero = thread_local(initialexec) global i32 1, align 4
+ at intern_int_zero = internal thread_local(initialexec) global i32 0, align 4
+ at intern_int_nonzero = internal thread_local(initialexec) global i32 1, align 4
+
+ at global_long_zero = thread_local(initialexec) global i64 0, align 8
+ at global_long_nonzero = thread_local(initialexec) global i64 1, align 8
+ at intern_long_zero = internal thread_local(initialexec) global i64 0, align 8
+ at intern_long_nonzero = internal thread_local(initialexec) global i64 1, align 8
+
+ at global_float_zero = thread_local(initialexec) global float 0.000000, align 4
+ at global_float_nonzero = thread_local(initialexec) global float 1.000000, align 4
+ at intern_float_zero = internal thread_local(initialexec) global float 0.000000, align 4
+ at intern_float_nonzero = internal thread_local(initialexec) global float 1.000000, align 4
+
+ at global_double_zero = thread_local(initialexec) global double 0.000000, align 8
+ at global_double_nonzero = thread_local(initialexec) global double 1.000000, align 8
+ at intern_double_zero = internal thread_local(initialexec) global double 0.000000, align 8
+ at intern_double_nonzero = internal thread_local(initialexec) global double 1.000000, align 8
+
+define void @store_global_int_zero(i32 noundef signext %i) {
+; LARGE64-LABEL: store_global_int_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r4, L..C0 at u(r2)
+; LARGE64-NEXT: ld r4, L..C0 at l(r4)
+; LARGE64-NEXT: stwx r3, r13, r4
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_global_int_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r4, L..C0(r2) # target-flags(ppc-tprel) @global_int_zero
+; SMALL64-NEXT: stwx r3, r13, r4
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_global_int_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: mr r4, r3
+; LARGE32-NEXT: addis r3, L..C0 at u(r2)
+; LARGE32-NEXT: lwz r5, L..C0 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stwx r4, r3, r5
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_global_int_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r5, L..C0(r2) # target-flags(ppc-tprel) @global_int_zero
+; SMALL32-NEXT: mr r4, r3
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stwx r4, r3, r5
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @global_int_zero)
+ store i32 %i, ptr %addr, align 4
+ ret void
+}
+
+define void @store_global_int_nonzero(i32 noundef signext %i) {
+; LARGE64-LABEL: store_global_int_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r4, L..C1 at u(r2)
+; LARGE64-NEXT: ld r4, L..C1 at l(r4)
+; LARGE64-NEXT: stwx r3, r13, r4
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_global_int_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r4, L..C1(r2) # target-flags(ppc-tprel) @global_int_nonzero
+; SMALL64-NEXT: stwx r3, r13, r4
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_global_int_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: mr r4, r3
+; LARGE32-NEXT: addis r3, L..C1 at u(r2)
+; LARGE32-NEXT: lwz r5, L..C1 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stwx r4, r3, r5
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_global_int_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r5, L..C1(r2) # target-flags(ppc-tprel) @global_int_nonzero
+; SMALL32-NEXT: mr r4, r3
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stwx r4, r3, r5
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @global_int_nonzero)
+ store i32 %i, ptr %addr, align 4
+ ret void
+}
+
+define void @store_intern_int_zero(i32 noundef signext %i) {
+; LARGE64-LABEL: store_intern_int_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r4, L..C2 at u(r2)
+; LARGE64-NEXT: ld r4, L..C2 at l(r4)
+; LARGE64-NEXT: stwx r3, r13, r4
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_intern_int_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r4, L..C2(r2) # target-flags(ppc-tprel) @intern_int_zero
+; SMALL64-NEXT: stwx r3, r13, r4
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_intern_int_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: mr r4, r3
+; LARGE32-NEXT: addis r3, L..C2 at u(r2)
+; LARGE32-NEXT: lwz r5, L..C2 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stwx r4, r3, r5
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_intern_int_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r5, L..C2(r2) # target-flags(ppc-tprel) @intern_int_zero
+; SMALL32-NEXT: mr r4, r3
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stwx r4, r3, r5
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_int_zero)
+ store i32 %i, ptr %addr, align 4
+ ret void
+}
+
+define void @store_intern_int_nonzero(i32 noundef signext %i) {
+; LARGE64-LABEL: store_intern_int_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r4, L..C3 at u(r2)
+; LARGE64-NEXT: ld r4, L..C3 at l(r4)
+; LARGE64-NEXT: stwx r3, r13, r4
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_intern_int_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r4, L..C3(r2) # target-flags(ppc-tprel) @intern_int_nonzero
+; SMALL64-NEXT: stwx r3, r13, r4
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_intern_int_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: mr r4, r3
+; LARGE32-NEXT: addis r3, L..C3 at u(r2)
+; LARGE32-NEXT: lwz r5, L..C3 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stwx r4, r3, r5
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_intern_int_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r5, L..C3(r2) # target-flags(ppc-tprel) @intern_int_nonzero
+; SMALL32-NEXT: mr r4, r3
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stwx r4, r3, r5
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_int_nonzero)
+ store i32 %i, ptr %addr, align 4
+ ret void
+}
+
+define signext i32 @load_global_int_zero() {
+; LARGE64-LABEL: load_global_int_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C0 at u(r2)
+; LARGE64-NEXT: ld r3, L..C0 at l(r3)
+; LARGE64-NEXT: lwax r3, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_global_int_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C0(r2) # target-flags(ppc-tprel) @global_int_zero
+; SMALL64-NEXT: lwax r3, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_global_int_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C0 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C0 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lwzx r3, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_global_int_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C0(r2) # target-flags(ppc-tprel) @global_int_zero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lwzx r3, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @global_int_zero)
+ %val = load i32, ptr %addr, align 4
+ ret i32 %val
+}
+
+define signext i32 @load_global_int_nonzero() {
+; LARGE64-LABEL: load_global_int_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C1 at u(r2)
+; LARGE64-NEXT: ld r3, L..C1 at l(r3)
+; LARGE64-NEXT: lwax r3, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_global_int_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C1(r2) # target-flags(ppc-tprel) @global_int_nonzero
+; SMALL64-NEXT: lwax r3, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_global_int_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C1 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C1 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lwzx r3, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_global_int_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C1(r2) # target-flags(ppc-tprel) @global_int_nonzero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lwzx r3, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @global_int_nonzero)
+ %val = load i32, ptr %addr, align 4
+ ret i32 %val
+}
+
+define signext i32 @load_intern_int_zero() {
+; LARGE64-LABEL: load_intern_int_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C2 at u(r2)
+; LARGE64-NEXT: ld r3, L..C2 at l(r3)
+; LARGE64-NEXT: lwax r3, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_intern_int_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C2(r2) # target-flags(ppc-tprel) @intern_int_zero
+; SMALL64-NEXT: lwax r3, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_intern_int_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C2 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C2 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lwzx r3, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_intern_int_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C2(r2) # target-flags(ppc-tprel) @intern_int_zero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lwzx r3, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_int_zero)
+ %val = load i32, ptr %addr, align 4
+ ret i32 %val
+}
+
+define signext i32 @load_intern_int_nonzero() {
+; LARGE64-LABEL: load_intern_int_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C3 at u(r2)
+; LARGE64-NEXT: ld r3, L..C3 at l(r3)
+; LARGE64-NEXT: lwax r3, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_intern_int_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C3(r2) # target-flags(ppc-tprel) @intern_int_nonzero
+; SMALL64-NEXT: lwax r3, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_intern_int_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C3 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C3 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lwzx r3, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_intern_int_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C3(r2) # target-flags(ppc-tprel) @intern_int_nonzero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lwzx r3, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_int_nonzero)
+ %val = load i32, ptr %addr, align 4
+ ret i32 %val
+}
+
+define void @store_global_long_zero(i64 noundef %i) {
+; LARGE64-LABEL: store_global_long_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r4, L..C4 at u(r2)
+; LARGE64-NEXT: ld r4, L..C4 at l(r4)
+; LARGE64-NEXT: stdx r3, r13, r4
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_global_long_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r4, L..C4(r2) # target-flags(ppc-tprel) @global_long_zero
+; SMALL64-NEXT: stdx r3, r13, r4
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_global_long_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: mr r5, r3
+; LARGE32-NEXT: addis r3, L..C4 at u(r2)
+; LARGE32-NEXT: lwz r6, L..C4 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: add r3, r3, r6
+; LARGE32-NEXT: stw r4, 4(r3)
+; LARGE32-NEXT: stw r5, 0(r3)
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_global_long_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r6, L..C4(r2) # target-flags(ppc-tprel) @global_long_zero
+; SMALL32-NEXT: mr r5, r3
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: add r3, r3, r6
+; SMALL32-NEXT: stw r4, 4(r3)
+; SMALL32-NEXT: stw r5, 0(r3)
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @global_long_zero)
+ store i64 %i, ptr %addr, align 8
+ ret void
+}
+
+define void @store_global_long_nonzero(i64 noundef %i) {
+; LARGE64-LABEL: store_global_long_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r4, L..C5 at u(r2)
+; LARGE64-NEXT: ld r4, L..C5 at l(r4)
+; LARGE64-NEXT: stdx r3, r13, r4
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_global_long_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r4, L..C5(r2) # target-flags(ppc-tprel) @global_long_nonzero
+; SMALL64-NEXT: stdx r3, r13, r4
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_global_long_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: mr r5, r3
+; LARGE32-NEXT: addis r3, L..C5 at u(r2)
+; LARGE32-NEXT: lwz r6, L..C5 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: add r3, r3, r6
+; LARGE32-NEXT: stw r4, 4(r3)
+; LARGE32-NEXT: stw r5, 0(r3)
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_global_long_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r6, L..C5(r2) # target-flags(ppc-tprel) @global_long_nonzero
+; SMALL32-NEXT: mr r5, r3
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: add r3, r3, r6
+; SMALL32-NEXT: stw r4, 4(r3)
+; SMALL32-NEXT: stw r5, 0(r3)
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @global_long_nonzero)
+ store i64 %i, ptr %addr, align 8
+ ret void
+}
+
+define void @store_intern_long_zero(i64 noundef %i) {
+; LARGE64-LABEL: store_intern_long_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r4, L..C6 at u(r2)
+; LARGE64-NEXT: ld r4, L..C6 at l(r4)
+; LARGE64-NEXT: stdx r3, r13, r4
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_intern_long_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r4, L..C6(r2) # target-flags(ppc-tprel) @intern_long_zero
+; SMALL64-NEXT: stdx r3, r13, r4
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_intern_long_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: mr r5, r3
+; LARGE32-NEXT: addis r3, L..C6 at u(r2)
+; LARGE32-NEXT: lwz r6, L..C6 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: add r3, r3, r6
+; LARGE32-NEXT: stw r4, 4(r3)
+; LARGE32-NEXT: stw r5, 0(r3)
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_intern_long_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r6, L..C6(r2) # target-flags(ppc-tprel) @intern_long_zero
+; SMALL32-NEXT: mr r5, r3
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: add r3, r3, r6
+; SMALL32-NEXT: stw r4, 4(r3)
+; SMALL32-NEXT: stw r5, 0(r3)
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @intern_long_zero)
+ store i64 %i, ptr %addr, align 8
+ ret void
+}
+
+define void @store_intern_long_nonzero(i64 noundef %i) {
+; LARGE64-LABEL: store_intern_long_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r4, L..C7 at u(r2)
+; LARGE64-NEXT: ld r4, L..C7 at l(r4)
+; LARGE64-NEXT: stdx r3, r13, r4
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_intern_long_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r4, L..C7(r2) # target-flags(ppc-tprel) @intern_long_nonzero
+; SMALL64-NEXT: stdx r3, r13, r4
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_intern_long_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: mr r5, r3
+; LARGE32-NEXT: addis r3, L..C7 at u(r2)
+; LARGE32-NEXT: lwz r6, L..C7 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: add r3, r3, r6
+; LARGE32-NEXT: stw r4, 4(r3)
+; LARGE32-NEXT: stw r5, 0(r3)
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_intern_long_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r6, L..C7(r2) # target-flags(ppc-tprel) @intern_long_nonzero
+; SMALL32-NEXT: mr r5, r3
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: add r3, r3, r6
+; SMALL32-NEXT: stw r4, 4(r3)
+; SMALL32-NEXT: stw r5, 0(r3)
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @intern_long_nonzero)
+ store i64 %i, ptr %addr, align 8
+ ret void
+}
+
+define i64 @load_global_long_zero() {
+; LARGE64-LABEL: load_global_long_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C4 at u(r2)
+; LARGE64-NEXT: ld r3, L..C4 at l(r3)
+; LARGE64-NEXT: ldx r3, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_global_long_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C4(r2) # target-flags(ppc-tprel) @global_long_zero
+; SMALL64-NEXT: ldx r3, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_global_long_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C4 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C4 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: add r4, r3, r4
+; LARGE32-NEXT: lwz r3, 0(r4)
+; LARGE32-NEXT: lwz r4, 4(r4)
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_global_long_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C4(r2) # target-flags(ppc-tprel) @global_long_zero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: add r4, r3, r4
+; SMALL32-NEXT: lwz r3, 0(r4)
+; SMALL32-NEXT: lwz r4, 4(r4)
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @global_long_zero)
+ %val = load i64, ptr %addr, align 8
+ ret i64 %val
+}
+
+define i64 @load_global_long_nonzero() {
+; LARGE64-LABEL: load_global_long_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C5 at u(r2)
+; LARGE64-NEXT: ld r3, L..C5 at l(r3)
+; LARGE64-NEXT: ldx r3, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_global_long_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C5(r2) # target-flags(ppc-tprel) @global_long_nonzero
+; SMALL64-NEXT: ldx r3, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_global_long_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C5 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C5 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: add r4, r3, r4
+; LARGE32-NEXT: lwz r3, 0(r4)
+; LARGE32-NEXT: lwz r4, 4(r4)
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_global_long_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C5(r2) # target-flags(ppc-tprel) @global_long_nonzero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: add r4, r3, r4
+; SMALL32-NEXT: lwz r3, 0(r4)
+; SMALL32-NEXT: lwz r4, 4(r4)
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @global_long_nonzero)
+ %val = load i64, ptr %addr, align 8
+ ret i64 %val
+}
+
+define i64 @load_intern_long_zero() {
+; LARGE64-LABEL: load_intern_long_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C6 at u(r2)
+; LARGE64-NEXT: ld r3, L..C6 at l(r3)
+; LARGE64-NEXT: ldx r3, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_intern_long_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C6(r2) # target-flags(ppc-tprel) @intern_long_zero
+; SMALL64-NEXT: ldx r3, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_intern_long_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C6 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C6 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: add r4, r3, r4
+; LARGE32-NEXT: lwz r3, 0(r4)
+; LARGE32-NEXT: lwz r4, 4(r4)
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_intern_long_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C6(r2) # target-flags(ppc-tprel) @intern_long_zero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: add r4, r3, r4
+; SMALL32-NEXT: lwz r3, 0(r4)
+; SMALL32-NEXT: lwz r4, 4(r4)
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @intern_long_zero)
+ %val = load i64, ptr %addr, align 8
+ ret i64 %val
+}
+
+define i64 @load_intern_long_nonzero() {
+; LARGE64-LABEL: load_intern_long_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C7 at u(r2)
+; LARGE64-NEXT: ld r3, L..C7 at l(r3)
+; LARGE64-NEXT: ldx r3, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_intern_long_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C7(r2) # target-flags(ppc-tprel) @intern_long_nonzero
+; SMALL64-NEXT: ldx r3, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_intern_long_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C7 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C7 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: add r4, r3, r4
+; LARGE32-NEXT: lwz r3, 0(r4)
+; LARGE32-NEXT: lwz r4, 4(r4)
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_intern_long_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C7(r2) # target-flags(ppc-tprel) @intern_long_nonzero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: add r4, r3, r4
+; SMALL32-NEXT: lwz r3, 0(r4)
+; SMALL32-NEXT: lwz r4, 4(r4)
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @intern_long_nonzero)
+ %val = load i64, ptr %addr, align 8
+ ret i64 %val
+}
+
+define void @store_global_float_zero(float noundef %i) {
+; LARGE64-LABEL: store_global_float_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C8 at u(r2)
+; LARGE64-NEXT: ld r3, L..C8 at l(r3)
+; LARGE64-NEXT: stfsx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_global_float_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C8(r2) # target-flags(ppc-tprel) @global_float_zero
+; SMALL64-NEXT: stfsx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_global_float_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C8 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C8 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stfsx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_global_float_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C8(r2) # target-flags(ppc-tprel) @global_float_zero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stfsx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @global_float_zero)
+ store float %i, ptr %addr, align 4
+ ret void
+}
+
+define void @store_global_float_nonzero(float noundef %i) {
+; LARGE64-LABEL: store_global_float_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C9 at u(r2)
+; LARGE64-NEXT: ld r3, L..C9 at l(r3)
+; LARGE64-NEXT: stfsx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_global_float_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C9(r2) # target-flags(ppc-tprel) @global_float_nonzero
+; SMALL64-NEXT: stfsx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_global_float_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C9 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C9 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stfsx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_global_float_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C9(r2) # target-flags(ppc-tprel) @global_float_nonzero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stfsx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @global_float_nonzero)
+ store float %i, ptr %addr, align 4
+ ret void
+}
+
+define void @store_intern_float_zero(float noundef %i) {
+; LARGE64-LABEL: store_intern_float_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C10 at u(r2)
+; LARGE64-NEXT: ld r3, L..C10 at l(r3)
+; LARGE64-NEXT: stfsx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_intern_float_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C10(r2) # target-flags(ppc-tprel) @intern_float_zero
+; SMALL64-NEXT: stfsx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_intern_float_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C10 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C10 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stfsx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_intern_float_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C10(r2) # target-flags(ppc-tprel) @intern_float_zero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stfsx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_float_zero)
+ store float %i, ptr %addr, align 4
+ ret void
+}
+
+define void @store_intern_float_nonzero(float noundef %i) {
+; LARGE64-LABEL: store_intern_float_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C11 at u(r2)
+; LARGE64-NEXT: ld r3, L..C11 at l(r3)
+; LARGE64-NEXT: stfsx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_intern_float_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C11(r2) # target-flags(ppc-tprel) @intern_float_nonzero
+; SMALL64-NEXT: stfsx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_intern_float_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C11 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C11 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stfsx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_intern_float_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C11(r2) # target-flags(ppc-tprel) @intern_float_nonzero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stfsx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_float_nonzero)
+ store float %i, ptr %addr, align 4
+ ret void
+}
+
+define float @load_global_float_zero() {
+; LARGE64-LABEL: load_global_float_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C8 at u(r2)
+; LARGE64-NEXT: ld r3, L..C8 at l(r3)
+; LARGE64-NEXT: lfsx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_global_float_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C8(r2) # target-flags(ppc-tprel) @global_float_zero
+; SMALL64-NEXT: lfsx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_global_float_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C8 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C8 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lfsx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_global_float_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C8(r2) # target-flags(ppc-tprel) @global_float_zero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lfsx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @global_float_zero)
+ %val = load float, ptr %addr, align 4
+ ret float %val
+}
+
+define float @load_global_float_nonzero() {
+; LARGE64-LABEL: load_global_float_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C9 at u(r2)
+; LARGE64-NEXT: ld r3, L..C9 at l(r3)
+; LARGE64-NEXT: lfsx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_global_float_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C9(r2) # target-flags(ppc-tprel) @global_float_nonzero
+; SMALL64-NEXT: lfsx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_global_float_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C9 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C9 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lfsx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_global_float_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C9(r2) # target-flags(ppc-tprel) @global_float_nonzero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lfsx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @global_float_nonzero)
+ %val = load float, ptr %addr, align 4
+ ret float %val
+}
+
+define float @load_intern_float_zero() {
+; LARGE64-LABEL: load_intern_float_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C10 at u(r2)
+; LARGE64-NEXT: ld r3, L..C10 at l(r3)
+; LARGE64-NEXT: lfsx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_intern_float_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C10(r2) # target-flags(ppc-tprel) @intern_float_zero
+; SMALL64-NEXT: lfsx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_intern_float_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C10 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C10 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lfsx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_intern_float_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C10(r2) # target-flags(ppc-tprel) @intern_float_zero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lfsx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_float_zero)
+ %val = load float, ptr %addr, align 4
+ ret float %val
+}
+
+define float @load_intern_float_nonzero() {
+; LARGE64-LABEL: load_intern_float_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C11 at u(r2)
+; LARGE64-NEXT: ld r3, L..C11 at l(r3)
+; LARGE64-NEXT: lfsx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_intern_float_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C11(r2) # target-flags(ppc-tprel) @intern_float_nonzero
+; SMALL64-NEXT: lfsx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_intern_float_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C11 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C11 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lfsx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_intern_float_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C11(r2) # target-flags(ppc-tprel) @intern_float_nonzero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lfsx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_float_nonzero)
+ %val = load float, ptr %addr, align 4
+ ret float %val
+}
+
+define void @store_global_double_zero(double noundef %i) {
+; LARGE64-LABEL: store_global_double_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C12 at u(r2)
+; LARGE64-NEXT: ld r3, L..C12 at l(r3)
+; LARGE64-NEXT: stfdx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_global_double_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C12(r2) # target-flags(ppc-tprel) @global_double_zero
+; SMALL64-NEXT: stfdx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_global_double_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C12 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C12 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stfdx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_global_double_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C12(r2) # target-flags(ppc-tprel) @global_double_zero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stfdx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @global_double_zero)
+ store double %i, ptr %addr, align 8
+ ret void
+}
+
+define void @store_global_double_nonzero(double noundef %i) {
+; LARGE64-LABEL: store_global_double_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C13 at u(r2)
+; LARGE64-NEXT: ld r3, L..C13 at l(r3)
+; LARGE64-NEXT: stfdx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_global_double_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C13(r2) # target-flags(ppc-tprel) @global_double_nonzero
+; SMALL64-NEXT: stfdx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_global_double_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C13 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C13 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stfdx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_global_double_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C13(r2) # target-flags(ppc-tprel) @global_double_nonzero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stfdx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @global_double_nonzero)
+ store double %i, ptr %addr, align 8
+ ret void
+}
+
+define void @store_intern_double_zero(double noundef %i) {
+; LARGE64-LABEL: store_intern_double_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C14 at u(r2)
+; LARGE64-NEXT: ld r3, L..C14 at l(r3)
+; LARGE64-NEXT: stfdx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_intern_double_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C14(r2) # target-flags(ppc-tprel) @intern_double_zero
+; SMALL64-NEXT: stfdx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_intern_double_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C14 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C14 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stfdx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_intern_double_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C14(r2) # target-flags(ppc-tprel) @intern_double_zero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stfdx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @intern_double_zero)
+ store double %i, ptr %addr, align 8
+ ret void
+}
+
+define void @store_intern_double_nonzero(double noundef %i) {
+; LARGE64-LABEL: store_intern_double_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C15 at u(r2)
+; LARGE64-NEXT: ld r3, L..C15 at l(r3)
+; LARGE64-NEXT: stfdx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: store_intern_double_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C15(r2) # target-flags(ppc-tprel) @intern_double_nonzero
+; SMALL64-NEXT: stfdx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: store_intern_double_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C15 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C15 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: stfdx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: store_intern_double_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C15(r2) # target-flags(ppc-tprel) @intern_double_nonzero
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: stfdx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @intern_double_nonzero)
+ store double %i, ptr %addr, align 8
+ ret void
+}
+
+define double @load_global_double_zero() {
+; LARGE64-LABEL: load_global_double_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C12 at u(r2)
+; LARGE64-NEXT: ld r3, L..C12 at l(r3)
+; LARGE64-NEXT: lfdx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_global_double_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C12(r2) # target-flags(ppc-tprel) @global_double_zero
+; SMALL64-NEXT: lfdx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_global_double_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C12 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C12 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lfdx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_global_double_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C12(r2) # target-flags(ppc-tprel) @global_double_zero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lfdx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @global_double_zero)
+ %val = load double, ptr %addr, align 8
+ ret double %val
+}
+
+define double @load_global_double_nonzero() {
+; LARGE64-LABEL: load_global_double_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C13 at u(r2)
+; LARGE64-NEXT: ld r3, L..C13 at l(r3)
+; LARGE64-NEXT: lfdx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_global_double_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C13(r2) # target-flags(ppc-tprel) @global_double_nonzero
+; SMALL64-NEXT: lfdx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_global_double_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C13 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C13 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lfdx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_global_double_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C13(r2) # target-flags(ppc-tprel) @global_double_nonzero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lfdx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @global_double_nonzero)
+ %val = load double, ptr %addr, align 8
+ ret double %val
+}
+
+define double @load_intern_double_zero() {
+; LARGE64-LABEL: load_intern_double_zero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C14 at u(r2)
+; LARGE64-NEXT: ld r3, L..C14 at l(r3)
+; LARGE64-NEXT: lfdx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_intern_double_zero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C14(r2) # target-flags(ppc-tprel) @intern_double_zero
+; SMALL64-NEXT: lfdx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_intern_double_zero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C14 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C14 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lfdx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_intern_double_zero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C14(r2) # target-flags(ppc-tprel) @intern_double_zero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lfdx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @intern_double_zero)
+ %val = load double, ptr %addr, align 8
+ ret double %val
+}
+
+define double @load_intern_double_nonzero() {
+; LARGE64-LABEL: load_intern_double_nonzero:
+; LARGE64: # %bb.0: # %entry
+; LARGE64-NEXT: addis r3, L..C15 at u(r2)
+; LARGE64-NEXT: ld r3, L..C15 at l(r3)
+; LARGE64-NEXT: lfdx f1, r13, r3
+; LARGE64-NEXT: blr
+;
+; SMALL64-LABEL: load_intern_double_nonzero:
+; SMALL64: # %bb.0: # %entry
+; SMALL64-NEXT: ld r3, L..C15(r2) # target-flags(ppc-tprel) @intern_double_nonzero
+; SMALL64-NEXT: lfdx f1, r13, r3
+; SMALL64-NEXT: blr
+;
+; LARGE32-LABEL: load_intern_double_nonzero:
+; LARGE32: # %bb.0: # %entry
+; LARGE32-NEXT: mflr r0
+; LARGE32-NEXT: stwu r1, -32(r1)
+; LARGE32-NEXT: stw r0, 40(r1)
+; LARGE32-NEXT: addis r3, L..C15 at u(r2)
+; LARGE32-NEXT: lwz r4, L..C15 at l(r3)
+; LARGE32-NEXT: bla .__get_tpointer[PR]
+; LARGE32-NEXT: lfdx f1, r3, r4
+; LARGE32-NEXT: addi r1, r1, 32
+; LARGE32-NEXT: lwz r0, 8(r1)
+; LARGE32-NEXT: mtlr r0
+; LARGE32-NEXT: blr
+;
+; SMALL32-LABEL: load_intern_double_nonzero:
+; SMALL32: # %bb.0: # %entry
+; SMALL32-NEXT: mflr r0
+; SMALL32-NEXT: stwu r1, -32(r1)
+; SMALL32-NEXT: lwz r4, L..C15(r2) # target-flags(ppc-tprel) @intern_double_nonzero
+; SMALL32-NEXT: stw r0, 40(r1)
+; SMALL32-NEXT: bla .__get_tpointer[PR]
+; SMALL32-NEXT: lfdx f1, r3, r4
+; SMALL32-NEXT: addi r1, r1, 32
+; SMALL32-NEXT: lwz r0, 8(r1)
+; SMALL32-NEXT: mtlr r0
+; SMALL32-NEXT: blr
+entry:
+ %addr = tail call align 8 ptr @llvm.threadlocal.address.p0(ptr align 8 @intern_double_nonzero)
+ %val = load double, ptr %addr, align 8
+ ret double %val
+}
+
+declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
+
+; Lines below check if the symbols have correct suffix for TLS model, not
+; generated by test update script, but kept well after updates.
+
+; LARGE64: L..C0:
+; LARGE64-NEXT: .tc global_int_zero[TE],global_int_zero[TL]@ie
+; LARGE64-NEXT: L..C1:
+; LARGE64-NEXT: .tc global_int_nonzero[TE],global_int_nonzero[TL]@ie
+; LARGE64-NEXT: L..C2:
+; LARGE64-NEXT: .tc intern_int_zero[TE],intern_int_zero[UL]@ie
+; LARGE64-NEXT: L..C3:
+; LARGE64-NEXT: .tc intern_int_nonzero[TE],intern_int_nonzero[TL]@ie
+; LARGE64-NEXT: L..C4:
+; LARGE64-NEXT: .tc global_long_zero[TE],global_long_zero[TL]@ie
+; LARGE64-NEXT: L..C5:
+; LARGE64-NEXT: .tc global_long_nonzero[TE],global_long_nonzero[TL]@ie
+; LARGE64-NEXT: L..C6:
+; LARGE64-NEXT: .tc intern_long_zero[TE],intern_long_zero[UL]@ie
+; LARGE64-NEXT: L..C7:
+; LARGE64-NEXT: .tc intern_long_nonzero[TE],intern_long_nonzero[TL]@ie
+; LARGE64-NEXT: L..C8:
+; LARGE64-NEXT: .tc global_float_zero[TE],global_float_zero[TL]@ie
+; LARGE64-NEXT: L..C9:
+; LARGE64-NEXT: .tc global_float_nonzero[TE],global_float_nonzero[TL]@ie
+; LARGE64-NEXT: L..C10:
+; LARGE64-NEXT: .tc intern_float_zero[TE],intern_float_zero[UL]@ie
+; LARGE64-NEXT: L..C11:
+; LARGE64-NEXT: .tc intern_float_nonzero[TE],intern_float_nonzero[TL]@ie
+; LARGE64-NEXT: L..C12:
+; LARGE64-NEXT: .tc global_double_zero[TE],global_double_zero[TL]@ie
+; LARGE64-NEXT: L..C13:
+; LARGE64-NEXT: .tc global_double_nonzero[TE],global_double_nonzero[TL]@ie
+; LARGE64-NEXT: L..C14:
+; LARGE64-NEXT: .tc intern_double_zero[TE],intern_double_zero[UL]@ie
+; LARGE64-NEXT: L..C15:
+; LARGE64-NEXT: .tc intern_double_nonzero[TE],intern_double_nonzero[TL]@ie
+
+; SMALL64: L..C0:
+; SMALL64-NEXT: .tc global_int_zero[TC],global_int_zero[TL]@ie
+; SMALL64-NEXT: L..C1:
+; SMALL64-NEXT: .tc global_int_nonzero[TC],global_int_nonzero[TL]@ie
+; SMALL64-NEXT: L..C2:
+; SMALL64-NEXT: .tc intern_int_zero[TC],intern_int_zero[UL]@ie
+; SMALL64-NEXT: L..C3:
+; SMALL64-NEXT: .tc intern_int_nonzero[TC],intern_int_nonzero[TL]@ie
+; SMALL64-NEXT: L..C4:
+; SMALL64-NEXT: .tc global_long_zero[TC],global_long_zero[TL]@ie
+; SMALL64-NEXT: L..C5:
+; SMALL64-NEXT: .tc global_long_nonzero[TC],global_long_nonzero[TL]@ie
+; SMALL64-NEXT: L..C6:
+; SMALL64-NEXT: .tc intern_long_zero[TC],intern_long_zero[UL]@ie
+; SMALL64-NEXT: L..C7:
+; SMALL64-NEXT: .tc intern_long_nonzero[TC],intern_long_nonzero[TL]@ie
+; SMALL64-NEXT: L..C8:
+; SMALL64-NEXT: .tc global_float_zero[TC],global_float_zero[TL]@ie
+; SMALL64-NEXT: L..C9:
+; SMALL64-NEXT: .tc global_float_nonzero[TC],global_float_nonzero[TL]@ie
+; SMALL64-NEXT: L..C10:
+; SMALL64-NEXT: .tc intern_float_zero[TC],intern_float_zero[UL]@ie
+; SMALL64-NEXT: L..C11:
+; SMALL64-NEXT: .tc intern_float_nonzero[TC],intern_float_nonzero[TL]@ie
+; SMALL64-NEXT: L..C12:
+; SMALL64-NEXT: .tc global_double_zero[TC],global_double_zero[TL]@ie
+; SMALL64-NEXT: L..C13:
+; SMALL64-NEXT: .tc global_double_nonzero[TC],global_double_nonzero[TL]@ie
+; SMALL64-NEXT: L..C14:
+; SMALL64-NEXT: .tc intern_double_zero[TC],intern_double_zero[UL]@ie
+; SMALL64-NEXT: L..C15:
+; SMALL64-NEXT: .tc intern_double_nonzero[TC],intern_double_nonzero[TL]@ie
+
+; LARGE32: L..C0:
+; LARGE32-NEXT: .tc global_int_zero[TE],global_int_zero[TL]@ie
+; LARGE32-NEXT: L..C1:
+; LARGE32-NEXT: .tc global_int_nonzero[TE],global_int_nonzero[TL]@ie
+; LARGE32-NEXT: L..C2:
+; LARGE32-NEXT: .tc intern_int_zero[TE],intern_int_zero[UL]@ie
+; LARGE32-NEXT: L..C3:
+; LARGE32-NEXT: .tc intern_int_nonzero[TE],intern_int_nonzero[TL]@ie
+; LARGE32-NEXT: L..C4:
+; LARGE32-NEXT: .tc global_long_zero[TE],global_long_zero[TL]@ie
+; LARGE32-NEXT: L..C5:
+; LARGE32-NEXT: .tc global_long_nonzero[TE],global_long_nonzero[TL]@ie
+; LARGE32-NEXT: L..C6:
+; LARGE32-NEXT: .tc intern_long_zero[TE],intern_long_zero[UL]@ie
+; LARGE32-NEXT: L..C7:
+; LARGE32-NEXT: .tc intern_long_nonzero[TE],intern_long_nonzero[TL]@ie
+; LARGE32-NEXT: L..C8:
+; LARGE32-NEXT: .tc global_float_zero[TE],global_float_zero[TL]@ie
+; LARGE32-NEXT: L..C9:
+; LARGE32-NEXT: .tc global_float_nonzero[TE],global_float_nonzero[TL]@ie
+; LARGE32-NEXT: L..C10:
+; LARGE32-NEXT: .tc intern_float_zero[TE],intern_float_zero[UL]@ie
+; LARGE32-NEXT: L..C11:
+; LARGE32-NEXT: .tc intern_float_nonzero[TE],intern_float_nonzero[TL]@ie
+; LARGE32-NEXT: L..C12:
+; LARGE32-NEXT: .tc global_double_zero[TE],global_double_zero[TL]@ie
+; LARGE32-NEXT: L..C13:
+; LARGE32-NEXT: .tc global_double_nonzero[TE],global_double_nonzero[TL]@ie
+; LARGE32-NEXT: L..C14:
+; LARGE32-NEXT: .tc intern_double_zero[TE],intern_double_zero[UL]@ie
+; LARGE32-NEXT: L..C15:
+; LARGE32-NEXT: .tc intern_double_nonzero[TE],intern_double_nonzero[TL]@ie
+
+; SMALL32: L..C0:
+; SMALL32-NEXT: .tc global_int_zero[TC],global_int_zero[TL]@ie
+; SMALL32-NEXT: L..C1:
+; SMALL32-NEXT: .tc global_int_nonzero[TC],global_int_nonzero[TL]@ie
+; SMALL32-NEXT: L..C2:
+; SMALL32-NEXT: .tc intern_int_zero[TC],intern_int_zero[UL]@ie
+; SMALL32-NEXT: L..C3:
+; SMALL32-NEXT: .tc intern_int_nonzero[TC],intern_int_nonzero[TL]@ie
+; SMALL32-NEXT: L..C4:
+; SMALL32-NEXT: .tc global_long_zero[TC],global_long_zero[TL]@ie
+; SMALL32-NEXT: L..C5:
+; SMALL32-NEXT: .tc global_long_nonzero[TC],global_long_nonzero[TL]@ie
+; SMALL32-NEXT: L..C6:
+; SMALL32-NEXT: .tc intern_long_zero[TC],intern_long_zero[UL]@ie
+; SMALL32-NEXT: L..C7:
+; SMALL32-NEXT: .tc intern_long_nonzero[TC],intern_long_nonzero[TL]@ie
+; SMALL32-NEXT: L..C8:
+; SMALL32-NEXT: .tc global_float_zero[TC],global_float_zero[TL]@ie
+; SMALL32-NEXT: L..C9:
+; SMALL32-NEXT: .tc global_float_nonzero[TC],global_float_nonzero[TL]@ie
+; SMALL32-NEXT: L..C10:
+; SMALL32-NEXT: .tc intern_float_zero[TC],intern_float_zero[UL]@ie
+; SMALL32-NEXT: L..C11:
+; SMALL32-NEXT: .tc intern_float_nonzero[TC],intern_float_nonzero[TL]@ie
+; SMALL32-NEXT: L..C12:
+; SMALL32-NEXT: .tc global_double_zero[TC],global_double_zero[TL]@ie
+; SMALL32-NEXT: L..C13:
+; SMALL32-NEXT: .tc global_double_nonzero[TC],global_double_nonzero[TL]@ie
+; SMALL32-NEXT: L..C14:
+; SMALL32-NEXT: .tc intern_double_zero[TC],intern_double_zero[UL]@ie
+; SMALL32-NEXT: L..C15:
+; SMALL32-NEXT: .tc intern_double_nonzero[TC],intern_double_nonzero[TL]@ie
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-ie-xcoff-reloc.ll b/llvm/test/CodeGen/PowerPC/aix-tls-ie-xcoff-reloc.ll
new file mode 100644
index 00000000000000..e34bb130d5ed21
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-ie-xcoff-reloc.ll
@@ -0,0 +1,387 @@
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -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=REL64 %s
+; RUN: llvm-readobj --syms %t.o | FileCheck --check-prefix=SYM64 %s
+; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck --check-prefix=DIS64 %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple=powerpc64-ibm-aix-xcoff -code-model=small \
+; 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=REL64 %s
+; RUN: llvm-readobj --syms %t.o | FileCheck --check-prefix=SYM64 %s
+; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck --check-prefix=DIS64 %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple=powerpc-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=REL32 %s
+; RUN: llvm-readobj --syms %t.o | FileCheck --check-prefix=SYM32 %s
+; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck --check-prefix=DIS32 %s
+
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mtriple=powerpc-ibm-aix-xcoff -code-model=small \
+; 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=REL32 %s
+; RUN: llvm-readobj --syms %t.o | FileCheck --check-prefix=SYM32 %s
+; RUN: llvm-objdump -D -r --symbol-description %t.o | FileCheck --check-prefix=DIS32 %s
+
+ at global_int_nonzero = thread_local(initialexec) global i32 1, align 4
+ at intern_int_zero = internal thread_local(initialexec) global i32 0, align 4
+
+define void @store_intern_int_zero(i32 noundef signext %i) {
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_int_zero)
+ store i32 %i, ptr %addr, align 4
+ ret void
+}
+
+define signext i32 @load_global_int_nonzero() {
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @global_int_nonzero)
+ %val = load i32, ptr %addr, align 4
+ ret i32 %val
+}
+
+define signext i32 @load_intern_int_zero() {
+entry:
+ %addr = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @intern_int_zero)
+ %val = load i32, ptr %addr, align 4
+ ret i32 %val
+}
+
+declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
+
+; REL64: File: {{.*}}aix-tls-ie-xcoff-reloc.ll.tmp.o
+; REL64-NEXT: Format: aix5coff64-rs6000
+; REL64-NEXT: Arch: powerpc64
+; REL64-NEXT: AddressSize: 64bit
+; REL64-NEXT: Relocations [
+; REL64: Virtual Address: 0x2
+; REL64-NEXT: Symbol: intern_int_zero (17)
+; REL64-NEXT: IsSigned: No
+; REL64-NEXT: FixupBitValue: 0
+; REL64-NEXT: Length: 16
+; REL64-NEXT: Type: R_TOC (0x3)
+; REL64-NEXT: }
+; REL64: Virtual Address: 0x12
+; REL64-NEXT: Symbol: global_int_nonzero (19)
+; REL64-NEXT: IsSigned: No
+; REL64-NEXT: FixupBitValue: 0
+; REL64-NEXT: Length: 16
+; REL64-NEXT: Type: R_TOC (0x3)
+; REL64-NEXT: }
+; REL64: Virtual Address: 0x22
+; REL64-NEXT: Symbol: intern_int_zero (17)
+; REL64-NEXT: IsSigned: No
+; REL64-NEXT: FixupBitValue: 0
+; REL64-NEXT: Length: 16
+; REL64-NEXT: Type: R_TOC (0x3)
+; REL64-NEXT: }
+; REL64: Virtual Address: 0x78
+; REL64-NEXT: Symbol: intern_int_zero (25)
+; REL64-NEXT: IsSigned: No
+; REL64-NEXT: FixupBitValue: 0
+; REL64-NEXT: Length: 64
+; REL64-NEXT: Type: R_TLS_IE (0x21)
+; REL64-NEXT: }
+; REL64: Virtual Address: 0x80
+; REL64-NEXT: Symbol: global_int_nonzero (23)
+; REL64-NEXT: IsSigned: No
+; REL64-NEXT: FixupBitValue: 0
+; REL64-NEXT: Length: 64
+; REL64-NEXT: Type: R_TLS_IE (0x21)
+; REL64-NEXT: }
+
+; SYM64: File: {{.*}}aix-tls-ie-xcoff-reloc.ll.tmp.o
+; SYM64-NEXT: Format: aix5coff64-rs6000
+; SYM64-NEXT: Arch: powerpc64
+; SYM64-NEXT: AddressSize: 64bit
+; SYM64-NEXT: Symbols [
+; SYM64: Index: 17
+; SYM64-NEXT: Name: intern_int_zero
+; SYM64-NEXT: Value (RelocatableAddress): 0x78
+; SYM64-NEXT: Section: .data
+; SYM64-NEXT: Type: 0x0
+; SYM64-NEXT: StorageClass: C_HIDEXT (0x6B)
+; SYM64-NEXT: NumberOfAuxEntries: 1
+; SYM64-NEXT: CSECT Auxiliary Entry {
+; SYM64-NEXT: Index: 18
+; SYM64-NEXT: SectionLen: 8
+; SYM64-NEXT: ParameterHashIndex: 0x0
+; SYM64-NEXT: TypeChkSectNum: 0x0
+; SYM64-NEXT: SymbolAlignmentLog2: 3
+; SYM64-NEXT: SymbolType: XTY_SD (0x1)
+; SYM64-NEXT: StorageMappingClass: XMC_TC (0x3)
+; SYM64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+; SYM64-NEXT: }
+; SYM64-NEXT: }
+; SYM64: Index: 19
+; SYM64-NEXT: Name: global_int_nonzero
+; SYM64-NEXT: Value (RelocatableAddress): 0x80
+; SYM64-NEXT: Section: .data
+; SYM64-NEXT: Type: 0x0
+; SYM64-NEXT: StorageClass: C_HIDEXT (0x6B)
+; SYM64-NEXT: NumberOfAuxEntries: 1
+; SYM64-NEXT: CSECT Auxiliary Entry {
+; SYM64-NEXT: Index: 20
+; SYM64-NEXT: SectionLen: 8
+; SYM64-NEXT: ParameterHashIndex: 0x0
+; SYM64-NEXT: TypeChkSectNum: 0x0
+; SYM64-NEXT: SymbolAlignmentLog2: 3
+; SYM64-NEXT: SymbolType: XTY_SD (0x1)
+; SYM64-NEXT: StorageMappingClass: XMC_TC (0x3)
+; SYM64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+; SYM64-NEXT: }
+; SYM64-NEXT: }
+; SYM64: Index: 23
+; SYM64-NEXT: Name: global_int_nonzero
+; SYM64-NEXT: Value (RelocatableAddress): 0x0
+; SYM64-NEXT: Section: .tdata
+; SYM64-NEXT: Type: 0x0
+; SYM64-NEXT: StorageClass: C_EXT (0x2)
+; SYM64-NEXT: NumberOfAuxEntries: 1
+; SYM64-NEXT: CSECT Auxiliary Entry {
+; SYM64-NEXT: Index: 24
+; SYM64-NEXT: ContainingCsectSymbolIndex: 21
+; SYM64-NEXT: ParameterHashIndex: 0x0
+; SYM64-NEXT: TypeChkSectNum: 0x0
+; SYM64-NEXT: SymbolAlignmentLog2: 0
+; SYM64-NEXT: SymbolType: XTY_LD (0x2)
+; SYM64-NEXT: StorageMappingClass: XMC_TL (0x14)
+; SYM64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+; SYM64-NEXT: }
+; SYM64-NEXT: }
+; SYM64: Index: 25
+; SYM64-NEXT: Name: intern_int_zero
+; SYM64-NEXT: Value (RelocatableAddress): 0x4
+; SYM64-NEXT: Section: .tbss
+; SYM64-NEXT: Type: 0x0
+; SYM64-NEXT: StorageClass: C_HIDEXT (0x6B)
+; SYM64-NEXT: NumberOfAuxEntries: 1
+; SYM64-NEXT: CSECT Auxiliary Entry {
+; SYM64-NEXT: Index: 26
+; SYM64-NEXT: SectionLen: 4
+; SYM64-NEXT: ParameterHashIndex: 0x0
+; SYM64-NEXT: TypeChkSectNum: 0x0
+; SYM64-NEXT: SymbolAlignmentLog2: 2
+; SYM64-NEXT: SymbolType: XTY_CM (0x3)
+; SYM64-NEXT: StorageMappingClass: XMC_UL (0x15)
+; SYM64-NEXT: Auxiliary Type: AUX_CSECT (0xFB)
+; SYM64-NEXT: }
+; SYM64-NEXT: }
+
+; DIS64: {{.*}}aix-tls-ie-xcoff-reloc.ll.tmp.o: file format aix5coff64-rs6000
+; DIS64: Disassembly of section .text:
+; DIS64: (idx: 3) .store_intern_int_zero:
+; DIS64-NEXT: ld 4, 0(2)
+; DIS64-NEXT: (idx: 17) intern_int_zero[TC]
+; DIS64-NEXT: stwx 3, 13, 4
+; DIS64-NEXT: blr
+; DIS64: (idx: 5) .load_global_int_nonzero:
+; DIS64-NEXT: ld 3, 8(2)
+; DIS64-NEXT: (idx: 19) global_int_nonzero[TC]
+; DIS64-NEXT: lwax 3, 13, 3
+; DIS64-NEXT: blr
+; DIS64: (idx: 7) .load_intern_int_zero:
+; DIS64-NEXT: ld 3, 0(2)
+; DIS64-NEXT: (idx: 17) intern_int_zero[TC]
+; DIS64-NEXT: lwax 3, 13, 3
+; DIS64-NEXT: blr
+
+; DIS64: Disassembly of section .data:
+; DIS64: (idx: 9) store_intern_int_zero[DS]:
+; DIS64: R_POS (idx: 3) .store_intern_int_zero
+; DIS64: R_POS (idx: 15) TOC[TC0]
+; DIS64: (idx: 11) load_global_int_nonzero[DS]:
+; DIS64: R_POS (idx: 5) .load_global_int_nonzero
+; DIS64: R_POS (idx: 15) TOC[TC0]
+; DIS64: (idx: 13) load_intern_int_zero[DS]:
+; DIS64: R_POS (idx: 7) .load_intern_int_zero
+; DIS64: R_POS (idx: 15) TOC[TC0]
+; DIS64: (idx: 17) intern_int_zero[TC]:
+; DIS64: R_TLS_IE (idx: 25) intern_int_zero[UL]
+; DIS64: (idx: 19) global_int_nonzero[TC]:
+; DIS64: R_TLS_IE (idx: 23) global_int_nonzero
+
+; DIS64: Disassembly of section .tdata:
+; DIS64: (idx: 23) global_int_nonzero:
+
+; DIS64: Disassembly of section .tbss:
+; DIS64: (idx: 25) intern_int_zero[UL]:
+
+; REL32: File: {{.*}}aix-tls-ie-xcoff-reloc.ll.tmp.o
+; REL32-NEXT: Format: aixcoff-rs6000
+; REL32-NEXT: Arch: powerpc
+; REL32-NEXT: AddressSize: 32bit
+; REL32-NEXT: Relocations [
+; REL32: Virtual Address: 0xA
+; REL32-NEXT: Symbol: intern_int_zero (19)
+; REL32-NEXT: IsSigned: No
+; REL32-NEXT: FixupBitValue: 0
+; REL32-NEXT: Length: 16
+; REL32-NEXT: Type: R_TOC (0x3)
+; REL32-NEXT: }
+; REL32: Virtual Address: 0x10
+; REL32-NEXT: Symbol: .__get_tpointer (1)
+; REL32-NEXT: IsSigned: No
+; REL32-NEXT: FixupBitValue: 0
+; REL32-NEXT: Length: 26
+; REL32-NEXT: Type: R_RBA (0x18)
+; REL32-NEXT: }
+; REL32: Virtual Address: 0x3A
+; REL32-NEXT: Symbol: global_int_nonzero (21)
+; REL32-NEXT: IsSigned: No
+; REL32-NEXT: FixupBitValue: 0
+; REL32-NEXT: Length: 16
+; REL32-NEXT: Type: R_TOC (0x3)
+; REL32-NEXT: }
+; REL32: Virtual Address: 0x40
+; REL32-NEXT: Symbol: .__get_tpointer (1)
+; REL32-NEXT: IsSigned: No
+; REL32-NEXT: FixupBitValue: 0
+; REL32-NEXT: Length: 26
+; REL32-NEXT: Type: R_RBA (0x18)
+; REL32-NEXT: }
+; REL32: Virtual Address: 0x6A
+; REL32-NEXT: Symbol: intern_int_zero (19)
+; REL32-NEXT: IsSigned: No
+; REL32-NEXT: FixupBitValue: 0
+; REL32-NEXT: Length: 16
+; REL32-NEXT: Type: R_TOC (0x3)
+; REL32-NEXT: }
+; REL32: Virtual Address: 0x70
+; REL32-NEXT: Symbol: .__get_tpointer (1)
+; REL32-NEXT: IsSigned: No
+; REL32-NEXT: FixupBitValue: 0
+; REL32-NEXT: Length: 26
+; REL32-NEXT: Type: R_RBA (0x18)
+; REL32-NEXT: }
+; REL32: Virtual Address: 0xAC
+; REL32-NEXT: Symbol: intern_int_zero (27)
+; REL32-NEXT: IsSigned: No
+; REL32-NEXT: FixupBitValue: 0
+; REL32-NEXT: Length: 32
+; REL32-NEXT: Type: R_TLS_IE (0x21)
+; REL32-NEXT: }
+; REL32: Virtual Address: 0xB0
+; REL32-NEXT: Symbol: global_int_nonzero (25)
+; REL32-NEXT: IsSigned: No
+; REL32-NEXT: FixupBitValue: 0
+; REL32-NEXT: Length: 32
+; REL32-NEXT: Type: R_TLS_IE (0x21)
+; REL32-NEXT: }
+
+; SYM32: File: {{.*}}aix-tls-ie-xcoff-reloc.ll.tmp.o
+; SYM32-NEXT: Format: aixcoff-rs6000
+; SYM32-NEXT: Arch: powerpc
+; SYM32-NEXT: AddressSize: 32bit
+; SYM32-NEXT: Symbols [
+; SYM32: Index: 19
+; SYM32-NEXT: Name: intern_int_zero
+; SYM32-NEXT: Value (RelocatableAddress): 0xAC
+; SYM32-NEXT: Section: .data
+; SYM32-NEXT: Type: 0x0
+; SYM32-NEXT: StorageClass: C_HIDEXT (0x6B)
+; SYM32-NEXT: NumberOfAuxEntries: 1
+; SYM32-NEXT: CSECT Auxiliary Entry {
+; SYM32-NEXT: Index: 20
+; SYM32-NEXT: SectionLen: 4
+; SYM32-NEXT: ParameterHashIndex: 0x0
+; SYM32-NEXT: TypeChkSectNum: 0x0
+; SYM32-NEXT: SymbolAlignmentLog2: 2
+; SYM32-NEXT: SymbolType: XTY_SD (0x1)
+; SYM32-NEXT: StorageMappingClass: XMC_TC (0x3)
+; SYM32-NEXT: StabInfoIndex: 0x0
+; SYM32-NEXT: StabSectNum: 0x0
+; SYM32-NEXT: }
+; SYM32-NEXT: }
+; SYM32: Index: 21
+; SYM32-NEXT: Name: global_int_nonzero
+; SYM32-NEXT: Value (RelocatableAddress): 0xB0
+; SYM32-NEXT: Section: .data
+; SYM32-NEXT: Type: 0x0
+; SYM32-NEXT: StorageClass: C_HIDEXT (0x6B)
+; SYM32-NEXT: NumberOfAuxEntries: 1
+; SYM32-NEXT: CSECT Auxiliary Entry {
+; SYM32-NEXT: Index: 22
+; SYM32-NEXT: SectionLen: 4
+; SYM32-NEXT: ParameterHashIndex: 0x0
+; SYM32-NEXT: TypeChkSectNum: 0x0
+; SYM32-NEXT: SymbolAlignmentLog2: 2
+; SYM32-NEXT: SymbolType: XTY_SD (0x1)
+; SYM32-NEXT: StorageMappingClass: XMC_TC (0x3)
+; SYM32-NEXT: StabInfoIndex: 0x0
+; SYM32-NEXT: StabSectNum: 0x0
+; SYM32-NEXT: }
+; SYM32-NEXT: }
+; SYM32: Index: 25
+; SYM32-NEXT: Name: global_int_nonzero
+; SYM32-NEXT: Value (RelocatableAddress): 0x0
+; SYM32-NEXT: Section: .tdata
+; SYM32-NEXT: Type: 0x0
+; SYM32-NEXT: StorageClass: C_EXT (0x2)
+; SYM32-NEXT: NumberOfAuxEntries: 1
+; SYM32-NEXT: CSECT Auxiliary Entry {
+; SYM32-NEXT: Index: 26
+; SYM32-NEXT: ContainingCsectSymbolIndex: 23
+; SYM32-NEXT: ParameterHashIndex: 0x0
+; SYM32-NEXT: TypeChkSectNum: 0x0
+; SYM32-NEXT: SymbolAlignmentLog2: 0
+; SYM32-NEXT: SymbolType: XTY_LD (0x2)
+; SYM32-NEXT: StorageMappingClass: XMC_TL (0x14)
+; SYM32-NEXT: StabInfoIndex: 0x0
+; SYM32-NEXT: StabSectNum: 0x0
+; SYM32-NEXT: }
+; SYM32-NEXT: }
+; SYM32: Index: 27
+; SYM32-NEXT: Name: intern_int_zero
+; SYM32-NEXT: Value (RelocatableAddress): 0x4
+; SYM32-NEXT: Section: .tbss
+; SYM32-NEXT: Type: 0x0
+; SYM32-NEXT: StorageClass: C_HIDEXT (0x6B)
+; SYM32-NEXT: NumberOfAuxEntries: 1
+; SYM32-NEXT: CSECT Auxiliary Entry {
+; SYM32-NEXT: Index: 28
+; SYM32-NEXT: SectionLen: 4
+; SYM32-NEXT: ParameterHashIndex: 0x0
+; SYM32-NEXT: TypeChkSectNum: 0x0
+; SYM32-NEXT: SymbolAlignmentLog2: 2
+; SYM32-NEXT: SymbolType: XTY_CM (0x3)
+; SYM32-NEXT: StorageMappingClass: XMC_UL (0x15)
+; SYM32-NEXT: StabInfoIndex: 0x0
+; SYM32-NEXT: StabSectNum: 0x0
+; SYM32-NEXT: }
+; SYM32-NEXT: }
+
+; DIS32: {{.*}}aix-tls-ie-xcoff-reloc.ll.tmp.o: file format aixcoff-rs6000
+; DIS32: Disassembly of section .text:
+; DIS32: (idx: 5) .store_intern_int_zero:
+; DIS32: R_TOC (idx: 19) intern_int_zero[TC]
+; DIS32: R_RBA (idx: 1) .__get_tpointer[PR]
+; DIS32: blr
+; DIS32: (idx: 7) .load_global_int_nonzero:
+; DIS32: R_TOC (idx: 21) global_int_nonzero[TC]
+; DIS32: R_RBA (idx: 1) .__get_tpointer[PR]
+; DIS32: blr
+; DIS32: (idx: 9) .load_intern_int_zero:
+; DIS32: R_TOC (idx: 19) intern_int_zero[TC]
+; DIS32: R_RBA (idx: 1) .__get_tpointer[PR]
+; DIS32: blr
+
+; DIS32: Disassembly of section .data:
+; DIS32: (idx: 11) store_intern_int_zero[DS]:
+; DIS32: R_POS (idx: 5) .store_intern_int_zero
+; DIS32: R_POS (idx: 17) TOC[TC0]
+; DIS32: (idx: 13) load_global_int_nonzero[DS]:
+; DIS32: R_POS (idx: 7) .load_global_int_nonzero
+; DIS32: R_POS (idx: 17) TOC[TC0]
+; DIS32: (idx: 15) load_intern_int_zero[DS]:
+; DIS32: R_POS (idx: 9) .load_intern_int_zero
+; DIS32: R_POS (idx: 17) TOC[TC0]
+; DIS32: (idx: 19) intern_int_zero[TC]:
+; DIS32: R_TLS_IE (idx: 27) intern_int_zero[UL]
+; DIS32: (idx: 21) global_int_nonzero[TC]:
+; DIS32: R_TLS_IE (idx: 25) global_int_nonzero
+
+; DIS32: Disassembly of section .tdata:
+; DIS32: (idx: 25) global_int_nonzero:
+
+; DIS32: Disassembly of section .tbss:
+; DIS32: (idx: 27) intern_int_zero[UL]:
More information about the llvm-commits
mailing list