Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ llvm/lib/Target/X86/X86ISelLowering.cpp @@ -20493,6 +20493,13 @@ (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; Index: llvm/test/CodeGen/X86/code-model-elf.ll =================================================================== --- llvm/test/CodeGen/X86/code-model-elf.ll +++ 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: