llvm.org GIT mirror llvm / 509132b
Represent runtime preemption in the IR. Currently we do not represent runtime preemption in the IR, which has several drawbacks: 1) The semantics of GlobalValues differ depending on the object file format you are targeting (as well as the relocation-model and -fPIE value). 2) We have no way of disabling inlining of run time interposable functions, since in the IR we only know if a function is link-time interposable. Because of this llvm cannot support elf-interposition semantics. 3) In LTO builds of executables we will have extra knowledge that a symbol resolved to a local definition and can't be preemptable, but have no way to propagate that knowledge through the compiler. This patch adds preemptability specifiers to the IR with the following meaning: dso_local --> means the compiler may assume the symbol will resolve to a definition within the current linkage unit and the symbol may be accessed directly even if the definition is not within this compilation unit. dso_preemptable --> means that the compiler must assume the GlobalValue may be replaced with a definition from outside the current linkage unit at runtime. To ease transitioning dso_preemptable is treated as a 'default' in that low-level codegen will still do the same checks it did previously to see if a symbol should be accessed indirectly. Eventually when IR producers emit the specifiers on all Globalvalues we can change dso_preemptable to mean 'always access indirectly', and remove the current logic. Differential Revision: https://reviews.llvm.org/D20217 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316668 91177308-0d34-0410-b5e6-96231b3b80d8 Sean Fertile 1 year, 9 months ago
20 changed file(s) with 1263 addition(s) and 50 deletion(s). Raw diff Collapse all Expand all
680680 MODULE_CODE_GLOBALVAR Record
681681 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
682682
683 ``[GLOBALVAR, strtab offset, strtab size, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal, unnamed_addr, externally_initialized, dllstorageclass, comdat]``
683 ``[GLOBALVAR, strtab offset, strtab size, pointer type, isconst, initid, linkage, alignment, section, visibility, threadlocal, unnamed_addr, externally_initialized, dllstorageclass, comdat, attributes, preemptionspecifier]``
684684
685685 The ``GLOBALVAR`` record (code 7) marks the declaration or definition of a
686686 global variable. The operand fields are:
760760
761761 * *comdat*: An encoding of the COMDAT of this function
762762
763 * *attributes*: If nonzero, the 1-based index into the table of AttributeLists.
764
765 .. _bcpreemptionspecifier:
766
767 * *preemptionspecifier*: If present, an encoding of the runtime preemption specifier of this variable:
768
769 * ``dso_preemptable``: code 0
770 * ``dso_local``: code 1
771
763772 .. _FUNCTION:
764773
765774 MODULE_CODE_FUNCTION Record
766775 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
767776
768 ``[FUNCTION, strtab offset, strtab size, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prologuedata, dllstorageclass, comdat, prefixdata, personalityfn]``
777 ``[FUNCTION, strtab offset, strtab size, type, callingconv, isproto, linkage, paramattr, alignment, section, visibility, gc, prologuedata, dllstorageclass, comdat, prefixdata, personalityfn, preemptionspecifier]``
769778
770779 The ``FUNCTION`` record (code 8) marks the declaration or definition of a
771780 function. The operand fields are:
827836 * *personalityfn*: If non-zero, the value index of the personality function for this function,
828837 plus 1.
829838
839 * *preemptionspecifier*: If present, an encoding of the :ref:`runtime preemption specifier` of this function.
840
830841 MODULE_CODE_ALIAS Record
831842 ^^^^^^^^^^^^^^^^^^^^^^^^
832843
833 ``[ALIAS, strtab offset, strtab size, alias type, aliasee val#, linkage, visibility, dllstorageclass, threadlocal, unnamed_addr]``
844 ``[ALIAS, strtab offset, strtab size, alias type, aliasee val#, linkage, visibility, dllstorageclass, threadlocal, unnamed_addr, preemptionspecifier]``
834845
835846 The ``ALIAS`` record (code 9) marks the definition of an alias. The operand
836847 fields are
854865
855866 * *unnamed_addr*: If present, an encoding of the
856867 :ref:`unnamed_addr` attribute of this alias
868
869 * *preemptionspecifier*: If present, an encoding of the :ref:`runtime preemption specifier` of this alias.
857870
858871 .. _MODULE_CODE_GCNAME:
859872
526526 For platforms without linker support of ELF TLS model, the -femulated-tls
527527 flag can be used to generate GCC compatible emulated TLS code.
528528
529 .. _runtime_preemption_model:
530
531 Runtime Preemption Specifiers
532 -----------------------------
533
534 Global variables, functions and aliases may have an optional runtime preemption
535 specifier. If a preemption specifier isn't given explicitly, then a
536 symbol is assumed to be ``dso_preemptable``.
537
538 ``dso_preemptable``
539 Indicates that the function or variable may be replaced by a symbol from
540 outside the linkage unit at runtime.
541
542 ``dso_local``
543 The compiler may assume that a function or variable marked as ``dso_local``
544 will resolve to a symbol within the same linkage unit. Direct access will
545 be generated even if the definition is not within this compilation unit.
546
529547 .. _namedtypes:
530548
531549 Structure Types
649667 iteration. The maximum alignment is ``1 << 29``.
650668
651669 Globals can also have a :ref:`DLL storage class `,
670 an optional :ref:`runtime preemption specifier `,
652671 an optional :ref:`global attributes ` and
653672 an optional list of attached :ref:`metadata `.
654673
657676
658677 Syntax::
659678
660 @ = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
679 @ = [Linkage] [PreemptionSpecifier] [Visibility]
680 [DLLStorageClass] [ThreadLocal]
661681 [(unnamed_addr|local_unnamed_addr)] [AddrSpace]
662682 [ExternallyInitialized]
663683 []
690710 ---------
691711
692712 LLVM function definitions consist of the "``define``" keyword, an
693 optional :ref:`linkage type `, an optional :ref:`visibility
713 optional :ref:`linkage type `, an optional :ref:`runtime preemption
714 specifier `, an optional :ref:`visibility
694715 style `, an optional :ref:`DLL storage class `,
695716 an optional :ref:`calling convention `,
696717 an optional ``unnamed_addr`` attribute, a return type, an optional
749770
750771 Syntax::
751772
752 define [linkage] [visibility] [DLLStorageClass]
773 define [linkage] [PreemptionSpecifier] [visibility] [DLLStorageClass]
753774 [cconv] [ret attrs]
754775 @ ([argument list])
755776 [(unnamed_addr|local_unnamed_addr)] [fn Attrs] [section "name"]
776797 constant expression.
777798
778799 Aliases may have an optional :ref:`linkage type `, an optional
800 :ref:`runtime preemption specifier `, an optional
779801 :ref:`visibility style `, an optional :ref:`DLL storage class
780802 ` and an optional :ref:`tls model `.
781803
782804 Syntax::
783805
784 @ = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] alias , * @
806 @ = [Linkage] [PreemptionSpecifier] [Visibility] [DLLStorageClass] [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] alias , * @
785807
786808 The linkage must be one of ``private``, ``internal``, ``linkonce``, ``weak``,
787809 ``linkonce_odr``, ``weak_odr``, ``external``. Note that some system linkers
7979 ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility),
8080 UnnamedAddrVal(unsigned(UnnamedAddr::None)),
8181 DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal),
82 HasLLVMReservedName(false), IntID((Intrinsic::ID)0U), Parent(nullptr) {
82 HasLLVMReservedName(false), IsDSOLocal(false),
83 IntID((Intrinsic::ID)0U), Parent(nullptr) {
8384 setName(Name);
8485 }
8586
8687 Type *ValueType;
8788
88 static const unsigned GlobalValueSubClassDataBits = 18;
89 static const unsigned GlobalValueSubClassDataBits = 17;
8990
9091 // All bitfields use unsigned as the underlying type so that MSVC will pack
9192 // them.
102103 /// Function::intrinsicID() returns Intrinsic::not_intrinsic.
103104 unsigned HasLLVMReservedName : 1;
104105
106 /// If true then there is a definition within the same linkage unit and that
107 /// definition cannot be runtime preempted.
108 unsigned IsDSOLocal : 1;
109
105110 private:
106111 friend class Constant;
107112
108113 // Give subclasses access to what otherwise would be wasted padding.
109 // (18 + 4 + 2 + 2 + 2 + 3 + 1) == 32.
114 // (17 + 4 + 2 + 2 + 2 + 3 + 1 + 1) == 32.
110115 unsigned SubClassData : GlobalValueSubClassDataBits;
111116
112117 void destroyConstantImpl();
260265
261266 Type *getValueType() const { return ValueType; }
262267
268 void setDSOLocal(bool Local) { IsDSOLocal = Local; }
269
270 bool isDSOLocal() const {
271 return IsDSOLocal;
272 }
273
263274 static LinkageTypes getLinkOnceLinkage(bool ODR) {
264275 return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage;
265276 }
492492 KEYWORD(true); KEYWORD(false);
493493 KEYWORD(declare); KEYWORD(define);
494494 KEYWORD(global); KEYWORD(constant);
495
496 KEYWORD(dso_local);
497 KEYWORD(dso_preemptable);
495498
496499 KEYWORD(private);
497500 KEYWORD(internal);
482482
483483 /// ParseUnnamedGlobal:
484484 /// OptionalVisibility (ALIAS | IFUNC) ...
485 /// OptionalLinkage OptionalVisibility OptionalDLLStorageClass
485 /// OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
486 /// OptionalDLLStorageClass
486487 /// ... -> global variable
487488 /// GlobalID '=' OptionalVisibility (ALIAS | IFUNC) ...
488 /// GlobalID '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
489 /// GlobalID '=' OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
490 /// OptionalDLLStorageClass
489491 /// ... -> global variable
490492 bool LLParser::ParseUnnamedGlobal() {
491493 unsigned VarID = NumberedVals.size();
505507
506508 bool HasLinkage;
507509 unsigned Linkage, Visibility, DLLStorageClass;
510 bool DSOLocal;
508511 GlobalVariable::ThreadLocalMode TLM;
509512 GlobalVariable::UnnamedAddr UnnamedAddr;
510 if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) ||
513 if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
514 DSOLocal) ||
511515 ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr))
512516 return true;
513517
514518 if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
515519 return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
516 DLLStorageClass, TLM, UnnamedAddr);
520 DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
517521
518522 return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
519 DLLStorageClass, TLM, UnnamedAddr);
523 DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
520524 }
521525
522526 /// ParseNamedGlobal:
523527 /// GlobalVar '=' OptionalVisibility (ALIAS | IFUNC) ...
524 /// GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
528 /// GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
529 /// OptionalVisibility OptionalDLLStorageClass
525530 /// ... -> global variable
526531 bool LLParser::ParseNamedGlobal() {
527532 assert(Lex.getKind() == lltok::GlobalVar);
531536
532537 bool HasLinkage;
533538 unsigned Linkage, Visibility, DLLStorageClass;
539 bool DSOLocal;
534540 GlobalVariable::ThreadLocalMode TLM;
535541 GlobalVariable::UnnamedAddr UnnamedAddr;
536542 if (ParseToken(lltok::equal, "expected '=' in global variable") ||
537 ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) ||
543 ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
544 DSOLocal) ||
538545 ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr))
539546 return true;
540547
541548 if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
542549 return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
543 DLLStorageClass, TLM, UnnamedAddr);
550 DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
544551
545552 return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
546 DLLStorageClass, TLM, UnnamedAddr);
553 DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
547554 }
548555
549556 bool LLParser::parseComdat() {
708715 }
709716
710717 /// parseIndirectSymbol:
711 /// ::= GlobalVar '=' OptionalLinkage OptionalVisibility
712 /// OptionalDLLStorageClass OptionalThreadLocal
713 /// OptionalUnnamedAddr 'alias|ifunc' IndirectSymbol
718 /// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
719 /// OptionalVisibility OptionalDLLStorageClass
720 /// OptionalThreadLocal OptionalUnnamedAddr
721 // 'alias|ifunc' IndirectSymbol
714722 ///
715723 /// IndirectSymbol
716724 /// ::= TypeAndValue
717725 ///
718726 /// Everything through OptionalUnnamedAddr has already been parsed.
719727 ///
720 bool LLParser::parseIndirectSymbol(
721 const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility,
722 unsigned DLLStorageClass, GlobalVariable::ThreadLocalMode TLM,
723 GlobalVariable::UnnamedAddr UnnamedAddr) {
728 bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
729 unsigned L, unsigned Visibility,
730 unsigned DLLStorageClass, bool DSOLocal,
731 GlobalVariable::ThreadLocalMode TLM,
732 GlobalVariable::UnnamedAddr UnnamedAddr) {
724733 bool IsAlias;
725734 if (Lex.getKind() == lltok::kw_alias)
726735 IsAlias = true;
738747 if (!isValidVisibilityForLinkage(Visibility, L))
739748 return Error(NameLoc,
740749 "symbol with local linkage must have default visibility");
750
751 if (DSOLocal && !IsAlias) {
752 return Error(NameLoc,
753 "dso_local is invalid on ifunc");
754 }
741755
742756 Type *Ty;
743757 LocTy ExplicitTypeLoc = Lex.getLoc();
811825 GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
812826 GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
813827 GA->setUnnamedAddr(UnnamedAddr);
828 GA->setDSOLocal(DSOLocal);
814829
815830 if (Name.empty())
816831 NumberedVals.push_back(GA.get());
842857 }
843858
844859 /// ParseGlobal
845 /// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
860 /// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
861 /// OptionalVisibility OptionalDLLStorageClass
846862 /// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace
847863 /// OptionalExternallyInitialized GlobalType Type Const OptionalAttrs
848 /// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
849 /// OptionalThreadLocal OptionalUnnamedAddr OptionalAddrSpace
850 /// OptionalExternallyInitialized GlobalType Type Const OptionalAttrs
864 /// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
865 /// OptionalDLLStorageClass OptionalThreadLocal OptionalUnnamedAddr
866 /// OptionalAddrSpace OptionalExternallyInitialized GlobalType Type
867 /// Const OptionalAttrs
851868 ///
852869 /// Everything up to and including OptionalUnnamedAddr has been parsed
853870 /// already.
855872 bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
856873 unsigned Linkage, bool HasLinkage,
857874 unsigned Visibility, unsigned DLLStorageClass,
858 GlobalVariable::ThreadLocalMode TLM,
875 bool DSOLocal, GlobalVariable::ThreadLocalMode TLM,
859876 GlobalVariable::UnnamedAddr UnnamedAddr) {
860877 if (!isValidVisibilityForLinkage(Visibility, Linkage))
861878 return Error(NameLoc,
929946 GV->setInitializer(Init);
930947 GV->setConstant(IsConstant);
931948 GV->setLinkage((GlobalValue::LinkageTypes)Linkage);
949 GV->setDSOLocal(DSOLocal);
932950 GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
933951 GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
934952 GV->setExternallyInitialized(IsExternallyInitialized);
16071625 /// ::= 'external'
16081626 bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage,
16091627 unsigned &Visibility,
1610 unsigned &DLLStorageClass) {
1628 unsigned &DLLStorageClass,
1629 bool &DSOLocal) {
16111630 Res = parseOptionalLinkageAux(Lex.getKind(), HasLinkage);
16121631 if (HasLinkage)
16131632 Lex.Lex();
1633 ParseOptionalDSOLocal(DSOLocal);
16141634 ParseOptionalVisibility(Visibility);
16151635 ParseOptionalDLLStorageClass(DLLStorageClass);
1616 return false;
1636
1637 if (DSOLocal && DLLStorageClass == GlobalValue::DLLImportStorageClass) {
1638 return Error(Lex.getLoc(), "dso_location and DLL-StorageClass mismatch");
1639 }
1640
1641 return false;
1642 }
1643
1644 void LLParser::ParseOptionalDSOLocal(bool &DSOLocal) {
1645 switch (Lex.getKind()) {
1646 default:
1647 DSOLocal = false;
1648 break;
1649 case lltok::kw_dso_local:
1650 DSOLocal = true;
1651 Lex.Lex();
1652 break;
1653 case lltok::kw_dso_preemptable:
1654 DSOLocal = false;
1655 Lex.Lex();
1656 break;
1657 }
16171658 }
16181659
16191660 /// ParseOptionalVisibility
46984739 }
46994740
47004741 /// FunctionHeader
4701 /// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs
4702 /// OptUnnamedAddr Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection
4703 /// OptionalAlign OptGC OptionalPrefix OptionalPrologue OptPersonalityFn
4742 /// ::= OptionalLinkage OptionalPreemptionSpecifier OptionalVisibility
4743 /// OptionalCallingConv OptRetAttrs OptUnnamedAddr Type GlobalName
4744 /// '(' ArgList ')' OptFuncAttrs OptSection OptionalAlign OptGC
4745 /// OptionalPrefix OptionalPrologue OptPersonalityFn
47044746 bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
47054747 // Parse the linkage.
47064748 LocTy LinkageLoc = Lex.getLoc();
47074749 unsigned Linkage;
4708
47094750 unsigned Visibility;
47104751 unsigned DLLStorageClass;
4752 bool DSOLocal;
47114753 AttrBuilder RetAttrs;
47124754 unsigned CC;
47134755 bool HasLinkage;
47144756 Type *RetType = nullptr;
47154757 LocTy RetTypeLoc = Lex.getLoc();
4716 if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) ||
4758 if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass,
4759 DSOLocal) ||
47174760 ParseOptionalCallingConv(CC) || ParseOptionalReturnAttrs(RetAttrs) ||
47184761 ParseType(RetType, RetTypeLoc, true /*void allowed*/))
47194762 return true;
48754918 NumberedVals.push_back(Fn);
48764919
48774920 Fn->setLinkage((GlobalValue::LinkageTypes)Linkage);
4921 Fn->setDSOLocal(DSOLocal);
48784922 Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility);
48794923 Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
48804924 Fn->setCallingConv(CC);
239239 bool ParseOptionalParamAttrs(AttrBuilder &B);
240240 bool ParseOptionalReturnAttrs(AttrBuilder &B);
241241 bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage,
242 unsigned &Visibility, unsigned &DLLStorageClass);
242 unsigned &Visibility, unsigned &DLLStorageClass,
243 bool &DSOLocal);
244 void ParseOptionalDSOLocal(bool &DSOLocal);
243245 void ParseOptionalVisibility(unsigned &Visibility);
244246 void ParseOptionalDLLStorageClass(unsigned &DLLStorageClass);
245247 bool ParseOptionalCallingConv(unsigned &CC);
283285 bool ParseNamedGlobal();
284286 bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
285287 bool HasLinkage, unsigned Visibility,
286 unsigned DLLStorageClass,
288 unsigned DLLStorageClass, bool DSOLocal,
287289 GlobalVariable::ThreadLocalMode TLM,
288290 GlobalVariable::UnnamedAddr UnnamedAddr);
289291 bool parseIndirectSymbol(const std::string &Name, LocTy Loc,
290292 unsigned Linkage, unsigned Visibility,
291 unsigned DLLStorageClass,
293 unsigned DLLStorageClass, bool DSOLocal,
292294 GlobalVariable::ThreadLocalMode TLM,
293295 GlobalVariable::UnnamedAddr UnnamedAddr);
294296 bool parseComdat();
4343 kw_define,
4444 kw_global,
4545 kw_constant,
46
47 kw_dso_local,
48 kw_dso_preemptable,
4649
4750 kw_private,
4851 kw_internal,
907907 case 0: return GlobalValue::DefaultStorageClass;
908908 case 1: return GlobalValue::DLLImportStorageClass;
909909 case 2: return GlobalValue::DLLExportStorageClass;
910 }
911 }
912
913 static bool getDecodedDSOLocal(unsigned Val) {
914 switch(Val) {
915 default: // Map unknown values to preemptable.
916 case 0: return false;
917 case 1: return true;
910918 }
911919 }
912920
28022810 Error BitcodeReader::parseGlobalVarRecord(ArrayRef Record) {
28032811 // v1: [pointer type, isconst, initid, linkage, alignment, section,
28042812 // visibility, threadlocal, unnamed_addr, externally_initialized,
2805 // dllstorageclass, comdat, attributes] (name in VST)
2813 // dllstorageclass, comdat, attributes, preemption specifier] (name in VST)
28062814 // v2: [strtab_offset, strtab_size, v1]
28072815 StringRef Name;
28082816 std::tie(Name, Record) = readNameFromStrtab(Record);
28872895 auto AS = getAttributes(Record[12]).getFnAttributes();
28882896 NewGV->setAttributes(AS);
28892897 }
2898
2899 if (Record.size() > 13) {
2900 NewGV->setDSOLocal(getDecodedDSOLocal(Record[13]));
2901 }
2902
28902903 return Error::success();
28912904 }
28922905
28932906 Error BitcodeReader::parseFunctionRecord(ArrayRef Record) {
28942907 // v1: [type, callingconv, isproto, linkage, paramattr, alignment, section,
28952908 // visibility, gc, unnamed_addr, prologuedata, dllstorageclass, comdat,
2896 // prefixdata] (name in VST)
2909 // prefixdata, personalityfn, preemption specifier] (name in VST)
28972910 // v2: [strtab_offset, strtab_size, v1]
28982911 StringRef Name;
28992912 std::tie(Name, Record) = readNameFromStrtab(Record);
29672980 if (Record.size() > 14 && Record[14] != 0)
29682981 FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1));
29692982
2983 if (Record.size() > 15) {
2984 Func->setDSOLocal(getDecodedDSOLocal(Record[15]));
2985 }
2986
29702987 ValueList.push_back(Func);
29712988
29722989 // If this is a function with a body, remember the prototype we are
29833000 unsigned BitCode, ArrayRef Record) {
29843001 // v1 ALIAS_OLD: [alias type, aliasee val#, linkage] (name in VST)
29853002 // v1 ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility,
2986 // dllstorageclass] (name in VST)
3003 // dllstorageclass, threadlocal, unnamed_addr,
3004 // preemption specifier] (name in VST)
29873005 // v1 IFUNC: [alias type, addrspace, aliasee val#, linkage,
2988 // visibility, dllstorageclass] (name in VST)
3006 // visibility, dllstorageclass, threadlocal, unnamed_addr,
3007 // preemption specifier] (name in VST)
29893008 // v2: [strtab_offset, strtab_size, v1]
29903009 StringRef Name;
29913010 std::tie(Name, Record) = readNameFromStrtab(Record);
30353054 NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++]));
30363055 if (OpNum != Record.size())
30373056 NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++]));
3057 if (OpNum != Record.size())
3058 NewGA->setDSOLocal(getDecodedDSOLocal(Record[OpNum++]));
30383059 ValueList.push_back(NewGA);
30393060 IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
30403061 return Error::success();
11961196 // GLOBALVAR: [strtab offset, strtab size, type, isconst, initid,
11971197 // linkage, alignment, section, visibility, threadlocal,
11981198 // unnamed_addr, externally_initialized, dllstorageclass,
1199 // comdat, attributes]
1199 // comdat, attributes, DSO_Local]
12001200 Vals.push_back(addToStrtab(GV.getName()));
12011201 Vals.push_back(GV.getName().size());
12021202 Vals.push_back(VE.getTypeID(GV.getValueType()));
12121212 GV.isExternallyInitialized() ||
12131213 GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
12141214 GV.hasComdat() ||
1215 GV.hasAttributes()) {
1215 GV.hasAttributes() ||
1216 GV.isDSOLocal()) {
12161217 Vals.push_back(getEncodedVisibility(GV));
12171218 Vals.push_back(getEncodedThreadLocalMode(GV));
12181219 Vals.push_back(getEncodedUnnamedAddr(GV));
12221223
12231224 auto AL = GV.getAttributesAsList(AttributeList::FunctionIndex);
12241225 Vals.push_back(VE.getAttributeListID(AL));
1226
1227 Vals.push_back(GV.isDSOLocal());
12251228 } else {
12261229 AbbrevToUse = SimpleGVarAbbrev;
12271230 }
12351238 // FUNCTION: [strtab offset, strtab size, type, callingconv, isproto,
12361239 // linkage, paramattrs, alignment, section, visibility, gc,
12371240 // unnamed_addr, prologuedata, dllstorageclass, comdat,
1238 // prefixdata, personalityfn]
1241 // prefixdata, personalityfn, DSO_Local]
12391242 Vals.push_back(addToStrtab(F.getName()));
12401243 Vals.push_back(F.getName().size());
12411244 Vals.push_back(VE.getTypeID(F.getFunctionType()));
12571260 Vals.push_back(
12581261 F.hasPersonalityFn() ? (VE.getValueID(F.getPersonalityFn()) + 1) : 0);
12591262
1263 Vals.push_back(F.isDSOLocal());
12601264 unsigned AbbrevToUse = 0;
12611265 Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
12621266 Vals.clear();
12651269 // Emit the alias information.
12661270 for (const GlobalAlias &A : M.aliases()) {
12671271 // ALIAS: [strtab offset, strtab size, alias type, aliasee val#, linkage,
1268 // visibility, dllstorageclass, threadlocal, unnamed_addr]
1272 // visibility, dllstorageclass, threadlocal, unnamed_addr,
1273 // DSO_Local]
12691274 Vals.push_back(addToStrtab(A.getName()));
12701275 Vals.push_back(A.getName().size());
12711276 Vals.push_back(VE.getTypeID(A.getValueType()));
12761281 Vals.push_back(getEncodedDLLStorageClass(A));
12771282 Vals.push_back(getEncodedThreadLocalMode(A));
12781283 Vals.push_back(getEncodedUnnamedAddr(A));
1284 Vals.push_back(A.isDSOLocal());
1285
12791286 unsigned AbbrevToUse = 0;
12801287 Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
12811288 Vals.clear();
24922492 }
24932493 }
24942494
2495 static void PrintDSOLocation(bool IsDSOLocal, formatted_raw_ostream &Out){
2496 if (IsDSOLocal)
2497 Out << "dso_local ";
2498 }
2499
24952500 static void PrintDLLStorageClass(GlobalValue::DLLStorageClassTypes SCT,
24962501 formatted_raw_ostream &Out) {
24972502 switch (SCT) {
25622567 Out << "external ";
25632568
25642569 Out << getLinkagePrintName(GV->getLinkage());
2570 PrintDSOLocation(GV->isDSOLocal(), Out);
25652571 PrintVisibility(GV->getVisibility(), Out);
25662572 PrintDLLStorageClass(GV->getDLLStorageClass(), Out);
25672573 PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
26082614 Out << " = ";
26092615
26102616 Out << getLinkagePrintName(GIS->getLinkage());
2617 PrintDSOLocation(GIS->isDSOLocal(), Out);
26112618 PrintVisibility(GIS->getVisibility(), Out);
26122619 PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
26132620 PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
27192726 Out << "define ";
27202727
27212728 Out << getLinkagePrintName(F->getLinkage());
2729 PrintDSOLocation(F->isDSOLocal(), Out);
27222730 PrintVisibility(F->getVisibility(), Out);
27232731 PrintDLLStorageClass(F->getDLLStorageClass(), Out);
27242732
6666 setVisibility(Src->getVisibility());
6767 setUnnamedAddr(Src->getUnnamedAddr());
6868 setDLLStorageClass(Src->getDLLStorageClass());
69 setDSOLocal(Src->isDSOLocal());
6970 }
7071
7172 void GlobalValue::removeFromParent() {
567567 if (GV.isDeclarationForLinker())
568568 Assert(!GV.hasComdat(), "Declaration may not be in a Comdat!", &GV);
569569
570 if (GV.hasDLLImportStorageClass())
571 Assert(!GV.isDSOLocal(),
572 "GlobalValue with DLLImport Storage is dso_local!", &GV);
573
570574 forEachUser(&GV, GlobalValueVisited, [&](const Value *V) -> bool {
571575 if (const Instruction *I = dyn_cast(V)) {
572576 if (!I->getParent() || !I->getParent()->getParent())
127127 if (TT.isOSBinFormatCOFF() || (TT.isOSWindows() && TT.isOSBinFormatMachO()))
128128 return true;
129129
130 if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility()))
130 if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility() ||
131 GV->isDSOLocal()))
131132 return true;
132133
133134 if (TT.isOSBinFormatMachO()) {
0 ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
1
2 declare dso_local dllimport void @fun()
3 ; CHECK: error: dso_location and DLL-StorageClass mismatch
0 ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
1
2 @foo = dso_local ifunc i32 (i32), i64 ()* @foo_ifunc
3 ; CHECK: error: dso_local is invalid on ifunc
4
5 define internal i64 @foo_ifunc() {
6 entry:
7 ret i64 0
8 }
0 ; RUN: llvm-as < %s | llvm-dis | FileCheck %s
1
2 ; Tests parsing for the dso_local keyword as well as the serialization/
3 ; deserialization of the dso_local value on GlobalValues.
4
5 @local_global = dso_local global i32 0
6 ; CHECK: @local_global = dso_local global i32 0
7
8 @weak_local_global = weak dso_local global i32 0
9 ; CHECK: @weak_local_global = weak dso_local global i32 0
10
11 @external_local_global = external dso_local global i32
12 ; CHECK: @external_local_global = external dso_local global i32
13
14 @default_local_global = dso_local default global i32 0
15 ; CHECK: @default_local_global = dso_local global i32 0
16
17 @hidden_local_global = dso_local hidden global i32 0
18 ; CHECK: @hidden_local_global = dso_local hidden global i32 0
19
20 @protected_local_global = dso_local protected global i32 0
21 ; CHECK: @protected_local_global = dso_local protected global i32 0
22
23 @local_alias = dso_local alias i32, i32* @local_global
24 ; CHECK-DAG: @local_alias = dso_local alias i32, i32* @local_global
25
26 @preemptable_alias = dso_preemptable alias i32, i32* @hidden_local_global
27 ; CHECK-DAG: @preemptable_alias = alias i32, i32* @hidden_local_global
28
29 @preemptable_ifunc = dso_preemptable ifunc void (), i8* ()* @ifunc_resolver
30 ; CHECK-DAG: @preemptable_ifunc = ifunc void (), i8* ()* @ifunc_resolver
31 declare dso_local default void @default_local()
32 ; CHECK: declare dso_local void @default_local()
33
34 declare dso_local hidden void @hidden_local()
35 ; CHECK: declare dso_local hidden void @hidden_local()
36
37 define dso_local protected void @protected_local() {
38 ; CHECK: define dso_local protected void @protected_local()
39 entry:
40 ret void
41 }
42
43 define i8* @ifunc_resolver() {
44 entry:
45 ret i8* null
46 }
0 ; RUN: llc -mtriple powerpc64le-unkown-gnu-linux < %s | FileCheck %s
1 ; RUN: llc -mtriple powerpc64le-unkown-gnu-linux -relocation-model=static \
2 ; RUN: < %s | FileCheck --check-prefix=STATIC %s
3 ; RUN: llc -mtriple powerpc64le-unkown-gnu-linux -relocation-model=pic \
4 ; RUN: < %s | FileCheck %s
5
6 ; globals
7
8 @strong_default = global i32 55
9 define i32* @get_strong_default() #0 {
10 ret i32* @strong_default
11
12 ; STATIC-LABEL: @get_strong_default
13 ; STATIC: addis 3, 2, strong_default@toc@ha
14 ; STATIC: addi 3, 3, strong_default@toc@l
15 ; STATIC: blr
16
17 ; CHECK-LABEL: @get_strong_default
18 ; CHECK: addis 3, 2, .LC0@toc@ha
19 ; CHECK: ld 3, .LC0@toc@l(3)
20 ; CHECK: blr
21 }
22
23 @weak_default = weak global i32 55
24 define i32* @get_weak_default() #0 {
25 ret i32* @weak_default
26
27 ; STATIC-LABEL: @get_weak_default
28 ; STATIC: addis 3, 2, weak_default@toc@ha
29 ; STATIC: addi 3, 3, weak_default@toc@l
30 ; STATIC: blr
31
32 ; CHECK-LABEL: @get_weak_default
33 ; CHECK: addis 3, 2, .LC1@toc@ha
34 ; CHECK: ld 3, .LC1@toc@l(3)
35 ; CHECK: blr
36 }
37
38 @external_default_global = external global i32
39 define i32* @get_external_default_global() {
40 ret i32* @external_default_global
41
42 ; STATIC-LABEL: @get_external_default_global
43 ; STATIC: addis 3, 2, .LC0@toc@ha
44 ; STATIC: ld 3, .LC0@toc@l(3)
45 ; STATIC: blr
46
47 ; CHECK-LABEL: @get_external_default_global
48 ; CHECK: addis 3, 2, .LC2@toc@ha
49 ; CHECK: ld 3, .LC2@toc@l(3)
50 ; CHECK: blr
51 }
52
53
54 @strong_local_global = dso_local global i32 55
55 define i32* @get_strong_local_global() {
56 ret i32* @strong_local_global
57
58 ; STATIC-LABEL: @get_strong_local_global
59 ; STATIC: addis 3, 2, strong_local_global@toc@ha
60 ; STATIC: addi 3, 3, strong_local_global@toc@l
61 ; STATIC: blr
62
63 ; CHECK-LABEL: @get_strong_local_global
64 ; CHECK: addis 3, 2, strong_local_global@toc@ha
65 ; CHECK: addi 3, 3, strong_local_global@toc@l
66 ; CHECK: blr
67 }
68
69 @weak_local_global = weak dso_local global i32 42
70 define i32* @get_weak_local_global() {
71 ret i32* @weak_local_global
72
73 ; STATIC-LABEL: @get_weak_local_global
74 ; STATIC: addis 3, 2, weak_local_global@toc@ha
75 ; STATIC: addi 3, 3, weak_local_global@toc@l
76 ; STATIC: blr
77
78 ; CHECK-LABEL: @get_weak_local_global
79 ; CHECK: addis 3, 2, weak_local_global@toc@ha
80 ; CHECK: addi 3, 3, weak_local_global@toc@l
81 ; CHECK: blr
82 }
83
84 @external_local_global = external dso_local global i32
85 define i32* @get_external_local_global() {
86 ret i32* @external_local_global
87 ; STATIC-LABEL: @get_external_local_global
88 ; STATIC: addis 3, 2, external_local_global@toc@ha
89 ; STATIC: addi 3, 3, external_local_global@toc@l
90 ; STATIC: blr
91
92 ; CHECK-LABEL: @get_external_local_global
93 ; CHECK: addis 3, 2, external_local_global@toc@ha
94 ; CHECK: addi 3, 3, external_local_global@toc@l
95 ; CHECK: blr
96 }
97
98 @strong_preemptable_global = dso_preemptable global i32 42
99 define i32* @get_strong_preemptable_global() {
100 ret i32* @strong_preemptable_global
101
102 ; STATIC-LABEL: @get_strong_preemptable_global
103 ; STATIC: addis 3, 2, strong_preemptable_global@toc@ha
104 ; STATIC: addi 3, 3, strong_preemptable_global@toc@l
105 ; STATIC: blr
106
107 ; CHECK-LABEL: @get_strong_preemptable_global
108 ; CHECK: addis 3, 2, .LC3@toc@ha
109 ; CHECK: ld 3, .LC3@toc@l(3)
110 ; CHECK: blr
111 }
112
113 @weak_preemptable_global = weak dso_preemptable global i32 42
114 define i32* @get_weak_preemptable_global() {
115 ret i32* @weak_preemptable_global
116
117 ; STATIC-LABEL: @get_weak_preemptable_global
118 ; STATIC: addis 3, 2, weak_preemptable_global@toc@ha
119 ; STATIC: addi 3, 3, weak_preemptable_global@toc@l
120 ; STATIC: blr
121
122 ; CHECK-LABEL: @get_weak_preemptable_global
123 ; CHECK: addis 3, 2, .LC4@toc@ha
124 ; CHECK: ld 3, .LC4@toc@l(3)
125 ; CHECK: blr
126 }
127
128 @external_preemptable_global = external dso_preemptable global i32
129 define i32* @get_external_preemptable_global() {
130 ret i32* @external_preemptable_global
131
132 ; STATIC-LABEL: @get_external_preemptable_global
133 ; STATIC: addis 3, 2, .LC1@toc@ha
134 ; STATIC: ld 3, .LC1@toc@l(3)
135 ; STATIC: blr
136
137 ; CHECK-LABEL: @get_external_preemptable_global
138 ; CHECK: addis 3, 2, .LC5@toc@ha
139 ; CHECK: ld 3, .LC5@toc@l(3)
140 ; CHECK: blr
141 }
142
143 ; functions
144 define signext i32 @strong_default_function(i32 %i) {
145 ret i32 %i
146 }
147 define signext i32 @strong_default_function_caller(i32 %i) {
148 %call = notail call signext i32 @strong_default_function(i32 signext %i)
149 ret i32 %call
150
151 ; STATIC-LABEL: @strong_default_function_caller
152 ; STATIC: bl strong_default_function
153 ; STATIC-NOT: nop
154 ; STATIC: blr
155
156 ; CHECK-LABEL: @strong_default_function_caller
157 ; CHECK: bl strong_default_function
158 ; CHECK-NEXT: nop
159 ; CHECK: blr
160 }
161
162 define weak signext i32 @weak_default_function(i32 %i) {
163 ret i32 %i
164 }
165 define signext i32 @weak_default_function_caller(i32 %i) {
166 %call = notail call signext i32 @weak_default_function(i32 signext %i)
167 ret i32 %call
168
169 ; STATIC-LABEL: @weak_default_function_caller
170 ; STATIC: bl weak_default_function
171 ; STATIC-NOT: nop
172 ; STATIC: blr
173
174 ; CHECK-LABEL: @weak_default_function_caller
175 ; CHECK: bl weak_default_function
176 ; CHECK-NEXT: nop
177 ; CHECK: blr
178 }
179
180
181 declare i32 @external_default_function(i32 %i)
182 define i32 @external_default_function_caller(i32 %i) {
183 %call = notail call signext i32 @external_default_function(i32 signext %i)
184 ret i32 %call
185
186 ; STATIC-LABEL: @external_default_function_caller
187 ; STATIC: bl external_default_function
188 ; STATIC-NEXT: nop
189 ; STATIC: blr
190
191 ; CHECK-LABEL: @external_default_function_caller
192 ; CHECK: bl external_default_function
193 ; CHECK-NEXT: nop
194 ; CHECK: blr
195 }
196
197 define dso_local signext i32 @strong_local_function(i32 %i) {
198 ret i32 %i
199 }
200 define signext i32 @strong_local_function_caller(i32 %i) {
201 %call = notail call signext i32 @strong_local_function(i32 signext %i)
202 ret i32 %call
203
204 ; STATIC-LABEL: @strong_local_function_caller
205 ; STATIC: bl strong_local_function
206 ; STATIC-NOT: nop
207 ; STATIC: blr
208
209 ; CHECK-LABEL: @strong_local_function_caller
210 ; CHECK: bl strong_local_function
211 ; CHECK-NOT: nop
212 ; CHECK: blr
213 }
214
215 define weak dso_local signext i32 @weak_local_function(i32 %i) {
216 ret i32 %i
217 }
218 define signext i32 @weak_local_function_caller(i32 %i) {
219 %call = notail call signext i32 @weak_local_function(i32 signext %i)
220 ret i32 %call
221
222 ; STATIC-LABEL: @weak_local_function_caller
223 ; STATIC: bl weak_local_function
224 ; STATIC-NOT: nop
225 ; STATIC: blr
226
227 ; CHECK-LABEL: @weak_local_function_caller
228 ; CHECK: bl weak_local_function
229 ; CHECK-NOT: nop
230 ; CHECK: blr
231 }
232
233 declare dso_local i32 @external_local_function(i32 %i)
234 define i32 @external_local_function_caller(i32 %i) {
235 %call = notail call signext i32 @external_local_function(i32 signext %i)
236 ret i32 %call
237
238 ; STATIC-LABEL: @external_local_function_caller
239 ; STATIC: bl external_local_function
240 ; STATIC-NOT: nop
241 ; STATIC: blr
242
243 ; CHECK-LABEL: @external_local_function_caller
244 ; CHECK: bl external_local_function
245 ; CHECK-NOT: nop
246 ; CHECK: blr
247 }
248
249 define dso_preemptable signext i32 @strong_preemptable_function(i32 %i) {
250 ret i32 %i
251 }
252 define signext i32 @strong_preemptable_function_caller(i32 %i) {
253 %call = notail call signext i32 @strong_preemptable_function(i32 signext %i)
254 ret i32 %call
255
256 ; STATIC-LABEL: @strong_preemptable_function_caller
257 ; STATIC: bl strong_preemptable_function
258 ; STATIC-NOT: nop
259 ; STATIC: blr
260
261 ; CHECK-LABEL: @strong_preemptable_function_caller
262 ; CHECK: bl strong_preemptable_function
263 ; CHECK-NEXT: nop
264 ; CHECK: blr
265 }
266
267 define weak dso_preemptable signext i32 @weak_preemptable_function(i32 %i) {
268 ret i32 %i
269 }
270 define signext i32 @weak_preemptable_function_caller(i32 %i) {
271 %call = notail call signext i32 @weak_preemptable_function(i32 signext %i)
272 ret i32 %call
273
274 ; STATIC-LABEL: @weak_preemptable_function_caller
275 ; STATIC: bl weak_preemptable_function
276 ; STATIC-NOT: nop
277 ; STATIC: blr
278
279 ; CHECK-LABEL: @weak_preemptable_function_caller
280 ; CHECK: bl weak_preemptable_function
281 ; CHECK-NEXT: nop
282 ; CHECK: blr
283 }
284
285 declare dso_preemptable i32 @external_preemptable_function(i32 %i)
286 define i32 @external_preemptable_function_caller(i32 %i) {
287 %call = notail call signext i32 @external_preemptable_function(i32 signext %i)
288 ret i32 %call
289
290 ; STATIC-LABEL: @external_preemptable_function_caller
291 ; STATIC: bl external_preemptable_function
292 ; STATIC-NEXT: nop
293 ; STATIC: blr
294
295 ; CHECK-LABEL: @external_preemptable_function_caller
296 ; CHECK: bl external_preemptable_function
297 ; CHECK-NEXT: nop
298 ; CHECK: blr
299 }
300
0 ; RUN: llc -mtriple x86_64-apple-darwin \
1 ; RUN: -relocation-model=static < %s | FileCheck %s
2 ; RUN: llc -mtriple x86_64-apple-darwin \
3 ; RUN: -relocation-model=pic < %s | FileCheck %s
4 ; RUN: llc -mtriple x86_64-apple-darwin \
5 ; RUN: -relocation-model=dynamic-no-pic < %s | FileCheck %s
6
7 ; 32 bits
8
9 ; RUN: llc -mtriple i386-apple-darwin \
10 ; RUN: -relocation-model=static < %s | FileCheck --check-prefix=DARWIN32_S %s
11 ; RUN: llc -mtriple i386-apple-darwin \
12 ; RUN: -relocation-model=pic < %s | FileCheck --check-prefix=DARWIN32 %s
13 ; RUN: llc -mtriple i386-apple-darwin \
14 ; RUN: -relocation-model=dynamic-no-pic < %s | \
15 ; RUN: FileCheck --check-prefix=DARWIN32_DNP %s
16
17 ; globals
18
19 @strong_default_global = global i32 42
20 define i32* @get_strong_default_global() {
21 ret i32* @strong_default_global
22 }
23 ; CHECK: leaq _strong_default_global(%rip), %rax
24 ; DARWIN32: leal _strong_default_global-L{{.*}}$pb(%eax), %eax
25 ; DARWIN32_S: movl $_strong_default_global, %eax
26 ; DARWIN32_DNP: movl $_strong_default_global, %eax
27
28 @weak_default_global = weak global i32 42
29 define i32* @get_weak_default_global() {
30 ret i32* @weak_default_global
31 }
32 ; CHECK: movq _weak_default_global@GOTPCREL(%rip), %rax
33 ; DARWIN32: movl L_weak_default_global$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
34 ; DARWIN32_S: movl $_weak_default_global, %eax
35 ; DARWIN32_DNP: movl L_weak_default_global$non_lazy_ptr, %eax
36
37 @external_default_global = external global i32
38 define i32* @get_external_default_global() {
39 ret i32* @external_default_global
40 }
41 ; CHECK: movq _external_default_global@GOTPCREL(%rip), %rax
42 ; DARWIN32: movl L_external_default_global$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
43 ; DARWIN32_S: movl $_external_default_global, %eax
44 ; DARWIN32_DNP: movl L_external_default_global$non_lazy_ptr, %eax
45
46 @strong_local_global = dso_local global i32 42
47 define i32* @get_strong_local_global() {
48 ret i32* @strong_local_global
49 }
50 ; CHECK: leaq _strong_local_global(%rip), %rax
51 ; DARWIN32: leal _strong_local_global-L{{.*}}$pb(%eax), %eax
52 ; DARWIN32_S: movl $_strong_local_global, %eax
53 ; DARWIN32_DNP: movl $_strong_local_global, %eax
54
55 @weak_local_global = weak dso_local global i32 42
56 define i32* @get_weak_local_global() {
57 ret i32* @weak_local_global
58 }
59 ; CHECK: leaq _weak_local_global(%rip), %rax
60 ; DARWIN32: leal _weak_local_global-L{{.}}$pb(%eax), %eax
61 ; DARWIN32_S: movl $_weak_local_global, %eax
62 ; DARWIN32_DNP: movl $_weak_local_global, %eax
63
64 @external_local_global = external dso_local global i32
65 define i32* @get_external_local_global() {
66 ret i32* @external_local_global
67 }
68 ; CHECK: leaq _external_local_global(%rip), %rax
69 ; DARWIN32: movl L_external_local_global$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
70 ; DARWIN32_S: movl $_external_local_global, %eax
71 ; DARWIN32_DNP: movl $_external_local_global, %eax
72
73 @strong_preemptable_global = dso_preemptable global i32 42
74 define i32* @get_strong_preemptable_global() {
75 ret i32* @strong_preemptable_global
76 }
77 ; CHECK: leaq _strong_preemptable_global(%rip), %rax
78 ; DARWIN32: leal _strong_preemptable_global-L{{.*}}$pb(%eax), %eax
79 ; DARWIN32_S: movl $_strong_preemptable_global, %eax
80 ; DARWIN32_DNP: movl $_strong_preemptable_global, %eax
81
82 @weak_preemptable_global = weak dso_preemptable global i32 42
83 define i32* @get_weak_preemptable_global() {
84 ret i32* @weak_preemptable_global
85 }
86 ; CHECK: movq _weak_preemptable_global@GOTPCREL(%rip), %rax
87 ; DARWIN32: movl L_weak_preemptable_global$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
88 ; DARWIN32_S: movl $_weak_preemptable_global, %eax
89 ; DARWIN32_DNP: movl L_weak_preemptable_global$non_lazy_ptr, %eax
90
91 @external_preemptable_global = external dso_preemptable global i32
92 define i32* @get_external_preemptable_global() {
93 ret i32* @external_preemptable_global
94 }
95 ; CHECK: movq _external_preemptable_global@GOTPCREL(%rip), %rax
96 ; DARWIN32: movl L_external_preemptable_global$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
97 ; DARWIN32_S: movl $_external_preemptable_global, %eax
98 ; DARWIN32_DNP: movl L_external_preemptable_global$non_lazy_ptr, %eax
99
100 ; aliases
101 @aliasee = global i32 42
102
103 @strong_default_alias = alias i32, i32* @aliasee
104 define i32* @get_strong_default_alias() {
105 ret i32* @strong_default_alias
106 }
107 ; CHECK: leaq _strong_default_alias(%rip), %rax
108 ; DARWIN32: leal _strong_default_alias-L{{.*}}$pb(%eax), %eax
109 ; DARWIN32_S: movl $_strong_default_alias, %eax
110 ; DARWIN32_DNP: movl $_strong_default_alias, %eax
111
112 @weak_default_alias = weak alias i32, i32* @aliasee
113 define i32* @get_weak_default_alias() {
114 ret i32* @weak_default_alias
115 }
116 ; CHECK: movq _weak_default_alias@GOTPCREL(%rip), %rax
117 ; DARWIN32: movl L_weak_default_alias$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
118 ; DARWIN32_S: movl $_weak_default_alias, %eax
119 ; DARWIN32_DNP: movl L_weak_default_alias$non_lazy_ptr, %eax
120
121 @strong_local_alias = dso_local alias i32, i32* @aliasee
122 define i32* @get_strong_local_alias() {
123 ret i32* @strong_local_alias
124 }
125 ; CHECK: leaq _strong_local_alias(%rip), %rax
126 ; DARWIN32: leal _strong_local_alias-L{{.*}}$pb(%eax), %eax
127 ; DARWIN32_S: movl $_strong_local_alias, %eax
128 ; DARWIN32_DNP: movl $_strong_local_alias, %eax
129
130 @weak_local_alias = weak dso_local alias i32, i32* @aliasee
131 define i32* @get_weak_local_alias() {
132 ret i32* @weak_local_alias
133 }
134 ; CHECK: leaq _weak_local_alias(%rip), %rax
135 ; DARWIN32: leal _weak_local_alias-L{{.*}}$pb(%eax), %eax
136 ; DARWIN32_S: movl $_weak_local_alias, %eax
137 ; DARWIN32_DNP: movl $_weak_local_alias, %eax
138
139 @strong_preemptable_alias = dso_preemptable alias i32, i32* @aliasee
140 define i32* @get_strong_preemptable_alias() {
141 ret i32* @strong_preemptable_alias
142 }
143 ; CHECK: leaq _strong_preemptable_alias(%rip), %rax
144 ; DARWIN32: leal _strong_preemptable_alias-L{{.*}}$pb(%eax), %eax
145 ; DARWIN32_S: movl $_strong_preemptable_alias, %eax
146 ; DARWIN32_DNP: movl $_strong_preemptable_alias, %eax
147
148 @weak_preemptable_alias = weak dso_preemptable alias i32, i32* @aliasee
149 define i32* @get_weak_preemptable_alias() {
150 ret i32* @weak_preemptable_alias
151 }
152 ; CHECK: movq _weak_preemptable_alias@GOTPCREL(%rip), %rax
153 ; DARWIN32: movl L_weak_preemptable_alias$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
154 ; DARWIN32_S: movl $_weak_preemptable_alias, %eax
155 ; DARWIN32_DNP: movl L_weak_preemptable_alias$non_lazy_ptr, %eax
156
157 ; functions
158
159 define void @strong_default_function() {
160 ret void
161 }
162 define void()* @get_strong_default_function() {
163 ret void()* @strong_default_function
164 }
165 ; CHECK: leaq _strong_default_function(%rip), %rax
166 ; DARWIN32: leal _strong_default_function-L{{.*}}$pb(%eax), %eax
167 ; DARWIN32_S: movl $_strong_default_function, %eax
168 ; DARWIN32_DNP: movl $_strong_default_function, %eax
169
170 define weak void @weak_default_function() {
171 ret void
172 }
173 define void()* @get_weak_default_function() {
174 ret void()* @weak_default_function
175 }
176 ; CHECK: movq _weak_default_function@GOTPCREL(%rip), %rax
177 ; DARWIN32: movl L_weak_default_function$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
178 ; DARWIN32_S: movl $_weak_default_function, %eax
179 ; DARWIN32_DNP: movl L_weak_default_function$non_lazy_ptr, %eax
180
181 declare void @external_default_function()
182 define void()* @get_external_default_function() {
183 ret void()* @external_default_function
184 }
185 ; CHECK: movq _external_default_function@GOTPCREL(%rip), %rax
186 ; DARWIN32: movl L_external_default_function$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
187 ; DARWIN32_S: movl $_external_default_function, %eax
188 ; DARWIN32_DNP: movl L_external_default_function$non_lazy_ptr, %eax
189
190 define dso_local void @strong_local_function() {
191 ret void
192 }
193 define void()* @get_strong_local_function() {
194 ret void()* @strong_local_function
195 }
196 ; CHECK: leaq _strong_local_function(%rip), %rax
197 ; DARWIN32: leal _strong_local_function-L{{.*}}$pb(%eax), %eax
198 ; DARWIN32_S: movl $_strong_local_function, %eax
199 ; DARWIN32_DNP: movl $_strong_local_function, %eax
200
201 define weak dso_local void @weak_local_function() {
202 ret void
203 }
204 define void()* @get_weak_local_function() {
205 ret void()* @weak_local_function
206 }
207 ; CHECK: leaq _weak_local_function(%rip), %rax
208 ; DARWIN32: leal _weak_local_function-L{{.*}}$pb(%eax), %eax
209 ; DARWIN32_S: movl $_weak_local_function, %eax
210 ; DARWIN32_DNP: movl $_weak_local_function, %eax
211
212 declare dso_local void @external_local_function()
213 define void()* @get_external_local_function() {
214 ret void()* @external_local_function
215 }
216 ; CHECK: leaq _external_local_function(%rip), %rax
217 ; DARWIN32: movl L_external_local_function$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
218 ; DARWIN32_S: movl $_external_local_function, %eax
219 ; DARWIN32_DNP: movl $_external_local_function, %eax
220
221 define dso_preemptable void @strong_preemptable_function() {
222 ret void
223 }
224 define void()* @get_strong_preemptable_function() {
225 ret void()* @strong_preemptable_function
226 }
227 ; CHECK: leaq _strong_preemptable_function(%rip), %rax
228 ; DARWIN32: leal _strong_preemptable_function-L{{.*}}$pb(%eax), %eax
229 ; DARWIN32_S: movl $_strong_preemptable_function, %eax
230 ; DARWIN32_DNP: movl $_strong_preemptable_function, %eax
231
232 define weak dso_preemptable void @weak_preemptable_function() {
233 ret void
234 }
235 define void()* @get_weak_preemptable_function() {
236 ret void()* @weak_preemptable_function
237 }
238 ; CHECK: movq _weak_preemptable_function@GOTPCREL(%rip), %rax
239 ; DARWIN32: movl L_weak_preemptable_function$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
240 ; DARWIN32_S: movl $_weak_preemptable_function, %eax
241 ; DARWIN32_DNP: movl L_weak_preemptable_function$non_lazy_ptr, %eax
242
243 declare dso_preemptable void @external_preemptable_function()
244 define void()* @get_external_preemptable_function() {
245 ret void()* @external_preemptable_function
246 }
247 ; CHECK: movq _external_preemptable_function@GOTPCREL(%rip), %rax
248 ; DARWIN32: movl L_external_preemptable_function$non_lazy_ptr-L{{.*}}$pb(%eax), %eax
249 ; DARWIN32_S: movl $_external_preemptable_function, %eax
250 ; DARWIN32_DNP: movl L_external_preemptable_function$non_lazy_ptr, %eax
0 ; RUN: llc -mtriple x86_64-pc-linux \
1 ; RUN: -relocation-model=static < %s | FileCheck --check-prefix=STATIC %s
2 ; RUN: llc -mtriple x86_64-pc-linux \
3 ; RUN: -relocation-model=pic < %s | FileCheck %s
4 ; RUN: llc -mtriple x86_64-pc-linux \
5 ; RUN: -relocation-model=dynamic-no-pic < %s | FileCheck %s
6
7 ; 32 bits
8
9 ; RUN: llc -mtriple i386-pc-linux \
10 ; RUN: -relocation-model=pic < %s | FileCheck --check-prefix=CHECK32 %s
11
12 ; globals
13
14 @strong_default_global = global i32 42
15 define i32* @get_strong_default_global() {
16 ret i32* @strong_default_global
17 }
18 ; CHECK: movq strong_default_global@GOTPCREL(%rip), %rax
19 ; STATIC: movl $strong_default_global, %eax
20 ; CHECK32: movl strong_default_global@GOT(%eax), %eax
21
22 @weak_default_global = weak global i32 42
23 define i32* @get_weak_default_global() {
24 ret i32* @weak_default_global
25 }
26 ; CHECK: movq weak_default_global@GOTPCREL(%rip), %rax
27 ; STATIC: movl $weak_default_global, %eax
28 ; CHECK32: movl weak_default_global@GOT(%eax), %eax
29
30 @external_default_global = external global i32
31 define i32* @get_external_default_global() {
32 ret i32* @external_default_global
33 }
34 ; CHECK: movq external_default_global@GOTPCREL(%rip), %rax
35 ; STATIC: movl $external_default_global, %eax
36 ; CHECK32: movl external_default_global@GOT(%eax), %eax
37
38 @strong_local_global = dso_local global i32 42
39 define i32* @get_strong_local_global() {
40 ret i32* @strong_local_global
41 }
42 ; CHECK: leaq strong_local_global(%rip), %rax
43 ; STATIC: movl $strong_local_global, %eax
44 ; CHECK32: leal strong_local_global@GOTOFF(%eax), %eax
45
46 @weak_local_global = weak dso_local global i32 42
47 define i32* @get_weak_local_global() {
48 ret i32* @weak_local_global
49 }
50 ; CHECK: leaq weak_local_global(%rip), %rax
51 ; STATIC: movl $weak_local_global, %eax
52 ; CHECK32: leal weak_local_global@GOTOFF(%eax), %eax
53
54 @external_local_global = external dso_local global i32
55 define i32* @get_external_local_global() {
56 ret i32* @external_local_global
57 }
58 ; CHECK: leaq external_local_global(%rip), %rax
59 ; STATIC: movl $external_local_global, %eax
60 ; CHECK32: leal external_local_global@GOTOFF(%eax), %eax
61
62
63 @strong_preemptable_global = dso_preemptable global i32 42
64 define i32* @get_strong_preemptable_global() {
65 ret i32* @strong_preemptable_global
66 }
67 ; CHECK: movq strong_preemptable_global@GOTPCREL(%rip), %rax
68 ; STATIC: movl $strong_preemptable_global, %eax
69 ; CHECK32: movl strong_preemptable_global@GOT(%eax), %eax
70
71 @weak_preemptable_global = weak dso_preemptable global i32 42
72 define i32* @get_weak_preemptable_global() {
73 ret i32* @weak_preemptable_global
74 }
75 ; CHECK ;ADD_LABEL_BACK; movq weak_preemptable_global@GOTPCREL(%rip), %rax
76 ; STATIC ;ADD_LABEL_BACK; movq weak_preemptable_global@GOTPCREL, %rax
77 ; CHECK32 ;ADD_LABEL_BACK; movl weak_preemptable_global@GOT(%eax), %eax
78
79 @external_preemptable_global = external dso_preemptable global i32
80 define i32* @get_external_preemptable_global() {
81 ret i32* @external_preemptable_global
82 }
83 ; CHECK: movq external_preemptable_global@GOTPCREL(%rip), %rax
84 ; STATIC: movl $external_preemptable_global, %eax
85 ; CHECK32: movl external_preemptable_global@GOT(%eax), %eax
86
87 ; aliases
88 @aliasee = global i32 42
89
90 @strong_default_alias = alias i32, i32* @aliasee
91 define i32* @get_strong_default_alias() {
92 ret i32* @strong_default_alias
93 }
94 ; CHECK: movq strong_default_alias@GOTPCREL(%rip), %rax
95 ; STATIC: movl $strong_default_alias, %eax
96 ; CHECK32: movl strong_default_alias@GOT(%eax), %eax
97
98 @weak_default_alias = weak alias i32, i32* @aliasee
99 define i32* @get_weak_default_alias() {
100 ret i32* @weak_default_alias
101 }
102 ; CHECK: movq weak_default_alias@GOTPCREL(%rip), %rax
103 ; STATIC: movl $weak_default_alias, %eax
104 ; CHECK32: movl weak_default_alias@GOT(%eax), %eax
105
106 @strong_local_alias = dso_local alias i32, i32* @aliasee
107 define i32* @get_strong_local_alias() {
108 ret i32* @strong_local_alias
109 }
110 ; CHECK: leaq strong_local_alias(%rip), %rax
111 ; STATIC: movl $strong_local_alias, %eax
112 ; CHECK32: leal strong_local_alias@GOTOFF(%eax), %eax
113
114 @weak_local_alias = weak dso_local alias i32, i32* @aliasee
115 define i32* @get_weak_local_alias() {
116 ret i32* @weak_local_alias
117 }
118 ; CHECK: leaq weak_local_alias(%rip), %rax
119 ; STATIC: movl $weak_local_alias, %eax
120 ; CHECK32: leal weak_local_alias@GOTOFF(%eax), %eax
121
122
123 @strong_preemptable_alias = dso_preemptable alias i32, i32* @aliasee
124 define i32* @get_strong_preemptable_alias() {
125 ret i32* @strong_preemptable_alias
126 }
127 ; CHECK: movq strong_preemptable_alias@GOTPCREL(%rip), %rax
128 ; STATIC: movl $strong_preemptable_alias, %eax
129 ; CHECK32: movl strong_preemptable_alias@GOT(%eax), %eax
130
131 @weak_preemptable_alias = weak dso_preemptable alias i32, i32* @aliasee
132 define i32* @get_weak_preemptable_alias() {
133 ret i32* @weak_preemptable_alias
134 }
135 ; CHECK: movq weak_preemptable_alias@GOTPCREL(%rip), %rax
136 ; STATIC: movl $weak_preemptable_alias, %eax
137 ; CHECK32: movl weak_preemptable_alias@GOT(%eax), %eax
138
139 ; functions
140
141 define void @strong_default_function() {
142 ret void
143 }
144 define void()* @get_strong_default_function() {
145 ret void()* @strong_default_function
146 }
147 ; CHECK: movq strong_default_function@GOTPCREL(%rip), %rax
148 ; STATIC: movl $strong_default_function, %eax
149 ; CHECK32: movl strong_default_function@GOT(%eax), %eax
150
151 define weak void @weak_default_function() {
152 ret void
153 }
154 define void()* @get_weak_default_function() {
155 ret void()* @weak_default_function
156 }
157 ; CHECK: movq weak_default_function@GOTPCREL(%rip), %rax
158 ; STATIC: movl $weak_default_function, %eax
159 ; CHECK32: movl weak_default_function@GOT(%eax), %eax
160
161 declare void @external_default_function()
162 define void()* @get_external_default_function() {
163 ret void()* @external_default_function
164 }
165 ; CHECK: movq external_default_function@GOTPCREL(%rip), %rax
166 ; STATIC: movl $external_default_function, %eax
167 ; CHECK32: movl external_default_function@GOT(%eax), %eax
168
169 define dso_local void @strong_local_function() {
170 ret void
171 }
172 define void()* @get_strong_local_function() {
173 ret void()* @strong_local_function
174 }
175 ; CHECK: leaq strong_local_function(%rip), %rax
176 ; STATIC: movl $strong_local_function, %eax
177 ; CHECK32: leal strong_local_function@GOTOFF(%eax), %eax
178
179 define weak dso_local void @weak_local_function() {
180 ret void
181 }
182 define void()* @get_weak_local_function() {
183 ret void()* @weak_local_function
184 }
185 ; CHECK: leaq weak_local_function(%rip), %rax
186 ; STATIC: movl $weak_local_function, %eax
187 ; CHECK32: leal weak_local_function@GOTOFF(%eax), %eax
188
189 declare dso_local void @external_local_function()
190 define void()* @get_external_local_function() {
191 ret void()* @external_local_function
192 }
193 ; CHECK: leaq external_local_function(%rip), %rax
194 ; STATIC: movl $external_local_function, %eax
195 ; CHECK32: leal external_local_function@GOTOFF(%eax), %eax
196
197
198 define dso_preemptable void @strong_preemptable_function() {
199 ret void
200 }
201 define void()* @get_strong_preemptable_function() {
202 ret void()* @strong_preemptable_function
203 }
204 ; CHECK: movq strong_preemptable_function@GOTPCREL(%rip), %rax
205 ; STATIC: movl $strong_preemptable_function, %eax
206 ; CHECK32: movl strong_preemptable_function@GOT(%eax), %eax
207
208 define weak dso_preemptable void @weak_preemptable_function() {
209 ret void
210 }
211 define void()* @get_weak_preemptable_function() {
212 ret void()* @weak_preemptable_function
213 }
214 ; CHECK: movq weak_preemptable_function@GOTPCREL(%rip), %rax
215 ; STATIC: movl $weak_preemptable_function, %eax
216 ; CHECK32: movl weak_preemptable_function@GOT(%eax), %eax
217
218 declare dso_preemptable void @external_preemptable_function()
219 define void()* @get_external_preemptable_function() {
220 ret void()* @external_preemptable_function
221 }
222 ; CHECK: movq external_preemptable_function@GOTPCREL(%rip), %rax
223 ; STATIC: movl $external_preemptable_function, %eax
224 ; CHECK32: movl external_preemptable_function@GOT(%eax), %eax
0 ; RUN: llc -mtriple x86_64-pc-win32 \
1 ; RUN: -relocation-model=static < %s | FileCheck --check-prefix=COFF_S %s
2 ; RUN: llc -mtriple x86_64-pc-win32 \
3 ; RUN: -relocation-model=pic < %s | FileCheck --check-prefix=COFF %s
4 ; RUN: llc -mtriple x86_64-pc-win32 \
5 ; RUN: -relocation-model=dynamic-no-pic < %s | FileCheck --check-prefix=COFF %s
6
7
8 ; 32 bits
9
10 ; RUN: llc -mtriple i386-pc-win32 \
11 ; RUN: -relocation-model=static < %s | FileCheck --check-prefix=COFF32 %s
12 ; RUN: llc -mtriple i386-pc-win32 \
13 ; RUN: -relocation-model=pic < %s | FileCheck --check-prefix=COFF32 %s
14 ; RUN: llc -mtriple i386-pc-win32 \
15 ; RUN: -relocation-model=dynamic-no-pic < %s | \
16 ; RUN: FileCheck --check-prefix=COFF32 %s
17
18 ; globals
19
20 @strong_default_global = global i32 42
21 define i32* @get_strong_default_global() {
22 ret i32* @strong_default_global
23 }
24 ; COFF: leaq strong_default_global(%rip), %rax
25 ; COFF_S: movl $strong_default_global, %eax
26 ; COFF32: movl $_strong_default_global, %eax
27
28 @weak_default_global = weak global i32 42
29 define i32* @get_weak_default_global() {
30 ret i32* @weak_default_global
31 }
32 ; COFF: leaq weak_default_global(%rip), %rax
33 ; COFF_S: movl $weak_default_global, %eax
34 ; COFF32: movl $_weak_default_global, %eax
35
36 @external_default_global = external global i32
37 define i32* @get_external_default_global() {
38 ret i32* @external_default_global
39 }
40 ; COFF: leaq external_default_global(%rip), %rax
41 ; COFF_S: movl $external_default_global, %eax
42 ; COFF32: movl $_external_default_global, %eax
43
44
45 @strong_local_global = dso_local global i32 42
46 define i32* @get_strong_local_global() {
47 ret i32* @strong_local_global
48 }
49 ; COFF: leaq strong_local_global(%rip), %rax
50 ; COFF_S: movl $strong_local_global, %eax
51 ; COFF32: movl $_strong_local_global, %eax
52
53 @weak_local_global = weak dso_local global i32 42
54 define i32* @get_weak_local_global() {
55 ret i32* @weak_local_global
56 }
57 ; COFF: leaq weak_local_global(%rip), %rax
58 ; COFF_S: movl $weak_local_global, %eax
59 ; COFF32: movl $_weak_local_global, %eax
60
61 @external_local_global = external dso_local global i32
62 define i32* @get_external_local_global() {
63 ret i32* @external_local_global
64 }
65 ; COFF: leaq external_local_global(%rip), %rax
66 ; COFF_S: movl $external_local_global, %eax
67 ; COFF32: movl $_external_local_global, %eax
68
69
70 @strong_preemptable_global = dso_preemptable global i32 42
71 define i32* @get_strong_preemptable_global() {
72 ret i32* @strong_preemptable_global
73 }
74 ; COFF: leaq strong_preemptable_global(%rip), %rax
75 ; COFF_S: movl $strong_preemptable_global, %eax
76 ; COFF32: movl $_strong_preemptable_global, %eax
77
78 @weak_preemptable_global = weak dso_preemptable global i32 42
79 define i32* @get_weak_preemptable_global() {
80 ret i32* @weak_preemptable_global
81 }
82 ; COFF: leaq weak_preemptable_global(%rip), %rax
83 ; COFF_S: movl $weak_preemptable_global, %eax
84 ; COFF32: movl $_weak_preemptable_global, %eax
85
86 @external_preemptable_global = external dso_preemptable global i32
87 define i32* @get_external_preemptable_global() {
88 ret i32* @external_preemptable_global
89 }
90 ; COFF: leaq external_preemptable_global(%rip), %rax
91 ; COFF_S: movl $external_preemptable_global, %eax
92 ; COFF32: movl $_external_preemptable_global, %eax
93
94
95 ; aliases
96 @aliasee = global i32 42
97
98 @strong_default_alias = alias i32, i32* @aliasee
99 define i32* @get_strong_default_alias() {
100 ret i32* @strong_default_alias
101 }
102 ; COFF: leaq strong_default_alias(%rip), %rax
103 ; COFF_S: movl $strong_default_alias, %eax
104 ; COFF32: movl $_strong_default_alias, %eax
105
106 @weak_default_alias = weak alias i32, i32* @aliasee
107 define i32* @get_weak_default_alias() {
108 ret i32* @weak_default_alias
109 }
110 ; COFF: leaq weak_default_alias(%rip), %rax
111 ; COFF_S: movl $weak_default_alias, %eax
112 ; COFF32: movl $_weak_default_alias, %eax
113
114
115 @strong_local_alias = dso_local alias i32, i32* @aliasee
116 define i32* @get_strong_local_alias() {
117 ret i32* @strong_local_alias
118 }
119 ; COFF: leaq strong_local_alias(%rip), %rax
120 ; COFF_S: movl $strong_local_alias, %eax
121 ; COFF32: movl $_strong_local_alias, %eax
122
123 @weak_local_alias = weak dso_local alias i32, i32* @aliasee
124 define i32* @get_weak_local_alias() {
125 ret i32* @weak_local_alias
126 }
127 ; COFF: leaq weak_local_alias(%rip), %rax
128 ; COFF_S: movl $weak_local_alias, %eax
129 ; COFF32: movl $_weak_local_alias, %eax
130
131
132 @strong_preemptable_alias = dso_preemptable alias i32, i32* @aliasee
133 define i32* @get_strong_preemptable_alias() {
134 ret i32* @strong_preemptable_alias
135 }
136 ; COFF: leaq strong_preemptable_alias(%rip), %rax
137 ; COFF_S: movl $strong_preemptable_alias, %eax
138 ; COFF32: movl $_strong_preemptable_alias, %eax
139
140 @weak_preemptable_alias = weak dso_preemptable alias i32, i32* @aliasee
141 define i32* @get_weak_preemptable_alias() {
142 ret i32* @weak_preemptable_alias
143 }
144 ; COFF: leaq weak_preemptable_alias(%rip), %rax
145 ; COFF_S: movl $weak_preemptable_alias, %eax
146 ; COFF32: movl $_weak_preemptable_alias, %eax
147
148
149 ; functions
150
151 define void @strong_default_function() {
152 ret void
153 }
154 define void()* @get_strong_default_function() {
155 ret void()* @strong_default_function
156 }
157 ; COFF: leaq strong_default_function(%rip), %rax
158 ; COFF_S: movl $strong_default_function, %eax
159 ; COFF32: movl $_strong_default_function, %eax
160
161 define weak void @weak_default_function() {
162 ret void
163 }
164 define void()* @get_weak_default_function() {
165 ret void()* @weak_default_function
166 }
167 ; COFF: leaq weak_default_function(%rip), %rax
168 ; COFF_S: movl $weak_default_function, %eax
169 ; COFF32: movl $_weak_default_function, %eax
170
171 declare void @external_default_function()
172 define void()* @get_external_default_function() {
173 ret void()* @external_default_function
174 }
175 ; COFF: leaq external_default_function(%rip), %rax
176 ; COFF_S: movl $external_default_function, %eax
177 ; COFF32: movl $_external_default_function, %eax
178
179
180 define dso_local void @strong_local_function() {
181 ret void
182 }
183 define void()* @get_strong_local_function() {
184 ret void()* @strong_local_function
185 }
186 ; COFF: leaq strong_local_function(%rip), %rax
187 ; COFF_S: movl $strong_local_function, %eax
188 ; COFF32: movl $_strong_local_function, %eax
189
190 define weak dso_local void @weak_local_function() {
191 ret void
192 }
193 define void()* @get_weak_local_function() {
194 ret void()* @weak_local_function
195 }
196 ; COFF: leaq weak_local_function(%rip), %rax
197 ; COFF_S: movl $weak_local_function, %eax
198 ; COFF32: movl $_weak_local_function, %eax
199
200 declare dso_local void @external_local_function()
201 define void()* @get_external_local_function() {
202 ret void()* @external_local_function
203 }
204 ; COFF: leaq external_local_function(%rip), %rax
205 ; COFF_S: movl $external_local_function, %eax
206 ; COFF32: movl $_external_local_function, %eax
207
208
209 define dso_preemptable void @strong_preemptable_function() {
210 ret void
211 }
212 define void()* @get_strong_preemptable_function() {
213 ret void()* @strong_preemptable_function
214 }
215 ; COFF: leaq strong_preemptable_function(%rip), %rax
216 ; COFF_S: movl $strong_preemptable_function, %eax
217 ; COFF32: movl $_strong_preemptable_function, %eax
218
219 define weak dso_preemptable void @weak_preemptable_function() {
220 ret void
221 }
222 define void()* @get_weak_preemptable_function() {
223 ret void()* @weak_preemptable_function
224 }
225 ; COFF: leaq weak_preemptable_function(%rip), %rax
226 ; COFF_S: movl $weak_preemptable_function, %eax
227 ; COFF32: movl $_weak_preemptable_function, %eax
228
229 declare dso_preemptable void @external_preemptable_function()
230 define void()* @get_external_preemptable_function() {
231 ret void()* @external_preemptable_function
232 }
233 ; COFF: leaq external_preemptable_function(%rip), %rax
234 ; COFF_S: movl $external_preemptable_function, %eax
235 ; COFF32: movl $_external_preemptable_function, %eax