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 @@ -20493,6 +20493,12 @@ (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)) + return X86ISD::WrapperRIP; + // GOTPCREL references must always use RIP. if (OpFlags == X86II::MO_GOTPCREL || OpFlags == X86II::MO_GOTPCREL_NORELAX) return X86ISD::WrapperRIP; 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 @@ -270,7 +270,7 @@ ; ; MEDIUM-STATIC-LABEL: lea_static_fn: ; MEDIUM-STATIC: # %bb.0: -; MEDIUM-STATIC-NEXT: movabsq $static_fn, %rax +; MEDIUM-STATIC-NEXT: leaq static_fn(%rip), %rax ; MEDIUM-STATIC-NEXT: retq ; ; LARGE-STATIC-LABEL: lea_static_fn: @@ -285,7 +285,7 @@ ; ; MEDIUM-PIC-LABEL: lea_static_fn: ; MEDIUM-PIC: # %bb.0: -; MEDIUM-PIC-NEXT: movabsq $static_fn, %rax +; MEDIUM-PIC-NEXT: leaq static_fn(%rip), %rax ; MEDIUM-PIC-NEXT: retq ; ; LARGE-PIC-LABEL: lea_static_fn: @@ -308,7 +308,7 @@ ; ; MEDIUM-STATIC-LABEL: lea_global_fn: ; MEDIUM-STATIC: # %bb.0: -; MEDIUM-STATIC-NEXT: movabsq $global_fn, %rax +; MEDIUM-STATIC-NEXT: leaq global_fn(%rip), %rax ; MEDIUM-STATIC-NEXT: retq ; ; LARGE-STATIC-LABEL: lea_global_fn: @@ -323,7 +323,7 @@ ; ; MEDIUM-PIC-LABEL: lea_global_fn: ; MEDIUM-PIC: # %bb.0: -; MEDIUM-PIC-NEXT: movabsq $global_fn, %rax +; MEDIUM-PIC-NEXT: leaq global_fn(%rip), %rax ; MEDIUM-PIC-NEXT: retq ; ; LARGE-PIC-LABEL: lea_global_fn: