llvm.org GIT mirror llvm / 43c3e8b
Merging r221703: ------------------------------------------------------------------------ r221703 | wschmidt | 2014-11-11 20:44:09 +0000 (Tue, 11 Nov 2014) | 48 lines [PowerPC] Replace foul hackery with real calls to __tls_get_addr My original support for the general dynamic and local dynamic TLS models contained some fairly obtuse hacks to generate calls to __tls_get_addr when lowering a TargetGlobalAddress. Rather than generating real calls, special GET_TLS_ADDR nodes were used to wrap the calls and only reveal them at assembly time. I attempted to provide correct parameter and return values by chaining CopyToReg and CopyFromReg nodes onto the GET_TLS_ADDR nodes, but this was also not fully correct. Problems were seen with two back-to-back stores to TLS variables, where the call sequences ended up overlapping with unhappy results. Additionally, since these weren't real calls, the proper register side effects of a call were not recorded, so clobbered values were kept live across the calls. The proper thing to do is to lower these into calls in the first place. This is relatively straightforward; see the changes to PPCTargetLowering::LowerGlobalTLSAddress() in PPCISelLowering.cpp. The changes here are standard call lowering, except that we need to track the fact that these calls will require a relocation. This is done by adding a machine operand flag of MO_TLSLD or MO_TLSGD to the TargetGlobalAddress operand that appears earlier in the sequence. The calls to LowerCallTo() eventually find their way to LowerCall_64SVR4() or LowerCall_32SVR4(), which call FinishCall(), which calls PrepareCall(). In PrepareCall(), we detect the calls to __tls_get_addr and immediately snag the TargetGlobalTLSAddress with the annotated relocation information. This becomes an extra operand on the call following the callee, which is expected for nodes of type tlscall. We change the call opcode to CALL_TLS for this case. Back in FinishCall(), we change it again to CALL_NOP_TLS for 64-bit only, since we require a TOC-restore nop following the call for the 64-bit ABIs. During selection, patterns in PPCInstrInfo.td and PPCInstr64Bit.td convert the CALL_TLS nodes into BL_TLS nodes, and convert the CALL_NOP_TLS nodes into BL8_NOP_TLS nodes. This replaces the code removed from PPCAsmPrinter.cpp, as the BL_TLS or BL8_NOP_TLS nodes can now be emitted normally using their patterns and the associated printTLSCall print method. Finally, as a result of these changes, all references to get-tls-addr in its various guises are no longer used, so they have been removed. There are existing TLS tests to verify the changes haven't messed anything up). I've added one new test that verifies that the problem with the original code has been fixed. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@223742 91177308-0d34-0410-b5e6-96231b3b80d8 Hal Finkel 5 years ago
8 changed file(s) with 115 addition(s) and 125 deletion(s). Raw diff Collapse all Expand all
9595 MO_TOC_LO = 7 << 4,
9696
9797 // Symbol for VK_PPC_TLS fixup attached to an ADD instruction
98 MO_TLS = 8 << 4
98 MO_TLS = 8 << 4,
99
100 // Symbols for VK_PPC_TLSGD and VK_PPC_TLSLD in __tls_get_addr
101 // call sequences.
102 MO_TLSLD = 9 << 4,
103 MO_TLSGD = 10 << 4
99104 };
100105 } // end namespace PPCII
101106
668668 .addExpr(SymGotTlsGD));
669669 return;
670670 }
671 case PPC::GETtlsADDR:
672 // Transform: %X3 = GETtlsADDR %X3,
673 // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsgd)
674 case PPC::GETtlsADDR32: {
675 // Transform: %R3 = GETtlsADDR32 %R3,
676 // Into: BL_TLS __tls_get_addr(sym@tlsgd)@PLT
677
678 StringRef Name = "__tls_get_addr";
679 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
680 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
681
682 if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
683 TM.getRelocationModel() == Reloc::PIC_)
684 Kind = MCSymbolRefExpr::VK_PLT;
685 const MCSymbolRefExpr *TlsRef =
686 MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
687 const MachineOperand &MO = MI->getOperand(2);
688 const GlobalValue *GValue = MO.getGlobal();
689 MCSymbol *MOSymbol = getSymbol(GValue);
690 const MCExpr *SymVar =
691 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
692 OutContext);
693 EmitToStreamer(OutStreamer,
694 MCInstBuilder(Subtarget.isPPC64() ?
695 PPC::BL8_NOP_TLS : PPC::BL_TLS)
696 .addExpr(TlsRef)
697 .addExpr(SymVar));
698 return;
699 }
700671 case PPC::ADDIStlsldHA: {
701672 // Transform: %Xd = ADDIStlsldHA %X2,
702673 // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha
732703 .addReg(MI->getOperand(0).getReg())
733704 .addReg(MI->getOperand(1).getReg())
734705 .addExpr(SymGotTlsLD));
735 return;
736 }
737 case PPC::GETtlsldADDR:
738 // Transform: %X3 = GETtlsldADDR %X3,
739 // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsld)
740 case PPC::GETtlsldADDR32: {
741 // Transform: %R3 = GETtlsldADDR32 %R3,
742 // Into: BL_TLS __tls_get_addr(sym@tlsld)@PLT
743
744 StringRef Name = "__tls_get_addr";
745 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
746 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
747
748 if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
749 TM.getRelocationModel() == Reloc::PIC_)
750 Kind = MCSymbolRefExpr::VK_PLT;
751
752 const MCSymbolRefExpr *TlsRef =
753 MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
754 const MachineOperand &MO = MI->getOperand(2);
755 const GlobalValue *GValue = MO.getGlobal();
756 MCSymbol *MOSymbol = getSymbol(GValue);
757 const MCExpr *SymVar =
758 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
759 OutContext);
760 EmitToStreamer(OutStreamer,
761 MCInstBuilder(Subtarget.isPPC64() ?
762 PPC::BL8_NOP_TLS : PPC::BL_TLS)
763 .addExpr(TlsRef)
764 .addExpr(SymVar));
765706 return;
766707 }
767708 case PPC::ADDISdtprelHA:
780780 case PPCISD::SHL: return "PPCISD::SHL";
781781 case PPCISD::CALL: return "PPCISD::CALL";
782782 case PPCISD::CALL_NOP: return "PPCISD::CALL_NOP";
783 case PPCISD::CALL_TLS: return "PPCISD::CALL_TLS";
784 case PPCISD::CALL_NOP_TLS: return "PPCISD::CALL_NOP_TLS";
783785 case PPCISD::MTCTR: return "PPCISD::MTCTR";
784786 case PPCISD::BCTRL: return "PPCISD::BCTRL";
785787 case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG";
809811 case PPCISD::ADD_TLS: return "PPCISD::ADD_TLS";
810812 case PPCISD::ADDIS_TLSGD_HA: return "PPCISD::ADDIS_TLSGD_HA";
811813 case PPCISD::ADDI_TLSGD_L: return "PPCISD::ADDI_TLSGD_L";
812 case PPCISD::GET_TLS_ADDR: return "PPCISD::GET_TLS_ADDR";
813814 case PPCISD::ADDIS_TLSLD_HA: return "PPCISD::ADDIS_TLSLD_HA";
814815 case PPCISD::ADDI_TLSLD_L: return "PPCISD::ADDI_TLSLD_L";
815 case PPCISD::GET_TLSLD_ADDR: return "PPCISD::GET_TLSLD_ADDR";
816816 case PPCISD::ADDIS_DTPREL_HA: return "PPCISD::ADDIS_DTPREL_HA";
817817 case PPCISD::ADDI_DTPREL_L: return "PPCISD::ADDI_DTPREL_L";
818818 case PPCISD::VADD_SPLAT: return "PPCISD::VADD_SPLAT";
16481648 return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG);
16491649 }
16501650
1651 // Generate a call to __tls_get_addr for the given GOT entry Op.
1652 std::pair
1653 PPCTargetLowering::lowerTLSCall(SDValue Op, SDLoc dl,
1654 SelectionDAG &DAG) const {
1655
1656 Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext());
1657 TargetLowering::ArgListTy Args;
1658 TargetLowering::ArgListEntry Entry;
1659 Entry.Node = Op;
1660 Entry.Ty = IntPtrTy;
1661 Args.push_back(Entry);
1662
1663 TargetLowering::CallLoweringInfo CLI(DAG);
1664 CLI.setDebugLoc(dl).setChain(DAG.getEntryNode())
1665 .setCallee(CallingConv::C, IntPtrTy,
1666 DAG.getTargetExternalSymbol("__tls_get_addr", getPointerTy()),
1667 std::move(Args), 0);
1668
1669 return LowerCallTo(CLI);
1670 }
1671
16511672 SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
16521673 SelectionDAG &DAG) const {
16531674
16911712 }
16921713
16931714 if (Model == TLSModel::GeneralDynamic) {
1694 SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
1715 SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
1716 PPCII::MO_TLSGD);
16951717 SDValue GOTPtr;
16961718 if (is64bit) {
16971719 SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
17021724 }
17031725 SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSGD_L, dl, PtrVT,
17041726 GOTPtr, TGA);
1705
1706 // We need a chain node, and don't have one handy. The underlying
1707 // call has no side effects, so using the function entry node
1708 // suffices.
1709 SDValue Chain = DAG.getEntryNode();
1710 Chain = DAG.getCopyToReg(Chain, dl,
1711 is64bit ? PPC::X3 : PPC::R3, GOTEntry);
1712 SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3,
1713 is64bit ? MVT::i64 : MVT::i32);
1714 SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLS_ADDR, dl,
1715 PtrVT, ParmReg, TGA);
1716 // The return value from GET_TLS_ADDR really is in X3 already, but
1717 // some hacks are needed here to tie everything together. The extra
1718 // copies dissolve during subsequent transforms.
1719 Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr);
1720 return DAG.getCopyFromReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, PtrVT);
1727 std::pair CallResult = lowerTLSCall(GOTEntry, dl, DAG);
1728 return CallResult.first;
17211729 }
17221730
17231731 if (Model == TLSModel::LocalDynamic) {
1724 SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
1732 SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
1733 PPCII::MO_TLSLD);
17251734 SDValue GOTPtr;
17261735 if (is64bit) {
17271736 SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
17321741 }
17331742 SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSLD_L, dl, PtrVT,
17341743 GOTPtr, TGA);
1735
1736 // We need a chain node, and don't have one handy. The underlying
1737 // call has no side effects, so using the function entry node
1738 // suffices.
1739 SDValue Chain = DAG.getEntryNode();
1740 Chain = DAG.getCopyToReg(Chain, dl,
1741 is64bit ? PPC::X3 : PPC::R3, GOTEntry);
1742 SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3,
1743 is64bit ? MVT::i64 : MVT::i32);
1744 SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLSLD_ADDR, dl,
1745 PtrVT, ParmReg, TGA);
1746 // The return value from GET_TLSLD_ADDR really is in X3 already, but
1747 // some hacks are needed here to tie everything together. The extra
1748 // copies dissolve during subsequent transforms.
1749 Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr);
1744 std::pair CallResult = lowerTLSCall(GOTEntry, dl, DAG);
1745 SDValue TLSAddr = CallResult.first;
1746 SDValue Chain = CallResult.second;
17501747 SDValue DtvOffsetHi = DAG.getNode(PPCISD::ADDIS_DTPREL_HA, dl, PtrVT,
1751 Chain, ParmReg, TGA);
1748 Chain, TLSAddr, TGA);
17521749 return DAG.getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
17531750 }
17541751
37113708 if (Callee.getNode()) {
37123709 Ops.push_back(Chain);
37133710 Ops.push_back(Callee);
3711
3712 // If this is a call to __tls_get_addr, find the symbol whose address
3713 // is to be taken and add it to the list. This will be used to
3714 // generate __tls_get_addr(@tlsgd) or __tls_get_addr(@tlsld).
3715 // We find the symbol by walking the chain to the CopyFromReg, walking
3716 // back from the CopyFromReg to the ADDI_TLSGD_L or ADDI_TLSLD_L, and
3717 // pulling the symbol from that node.
3718 if (ExternalSymbolSDNode *S = dyn_cast(Callee))
3719 if (!strcmp(S->getSymbol(), "__tls_get_addr")) {
3720 assert(!needIndirectCall && "Indirect call to __tls_get_addr???");
3721 SDNode *AddI = Chain.getNode()->getOperand(2).getNode();
3722 SDValue TGTAddr = AddI->getOperand(1);
3723 assert(TGTAddr.getNode()->getOpcode() == ISD::TargetGlobalTLSAddress &&
3724 "Didn't find target global TLS address where we expected one");
3725 Ops.push_back(TGTAddr);
3726 CallOpc = PPCISD::CALL_TLS;
3727 }
37143728 }
37153729 // If this is a tail call add stack pointer delta.
37163730 if (isTailCall)
38623876 DAG.getTarget().getRelocationModel() == Reloc::PIC_)) {
38633877 // Otherwise insert NOP for non-local calls.
38643878 CallOpc = PPCISD::CALL_NOP;
3865 }
3879 } else if (CallOpc == PPCISD::CALL_TLS)
3880 // For 64-bit SVR4, TLS calls are always non-local.
3881 CallOpc = PPCISD::CALL_NOP_TLS;
38663882 }
38673883
38683884 Chain = DAG.getNode(CallOpc, dl, NodeTys, Ops);
9898 /// SVR4 calls.
9999 CALL, CALL_NOP,
100100
101 /// CALL_TLS and CALL_NOP_TLS - Versions of CALL and CALL_NOP used
102 /// to access TLS variables.
103 CALL_TLS, CALL_NOP_TLS,
104
101105 /// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a
102106 /// MTCTR instruction.
103107 MTCTR,
213217 /// sym\@got\@tlsgd\@l.
214218 ADDI_TLSGD_L,
215219
216 /// G8RC = GET_TLS_ADDR %X3, Symbol - For the general-dynamic TLS
217 /// model, produces a call to __tls_get_addr(sym\@tlsgd).
218 GET_TLS_ADDR,
219
220220 /// G8RC = ADDIS_TLSLD_HA %X2, Symbol - For the local-dynamic TLS
221221 /// model, produces an ADDIS8 instruction that adds the GOT base
222222 /// register to sym\@got\@tlsld\@ha.
226226 /// model, produces an ADDI8 instruction that adds G8RReg to
227227 /// sym\@got\@tlsld\@l.
228228 ADDI_TLSLD_L,
229
230 /// G8RC = GET_TLSLD_ADDR %X3, Symbol - For the local-dynamic TLS
231 /// model, produces a call to __tls_get_addr(sym\@tlsld).
232 GET_TLSLD_ADDR,
233229
234230 /// G8RC = ADDIS_DTPREL_HA %X3, Symbol, Chain - For the
235231 /// local-dynamic TLS model, produces an ADDIS8 instruction
551547 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
552548 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
553549 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
550 std::pair lowerTLSCall(SDValue Op, SDLoc dl,
551 SelectionDAG &DAG) const;
554552 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
555553 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
556554 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
186186 (BL8 texternalsym:$dst)>;
187187 def : Pat<(PPCcall_nop (i64 texternalsym:$dst)),
188188 (BL8_NOP texternalsym:$dst)>;
189
190 def : Pat<(PPCcall_nop_tls texternalsym:$func, tglobaltlsaddr:$sym),
191 (BL8_NOP_TLS texternalsym:$func, tglobaltlsaddr:$sym)>;
189192
190193 // Atomic operations
191194 let usesCustomInserter = 1 in {
875878 [(set i64:$rD,
876879 (PPCaddiTlsgdL i64:$reg, tglobaltlsaddr:$disp))]>,
877880 isPPC64;
878 def GETtlsADDR : Pseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
879 "#GETtlsADDR",
880 [(set i64:$rD,
881 (PPCgetTlsAddr i64:$reg, tglobaltlsaddr:$sym))]>,
882 isPPC64;
883881 def ADDIStlsldHA: Pseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
884882 "#ADDIStlsldHA",
885883 [(set i64:$rD,
890888 [(set i64:$rD,
891889 (PPCaddiTlsldL i64:$reg, tglobaltlsaddr:$disp))]>,
892890 isPPC64;
893 def GETtlsldADDR : Pseudo<(outs g8rc:$rD), (ins g8rc:$reg, tlsgd:$sym),
894 "#GETtlsldADDR",
895 [(set i64:$rD,
896 (PPCgetTlsldAddr i64:$reg, tglobaltlsaddr:$sym))]>,
897 isPPC64;
898891 def ADDISdtprelHA: Pseudo<(outs g8rc:$rD), (ins g8rc_nox0:$reg, s16imm64:$disp),
899892 "#ADDISdtprelHA",
900893 [(set i64:$rD,
109109 def PPCaddTls : SDNode<"PPCISD::ADD_TLS", SDTIntBinOp, []>;
110110 def PPCaddisTlsgdHA : SDNode<"PPCISD::ADDIS_TLSGD_HA", SDTIntBinOp>;
111111 def PPCaddiTlsgdL : SDNode<"PPCISD::ADDI_TLSGD_L", SDTIntBinOp>;
112 def PPCgetTlsAddr : SDNode<"PPCISD::GET_TLS_ADDR", SDTIntBinOp>;
113112 def PPCaddisTlsldHA : SDNode<"PPCISD::ADDIS_TLSLD_HA", SDTIntBinOp>;
114113 def PPCaddiTlsldL : SDNode<"PPCISD::ADDI_TLSLD_L", SDTIntBinOp>;
115 def PPCgetTlsldAddr : SDNode<"PPCISD::GET_TLSLD_ADDR", SDTIntBinOp>;
116114 def PPCaddisDtprelHA : SDNode<"PPCISD::ADDIS_DTPREL_HA", SDTIntBinOp,
117115 [SDNPHasChain]>;
118116 def PPCaddiDtprelL : SDNode<"PPCISD::ADDI_DTPREL_L", SDTIntBinOp>;
135133 def PPCcall : SDNode<"PPCISD::CALL", SDT_PPCCall,
136134 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
137135 SDNPVariadic]>;
136 def PPCcall_tls : SDNode<"PPCISD::CALL_TLS", SDT_PPCCall,
137 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
138 SDNPVariadic]>;
138139 def PPCcall_nop : SDNode<"PPCISD::CALL_NOP", SDT_PPCCall,
139140 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
140141 SDNPVariadic]>;
142 def PPCcall_nop_tls : SDNode<"PPCISD::CALL_NOP_TLS", SDT_PPCCall,
143 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
144 SDNPVariadic]>;
141145 def PPCload : SDNode<"PPCISD::LOAD", SDTypeProfile<1, 1, []>,
142146 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
143147 def PPCload_toc : SDNode<"PPCISD::LOAD_TOC", SDTypeProfile<0, 1, []>,
23652369 def : Pat<(PPCcall (i32 texternalsym:$dst)),
23662370 (BL texternalsym:$dst)>;
23672371
2372 def : Pat<(PPCcall_tls texternalsym:$func, tglobaltlsaddr:$sym),
2373 (BL_TLS texternalsym:$func, tglobaltlsaddr:$sym)>;
23682374
23692375 def : Pat<(PPCtc_return (i32 tglobaladdr:$dst), imm:$imm),
23702376 (TCRETURNdi tglobaladdr:$dst, imm:$imm)>;
24202426 "#ADDItlsgdL32",
24212427 [(set i32:$rD,
24222428 (PPCaddiTlsgdL i32:$reg, tglobaltlsaddr:$disp))]>;
2423 def GETtlsADDR32 : Pseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
2424 "#GETtlsADDR32",
2425 [(set i32:$rD,
2426 (PPCgetTlsAddr i32:$reg, tglobaltlsaddr:$sym))]>;
24272429 def ADDItlsldL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
24282430 "#ADDItlsldL32",
24292431 [(set i32:$rD,
24302432 (PPCaddiTlsldL i32:$reg, tglobaltlsaddr:$disp))]>;
2431 def GETtlsldADDR32 : Pseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
2432 "#GETtlsldADDR32",
2433 [(set i32:$rD,
2434 (PPCgetTlsldAddr i32:$reg, tglobaltlsaddr:$sym))]>;
24352433 def ADDIdtprelL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
24362434 "#ADDIdtprelL32",
24372435 [(set i32:$rD,
136136 case PPCII::MO_TLS:
137137 RefKind = MCSymbolRefExpr::VK_PPC_TLS;
138138 break;
139 case PPCII::MO_TLSGD:
140 RefKind = MCSymbolRefExpr::VK_PPC_TLSGD;
141 break;
142 case PPCII::MO_TLSLD:
143 RefKind = MCSymbolRefExpr::VK_PPC_TLSLD;
144 break;
139145 }
140146
141147 if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && !isDarwin)
0 ; RUN: llc -march=ppc64 -mcpu=pwr7 -O2 -relocation-model=pic < %s | FileCheck %s
1
2 target datalayout = "e-m:e-i64:64-n32:64"
3 target triple = "powerpc64le-unknown-linux-gnu"
4
5 ; Test back-to-back stores of TLS variables to ensure call sequences no
6 ; longer overlap.
7
8 @__once_callable = external thread_local global i8**
9 @__once_call = external thread_local global void ()*
10
11 define i64 @call_once(i64 %flag, i8* %ptr) {
12 entry:
13 %var = alloca i8*, align 8
14 store i8* %ptr, i8** %var, align 8
15 store i8** %var, i8*** @__once_callable, align 8
16 store void ()* @__once_call_impl, void ()** @__once_call, align 8
17 ret i64 %flag
18 }
19
20 ; CHECK-LABEL: call_once:
21 ; CHECK: addis 3, 2, __once_callable@got@tlsgd@ha
22 ; CHECK: addi 3, 3, __once_callable@got@tlsgd@l
23 ; CHECK: bl __tls_get_addr(__once_callable@tlsgd)
24 ; CHECK-NEXT: nop
25 ; CHECK: std {{[0-9]+}}, 0(3)
26 ; CHECK: addis 3, 2, __once_call@got@tlsgd@ha
27 ; CHECK: addi 3, 3, __once_call@got@tlsgd@l
28 ; CHECK: bl __tls_get_addr(__once_call@tlsgd)
29 ; CHECK-NEXT: nop
30 ; CHECK: std {{[0-9]+}}, 0(3)
31
32 declare void @__once_call_impl()