[llvm] 82be8a1 - [X86] Emit RIP-relative access to local function in PIC medium code model

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 28 11:14:43 PST 2022


Author: Thomas Köppe
Date: 2022-12-28T11:14:39-08:00
New Revision: 82be8a1d2b00f6e89096b86f670a8be894c7b9e6

URL: https://github.com/llvm/llvm-project/commit/82be8a1d2b00f6e89096b86f670a8be894c7b9e6
DIFF: https://github.com/llvm/llvm-project/commit/82be8a1d2b00f6e89096b86f670a8be894c7b9e6.diff

LOG: [X86] Emit RIP-relative access to local function in PIC medium code model

Currently, the medium code model for x86_64 emits position-dependent relocations (R_X86_64_64) for local functions, regardless of PIC or no-PIC mode. (This means generically that code compiled with the medium model cannot be linked into a position-independent executable.)

Example:

```
static int g(int n) {
  return 2 * n + 3;
}

void f(int(**p)(int)) {
  *p = g;
}
```

This results in:

```
Disassembly of section .text:

0000000000000000 <f>:
       0: 48 b8 00 00 00 00 00 00 00 00	movabs	rax, 0x0
       a: 48 89 07                     	mov	qword ptr [rdi], rax
       d: c3                           	ret
```

```
Relocation section '.rela.text' at offset 0xf0 contains 1 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000002  0000000200000001 R_X86_64_64            0000000000000000 .text + 10
```

This patch changes the behaviour to unconditionally emit a RIP-relative access, both in PIC and non-PIC mode. This fixes PIC mode, and is perhaps an improvement in non-PIC mode, too, since it results in a shorter instruction. A 32-bit relocation should suffice since the medium memory model demands that all code fit within 2GiB.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D140593

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/code-model-elf.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 119d96f75ef37..c0aeed8e45fb1 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -20493,6 +20493,12 @@ unsigned X86TargetLowering::getGlobalWrapperKind(
       (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<Function>(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
index c3015f50772a6..e727459740a80 100644
--- a/llvm/test/CodeGen/X86/code-model-elf.ll
+++ b/llvm/test/CodeGen/X86/code-model-elf.ll
@@ -270,7 +270,7 @@ define dso_local ptr @lea_static_fn() #0 {
 ;
 ; 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 @@ define dso_local ptr @lea_static_fn() #0 {
 ;
 ; 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 @@ define dso_local ptr @lea_global_fn() #0 {
 ;
 ; 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 @@ define dso_local ptr @lea_global_fn() #0 {
 ;
 ; 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:


        


More information about the llvm-commits mailing list