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 @@ -1155,7 +1155,8 @@ // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd) case PPC::GETtlsADDRPCREL: case PPC::GETtlsADDR32AIX: - // Transform: %r3 = GETtlsADDR32AIX %r3, %r4 + case PPC::GETtlsADDR64AIX: + // Transform: %r3 = GETtlsADDRNNAIX %r3, %r4 (for NN == 32/64). // Into: BLA .__tls_get_addr() // Unlike on Linux, there is no symbol or relocation needed for this call. case PPC::GETtlsADDR32: { @@ -2312,6 +2313,7 @@ switch (MI->getOpcode()) { default: break; + case PPC::GETtlsADDR64AIX: case PPC::GETtlsADDR32AIX: { // The reference to .__tls_get_addr is unknown to the assembler // so we need to emit an external symbol reference. 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 @@ -3131,9 +3131,6 @@ if (DAG.getTarget().useEmulatedTLS()) report_fatal_error("Emulated TLS is not yet supported on AIX"); - if (Subtarget.isPPC64()) - report_fatal_error("TLS is not yet supported on AIX PPC64"); - SDLoc dl(GA); const GlobalValue *GV = GA->getGlobal(); EVT PtrVT = getPointerTy(DAG.getDataLayout()); 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 @@ -1301,6 +1301,18 @@ def GETtlsldADDR : GETtlsldADDRPseudo <"#GETtlsldADDR">; let Defs = [X0,X2,X4,X5,X6,X7,X8,X9,X10,X11,X12,LR8,CTR8,CR0,CR1,CR5,CR6,CR7] in def GETtlsldADDRPCREL : GETtlsldADDRPseudo <"#GETtlsldADDRPCREL">; + +// On AIX, the call to __tls_get_addr needs two inputs in X3/X4 for the +// offset and region handle respectively. The call is not followed by a nop +// so we don't need to mark it with a size of 8 bytes. Finally, the assembly +// manual mentions this exact set of registers as the clobbered set, others +// are guaranteed not to be clobbered. +let Defs = [X0,X4,X5,X11,LR8,CR0] in +def GETtlsADDR64AIX : + PPCEmitTimePseudo<(outs g8rc:$rD),(ins g8rc:$offset, g8rc:$handle), + "GETtlsADDR64AIX", + [(set i64:$rD, + (PPCgetTlsAddr i64:$offset, i64:$handle))]>, isPPC64; } // Combined op for ADDItlsgdL and GETtlsADDR, late expanded. X3 and LR8 @@ -1326,6 +1338,13 @@ [(set i64:$rD, (PPCaddiTlsldL i64:$reg, tglobaltlsaddr:$disp))]>, isPPC64; +// This pseudo is expanded to two copies to put the variable offset in R4 and +// the region handle in R3 and GETtlsADDR64AIX. +def TLSGDAIX8 : + PPCEmitTimePseudo<(outs g8rc:$rD), (ins g8rc:$offset, g8rc:$handle), + "#TLSGDAIX8", + [(set i64:$rD, + (PPCTlsgdAIX i64:$offset, i64:$handle))]>; // Combined op for ADDItlsldL and GETtlsADDR, late expanded. X3 and LR8 // are true defines, while the rest of the Defs are clobbers. let hasExtraSrcRegAllocReq = 1, hasExtraDefRegAllocReq = 1, @@ -1594,6 +1613,10 @@ def : Pat<(add i64:$in, (PPChi tblockaddress:$g, 0)), (ADDIS8 $in, tblockaddress:$g)>; +// AIX 64-bit small code model TLS access. +def : Pat<(i64 (PPCtoc_entry tglobaltlsaddr:$disp, i64:$reg)), + (i64 (LDtoc tglobaltlsaddr:$disp, i64:$reg))>; + // Patterns to match r+r indexed loads and stores for // addresses without at least 4-byte alignment. def : Pat<(i64 (NonDSFormSextLoadi32 xoaddr:$src)), diff --git a/llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp b/llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp --- a/llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp +++ b/llvm/lib/Target/PowerPC/PPCTLSDynamicCall.cpp @@ -62,7 +62,8 @@ MI.getOpcode() != PPC::ADDItlsldLADDR && MI.getOpcode() != PPC::ADDItlsgdLADDR32 && MI.getOpcode() != PPC::ADDItlsldLADDR32 && - MI.getOpcode() != PPC::TLSGDAIX && !IsPCREL) { + MI.getOpcode() != PPC::TLSGDAIX && + MI.getOpcode() != PPC::TLSGDAIX8 && !IsPCREL) { // Although we create ADJCALLSTACKDOWN and ADJCALLSTACKUP // as scheduling fences, we skip creating fences if we already // have existing ADJCALLSTACKDOWN/UP to avoid nesting, @@ -109,6 +110,11 @@ Opc1 = PPC::ADDItlsldL32; Opc2 = PPC::GETtlsldADDR32; break; + case PPC::TLSGDAIX8: + // TLSGDAIX8 is expanded to two copies and GET_TLS_ADDR, so we only + // set Opc2 here. + Opc2 = PPC::GETtlsADDR64AIX; + break; case PPC::TLSGDAIX: // TLSGDAIX is expanded to two copies and GET_TLS_ADDR, so we only // set Opc2 here. @@ -140,7 +146,7 @@ if (IsAIX) { // The variable offset and region handle are copied in r4 and r3. The - // copies are followed by the GETtlsADDR32AIX instruction. + // copies are followed by GETtlsADDR32AIX/GETtlsADDR64AIX. BuildMI(MBB, I, DL, TII->get(TargetOpcode::COPY), GPR4) .addReg(MI.getOperand(1).getReg()); BuildMI(MBB, I, DL, TII->get(TargetOpcode::COPY), GPR3) diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-checks.ll b/llvm/test/CodeGen/PowerPC/aix-tls-checks.ll deleted file mode 100644 --- a/llvm/test/CodeGen/PowerPC/aix-tls-checks.ll +++ /dev/null @@ -1,11 +0,0 @@ -; RUN: not --crash llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ -; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s - 2>&1 | FileCheck %s - -; CHECK: TLS is not yet supported on AIX PPC64 - -@tls1 = thread_local global i32 0, align 4 - -define i32* @getTls1Addr() { -entry: - ret i32* @tls1 -} diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll b/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll --- a/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll +++ b/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll @@ -4,6 +4,12 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ ; RUN: -mtriple powerpc-ibm-aix-xcoff --code-model=large < %s \ ; RUN: | FileCheck %s --check-prefix=LARGE32 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s \ +; RUN: --check-prefix=SMALL64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large < %s \ +; RUN: | FileCheck %s --check-prefix=LARGE64 @TGInit = thread_local global double 1.000000e+00, align 8 @TWInit = weak thread_local global double 1.000000e+00, align 8 @@ -42,6 +48,36 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTGUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C0(2) +; SMALL64-NEXT: ld 4, L..C1(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: stfd 1, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTGUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C0@u(2) +; LARGE64-NEXT: addis 4, L..C1@u(2) +; LARGE64-NEXT: ld 3, L..C0@l(3) +; LARGE64-NEXT: ld 4, L..C1@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: stfd 1, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store double %Val, double* @TGUninit, align 8 ret void @@ -78,6 +114,36 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTGInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C2(2) +; SMALL64-NEXT: ld 4, L..C3(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: stfd 1, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTGInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C2@u(2) +; LARGE64-NEXT: addis 4, L..C3@u(2) +; LARGE64-NEXT: ld 3, L..C2@l(3) +; LARGE64-NEXT: ld 4, L..C3@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: stfd 1, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store double %Val, double* @TGInit, align 8 ret void @@ -114,6 +180,36 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTIInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C4(2) +; SMALL64-NEXT: ld 4, L..C5(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: stfd 1, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTIInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C4@u(2) +; LARGE64-NEXT: addis 4, L..C5@u(2) +; LARGE64-NEXT: ld 3, L..C4@l(3) +; LARGE64-NEXT: ld 4, L..C5@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: stfd 1, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store double %Val, double* @TIInit, align 8 ret void @@ -150,6 +246,36 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTWInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C6(2) +; SMALL64-NEXT: ld 4, L..C7(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: stfd 1, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTWInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C6@u(2) +; LARGE64-NEXT: addis 4, L..C7@u(2) +; LARGE64-NEXT: ld 3, L..C6@l(3) +; LARGE64-NEXT: ld 4, L..C7@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: stfd 1, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store double %Val, double* @TWInit, align 8 ret void @@ -193,6 +319,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTGUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C0(2) +; SMALL64-NEXT: ld 4, L..C1(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: lfd 0, 0(3) +; SMALL64-NEXT: lfd 1, 0(4) +; SMALL64-NEXT: fadd 1, 0, 1 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTGUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C0@u(2) +; LARGE64-NEXT: addis 4, L..C1@u(2) +; LARGE64-NEXT: ld 3, L..C0@l(3) +; LARGE64-NEXT: ld 4, L..C1@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: lfd 0, 0(3) +; LARGE64-NEXT: ld 3, L..C8@l(4) +; LARGE64-NEXT: lfd 1, 0(3) +; LARGE64-NEXT: fadd 1, 0, 1 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load double, double* @TGUninit, align 8 %1 = load double, double* @GInit, align 8 @@ -238,6 +401,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTGInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C2(2) +; SMALL64-NEXT: ld 4, L..C3(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: lfd 0, 0(3) +; SMALL64-NEXT: lfd 1, 0(4) +; SMALL64-NEXT: fadd 1, 0, 1 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTGInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C2@u(2) +; LARGE64-NEXT: addis 4, L..C3@u(2) +; LARGE64-NEXT: ld 3, L..C2@l(3) +; LARGE64-NEXT: ld 4, L..C3@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: lfd 0, 0(3) +; LARGE64-NEXT: ld 3, L..C8@l(4) +; LARGE64-NEXT: lfd 1, 0(3) +; LARGE64-NEXT: fadd 1, 0, 1 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load double, double* @TGInit, align 8 %1 = load double, double* @GInit, align 8 @@ -283,6 +483,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTIInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C4(2) +; SMALL64-NEXT: ld 4, L..C5(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: lfd 0, 0(3) +; SMALL64-NEXT: lfd 1, 0(4) +; SMALL64-NEXT: fadd 1, 0, 1 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTIInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C4@u(2) +; LARGE64-NEXT: addis 4, L..C5@u(2) +; LARGE64-NEXT: ld 3, L..C4@l(3) +; LARGE64-NEXT: ld 4, L..C5@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: lfd 0, 0(3) +; LARGE64-NEXT: ld 3, L..C8@l(4) +; LARGE64-NEXT: lfd 1, 0(3) +; LARGE64-NEXT: fadd 1, 0, 1 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load double, double* @TIInit, align 8 %1 = load double, double* @GInit, align 8 @@ -328,6 +565,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTWInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C6(2) +; SMALL64-NEXT: ld 4, L..C7(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: lfd 0, 0(3) +; SMALL64-NEXT: lfd 1, 0(4) +; SMALL64-NEXT: fadd 1, 0, 1 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTWInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C6@u(2) +; LARGE64-NEXT: addis 4, L..C7@u(2) +; LARGE64-NEXT: ld 3, L..C6@l(3) +; LARGE64-NEXT: ld 4, L..C7@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: lfd 0, 0(3) +; LARGE64-NEXT: ld 3, L..C8@l(4) +; LARGE64-NEXT: lfd 1, 0(3) +; LARGE64-NEXT: fadd 1, 0, 1 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load double, double* @TWInit, align 8 %1 = load double, double* @GInit, align 8 @@ -377,5 +651,46 @@ ; LARGE32-LABEL: L..C8: ; LARGE32-NEXT: .tc GInit[TE],GInit[RW] +; SMALL64-LABEL: .toc +; SMALL64-LABEL: L..C0: +; SMALL64-NEXT: .tc .TGUninit[TC],TGUninit[TL]@m +; SMALL64-LABEL: L..C1: +; SMALL64-NEXT: .tc TGUninit[TC],TGUninit[TL] +; SMALL64-LABEL: L..C2: +; SMALL64-NEXT: .tc .TGInit[TC],TGInit[TL]@m +; SMALL64-LABEL: L..C3: +; SMALL64-NEXT: .tc TGInit[TC],TGInit[TL] +; SMALL64-LABEL: L..C4: +; SMALL64-NEXT: .tc .TIInit[TC],TIInit[TL]@m +; SMALL64-LABEL: L..C5: +; SMALL64-NEXT: .tc TIInit[TC],TIInit[TL] +; SMALL64-LABEL: L..C6: +; SMALL64-NEXT: .tc .TWInit[TC],TWInit[TL]@m +; SMALL64-LABEL: L..C7: +; SMALL64-NEXT: .tc TWInit[TC],TWInit[TL] +; SMALL64-LABEL: L..C8: +; SMALL64-NEXT: .tc GInit[TC],GInit[RW] + +; LARGE64-LABEL: .toc +; LARGE64-LABEL: L..C0: +; LARGE64-NEXT: .tc .TGUninit[TE],TGUninit[TL]@m +; LARGE64-LABEL: L..C1: +; LARGE64-NEXT: .tc TGUninit[TE],TGUninit[TL] +; LARGE64-LABEL: L..C2: +; LARGE64-NEXT: .tc .TGInit[TE],TGInit[TL]@m +; LARGE64-LABEL: L..C3: +; LARGE64-NEXT: .tc TGInit[TE],TGInit[TL] +; LARGE64-LABEL: L..C4: +; LARGE64-NEXT: .tc .TIInit[TE],TIInit[TL]@m +; LARGE64-LABEL: L..C5: +; LARGE64-NEXT: .tc TIInit[TE],TIInit[TL] +; LARGE64-LABEL: L..C6: +; LARGE64-NEXT: .tc .TWInit[TE],TWInit[TL]@m +; LARGE64-LABEL: L..C7: +; LARGE64-NEXT: .tc TWInit[TE],TWInit[TL] +; LARGE64-LABEL: L..C8: +; LARGE64-NEXT: .tc GInit[TE],GInit[RW] + + attributes #0 = { nofree norecurse nounwind willreturn writeonly "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr4" "target-features"="-altivec,-bpermd,-crypto,-direct-move,-extdiv,-float128,-htm,-mma,-paired-vector-memops,-power10-vector,-power8-vector,-power9-vector,-rop-protection,-spe,-vsx" } attributes #1 = { norecurse nounwind readonly willreturn "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr4" "target-features"="-altivec,-bpermd,-crypto,-direct-move,-extdiv,-float128,-htm,-mma,-paired-vector-memops,-power10-vector,-power8-vector,-power9-vector,-rop-protection,-spe,-vsx" } diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll b/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll --- a/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll +++ b/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll @@ -4,6 +4,12 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ ; RUN: -mtriple powerpc-ibm-aix-xcoff --code-model=large < %s \ ; RUN: | FileCheck %s --check-prefix=LARGE32 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s \ +; RUN: --check-prefix=SMALL64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large < %s \ +; RUN: | FileCheck %s --check-prefix=LARGE64 @TGInit = thread_local global i32 1, align 4 @GInit = global i32 1, align 4 @@ -44,6 +50,38 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTGUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: mr 6, 3 +; SMALL64-NEXT: ld 3, L..C0(2) +; SMALL64-NEXT: ld 4, L..C1(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: stw 6, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTGUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: mr 6, 3 +; LARGE64-NEXT: addis 3, L..C0@u(2) +; LARGE64-NEXT: addis 4, L..C1@u(2) +; LARGE64-NEXT: ld 3, L..C0@l(3) +; LARGE64-NEXT: ld 4, L..C1@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: stw 6, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store i32 %Val, i32* @TGUninit, align 4 ret void @@ -82,6 +120,38 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTGInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: mr 6, 3 +; SMALL64-NEXT: ld 3, L..C2(2) +; SMALL64-NEXT: ld 4, L..C3(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: stw 6, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTGInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: mr 6, 3 +; LARGE64-NEXT: addis 3, L..C2@u(2) +; LARGE64-NEXT: addis 4, L..C3@u(2) +; LARGE64-NEXT: ld 3, L..C2@l(3) +; LARGE64-NEXT: ld 4, L..C3@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: stw 6, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store i32 %Val, i32* @TGInit, align 4 ret void @@ -120,6 +190,38 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTIUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: mr 6, 3 +; SMALL64-NEXT: ld 3, L..C4(2) +; SMALL64-NEXT: ld 4, L..C5(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: stw 6, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTIUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: mr 6, 3 +; LARGE64-NEXT: addis 3, L..C4@u(2) +; LARGE64-NEXT: addis 4, L..C5@u(2) +; LARGE64-NEXT: ld 3, L..C4@l(3) +; LARGE64-NEXT: ld 4, L..C5@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: stw 6, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store i32 %Val, i32* @TIUninit, align 4 ret void @@ -158,6 +260,38 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTWUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: mr 6, 3 +; SMALL64-NEXT: ld 3, L..C6(2) +; SMALL64-NEXT: ld 4, L..C7(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: stw 6, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTWUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: mr 6, 3 +; LARGE64-NEXT: addis 3, L..C6@u(2) +; LARGE64-NEXT: addis 4, L..C7@u(2) +; LARGE64-NEXT: ld 3, L..C6@l(3) +; LARGE64-NEXT: ld 4, L..C7@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: stw 6, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store i32 %Val, i32* @TWUninit, align 4 ret void @@ -201,6 +335,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTGUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C0(2) +; SMALL64-NEXT: ld 4, L..C1(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: lwz 3, 0(3) +; SMALL64-NEXT: lwz 4, 0(4) +; SMALL64-NEXT: add 3, 4, 3 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTGUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C0@u(2) +; LARGE64-NEXT: addis 4, L..C1@u(2) +; LARGE64-NEXT: ld 3, L..C0@l(3) +; LARGE64-NEXT: ld 4, L..C1@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: lwz 3, 0(3) +; LARGE64-NEXT: ld 4, L..C8@l(4) +; LARGE64-NEXT: lwz 4, 0(4) +; LARGE64-NEXT: add 3, 4, 3 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load i32, i32* @TGUninit, align 4 %1 = load i32, i32* @GInit, align 4 @@ -246,6 +417,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTGInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C2(2) +; SMALL64-NEXT: ld 4, L..C3(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: lwz 3, 0(3) +; SMALL64-NEXT: lwz 4, 0(4) +; SMALL64-NEXT: add 3, 4, 3 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTGInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C2@u(2) +; LARGE64-NEXT: addis 4, L..C3@u(2) +; LARGE64-NEXT: ld 3, L..C2@l(3) +; LARGE64-NEXT: ld 4, L..C3@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: lwz 3, 0(3) +; LARGE64-NEXT: ld 4, L..C8@l(4) +; LARGE64-NEXT: lwz 4, 0(4) +; LARGE64-NEXT: add 3, 4, 3 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load i32, i32* @TGInit, align 4 %1 = load i32, i32* @GInit, align 4 @@ -291,6 +499,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTIUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C4(2) +; SMALL64-NEXT: ld 4, L..C5(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: lwz 3, 0(3) +; SMALL64-NEXT: lwz 4, 0(4) +; SMALL64-NEXT: add 3, 4, 3 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTIUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C4@u(2) +; LARGE64-NEXT: addis 4, L..C5@u(2) +; LARGE64-NEXT: ld 3, L..C4@l(3) +; LARGE64-NEXT: ld 4, L..C5@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: lwz 3, 0(3) +; LARGE64-NEXT: ld 4, L..C8@l(4) +; LARGE64-NEXT: lwz 4, 0(4) +; LARGE64-NEXT: add 3, 4, 3 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load i32, i32* @TIUninit, align 4 %1 = load i32, i32* @GInit, align 4 @@ -336,6 +581,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTWUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C6(2) +; SMALL64-NEXT: ld 4, L..C7(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: lwz 3, 0(3) +; SMALL64-NEXT: lwz 4, 0(4) +; SMALL64-NEXT: add 3, 4, 3 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTWUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C6@u(2) +; LARGE64-NEXT: addis 4, L..C7@u(2) +; LARGE64-NEXT: ld 3, L..C6@l(3) +; LARGE64-NEXT: ld 4, L..C7@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: lwz 3, 0(3) +; LARGE64-NEXT: ld 4, L..C8@l(4) +; LARGE64-NEXT: lwz 4, 0(4) +; LARGE64-NEXT: add 3, 4, 3 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load i32, i32* @TWUninit, align 4 %1 = load i32, i32* @GInit, align 4 @@ -385,5 +667,45 @@ ; LARGE32-LABEL: L..C8: ; LARGE32-NEXT: .tc GInit[TE],GInit[RW] +; SMALL64-LABEL: .toc +; SMALL64-LABEL: L..C0: +; SMALL64-NEXT: .tc .TGUninit[TC],TGUninit[TL]@m +; SMALL64-LABEL: L..C1: +; SMALL64-NEXT: .tc TGUninit[TC],TGUninit[TL] +; SMALL64-LABEL: L..C2: +; SMALL64-NEXT: .tc .TGInit[TC],TGInit[TL]@m +; SMALL64-LABEL: L..C3: +; SMALL64-NEXT: .tc TGInit[TC],TGInit[TL] +; SMALL64-LABEL: L..C4: +; SMALL64-NEXT: .tc .TIUninit[TC],TIUninit[UL]@m +; SMALL64-LABEL: L..C5: +; SMALL64-NEXT: .tc TIUninit[TC],TIUninit[UL] +; SMALL64-LABEL: L..C6: +; SMALL64-NEXT: .tc .TWUninit[TC],TWUninit[TL]@m +; SMALL64-LABEL: L..C7: +; SMALL64-NEXT: .tc TWUninit[TC],TWUninit[TL] +; SMALL64-LABEL: L..C8: +; SMALL64-NEXT: .tc GInit[TC],GInit[RW] + +; LARGE64-LABEL: .toc +; LARGE64-LABEL: L..C0: +; LARGE64-NEXT: .tc .TGUninit[TE],TGUninit[TL]@m +; LARGE64-LABEL: L..C1: +; LARGE64-NEXT: .tc TGUninit[TE],TGUninit[TL] +; LARGE64-LABEL: L..C2: +; LARGE64-NEXT: .tc .TGInit[TE],TGInit[TL]@m +; LARGE64-LABEL: L..C3: +; LARGE64-NEXT: .tc TGInit[TE],TGInit[TL] +; LARGE64-LABEL: L..C4: +; LARGE64-NEXT: .tc .TIUninit[TE],TIUninit[UL]@m +; LARGE64-LABEL: L..C5: +; LARGE64-NEXT: .tc TIUninit[TE],TIUninit[UL] +; LARGE64-LABEL: L..C6: +; LARGE64-NEXT: .tc .TWUninit[TE],TWUninit[TL]@m +; LARGE64-LABEL: L..C7: +; LARGE64-NEXT: .tc TWUninit[TE],TWUninit[TL] +; LARGE64-LABEL: L..C8: +; LARGE64-NEXT: .tc GInit[TE],GInit[RW] + attributes #0 = { nofree norecurse nounwind willreturn writeonly "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr4" "target-features"="-altivec,-bpermd,-crypto,-direct-move,-extdiv,-float128,-htm,-mma,-paired-vector-memops,-power10-vector,-power8-vector,-power9-vector,-rop-protection,-spe,-vsx" } attributes #1 = { norecurse nounwind readonly willreturn "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr4" "target-features"="-altivec,-bpermd,-crypto,-direct-move,-extdiv,-float128,-htm,-mma,-paired-vector-memops,-power10-vector,-power8-vector,-power9-vector,-rop-protection,-spe,-vsx" } diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll b/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll --- a/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll +++ b/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll @@ -4,6 +4,12 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ ; RUN: -mtriple powerpc-ibm-aix-xcoff --code-model=large < %s \ ; RUN: | FileCheck %s --check-prefix=LARGE32 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s \ +; RUN: --check-prefix=SMALL64 +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec \ +; RUN: -mtriple powerpc64-ibm-aix-xcoff --code-model=large < %s \ +; RUN: | FileCheck %s --check-prefix=LARGE64 @TGInit = thread_local global i64 1, align 8 @TWInit = weak thread_local global i64 1, align 8 @@ -48,6 +54,38 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTGInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: mr 6, 3 +; SMALL64-NEXT: ld 3, L..C0(2) +; SMALL64-NEXT: ld 4, L..C1(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: std 6, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTGInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: mr 6, 3 +; LARGE64-NEXT: addis 3, L..C0@u(2) +; LARGE64-NEXT: addis 4, L..C1@u(2) +; LARGE64-NEXT: ld 3, L..C0@l(3) +; LARGE64-NEXT: ld 4, L..C1@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: std 6, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store i64 %Val, i64* @TGInit, align 8 ret void @@ -90,6 +128,38 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTIUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: mr 6, 3 +; SMALL64-NEXT: ld 3, L..C2(2) +; SMALL64-NEXT: ld 4, L..C3(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: std 6, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTIUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: mr 6, 3 +; LARGE64-NEXT: addis 3, L..C2@u(2) +; LARGE64-NEXT: addis 4, L..C3@u(2) +; LARGE64-NEXT: ld 3, L..C2@l(3) +; LARGE64-NEXT: ld 4, L..C3@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: std 6, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store i64 %Val, i64* @TIUninit, align 8 ret void @@ -132,6 +202,38 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTIInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: mr 6, 3 +; SMALL64-NEXT: ld 3, L..C4(2) +; SMALL64-NEXT: ld 4, L..C5(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: std 6, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTIInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: mr 6, 3 +; LARGE64-NEXT: addis 3, L..C4@u(2) +; LARGE64-NEXT: addis 4, L..C5@u(2) +; LARGE64-NEXT: ld 3, L..C4@l(3) +; LARGE64-NEXT: ld 4, L..C5@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: std 6, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store i64 %Val, i64* @TIInit, align 8 ret void @@ -174,6 +276,38 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: storesTWInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: mr 6, 3 +; SMALL64-NEXT: ld 3, L..C6(2) +; SMALL64-NEXT: ld 4, L..C7(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: std 6, 0(3) +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: storesTWInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: mr 6, 3 +; LARGE64-NEXT: addis 3, L..C6@u(2) +; LARGE64-NEXT: addis 4, L..C7@u(2) +; LARGE64-NEXT: ld 3, L..C6@l(3) +; LARGE64-NEXT: ld 4, L..C7@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: std 6, 0(3) +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: store i64 %Val, i64* @TWInit, align 8 ret void @@ -223,6 +357,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTGInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C0(2) +; SMALL64-NEXT: ld 4, L..C1(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: ld 3, 0(3) +; SMALL64-NEXT: ld 4, 0(4) +; SMALL64-NEXT: add 3, 4, 3 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTGInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C0@u(2) +; LARGE64-NEXT: addis 4, L..C1@u(2) +; LARGE64-NEXT: ld 3, L..C0@l(3) +; LARGE64-NEXT: ld 4, L..C1@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: ld 3, 0(3) +; LARGE64-NEXT: ld 4, L..C8@l(4) +; LARGE64-NEXT: ld 4, 0(4) +; LARGE64-NEXT: add 3, 4, 3 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load i64, i64* @TGInit, align 8 %1 = load i64, i64* @GInit, align 8 @@ -274,6 +445,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTIUninit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C2(2) +; SMALL64-NEXT: ld 4, L..C3(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: ld 3, 0(3) +; SMALL64-NEXT: ld 4, 0(4) +; SMALL64-NEXT: add 3, 4, 3 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTIUninit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C2@u(2) +; LARGE64-NEXT: addis 4, L..C3@u(2) +; LARGE64-NEXT: ld 3, L..C2@l(3) +; LARGE64-NEXT: ld 4, L..C3@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: ld 3, 0(3) +; LARGE64-NEXT: ld 4, L..C8@l(4) +; LARGE64-NEXT: ld 4, 0(4) +; LARGE64-NEXT: add 3, 4, 3 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load i64, i64* @TIUninit, align 8 %1 = load i64, i64* @GInit, align 8 @@ -325,6 +533,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTIInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C4(2) +; SMALL64-NEXT: ld 4, L..C5(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: ld 3, 0(3) +; SMALL64-NEXT: ld 4, 0(4) +; SMALL64-NEXT: add 3, 4, 3 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTIInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C4@u(2) +; LARGE64-NEXT: addis 4, L..C5@u(2) +; LARGE64-NEXT: ld 3, L..C4@l(3) +; LARGE64-NEXT: ld 4, L..C5@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: ld 3, 0(3) +; LARGE64-NEXT: ld 4, L..C8@l(4) +; LARGE64-NEXT: ld 4, 0(4) +; LARGE64-NEXT: add 3, 4, 3 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load i64, i64* @TIInit, align 8 %1 = load i64, i64* @GInit, align 8 @@ -376,6 +621,43 @@ ; LARGE32-NEXT: lwz 0, 8(1) ; LARGE32-NEXT: mtlr 0 ; LARGE32-NEXT: blr +; +; SMALL64-LABEL: loadsTWInit: +; SMALL64: # %bb.0: # %entry +; SMALL64-NEXT: mflr 0 +; SMALL64-NEXT: std 0, 16(1) +; SMALL64-NEXT: stdu 1, -48(1) +; SMALL64-NEXT: ld 3, L..C6(2) +; SMALL64-NEXT: ld 4, L..C7(2) +; SMALL64-NEXT: bla .__tls_get_addr +; SMALL64-NEXT: ld 4, L..C8(2) +; SMALL64-NEXT: ld 3, 0(3) +; SMALL64-NEXT: ld 4, 0(4) +; SMALL64-NEXT: add 3, 4, 3 +; SMALL64-NEXT: addi 1, 1, 48 +; SMALL64-NEXT: ld 0, 16(1) +; SMALL64-NEXT: mtlr 0 +; SMALL64-NEXT: blr +; +; LARGE64-LABEL: loadsTWInit: +; LARGE64: # %bb.0: # %entry +; LARGE64-NEXT: mflr 0 +; LARGE64-NEXT: std 0, 16(1) +; LARGE64-NEXT: stdu 1, -48(1) +; LARGE64-NEXT: addis 3, L..C6@u(2) +; LARGE64-NEXT: addis 4, L..C7@u(2) +; LARGE64-NEXT: ld 3, L..C6@l(3) +; LARGE64-NEXT: ld 4, L..C7@l(4) +; LARGE64-NEXT: bla .__tls_get_addr +; LARGE64-NEXT: addis 4, L..C8@u(2) +; LARGE64-NEXT: ld 3, 0(3) +; LARGE64-NEXT: ld 4, L..C8@l(4) +; LARGE64-NEXT: ld 4, 0(4) +; LARGE64-NEXT: add 3, 4, 3 +; LARGE64-NEXT: addi 1, 1, 48 +; LARGE64-NEXT: ld 0, 16(1) +; LARGE64-NEXT: mtlr 0 +; LARGE64-NEXT: blr entry: %0 = load i64, i64* @TWInit, align 8 %1 = load i64, i64* @GInit, align 8 @@ -424,5 +706,46 @@ ; LARGE32-NEXT: .tc TWInit[TE],TWInit[TL] ; LARGE32-LABEL: L..C8: ; LARGE32-NEXT: .tc GInit[TE],GInit[RW] + +; SMALL64-LABEL: .toc +; SMALL64-LABEL: L..C0: +; SMALL64-NEXT: .tc .TGInit[TC],TGInit[TL]@m +; SMALL64-LABEL: L..C1: +; SMALL64-NEXT: .tc TGInit[TC],TGInit[TL] +; SMALL64-LABEL: L..C2: +; SMALL64-NEXT: .tc .TIUninit[TC],TIUninit[UL]@m +; SMALL64-LABEL: L..C3: +; SMALL64-NEXT: .tc TIUninit[TC],TIUninit[UL] +; SMALL64-LABEL: L..C4: +; SMALL64-NEXT: .tc .TIInit[TC],TIInit[TL]@m +; SMALL64-LABEL: L..C5: +; SMALL64-NEXT: .tc TIInit[TC],TIInit[TL] +; SMALL64-LABEL: L..C6: +; SMALL64-NEXT: .tc .TWInit[TC],TWInit[TL]@m +; SMALL64-LABEL: L..C7: +; SMALL64-NEXT: .tc TWInit[TC],TWInit[TL] +; SMALL64-LABEL: L..C8: +; SMALL64-NEXT: .tc GInit[TC],GInit[RW] + +; LARGE64-LABEL: .toc +; LARGE64-LABEL: L..C0: +; LARGE64-NEXT: .tc .TGInit[TE],TGInit[TL]@m +; LARGE64-LABEL: L..C1: +; LARGE64-NEXT: .tc TGInit[TE],TGInit[TL] +; LARGE64-LABEL: L..C2: +; LARGE64-NEXT: .tc .TIUninit[TE],TIUninit[UL]@m +; LARGE64-LABEL: L..C3: +; LARGE64-NEXT: .tc TIUninit[TE],TIUninit[UL] +; LARGE64-LABEL: L..C4: +; LARGE64-NEXT: .tc .TIInit[TE],TIInit[TL]@m +; LARGE64-LABEL: L..C5: +; LARGE64-NEXT: .tc TIInit[TE],TIInit[TL] +; LARGE64-LABEL: L..C6: +; LARGE64-NEXT: .tc .TWInit[TE],TWInit[TL]@m +; LARGE64-LABEL: L..C7: +; LARGE64-NEXT: .tc TWInit[TE],TWInit[TL] +; LARGE64-LABEL: L..C8: +; LARGE64-NEXT: .tc GInit[TE],GInit[RW] + attributes #0 = { nofree norecurse nounwind willreturn writeonly "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr4" "target-features"="-altivec,-bpermd,-crypto,-direct-move,-extdiv,-float128,-htm,-mma,-paired-vector-memops,-power10-vector,-power8-vector,-power9-vector,-rop-protection,-spe,-vsx" } attributes #1 = { norecurse nounwind readonly willreturn "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="pwr4" "target-features"="-altivec,-bpermd,-crypto,-direct-move,-extdiv,-float128,-htm,-mma,-paired-vector-memops,-power10-vector,-power8-vector,-power9-vector,-rop-protection,-spe,-vsx" }