llvm.org GIT mirror llvm / 10161a0
[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/trunk@221703 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Schmidt 5 years ago
8 changed file(s) with 115 addition(s) and 125 deletion(s). Raw diff Collapse all Expand all
9292 MO_TOC_LO = 7 << 4,
9393
9494 // Symbol for VK_PPC_TLS fixup attached to an ADD instruction
95 MO_TLS = 8 << 4
95 MO_TLS = 8 << 4,
96
97 // Symbols for VK_PPC_TLSGD and VK_PPC_TLSLD in __tls_get_addr
98 // call sequences.
99 MO_TLSLD = 9 << 4,
100 MO_TLSGD = 10 << 4
96101 };
97102 } // end namespace PPCII
98103
680680 .addExpr(SymGotTlsGD));
681681 return;
682682 }
683 case PPC::GETtlsADDR:
684 // Transform: %X3 = GETtlsADDR %X3,
685 // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsgd)
686 case PPC::GETtlsADDR32: {
687 // Transform: %R3 = GETtlsADDR32 %R3,
688 // Into: BL_TLS __tls_get_addr(sym@tlsgd)@PLT
689
690 StringRef Name = "__tls_get_addr";
691 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
692 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
693
694 if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
695 TM.getRelocationModel() == Reloc::PIC_)
696 Kind = MCSymbolRefExpr::VK_PLT;
697 const MCSymbolRefExpr *TlsRef =
698 MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
699 const MachineOperand &MO = MI->getOperand(2);
700 const GlobalValue *GValue = MO.getGlobal();
701 MCSymbol *MOSymbol = getSymbol(GValue);
702 const MCExpr *SymVar =
703 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSGD,
704 OutContext);
705 EmitToStreamer(OutStreamer,
706 MCInstBuilder(Subtarget.isPPC64() ?
707 PPC::BL8_NOP_TLS : PPC::BL_TLS)
708 .addExpr(TlsRef)
709 .addExpr(SymVar));
710 return;
711 }
712683 case PPC::ADDIStlsldHA: {
713684 // Transform: %Xd = ADDIStlsldHA %X2,
714685 // Into: %Xd = ADDIS8 %X2, sym@got@tlsld@ha
744715 .addReg(MI->getOperand(0).getReg())
745716 .addReg(MI->getOperand(1).getReg())
746717 .addExpr(SymGotTlsLD));
747 return;
748 }
749 case PPC::GETtlsldADDR:
750 // Transform: %X3 = GETtlsldADDR %X3,
751 // Into: BL8_NOP_TLS __tls_get_addr(sym@tlsld)
752 case PPC::GETtlsldADDR32: {
753 // Transform: %R3 = GETtlsldADDR32 %R3,
754 // Into: BL_TLS __tls_get_addr(sym@tlsld)@PLT
755
756 StringRef Name = "__tls_get_addr";
757 MCSymbol *TlsGetAddr = OutContext.GetOrCreateSymbol(Name);
758 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
759
760 if (!Subtarget.isPPC64() && !Subtarget.isDarwin() &&
761 TM.getRelocationModel() == Reloc::PIC_)
762 Kind = MCSymbolRefExpr::VK_PLT;
763
764 const MCSymbolRefExpr *TlsRef =
765 MCSymbolRefExpr::Create(TlsGetAddr, Kind, OutContext);
766 const MachineOperand &MO = MI->getOperand(2);
767 const GlobalValue *GValue = MO.getGlobal();
768 MCSymbol *MOSymbol = getSymbol(GValue);
769 const MCExpr *SymVar =
770 MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_TLSLD,
771 OutContext);
772 EmitToStreamer(OutStreamer,
773 MCInstBuilder(Subtarget.isPPC64() ?
774 PPC::BL8_NOP_TLS : PPC::BL_TLS)
775 .addExpr(TlsRef)
776 .addExpr(SymVar));
777718 return;
778719 }
779720 case PPC::ADDISdtprelHA:
779779 case PPCISD::SHL: return "PPCISD::SHL";
780780 case PPCISD::CALL: return "PPCISD::CALL";
781781 case PPCISD::CALL_NOP: return "PPCISD::CALL_NOP";
782 case PPCISD::CALL_TLS: return "PPCISD::CALL_TLS";
783 case PPCISD::CALL_NOP_TLS: return "PPCISD::CALL_NOP_TLS";
782784 case PPCISD::MTCTR: return "PPCISD::MTCTR";
783785 case PPCISD::BCTRL: return "PPCISD::BCTRL";
784786 case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG";
808810 case PPCISD::ADD_TLS: return "PPCISD::ADD_TLS";
809811 case PPCISD::ADDIS_TLSGD_HA: return "PPCISD::ADDIS_TLSGD_HA";
810812 case PPCISD::ADDI_TLSGD_L: return "PPCISD::ADDI_TLSGD_L";
811 case PPCISD::GET_TLS_ADDR: return "PPCISD::GET_TLS_ADDR";
812813 case PPCISD::ADDIS_TLSLD_HA: return "PPCISD::ADDIS_TLSLD_HA";
813814 case PPCISD::ADDI_TLSLD_L: return "PPCISD::ADDI_TLSLD_L";
814 case PPCISD::GET_TLSLD_ADDR: return "PPCISD::GET_TLSLD_ADDR";
815815 case PPCISD::ADDIS_DTPREL_HA: return "PPCISD::ADDIS_DTPREL_HA";
816816 case PPCISD::ADDI_DTPREL_L: return "PPCISD::ADDI_DTPREL_L";
817817 case PPCISD::VADD_SPLAT: return "PPCISD::VADD_SPLAT";
16551655 return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG);
16561656 }
16571657
1658 // Generate a call to __tls_get_addr for the given GOT entry Op.
1659 std::pair
1660 PPCTargetLowering::lowerTLSCall(SDValue Op, SDLoc dl,
1661 SelectionDAG &DAG) const {
1662
1663 Type *IntPtrTy = getDataLayout()->getIntPtrType(*DAG.getContext());
1664 TargetLowering::ArgListTy Args;
1665 TargetLowering::ArgListEntry Entry;
1666 Entry.Node = Op;
1667 Entry.Ty = IntPtrTy;
1668 Args.push_back(Entry);
1669
1670 TargetLowering::CallLoweringInfo CLI(DAG);
1671 CLI.setDebugLoc(dl).setChain(DAG.getEntryNode())
1672 .setCallee(CallingConv::C, IntPtrTy,
1673 DAG.getTargetExternalSymbol("__tls_get_addr", getPointerTy()),
1674 std::move(Args), 0);
1675
1676 return LowerCallTo(CLI);
1677 }
1678
16581679 SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
16591680 SelectionDAG &DAG) const {
16601681
16981719 }
16991720
17001721 if (Model == TLSModel::GeneralDynamic) {
1701 SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
1722 SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
1723 PPCII::MO_TLSGD);
17021724 SDValue GOTPtr;
17031725 if (is64bit) {
17041726 SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
17091731 }
17101732 SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSGD_L, dl, PtrVT,
17111733 GOTPtr, TGA);
1712
1713 // We need a chain node, and don't have one handy. The underlying
1714 // call has no side effects, so using the function entry node
1715 // suffices.
1716 SDValue Chain = DAG.getEntryNode();
1717 Chain = DAG.getCopyToReg(Chain, dl,
1718 is64bit ? PPC::X3 : PPC::R3, GOTEntry);
1719 SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3,
1720 is64bit ? MVT::i64 : MVT::i32);
1721 SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLS_ADDR, dl,
1722 PtrVT, ParmReg, TGA);
1723 // The return value from GET_TLS_ADDR really is in X3 already, but
1724 // some hacks are needed here to tie everything together. The extra
1725 // copies dissolve during subsequent transforms.
1726 Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr);
1727 return DAG.getCopyFromReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, PtrVT);
1734 std::pair CallResult = lowerTLSCall(GOTEntry, dl, DAG);
1735 return CallResult.first;
17281736 }
17291737
17301738 if (Model == TLSModel::LocalDynamic) {
1731 SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
1739 SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
1740 PPCII::MO_TLSLD);
17321741 SDValue GOTPtr;
17331742 if (is64bit) {
17341743 SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
17391748 }
17401749 SDValue GOTEntry = DAG.getNode(PPCISD::ADDI_TLSLD_L, dl, PtrVT,
17411750 GOTPtr, TGA);
1742
1743 // We need a chain node, and don't have one handy. The underlying
1744 // call has no side effects, so using the function entry node
1745 // suffices.
1746 SDValue Chain = DAG.getEntryNode();
1747 Chain = DAG.getCopyToReg(Chain, dl,
1748 is64bit ? PPC::X3 : PPC::R3, GOTEntry);
1749 SDValue ParmReg = DAG.getRegister(is64bit ? PPC::X3 : PPC::R3,
1750 is64bit ? MVT::i64 : MVT::i32);
1751 SDValue TLSAddr = DAG.getNode(PPCISD::GET_TLSLD_ADDR, dl,
1752 PtrVT, ParmReg, TGA);
1753 // The return value from GET_TLSLD_ADDR really is in X3 already, but
1754 // some hacks are needed here to tie everything together. The extra
1755 // copies dissolve during subsequent transforms.
1756 Chain = DAG.getCopyToReg(Chain, dl, is64bit ? PPC::X3 : PPC::R3, TLSAddr);
1751 std::pair CallResult = lowerTLSCall(GOTEntry, dl, DAG);
1752 SDValue TLSAddr = CallResult.first;
1753 SDValue Chain = CallResult.second;
17571754 SDValue DtvOffsetHi = DAG.getNode(PPCISD::ADDIS_DTPREL_HA, dl, PtrVT,
1758 Chain, ParmReg, TGA);
1755 Chain, TLSAddr, TGA);
17591756 return DAG.getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
17601757 }
17611758
37153712 if (Callee.getNode()) {
37163713 Ops.push_back(Chain);
37173714 Ops.push_back(Callee);
3715
3716 // If this is a call to __tls_get_addr, find the symbol whose address
3717 // is to be taken and add it to the list. This will be used to
3718 // generate __tls_get_addr(@tlsgd) or __tls_get_addr(@tlsld).
3719 // We find the symbol by walking the chain to the CopyFromReg, walking
3720 // back from the CopyFromReg to the ADDI_TLSGD_L or ADDI_TLSLD_L, and
3721 // pulling the symbol from that node.
3722 if (ExternalSymbolSDNode *S = dyn_cast(Callee))
3723 if (!strcmp(S->getSymbol(), "__tls_get_addr")) {
3724 assert(!needIndirectCall && "Indirect call to __tls_get_addr???");
3725 SDNode *AddI = Chain.getNode()->getOperand(2).getNode();
3726 SDValue TGTAddr = AddI->getOperand(1);
3727 assert(TGTAddr.getNode()->getOpcode() == ISD::TargetGlobalTLSAddress &&
3728 "Didn't find target global TLS address where we expected one");
3729 Ops.push_back(TGTAddr);
3730 CallOpc = PPCISD::CALL_TLS;
3731 }
37183732 }
37193733 // If this is a tail call add stack pointer delta.
37203734 if (isTailCall)
38673881 DAG.getTarget().getRelocationModel() == Reloc::PIC_)) {
38683882 // Otherwise insert NOP for non-local calls.
38693883 CallOpc = PPCISD::CALL_NOP;
3870 }
3884 } else if (CallOpc == PPCISD::CALL_TLS)
3885 // For 64-bit SVR4, TLS calls are always non-local.
3886 CallOpc = PPCISD::CALL_NOP_TLS;
38713887 }
38723888
38733889 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
566562 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
567563 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
568564 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
565 std::pair lowerTLSCall(SDValue Op, SDLoc dl,
566 SelectionDAG &DAG) const;
569567 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
570568 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
571569 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, []>,
24252429 def : Pat<(PPCcall (i32 texternalsym:$dst)),
24262430 (BL texternalsym:$dst)>;
24272431
2432 def : Pat<(PPCcall_tls texternalsym:$func, tglobaltlsaddr:$sym),
2433 (BL_TLS texternalsym:$func, tglobaltlsaddr:$sym)>;
24282434
24292435 def : Pat<(PPCtc_return (i32 tglobaladdr:$dst), imm:$imm),
24302436 (TCRETURNdi tglobaladdr:$dst, imm:$imm)>;
24802486 "#ADDItlsgdL32",
24812487 [(set i32:$rD,
24822488 (PPCaddiTlsgdL i32:$reg, tglobaltlsaddr:$disp))]>;
2483 def GETtlsADDR32 : Pseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
2484 "#GETtlsADDR32",
2485 [(set i32:$rD,
2486 (PPCgetTlsAddr i32:$reg, tglobaltlsaddr:$sym))]>;
24872489 def ADDItlsldL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
24882490 "#ADDItlsldL32",
24892491 [(set i32:$rD,
24902492 (PPCaddiTlsldL i32:$reg, tglobaltlsaddr:$disp))]>;
2491 def GETtlsldADDR32 : Pseudo<(outs gprc:$rD), (ins gprc:$reg, tlsgd32:$sym),
2492 "#GETtlsldADDR32",
2493 [(set i32:$rD,
2494 (PPCgetTlsldAddr i32:$reg, tglobaltlsaddr:$sym))]>;
24952493 def ADDIdtprelL32 : Pseudo<(outs gprc:$rD), (ins gprc_nor0:$reg, s16imm:$disp),
24962494 "#ADDIdtprelL32",
24972495 [(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()