diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index ff4f769dcc0db..c0bd978b501ad 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -695,6 +695,9 @@ target supports it, it will emit globals to the section specified. Additionally, the global can placed in a comdat if the target has the necessary support. +For code models with a small/large data distinction, a global marked ``large`` +is considered large regardless of its size. + External declarations may have an explicit section specified. Section information is retained in LLVM IR for targets that make use of this information. Attaching section information to an external declaration is an @@ -755,7 +758,7 @@ Syntax:: [(unnamed_addr|local_unnamed_addr)] [AddrSpace] [ExternallyInitialized] [] - [, section "name"] [, partition "name"] + [, section "name"] [, large] [, partition "name"] [, comdat [($name)]] [, align ] [, no_sanitize_address] [, no_sanitize_hwaddress] [, sanitize_address_dyninit] [, sanitize_memtag] diff --git a/llvm/include/llvm/AsmParser/LLToken.h b/llvm/include/llvm/AsmParser/LLToken.h index c9dcd29b31955..ac460181e545d 100644 --- a/llvm/include/llvm/AsmParser/LLToken.h +++ b/llvm/include/llvm/AsmParser/LLToken.h @@ -115,6 +115,7 @@ enum Kind { kw_addrspace, kw_section, kw_partition, + kw_large, kw_alias, kw_ifunc, kw_module, diff --git a/llvm/include/llvm/IR/GlobalVariable.h b/llvm/include/llvm/IR/GlobalVariable.h index 5ddffd16acc68..89f1e722352c1 100644 --- a/llvm/include/llvm/IR/GlobalVariable.h +++ b/llvm/include/llvm/IR/GlobalVariable.h @@ -46,6 +46,9 @@ class GlobalVariable : public GlobalObject, public ilist_node { // Is this a global whose value can change from its initial value before // global initializers are run? bool isExternallyInitializedConstant : 1; + // Is this global unconditionally considered large in code models with a + // small/large data distinction? + bool isLargeGlobal : 1; public: /// GlobalVariable ctor - If a parent module is specified, the global is @@ -53,7 +56,7 @@ class GlobalVariable : public GlobalObject, public ilist_node { GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage, Constant *Initializer = nullptr, const Twine &Name = "", ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0, - bool isExternallyInitialized = false); + bool isExternallyInitialized = false, bool isLarge = false); /// GlobalVariable ctor - This creates a global and inserts it before the /// specified other global. GlobalVariable(Module &M, Type *Ty, bool isConstant, LinkageTypes Linkage, @@ -61,7 +64,7 @@ class GlobalVariable : public GlobalObject, public ilist_node { GlobalVariable *InsertBefore = nullptr, ThreadLocalMode = NotThreadLocal, std::optional AddressSpace = std::nullopt, - bool isExternallyInitialized = false); + bool isExternallyInitialized = false, bool isLarge = false); GlobalVariable(const GlobalVariable &) = delete; GlobalVariable &operator=(const GlobalVariable &) = delete; @@ -159,6 +162,8 @@ class GlobalVariable : public GlobalObject, public ilist_node { void setExternallyInitialized(bool Val) { isExternallyInitializedConstant = Val; } + bool isLarge() const { return isLargeGlobal; } + void setLarge(bool Val) { isLargeGlobal = Val; } /// copyAttributesFrom - copy all additional attributes (those not needed to /// create a GlobalVariable) from the GlobalVariable Src to this one. diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index da9e9f4a3c983..4309f0c45480d 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -570,6 +570,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(addrspace); KEYWORD(section); KEYWORD(partition); + KEYWORD(large); KEYWORD(alias); KEYWORD(ifunc); KEYWORD(module); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 9940bfb15d197..8e0d1e06dea93 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1286,6 +1286,9 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc, return true; if (Alignment) GV->setAlignment(*Alignment); + } else if (Lex.getKind() == lltok::kw_large) { + GV->setLarge(true); + Lex.Lex(); } else if (Lex.getKind() == lltok::MetadataVar) { if (parseGlobalObjectMetadataAttachment(*GV)) return true; diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 76431e883b8d9..9201d0bdbe2dd 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3917,6 +3917,9 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef Record) { NewGV->setSanitizerMetadata(Meta); } + if (Record.size() > 17 && Record[17]) + NewGV->setLarge(Record[17]); + return Error::success(); } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index d16b5c7781c24..fd4d47cf43f29 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1404,7 +1404,7 @@ void ModuleBitcodeWriter::writeModuleInfo() { // GLOBALVAR: [strtab offset, strtab size, type, isconst, initid, // linkage, alignment, section, visibility, threadlocal, // unnamed_addr, externally_initialized, dllstorageclass, - // comdat, attributes, DSO_Local, GlobalSanitizer] + // comdat, attributes, DSO_Local, GlobalSanitizer, large] Vals.push_back(addToStrtab(GV.getName())); Vals.push_back(GV.getName().size()); Vals.push_back(VE.getTypeID(GV.getValueType())); @@ -1421,7 +1421,7 @@ void ModuleBitcodeWriter::writeModuleInfo() { GV.isExternallyInitialized() || GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass || GV.hasComdat() || GV.hasAttributes() || GV.isDSOLocal() || - GV.hasPartition() || GV.hasSanitizerMetadata()) { + GV.hasPartition() || GV.hasSanitizerMetadata() || GV.isLarge()) { Vals.push_back(getEncodedVisibility(GV)); Vals.push_back(getEncodedThreadLocalMode(GV)); Vals.push_back(getEncodedUnnamedAddr(GV)); @@ -1439,6 +1439,7 @@ void ModuleBitcodeWriter::writeModuleInfo() { Vals.push_back((GV.hasSanitizerMetadata() ? serializeSanitizerMetadata( GV.getSanitizerMetadata()) : 0)); + Vals.push_back(GV.isLarge()); } else { AbbrevToUse = SimpleGVarAbbrev; } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 6d66b34423949..8b0414d79fc39 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -3642,6 +3642,8 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { printEscapedString(GV->getSection(), Out); Out << '"'; } + if (GV->isLarge()) + Out << ", large"; if (GV->hasPartition()) { Out << ", partition \""; printEscapedString(GV->getPartition(), Out); diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index 7bd4503a689e4..9d8decfad85b5 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -414,12 +414,13 @@ bool GlobalValue::canBeOmittedFromSymbolTable() const { GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, Constant *InitVal, const Twine &Name, ThreadLocalMode TLMode, unsigned AddressSpace, - bool isExternallyInitialized) + bool isExternallyInitialized, bool isLarge) : GlobalObject(Ty, Value::GlobalVariableVal, OperandTraits::op_begin(this), InitVal != nullptr, Link, Name, AddressSpace), isConstantGlobal(constant), - isExternallyInitializedConstant(isExternallyInitialized) { + isExternallyInitializedConstant(isExternallyInitialized), + isLargeGlobal(isLarge) { assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) && "invalid type for global variable"); setThreadLocalMode(TLMode); @@ -435,12 +436,12 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant, const Twine &Name, GlobalVariable *Before, ThreadLocalMode TLMode, std::optional AddressSpace, - bool isExternallyInitialized) + bool isExternallyInitialized, bool isLarge) : GlobalVariable(Ty, constant, Link, InitVal, Name, TLMode, AddressSpace ? *AddressSpace : M.getDataLayout().getDefaultGlobalsAddressSpace(), - isExternallyInitialized) { + isExternallyInitialized, isLarge) { if (Before) Before->getParent()->insertGlobalVariable(Before->getIterator(), this); else diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index 9dc00ff85e009..c0c6aeba97468 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -42,6 +42,8 @@ TargetMachine::~TargetMachine() = default; bool TargetMachine::isLargeData(const GlobalVariable *GV) const { if (getTargetTriple().getArch() != Triple::x86_64 || GV->isThreadLocal()) return false; + if (GV->isLarge()) + return true; // Large data under the large code model still needs to be thought about, so // restrict this to medium. if (getCodeModel() != CodeModel::Medium) diff --git a/llvm/test/Assembler/globalvariable-attributes.ll b/llvm/test/Assembler/globalvariable-attributes.ll index 544f9bdb270e9..06ec6d0d27c06 100644 --- a/llvm/test/Assembler/globalvariable-attributes.ll +++ b/llvm/test/Assembler/globalvariable-attributes.ll @@ -9,6 +9,7 @@ @g7 = global i32 2, sanitize_address_dyninit, align 4 @g8 = global i32 2, sanitize_memtag, align 4 @g9 = global i32 2, no_sanitize_address, no_sanitize_hwaddress, sanitize_memtag, align 4 +@g10 = global i32 2, large attributes #0 = { "string" = "value" nobuiltin norecurse } @@ -21,6 +22,7 @@ attributes #0 = { "string" = "value" nobuiltin norecurse } ; CHECK: @g7 = global i32 2, sanitize_address_dyninit, align 4 ; CHECK: @g8 = global i32 2, sanitize_memtag, align 4 ; CHECK: @g9 = global i32 2, no_sanitize_address, no_sanitize_hwaddress, sanitize_memtag, align 4 +; CHECK: @g10 = global i32 2, large ; CHECK: attributes #0 = { "key"="value" "key2"="value2" } ; CHECK: attributes #1 = { "key3"="value3" } diff --git a/llvm/test/CodeGen/X86/code-model-elf.ll b/llvm/test/CodeGen/X86/code-model-elf.ll index 901a62d26f77e..9a4e9f66c2908 100644 --- a/llvm/test/CodeGen/X86/code-model-elf.ll +++ b/llvm/test/CodeGen/X86/code-model-elf.ll @@ -37,6 +37,7 @@ target triple = "x86_64--linux" @global_data = dso_local global [10 x i32] [i32 1, i32 2, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0], align 16 @static_data = internal global [10 x i32] zeroinitializer, align 16 +@always_large_static_data = internal global [10 x i32] zeroinitializer, align 16, large @extern_data = external global [10 x i32], align 16 @thread_data = external thread_local global i32, align 4 @unknown_size_data = dso_local global [0 x i32] zeroinitializer, align 16 @@ -87,6 +88,53 @@ define dso_local ptr @lea_static_data() #0 { ret ptr @static_data } +define dso_local ptr @lea_always_large_static_data() #0 { +; SMALL-STATIC-LABEL: lea_always_large_static_data: +; SMALL-STATIC: # %bb.0: +; SMALL-STATIC-NEXT: movl $always_large_static_data, %eax +; SMALL-STATIC-NEXT: retq +; +; MEDIUM-STATIC-LABEL: lea_always_large_static_data: +; MEDIUM-STATIC: # %bb.0: +; MEDIUM-STATIC-NEXT: movabsq $always_large_static_data, %rax +; MEDIUM-STATIC-NEXT: retq +; +; LARGE-STATIC-LABEL: lea_always_large_static_data: +; LARGE-STATIC: # %bb.0: +; LARGE-STATIC-NEXT: movabsq $always_large_static_data, %rax +; LARGE-STATIC-NEXT: retq +; +; SMALL-PIC-LABEL: lea_always_large_static_data: +; SMALL-PIC: # %bb.0: +; SMALL-PIC-NEXT: leaq always_large_static_data(%rip), %rax +; SMALL-PIC-NEXT: retq +; +; MEDIUM-SMALL-DATA-PIC-LABEL: lea_always_large_static_data: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx +; MEDIUM-SMALL-DATA-PIC-NEXT: movabsq $always_large_static_data@GOTOFF, %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: addq %rcx, %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; +; MEDIUM-PIC-LABEL: lea_always_large_static_data: +; MEDIUM-PIC: # %bb.0: +; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx +; MEDIUM-PIC-NEXT: movabsq $always_large_static_data@GOTOFF, %rax +; MEDIUM-PIC-NEXT: addq %rcx, %rax +; MEDIUM-PIC-NEXT: retq +; +; LARGE-PIC-LABEL: lea_always_large_static_data: +; LARGE-PIC: # %bb.0: +; LARGE-PIC-NEXT: .L1$pb: +; LARGE-PIC-NEXT: leaq .L1$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx +; LARGE-PIC-NEXT: addq %rax, %rcx +; LARGE-PIC-NEXT: movabsq $always_large_static_data@GOTOFF, %rax +; LARGE-PIC-NEXT: addq %rcx, %rax +; LARGE-PIC-NEXT: retq + ret ptr @always_large_static_data +} + define dso_local ptr @lea_global_data() #0 { ; SMALL-STATIC-LABEL: lea_global_data: ; SMALL-STATIC: # %bb.0: @@ -122,9 +170,9 @@ define dso_local ptr @lea_global_data() #0 { ; ; LARGE-PIC-LABEL: lea_global_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L1$pb: -; LARGE-PIC-NEXT: leaq .L1$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L1$pb, %rcx +; LARGE-PIC-NEXT: .L2$pb: +; LARGE-PIC-NEXT: leaq .L2$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax ; LARGE-PIC-NEXT: addq %rcx, %rax @@ -165,9 +213,9 @@ define dso_local ptr @lea_extern_data() #0 { ; ; LARGE-PIC-LABEL: lea_extern_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L2$pb: -; LARGE-PIC-NEXT: leaq .L2$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L2$pb, %rcx +; LARGE-PIC-NEXT: .L3$pb: +; LARGE-PIC-NEXT: leaq .L3$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax ; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax @@ -212,9 +260,9 @@ define dso_local ptr @lea_unknown_size_data() #0 { ; ; LARGE-PIC-LABEL: lea_unknown_size_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L3$pb: -; LARGE-PIC-NEXT: leaq .L3$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L3$pb, %rcx +; LARGE-PIC-NEXT: .L4$pb: +; LARGE-PIC-NEXT: leaq .L4$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $unknown_size_data@GOTOFF, %rax ; LARGE-PIC-NEXT: addq %rcx, %rax @@ -260,9 +308,9 @@ define dso_local i32 @load_global_data() #0 { ; ; LARGE-PIC-LABEL: load_global_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L4$pb: -; LARGE-PIC-NEXT: leaq .L4$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L4$pb, %rcx +; LARGE-PIC-NEXT: .L5$pb: +; LARGE-PIC-NEXT: leaq .L5$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L5$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $global_data@GOTOFF, %rax ; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax @@ -310,9 +358,9 @@ define dso_local i32 @load_extern_data() #0 { ; ; LARGE-PIC-LABEL: load_extern_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L5$pb: -; LARGE-PIC-NEXT: leaq .L5$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L5$pb, %rcx +; LARGE-PIC-NEXT: .L6$pb: +; LARGE-PIC-NEXT: leaq .L6$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L6$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $extern_data@GOT, %rax ; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax @@ -361,9 +409,9 @@ define dso_local i32 @load_unknown_size_data() #0 { ; ; LARGE-PIC-LABEL: load_unknown_size_data: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L6$pb: -; LARGE-PIC-NEXT: leaq .L6$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L6$pb, %rcx +; LARGE-PIC-NEXT: .L7$pb: +; LARGE-PIC-NEXT: leaq .L7$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L7$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $unknown_size_data@GOTOFF, %rax ; LARGE-PIC-NEXT: movl 8(%rcx,%rax), %eax @@ -421,9 +469,9 @@ define dso_local ptr @lea_static_fn() #0 { ; ; LARGE-PIC-LABEL: lea_static_fn: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L9$pb: -; LARGE-PIC-NEXT: leaq .L9$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L9$pb, %rcx +; LARGE-PIC-NEXT: .L10$pb: +; LARGE-PIC-NEXT: leaq .L10$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L10$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $static_fn@GOTOFF, %rax ; LARGE-PIC-NEXT: addq %rcx, %rax @@ -464,9 +512,9 @@ define dso_local ptr @lea_global_fn() #0 { ; ; LARGE-PIC-LABEL: lea_global_fn: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L10$pb: -; LARGE-PIC-NEXT: leaq .L10$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L10$pb, %rcx +; LARGE-PIC-NEXT: .L11$pb: +; LARGE-PIC-NEXT: leaq .L11$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L11$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $global_fn@GOTOFF, %rax ; LARGE-PIC-NEXT: addq %rcx, %rax @@ -507,9 +555,9 @@ define dso_local ptr @lea_extern_fn() #0 { ; ; LARGE-PIC-LABEL: lea_extern_fn: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L11$pb: -; LARGE-PIC-NEXT: leaq .L11$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L11$pb, %rcx +; LARGE-PIC-NEXT: .L12$pb: +; LARGE-PIC-NEXT: leaq .L12$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L12$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq $extern_fn@GOT, %rax ; LARGE-PIC-NEXT: movq (%rcx,%rax), %rax @@ -585,9 +633,9 @@ define dso_local float @load_constant_pool(float %x) #0 { ; ; LARGE-PIC-LABEL: load_constant_pool: ; LARGE-PIC: # %bb.0: -; LARGE-PIC-NEXT: .L13$pb: -; LARGE-PIC-NEXT: leaq .L13$pb(%rip), %rax -; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L13$pb, %rcx +; LARGE-PIC-NEXT: .L14$pb: +; LARGE-PIC-NEXT: leaq .L14$pb(%rip), %rax +; LARGE-PIC-NEXT: movabsq $_GLOBAL_OFFSET_TABLE_-.L14$pb, %rcx ; LARGE-PIC-NEXT: addq %rax, %rcx ; LARGE-PIC-NEXT: movabsq ${{\.?LCPI[0-9]+_[0-9]+}}@GOTOFF, %rax ; LARGE-PIC-NEXT: addss (%rcx,%rax), %xmm0