diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -20905,15 +20905,10 @@ if (GV && GV->isAbsoluteSymbolRef()) return X86ISD::Wrapper; - CodeModel::Model M = getTargetMachine().getCodeModel(); + // The following OpFlags under RIP-rel PIC use RIP. if (Subtarget.isPICStyleRIPRel() && - (M == CodeModel::Small || M == CodeModel::Kernel)) - return X86ISD::WrapperRIP; - - // In the medium model, functions can always be referenced RIP-relatively, - // since they must be within 2GiB. This is also possible in non-PIC mode, and - // shorter than the 64-bit absolute immediate that would otherwise be emitted. - if (M == CodeModel::Medium && isa_and_nonnull(GV)) + (OpFlags == X86II::MO_NO_FLAG || OpFlags == X86II::MO_COFFSTUB || + OpFlags == X86II::MO_DLLIMPORT)) return X86ISD::WrapperRIP; // GOTPCREL references must always use RIP. @@ -20941,7 +20936,8 @@ SDValue Result = DAG.getTargetConstantPool( CP->getConstVal(), PtrVT, CP->getAlign(), CP->getOffset(), OpFlag); SDLoc DL(CP); - Result = DAG.getNode(getGlobalWrapperKind(), DL, PtrVT, Result); + Result = + DAG.getNode(getGlobalWrapperKind(nullptr, OpFlag), DL, PtrVT, Result); // With PIC, the address is actually $g + Offset. if (OpFlag) { Result = @@ -20962,7 +20958,8 @@ auto PtrVT = getPointerTy(DAG.getDataLayout()); SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, OpFlag); SDLoc DL(JT); - Result = DAG.getNode(getGlobalWrapperKind(), DL, PtrVT, Result); + Result = + DAG.getNode(getGlobalWrapperKind(nullptr, OpFlag), DL, PtrVT, Result); // With PIC, the address is actually $g + Offset. if (OpFlag) @@ -20988,7 +20985,8 @@ SDLoc dl(Op); auto PtrVT = getPointerTy(DAG.getDataLayout()); SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT, Offset, OpFlags); - Result = DAG.getNode(getGlobalWrapperKind(), dl, PtrVT, Result); + Result = + DAG.getNode(getGlobalWrapperKind(nullptr, OpFlags), dl, PtrVT, Result); // With PIC, the address is actually $g + Offset. if (isGlobalRelativeToPICBase(OpFlags)) { diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -95,12 +95,17 @@ case CodeModel::Large: return X86II::MO_GOTOFF; - // Medium is a hybrid: RIP-rel for code, GOTOFF for DSO local data. + // Medium is a hybrid: RIP-rel for code and non-large data, GOTOFF for + // remaining DSO local data. case CodeModel::Medium: // Constant pool and jump table handling pass a nullptr to this // function so we need to use isa_and_nonnull. if (isa_and_nonnull(GV)) return X86II::MO_NO_FLAG; // All code is RIP-relative + if (auto *GVar = dyn_cast_or_null(GV)) { + if (!TM.isLargeData(GVar)) + return X86II::MO_NO_FLAG; + } return X86II::MO_GOTOFF; // Local symbols use GOTOFF. } llvm_unreachable("invalid code model"); @@ -323,7 +328,7 @@ InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)), TLInfo(TM, *this), FrameLowering(*this, getStackAlignment()) { // Determine the PICStyle based on the target selected. - if (!isPositionIndependent()) + if (!isPositionIndependent() || TM.getCodeModel() == CodeModel::Large) setPICStyle(PICStyles::Style::None); else if (is64Bit()) setPICStyle(PICStyles::Style::RIPRel); diff --git a/llvm/test/CodeGen/X86/code-model-elf.ll b/llvm/test/CodeGen/X86/code-model-elf.ll --- a/llvm/test/CodeGen/X86/code-model-elf.ll +++ b/llvm/test/CodeGen/X86/code-model-elf.ll @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --no_x86_scrub_sp ; Run with --no_x86_scrub_rip because we care a lot about how globals are ; accessed in the code model. @@ -6,9 +6,12 @@ ; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-STATIC ; RUN: llc -verify-machineinstrs < %s -relocation-model=static -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-STATIC ; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=small | FileCheck %s --check-prefix=CHECK --check-prefix=SMALL-PIC +; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=medium -large-data-threshold=1000 | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-SMALL-DATA-PIC ; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=medium | FileCheck %s --check-prefix=CHECK --check-prefix=MEDIUM-PIC ; RUN: llc -verify-machineinstrs < %s -relocation-model=pic -code-model=large | FileCheck %s --check-prefix=CHECK --check-prefix=LARGE-PIC +; FIXME: small pic and medium pic w/ big enough large data threshold should be equivalent + ; Generated from this C source: ; ; static int static_data[10]; @@ -61,6 +64,11 @@ ; SMALL-PIC-NEXT: leaq static_data(%rip), %rax ; SMALL-PIC-NEXT: retq ; +; MEDIUM-SMALL-DATA-PIC-LABEL: lea_static_data: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: leaq static_data(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; ; MEDIUM-PIC-LABEL: lea_static_data: ; MEDIUM-PIC: # %bb.0: ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx @@ -101,6 +109,11 @@ ; SMALL-PIC-NEXT: leaq global_data(%rip), %rax ; SMALL-PIC-NEXT: retq ; +; MEDIUM-SMALL-DATA-PIC-LABEL: lea_global_data: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: leaq global_data(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; ; MEDIUM-PIC-LABEL: lea_global_data: ; MEDIUM-PIC: # %bb.0: ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx @@ -141,6 +154,11 @@ ; SMALL-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax ; SMALL-PIC-NEXT: retq ; +; MEDIUM-SMALL-DATA-PIC-LABEL: lea_extern_data: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; ; MEDIUM-PIC-LABEL: lea_extern_data: ; MEDIUM-PIC: # %bb.0: ; MEDIUM-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax @@ -181,6 +199,12 @@ ; SMALL-PIC-NEXT: movl global_data+8(%rip), %eax ; SMALL-PIC-NEXT: retq ; +; MEDIUM-SMALL-DATA-PIC-LABEL: load_global_data: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: leaq global_data(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: movl 8(%rax), %eax +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; ; MEDIUM-PIC-LABEL: load_global_data: ; MEDIUM-PIC: # %bb.0: ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax @@ -226,6 +250,12 @@ ; SMALL-PIC-NEXT: movl 8(%rax), %eax ; SMALL-PIC-NEXT: retq ; +; MEDIUM-SMALL-DATA-PIC-LABEL: load_extern_data: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: movl 8(%rax), %eax +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; ; MEDIUM-PIC-LABEL: load_extern_data: ; MEDIUM-PIC: # %bb.0: ; MEDIUM-PIC-NEXT: movq extern_data@GOTPCREL(%rip), %rax @@ -270,7 +300,7 @@ ; ; MEDIUM-STATIC-LABEL: lea_static_fn: ; MEDIUM-STATIC: # %bb.0: -; MEDIUM-STATIC-NEXT: leaq static_fn(%rip), %rax +; MEDIUM-STATIC-NEXT: movabsq $static_fn, %rax ; MEDIUM-STATIC-NEXT: retq ; ; LARGE-STATIC-LABEL: lea_static_fn: @@ -283,6 +313,11 @@ ; SMALL-PIC-NEXT: leaq static_fn(%rip), %rax ; SMALL-PIC-NEXT: retq ; +; MEDIUM-SMALL-DATA-PIC-LABEL: lea_static_fn: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: leaq static_fn(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; ; MEDIUM-PIC-LABEL: lea_static_fn: ; MEDIUM-PIC: # %bb.0: ; MEDIUM-PIC-NEXT: leaq static_fn(%rip), %rax @@ -308,7 +343,7 @@ ; ; MEDIUM-STATIC-LABEL: lea_global_fn: ; MEDIUM-STATIC: # %bb.0: -; MEDIUM-STATIC-NEXT: leaq global_fn(%rip), %rax +; MEDIUM-STATIC-NEXT: movabsq $global_fn, %rax ; MEDIUM-STATIC-NEXT: retq ; ; LARGE-STATIC-LABEL: lea_global_fn: @@ -321,6 +356,11 @@ ; SMALL-PIC-NEXT: leaq global_fn(%rip), %rax ; SMALL-PIC-NEXT: retq ; +; MEDIUM-SMALL-DATA-PIC-LABEL: lea_global_fn: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: leaq global_fn(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; ; MEDIUM-PIC-LABEL: lea_global_fn: ; MEDIUM-PIC: # %bb.0: ; MEDIUM-PIC-NEXT: leaq global_fn(%rip), %rax @@ -359,6 +399,11 @@ ; SMALL-PIC-NEXT: movq extern_fn@GOTPCREL(%rip), %rax ; SMALL-PIC-NEXT: retq ; +; MEDIUM-SMALL-DATA-PIC-LABEL: lea_extern_fn: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: movq extern_fn@GOTPCREL(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; ; MEDIUM-PIC-LABEL: lea_extern_fn: ; MEDIUM-PIC: # %bb.0: ; MEDIUM-PIC-NEXT: movq extern_fn@GOTPCREL(%rip), %rax @@ -432,6 +477,13 @@ ; SMALL-PIC-NEXT: addss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 ; SMALL-PIC-NEXT: retq ; +; MEDIUM-SMALL-DATA-PIC-LABEL: load_constant_pool: +; MEDIUM-SMALL-DATA-PIC: # %bb.0: +; MEDIUM-SMALL-DATA-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax +; MEDIUM-SMALL-DATA-PIC-NEXT: movabsq ${{\.?LCPI[0-9]+_[0-9]+}}@GOTOFF, %rcx +; MEDIUM-SMALL-DATA-PIC-NEXT: addss (%rax,%rcx), %xmm0 +; MEDIUM-SMALL-DATA-PIC-NEXT: retq +; ; MEDIUM-PIC-LABEL: load_constant_pool: ; MEDIUM-PIC: # %bb.0: ; MEDIUM-PIC-NEXT: leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax