https://github.com/KanRobert updated 
https://github.com/llvm/llvm-project/pull/106681

>From 88cbdf9765e42dee7d2b050dcf8a20a08b4b148f Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen....@intel.com>
Date: Tue, 25 Jun 2024 20:33:10 +0800
Subject: [PATCH 1/8] [X86,lld] Add relocation R_X86_64_REX2_GOTPCRELX

For

        mov        name@GOTPCREL(%rip), %reg
        test       %reg, name@GOTPCREL(%rip)
        binop      name@GOTPCREL(%rip), %reg

where binop is one of adc, add, and, cmp, or, sbb, sub, xor instructions,
add

 R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX = 43

if the instruction starts at 4 bytes before the relocation offset.  It
similar to R_X86_64_GOTPCRELX.

Linker can treat R_X86_64_REX2_GOTPCRELX/R_X86_64_CODE_4_GOTPCRELX
as R_X86_64_GOTPCREL or convert the above instructions to

        lea     name(%rip), %reg
        mov     $name, %reg
        test    $name, %reg
        binop   $name, %reg

if the first byte of the instruction at the relocation `offset - 4` is
`0xd5` (namely, encoded w/ REX2 prefix) when possible.

Binutils patch: 
https://github.com/bminor/binutils-gdb/commit/3d5a60de52556f6a53d71d7e607c6696450ae3e4
Binutils mailthread: 
https://sourceware.org/pipermail/binutils/2023-December/131462.html
ABI discussion: https://groups.google.com/g/x86-64-abi/c/KbzaNHRB6QU
Blog: https://kanrobert.github.io/rfc/All-about-APX-relocation
---
 clang/test/Driver/relax.s                     |  2 ++
 lld/ELF/Arch/X86_64.cpp                       |  3 ++
 lld/test/ELF/x86-64-gotpc-no-relax-err.s      | 10 ++++--
 lld/test/ELF/x86-64-gotpc-relax.s             |  2 +-
 .../llvm/BinaryFormat/ELFRelocs/x86_64.def    |  1 +
 llvm/lib/MC/MCTargetOptionsCommandFlags.cpp   |  4 +--
 .../Target/X86/MCTargetDesc/X86AsmBackend.cpp |  4 +++
 .../X86/MCTargetDesc/X86ELFObjectWriter.cpp   |  7 +++-
 .../Target/X86/MCTargetDesc/X86FixupKinds.h   |  4 +++
 .../X86/MCTargetDesc/X86MCCodeEmitter.cpp     | 19 +++++------
 .../X86/MCTargetDesc/X86MachObjectWriter.cpp  |  6 +++-
 .../MCTargetDesc/X86WinCOFFObjectWriter.cpp   |  2 ++
 llvm/test/MC/ELF/relocation-alias.s           |  3 ++
 llvm/test/MC/X86/gotpcrelx.s                  | 34 +++++++++++++++++++
 14 files changed, 83 insertions(+), 18 deletions(-)

diff --git a/clang/test/Driver/relax.s b/clang/test/Driver/relax.s
index 154d4db0a31385..b4a696a328eb56 100644
--- a/clang/test/Driver/relax.s
+++ b/clang/test/Driver/relax.s
@@ -8,5 +8,7 @@
 // RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s
 
 // REL: R_X86_64_REX_GOTPCRELX foo
+// REL: R_X86_64_REX2_GOTPCRELX foo
 
         movq   foo@GOTPCREL(%rip), %rax
+        movq   foo@GOTPCREL(%rip), %r16
diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 48f17718365e24..1371cee410dc82 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -388,6 +388,7 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
   case R_X86_64_GOTPCREL:
   case R_X86_64_GOTPCRELX:
   case R_X86_64_REX_GOTPCRELX:
+  case R_X86_64_REX2_GOTPCRELX:
   case R_X86_64_GOTTPOFF:
     return R_GOT_PC;
   case R_X86_64_GOTOFF64:
@@ -725,6 +726,7 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, 
RelType type) const {
   case R_X86_64_GOTPCREL:
   case R_X86_64_GOTPCRELX:
   case R_X86_64_REX_GOTPCRELX:
+  case R_X86_64_REX2_GOTPCRELX:
   case R_X86_64_PC32:
   case R_X86_64_GOTTPOFF:
   case R_X86_64_PLT32:
@@ -808,6 +810,7 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, 
uint64_t val) const {
     break;
   case R_X86_64_GOTPCRELX:
   case R_X86_64_REX_GOTPCRELX:
+  case R_X86_64_REX2_GOTPCRELX:
     if (rel.expr != R_GOT_PC) {
       relaxGot(loc, rel, val);
     } else {
diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s 
b/lld/test/ELF/x86-64-gotpc-no-relax-err.s
index 618dca47755f41..4280c8fd1dc97e 100644
--- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s
+++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s
@@ -7,15 +7,19 @@
 ## `>>> defined in` for linker synthesized __stop_* symbols (there is no
 ## associated file or linker script line number).
 
-# CHECK:      error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of 
range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data'
+# CHECK:      error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of 
range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data'
 # CHECK-NEXT: >>> defined in <internal>
 # CHECK-EMPTY:
-# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out 
of range: 2147483651 is not in [-2147483648, 2147483647]; references 
'__stop_data'
+# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out 
of range: 2147483659 is not in [-2147483648, 2147483647]; references 
'__stop_data'
+# CHECK-NEXT: >>> defined in <internal>
+# CHECK-EMPTY:
+# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX 
out of range: 2147483651 is not in [-2147483648, 2147483647]; references 
'__stop_data'
 # CHECK-NEXT: >>> defined in <internal>
 
 #--- a.s
   movl __stop_data@GOTPCREL(%rip), %eax  # out of range
   movq __stop_data@GOTPCREL(%rip), %rax  # out of range
+  movq __stop_data@GOTPCREL(%rip), %r16  # out of range
   movq __stop_data@GOTPCREL(%rip), %rax  # in range
 
 .section data,"aw",@progbits
@@ -23,5 +27,5 @@
 #--- lds
 SECTIONS {
   .text 0x200000 : { *(.text) }
-  .got 0x80200010 : { *(.got) }
+  .got 0x80200016 : { *(.got) }
 }
diff --git a/lld/test/ELF/x86-64-gotpc-relax.s 
b/lld/test/ELF/x86-64-gotpc-relax.s
index 5945bfc04a0225..1fb3a3c76852ab 100644
--- a/lld/test/ELF/x86-64-gotpc-relax.s
+++ b/lld/test/ELF/x86-64-gotpc-relax.s
@@ -1,5 +1,5 @@
 # REQUIRES: x86
-## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX GOT optimization.
+## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX/R_X86_64_REX2_GOTPCRELX 
GOT optimization.
 
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: ld.lld %t.o -o %t1 --no-apply-dynamic-relocs
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def 
b/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
index 18fdcf9472dc48..161b1969abfeb4 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/x86_64.def
@@ -43,3 +43,4 @@ ELF_RELOC(R_X86_64_TLSDESC,     36)
 ELF_RELOC(R_X86_64_IRELATIVE,   37)
 ELF_RELOC(R_X86_64_GOTPCRELX,   41)
 ELF_RELOC(R_X86_64_REX_GOTPCRELX,    42)
+ELF_RELOC(R_X86_64_REX2_GOTPCRELX,    43)
diff --git a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp 
b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
index 1a4f7e93eeb74a..92618bdabbe519 100644
--- a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
+++ b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
@@ -145,8 +145,8 @@ 
llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() {
 
   static cl::opt<bool> X86RelaxRelocations(
       "x86-relax-relocations",
-      cl::desc(
-          "Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
+      cl::desc("Emit GOTPCRELX/REX_GOTPCRELX/REX2_GOTPCRELX instead of "
+               "GOTPCREL on x86-64 ELF"),
       cl::init(true));
   MCBINDOPT(X86RelaxRelocations);
 
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp 
b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 1d08853faf582e..d1fd274433804b 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -631,8 +631,10 @@ const MCFixupKindInfo 
&X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
   const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = {
       {"reloc_riprel_4byte", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
       {"reloc_riprel_4byte_movq_load", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
+      {"reloc_riprel_4byte_movq_load_rex2", 0, 32, 
MCFixupKindInfo::FKF_IsPCRel},
       {"reloc_riprel_4byte_relax", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
       {"reloc_riprel_4byte_relax_rex", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
+      {"reloc_riprel_4byte_relax_rex2", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
       {"reloc_signed_4byte", 0, 32, 0},
       {"reloc_signed_4byte_relax", 0, 32, 0},
       {"reloc_global_offset_table", 0, 32, 0},
@@ -678,7 +680,9 @@ static unsigned getFixupKindSize(unsigned Kind) {
   case X86::reloc_riprel_4byte:
   case X86::reloc_riprel_4byte_relax:
   case X86::reloc_riprel_4byte_relax_rex:
+  case X86::reloc_riprel_4byte_relax_rex2:
   case X86::reloc_riprel_4byte_movq_load:
+  case X86::reloc_riprel_4byte_movq_load_rex2:
   case X86::reloc_signed_4byte:
   case X86::reloc_signed_4byte_relax:
   case X86::reloc_global_offset_table:
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp 
b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
index 0b2efdfc16cc5d..9fdc62b8c8516f 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
@@ -74,7 +74,9 @@ static X86_64RelType getType64(MCFixupKind Kind,
   case X86::reloc_riprel_4byte:
   case X86::reloc_riprel_4byte_relax:
   case X86::reloc_riprel_4byte_relax_rex:
+  case X86::reloc_riprel_4byte_relax_rex2:
   case X86::reloc_riprel_4byte_movq_load:
+  case X86::reloc_riprel_4byte_movq_load_rex2:
     return RT64_32;
   case X86::reloc_branch_4byte_pcrel:
     Modifier = MCSymbolRefExpr::VK_PLT;
@@ -205,7 +207,7 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
   case MCSymbolRefExpr::VK_GOTPCREL:
     checkIs32(Ctx, Loc, Type);
     // Older versions of ld.bfd/ld.gold/lld
-    // do not support GOTPCRELX/REX_GOTPCRELX,
+    // do not support GOTPCRELX/REX_GOTPCRELX/REX2_GOTPCRELX,
     // and we want to keep back-compatibility.
     if (!Ctx.getTargetOptions()->X86RelaxRelocations)
       return ELF::R_X86_64_GOTPCREL;
@@ -217,6 +219,9 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
     case X86::reloc_riprel_4byte_relax_rex:
     case X86::reloc_riprel_4byte_movq_load:
       return ELF::R_X86_64_REX_GOTPCRELX;
+    case X86::reloc_riprel_4byte_relax_rex2:
+    case X86::reloc_riprel_4byte_movq_load_rex2:
+     return ELF::R_X86_64_REX2_GOTPCRELX;
     }
     llvm_unreachable("unexpected relocation type!");
   case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h 
b/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
index 2d5217115d07cb..29bb7eebae3f22 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86FixupKinds.h
@@ -16,10 +16,14 @@ namespace X86 {
 enum Fixups {
   reloc_riprel_4byte = FirstTargetFixupKind, // 32-bit rip-relative
   reloc_riprel_4byte_movq_load,              // 32-bit rip-relative in movq
+  reloc_riprel_4byte_movq_load_rex2,         // 32-bit rip-relative in movq
+                                             // with rex2 prefix
   reloc_riprel_4byte_relax,                  // 32-bit rip-relative in 
relaxable
                                              // instruction
   reloc_riprel_4byte_relax_rex,              // 32-bit rip-relative in 
relaxable
                                              // instruction with rex prefix
+  reloc_riprel_4byte_relax_rex2,             // 32-bit rip-relative in 
relaxable
+                                             // instruction with rex2 prefix
   reloc_signed_4byte,                        // 32-bit signed. Unlike FK_Data_4
                                              // this will be sign extended at
                                              // runtime.
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp 
b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 71d42863fd5857..206436191c2584 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -568,8 +568,10 @@ void X86MCCodeEmitter::emitImmediate(const MCOperand 
&DispOp, SMLoc Loc,
   if (FixupKind == FK_PCRel_4 ||
       FixupKind == MCFixupKind(X86::reloc_riprel_4byte) ||
       FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) ||
+      FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load_rex2) ||
       FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) ||
       FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex) ||
+      FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex2) ||
       FixupKind == MCFixupKind(X86::reloc_branch_4byte_pcrel)) {
     ImmOffset -= 4;
     // If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
@@ -637,12 +639,11 @@ void X86MCCodeEmitter::emitMemModRMByte(
       default:
         return X86::reloc_riprel_4byte;
       case X86::MOV64rm:
-        // movq loads is a subset of reloc_riprel_4byte_relax_rex. It is a
+        // movq loads is a subset of reloc_riprel_4byte_relax_rex/rex2. It is a
         // special case because COFF and Mach-O don't support ELF's more
-        // flexible R_X86_64_REX_GOTPCRELX relaxation.
-        // TODO: Support new relocation for REX2.
-        assert(Kind == REX || Kind == REX2);
-        return X86::reloc_riprel_4byte_movq_load;
+        // flexible R_X86_64_REX_GOTPCRELX/R_X86_64_REX2_GOTPCRELX relaxation.
+        return Kind == REX2 ? X86::reloc_riprel_4byte_movq_load_rex2
+                            : X86::reloc_riprel_4byte_movq_load;
       case X86::ADC32rm:
       case X86::ADD32rm:
       case X86::AND32rm:
@@ -665,11 +666,9 @@ void X86MCCodeEmitter::emitMemModRMByte(
       case X86::SBB64rm:
       case X86::SUB64rm:
       case X86::XOR64rm:
-        // We haven't support relocation for REX2 prefix, so temporarily use 
REX
-        // relocation.
-        // TODO: Support new relocation for REX2.
-        return (Kind == REX || Kind == REX2) ? 
X86::reloc_riprel_4byte_relax_rex
-                                             : X86::reloc_riprel_4byte_relax;
+        return Kind == REX2  ? X86::reloc_riprel_4byte_relax_rex2
+               : Kind == REX ? X86::reloc_riprel_4byte_relax_rex
+                             : X86::reloc_riprel_4byte_relax;
       }
     }();
 
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp 
b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
index ec95b1ffec387d..41ce5c9fcb82ad 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp
@@ -66,8 +66,10 @@ class X86MachObjectWriter : public MCMachObjectTargetWriter {
 static bool isFixupKindRIPRel(unsigned Kind) {
   return Kind == X86::reloc_riprel_4byte ||
          Kind == X86::reloc_riprel_4byte_movq_load ||
+         Kind == X86::reloc_riprel_4byte_movq_load_rex2 ||
          Kind == X86::reloc_riprel_4byte_relax ||
-         Kind == X86::reloc_riprel_4byte_relax_rex;
+         Kind == X86::reloc_riprel_4byte_relax_rex ||
+         Kind == X86::reloc_riprel_4byte_relax_rex2;
 }
 
 static unsigned getFixupKindLog2Size(unsigned Kind) {
@@ -83,7 +85,9 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {
   case X86::reloc_riprel_4byte:
   case X86::reloc_riprel_4byte_relax:
   case X86::reloc_riprel_4byte_relax_rex:
+  case X86::reloc_riprel_4byte_relax_rex2:
   case X86::reloc_riprel_4byte_movq_load:
+  case X86::reloc_riprel_4byte_movq_load_rex2:
   case X86::reloc_signed_4byte:
   case X86::reloc_signed_4byte_relax:
   case X86::reloc_branch_4byte_pcrel:
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp 
b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
index 10fc176b59d8ab..7740500fb41830 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp
@@ -66,8 +66,10 @@ unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx,
     case FK_PCRel_4:
     case X86::reloc_riprel_4byte:
     case X86::reloc_riprel_4byte_movq_load:
+    case X86::reloc_riprel_4byte_movq_load_rex2:
     case X86::reloc_riprel_4byte_relax:
     case X86::reloc_riprel_4byte_relax_rex:
+    case X86::reloc_riprel_4byte_relax_rex2:
     case X86::reloc_branch_4byte_pcrel:
       return COFF::IMAGE_REL_AMD64_REL32;
     case FK_Data_4:
diff --git a/llvm/test/MC/ELF/relocation-alias.s 
b/llvm/test/MC/ELF/relocation-alias.s
index 51fb0c37052fe7..66bf2ceea508ba 100644
--- a/llvm/test/MC/ELF/relocation-alias.s
+++ b/llvm/test/MC/ELF/relocation-alias.s
@@ -16,7 +16,10 @@ movabsq $memcpy+2, %rax
 
 # CHECK:      movq (%rip), %rax
 # CHECK-NEXT:   R_X86_64_REX_GOTPCRELX  abs-0x4
+# CHECK:      movq (%rip), %r16
+# CHECK-NEXT:   R_X86_64_REX2_GOTPCRELX abs-0x4
 movq abs@GOTPCREL(%rip), %rax
+movq abs@GOTPCREL(%rip), %r16
 abs = 42
 
 # CHECK:      movabsq $0, %rbx
diff --git a/llvm/test/MC/X86/gotpcrelx.s b/llvm/test/MC/X86/gotpcrelx.s
index e63e3e9a946fd1..5a8ba454bc904c 100644
--- a/llvm/test/MC/X86/gotpcrelx.s
+++ b/llvm/test/MC/X86/gotpcrelx.s
@@ -37,6 +37,16 @@
 # CHECK-NEXT:     R_X86_64_REX_GOTPCRELX sbb
 # CHECK-NEXT:     R_X86_64_REX_GOTPCRELX sub
 # CHECK-NEXT:     R_X86_64_REX_GOTPCRELX xor
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX mov
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX test
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX adc
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX add
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX and
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX cmp
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX or
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX sbb
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX sub
+# CHECK-NEXT:     R_X86_64_REX2_GOTPCRELX xor
 # CHECK-NEXT:   }
 
 # NORELAX-NEXT:     R_X86_64_GOTPCREL mov
@@ -71,6 +81,16 @@
 # NORELAX-NEXT:     R_X86_64_GOTPCREL sbb
 # NORELAX-NEXT:     R_X86_64_GOTPCREL sub
 # NORELAX-NEXT:     R_X86_64_GOTPCREL xor
+# NORELAX-NEXT:     R_X86_64_GOTPCREL mov
+# NORELAX-NEXT:     R_X86_64_GOTPCREL test
+# NORELAX-NEXT:     R_X86_64_GOTPCREL adc
+# NORELAX-NEXT:     R_X86_64_GOTPCREL add
+# NORELAX-NEXT:     R_X86_64_GOTPCREL and
+# NORELAX-NEXT:     R_X86_64_GOTPCREL cmp
+# NORELAX-NEXT:     R_X86_64_GOTPCREL or
+# NORELAX-NEXT:     R_X86_64_GOTPCREL sbb
+# NORELAX-NEXT:     R_X86_64_GOTPCREL sub
+# NORELAX-NEXT:     R_X86_64_GOTPCREL xor
 # NORELAX-NEXT:   }
 
 movl mov@GOTPCREL(%rip), %eax
@@ -108,10 +128,22 @@ sbb sbb@GOTPCREL(%rip), %rax
 sub sub@GOTPCREL(%rip), %rax
 xor xor@GOTPCREL(%rip), %rax
 
+movq mov@GOTPCREL(%rip), %r16
+test %r16, test@GOTPCREL(%rip)
+adc adc@GOTPCREL(%rip), %r16
+add add@GOTPCREL(%rip), %r16
+and and@GOTPCREL(%rip), %r16
+cmp cmp@GOTPCREL(%rip), %r16
+or  or@GOTPCREL(%rip), %r16
+sbb sbb@GOTPCREL(%rip), %r16
+sub sub@GOTPCREL(%rip), %r16
+xor xor@GOTPCREL(%rip), %r16
+
 # COMMON-NEXT:   Section ({{.*}}) .rela.norelax {
 # COMMON-NEXT:     R_X86_64_GOTPCREL mov 0x0
 # COMMON-NEXT:     R_X86_64_GOTPCREL mov 0xFFFFFFFFFFFFFFFD
 # COMMON-NEXT:     R_X86_64_GOTPCREL mov 0xFFFFFFFFFFFFFFFC
+# COMMON-NEXT:     R_X86_64_GOTPCREL mov 0xFFFFFFFFFFFFFFFD
 # COMMON-NEXT:   }
 # COMMON-NEXT: ]
 
@@ -123,3 +155,5 @@ movl mov@GOTPCREL+4(%rip), %eax
 movq mov@GOTPCREL+1(%rip), %rax
 ## We could emit R_X86_64_GOTPCRELX, but it is probably unnecessary.
 movl mov@GOTPCREL+0(%rip), %eax
+## Don't emit R_X86_64_GOTPCRELX.
+movq mov@GOTPCREL+1(%rip), %r16

>From 732918170c2396a44bd0b333ebae568791dc30d7 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen....@intel.com>
Date: Fri, 30 Aug 2024 16:20:27 +0800
Subject: [PATCH 2/8] add more test

---
 llvm/test/MC/X86/reloc-directive-elf-64.s | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/llvm/test/MC/X86/reloc-directive-elf-64.s 
b/llvm/test/MC/X86/reloc-directive-elf-64.s
index 8f5d8c895e7d76..323603efc70618 100644
--- a/llvm/test/MC/X86/reloc-directive-elf-64.s
+++ b/llvm/test/MC/X86/reloc-directive-elf-64.s
@@ -9,6 +9,7 @@
 # PRINT-NEXT: .reloc 0, R_X86_64_64, .data+2
 # PRINT-NEXT: .reloc 0, R_X86_64_GOTPCRELX, foo+3
 # PRINT-NEXT: .reloc 0, R_X86_64_REX_GOTPCRELX, 5
+# PRINT-NEXT: .reloc 0, R_X86_64_REX2_GOTPCRELX, 7
 # PRINT:      .reloc 0, BFD_RELOC_NONE, 9
 # PRINT-NEXT: .reloc 0, BFD_RELOC_8, 9
 # PRINT-NEXT: .reloc 0, BFD_RELOC_16, 9
@@ -21,6 +22,7 @@
 # CHECK-NEXT: 0x0 R_X86_64_64 .data 0x2
 # CHECK-NEXT: 0x0 R_X86_64_GOTPCRELX foo 0x3
 # CHECK-NEXT: 0x0 R_X86_64_REX_GOTPCRELX - 0x5
+# CHECK-NEXT: 0x0 R_X86_64_REX2_GOTPCRELX - 0x7
 # CHECK-NEXT: 0x0 R_X86_64_NONE - 0x9
 # CHECK-NEXT: 0x0 R_X86_64_8 - 0x9
 # CHECK-NEXT: 0x0 R_X86_64_16 - 0x9
@@ -37,6 +39,7 @@
   .reloc 0, R_X86_64_64, .data+2
   .reloc 0, R_X86_64_GOTPCRELX, foo+3
   .reloc 0, R_X86_64_REX_GOTPCRELX, 5
+  .reloc 0, R_X86_64_REX2_GOTPCRELX, 7
 
   .reloc 0, BFD_RELOC_NONE, 9
   .reloc 0, BFD_RELOC_8, 9

>From 44b828a13031a48810372c43d26b8c4084677aa8 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen....@intel.com>
Date: Fri, 30 Aug 2024 16:30:18 +0800
Subject: [PATCH 3/8] clang-format

---
 llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp 
b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
index 9fdc62b8c8516f..90222278d1ad6f 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
@@ -221,7 +221,7 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc,
       return ELF::R_X86_64_REX_GOTPCRELX;
     case X86::reloc_riprel_4byte_relax_rex2:
     case X86::reloc_riprel_4byte_movq_load_rex2:
-     return ELF::R_X86_64_REX2_GOTPCRELX;
+      return ELF::R_X86_64_REX2_GOTPCRELX;
     }
     llvm_unreachable("unexpected relocation type!");
   case MCSymbolRefExpr::VK_GOTPCREL_NORELAX:

>From 6e981a096bb9f0edacfe5d655b8b295f945c23d1 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen....@intel.com>
Date: Fri, 30 Aug 2024 17:06:47 +0800
Subject: [PATCH 4/8] add more test

---
 lld/test/ELF/x86-64-gotpc-relax-nopic.s | 109 +++++++++++++++---------
 lld/test/ELF/x86-64-gotpc-relax.s       |  13 +++
 2 files changed, 82 insertions(+), 40 deletions(-)

diff --git a/lld/test/ELF/x86-64-gotpc-relax-nopic.s 
b/lld/test/ELF/x86-64-gotpc-relax-nopic.s
index 7481904d16f1b4..e3cd93d1d57962 100644
--- a/lld/test/ELF/x86-64-gotpc-relax-nopic.s
+++ b/lld/test/ELF/x86-64-gotpc-relax-nopic.s
@@ -10,30 +10,39 @@
 # SYMRELOC:      Symbols [
 # SYMRELOC:       Symbol {
 # SYMRELOC:        Name: bar
-# SYMRELOC-NEXT:   Value: 0x203248
+# SYMRELOC-NEXT:   Value: 0x203290
 
 ## 2105751 = 0x202197 (bar)
 # DISASM:      Disassembly of section .text:
 # DISASM-EMPTY:
 # DISASM-NEXT: <_start>:
-# DISASM-NEXT:   2011c8:       adcl  {{.*}}(%rip), %eax  # 0x202240
-# DISASM-NEXT:                 addl  {{.*}}(%rip), %ebx  # 0x202240
-# DISASM-NEXT:                 andl  {{.*}}(%rip), %ecx  # 0x202240
-# DISASM-NEXT:                 cmpl  {{.*}}(%rip), %edx  # 0x202240
-# DISASM-NEXT:                 orl   {{.*}}(%rip), %edi  # 0x202240
-# DISASM-NEXT:                 sbbl  {{.*}}(%rip), %esi  # 0x202240
-# DISASM-NEXT:                 subl  {{.*}}(%rip), %ebp  # 0x202240
-# DISASM-NEXT:                 xorl  $0x203248, %r8d
-# DISASM-NEXT:                 testl $0x203248, %r15d
-# DISASM-NEXT:   201200:       adcq  $0x203248, %rax
-# DISASM-NEXT:                 addq  $0x203248, %rbx
-# DISASM-NEXT:                 andq  $0x203248, %rcx
-# DISASM-NEXT:                 cmpq  $0x203248, %rdx
-# DISASM-NEXT:                 orq   $0x203248, %rdi
-# DISASM-NEXT:                 sbbq  $0x203248, %rsi
-# DISASM-NEXT:                 subq  $0x203248, %rbp
-# DISASM-NEXT:                 xorq  $0x203248, %r8
-# DISASM-NEXT:                 testq $0x203248, %r15
+# DISASM-NEXT:   2011c8:       adcl  {{.*}}(%rip), %eax  # 0x202288
+# DISASM-NEXT:                 addl  {{.*}}(%rip), %ebx  # 0x202288
+# DISASM-NEXT:                 andl  {{.*}}(%rip), %ecx  # 0x202288
+# DISASM-NEXT:                 cmpl  {{.*}}(%rip), %edx  # 0x202288
+# DISASM-NEXT:                 orl   {{.*}}(%rip), %edi  # 0x202288
+# DISASM-NEXT:                 sbbl  {{.*}}(%rip), %esi  # 0x202288
+# DISASM-NEXT:                 subl  {{.*}}(%rip), %ebp  # 0x202288
+# DISASM-NEXT:                 xorl  $0x203290, %r8d
+# DISASM-NEXT:                 testl $0x203290, %r15d
+# DISASM-NEXT:   201200:       adcq  $0x203290, %rax
+# DISASM-NEXT:                 addq  $0x203290, %rbx
+# DISASM-NEXT:                 andq  $0x203290, %rcx
+# DISASM-NEXT:                 cmpq  $0x203290, %rdx
+# DISASM-NEXT:                 orq   $0x203290, %rdi
+# DISASM-NEXT:                 sbbq  $0x203290, %rsi
+# DISASM-NEXT:                 subq  $0x203290, %rbp
+# DISASM-NEXT:                 xorq  $0x203290, %r8
+# DISASM-NEXT:                 testq $0x203290, %r15
+# DISASM-NEXT:   20123f:       adcq  $0x203290, %r16
+# DISASM-NEXT:                 addq  $0x203290, %r17
+# DISASM-NEXT:                 andq  $0x203290, %r18
+# DISASM-NEXT:                 cmpq  $0x203290, %r19
+# DISASM-NEXT:                 orq   $0x203290, %r20
+# DISASM-NEXT:                 sbbq  $0x203290, %r21
+# DISASM-NEXT:                 subq  $0x203290, %r22
+# DISASM-NEXT:                 xorq  $0x203290, %r23
+# DISASM-NEXT:                 testq $0x203290, %r24
 
 # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2
 # RUN: llvm-readobj -S -r -d %t2 | FileCheck --check-prefix=SEC-PIC    %s
@@ -46,8 +55,8 @@
 # SEC-PIC-NEXT:     SHF_ALLOC
 # SEC-PIC-NEXT:     SHF_WRITE
 # SEC-PIC-NEXT:   ]
-# SEC-PIC-NEXT:   Address: 0x2380
-# SEC-PIC-NEXT:   Offset: 0x380
+# SEC-PIC-NEXT:   Address: 0x23C8
+# SEC-PIC-NEXT:   Offset: 0x3C8
 # SEC-PIC-NEXT:   Size: 8
 # SEC-PIC-NEXT:   Link:
 # SEC-PIC-NEXT:   Info:
@@ -57,7 +66,7 @@
 # SEC-PIC:      0x000000006FFFFFF9 RELACOUNT            1
 # SEC-PIC:      Relocations [
 # SEC-PIC-NEXT:   Section ({{.*}}) .rela.dyn {
-# SEC-PIC-NEXT:     0x2380 R_X86_64_RELATIVE - 0x3388
+# SEC-PIC-NEXT:     0x23C8 R_X86_64_RELATIVE - 0x33D0
 # SEC-PIC-NEXT:   }
 # SEC-PIC-NEXT: ]
 
@@ -65,24 +74,33 @@
 # DISASM-PIC:      Disassembly of section .text:
 # DISASM-PIC-EMPTY:
 # DISASM-PIC-NEXT: <_start>:
-# DISASM-PIC-NEXT: 1268:       adcl  {{.*}}(%rip), %eax  # 0x2380
-# DISASM-PIC-NEXT:             addl  {{.*}}(%rip), %ebx  # 0x2380
-# DISASM-PIC-NEXT:             andl  {{.*}}(%rip), %ecx  # 0x2380
-# DISASM-PIC-NEXT:             cmpl  {{.*}}(%rip), %edx  # 0x2380
-# DISASM-PIC-NEXT:             orl   {{.*}}(%rip), %edi  # 0x2380
-# DISASM-PIC-NEXT:             sbbl  {{.*}}(%rip), %esi  # 0x2380
-# DISASM-PIC-NEXT:             subl  {{.*}}(%rip), %ebp  # 0x2380
-# DISASM-PIC-NEXT:             xorl  {{.*}}(%rip), %r8d  # 0x2380
-# DISASM-PIC-NEXT:             testl %r15d, {{.*}}(%rip) # 0x2380
-# DISASM-PIC-NEXT: 12a0:       adcq  {{.*}}(%rip), %rax  # 0x2380
-# DISASM-PIC-NEXT:             addq  {{.*}}(%rip), %rbx  # 0x2380
-# DISASM-PIC-NEXT:             andq  {{.*}}(%rip), %rcx  # 0x2380
-# DISASM-PIC-NEXT:             cmpq  {{.*}}(%rip), %rdx  # 0x2380
-# DISASM-PIC-NEXT:             orq   {{.*}}(%rip), %rdi  # 0x2380
-# DISASM-PIC-NEXT:             sbbq  {{.*}}(%rip), %rsi  # 0x2380
-# DISASM-PIC-NEXT:             subq  {{.*}}(%rip), %rbp  # 0x2380
-# DISASM-PIC-NEXT:             xorq  {{.*}}(%rip), %r8   # 0x2380
-# DISASM-PIC-NEXT:             testq %r15, {{.*}}(%rip)  # 0x2380
+# DISASM-PIC-NEXT: 1268:       adcl  {{.*}}(%rip), %eax  # 0x23c8
+# DISASM-PIC-NEXT:             addl  {{.*}}(%rip), %ebx  # 0x23c8
+# DISASM-PIC-NEXT:             andl  {{.*}}(%rip), %ecx  # 0x23c8
+# DISASM-PIC-NEXT:             cmpl  {{.*}}(%rip), %edx  # 0x23c8
+# DISASM-PIC-NEXT:             orl   {{.*}}(%rip), %edi  # 0x23c8
+# DISASM-PIC-NEXT:             sbbl  {{.*}}(%rip), %esi  # 0x23c8
+# DISASM-PIC-NEXT:             subl  {{.*}}(%rip), %ebp  # 0x23c8
+# DISASM-PIC-NEXT:             xorl  {{.*}}(%rip), %r8d  # 0x23c8
+# DISASM-PIC-NEXT:             testl %r15d, {{.*}}(%rip) # 0x23c8
+# DISASM-PIC-NEXT: 12a0:       adcq  {{.*}}(%rip), %rax  # 0x23c8
+# DISASM-PIC-NEXT:             addq  {{.*}}(%rip), %rbx  # 0x23c8
+# DISASM-PIC-NEXT:             andq  {{.*}}(%rip), %rcx  # 0x23c8
+# DISASM-PIC-NEXT:             cmpq  {{.*}}(%rip), %rdx  # 0x23c8
+# DISASM-PIC-NEXT:             orq   {{.*}}(%rip), %rdi  # 0x23c8
+# DISASM-PIC-NEXT:             sbbq  {{.*}}(%rip), %rsi  # 0x23c8
+# DISASM-PIC-NEXT:             subq  {{.*}}(%rip), %rbp  # 0x23c8
+# DISASM-PIC-NEXT:             xorq  {{.*}}(%rip), %r8   # 0x23c8
+# DISASM-PIC-NEXT:             testq %r15, {{.*}}(%rip)  # 0x23c8
+# DISASM-PIC-NEXT: 12df:       adcq  {{.*}}(%rip), %r16  # 0x23c8
+# DISASM-PIC-NEXT:             addq  {{.*}}(%rip), %r17  # 0x23c8
+# DISASM-PIC-NEXT:             andq  {{.*}}(%rip), %r18  # 0x23c8
+# DISASM-PIC-NEXT:             cmpq  {{.*}}(%rip), %r19  # 0x23c8
+# DISASM-PIC-NEXT:             orq   {{.*}}(%rip), %r20  # 0x23c8
+# DISASM-PIC-NEXT:             sbbq  {{.*}}(%rip), %r21  # 0x23c8
+# DISASM-PIC-NEXT:             subq  {{.*}}(%rip), %r22  # 0x23c8
+# DISASM-PIC-NEXT:             xorq  {{.*}}(%rip), %r23   # 0x23c8
+# DISASM-PIC-NEXT:             testq %r24, {{.*}}(%rip)  # 0x23c8
 
 .data
 .type   bar, @object
@@ -115,3 +133,14 @@ _start:
   subq    bar@GOTPCREL(%rip), %rbp
   xorq    bar@GOTPCREL(%rip), %r8
   testq   %r15, bar@GOTPCREL(%rip)
+
+## R_X86_64_REX2_GOTPCRELX
+  adcq    bar@GOTPCREL(%rip), %r16
+  addq    bar@GOTPCREL(%rip), %r17
+  andq    bar@GOTPCREL(%rip), %r18
+  cmpq    bar@GOTPCREL(%rip), %r19
+  orq     bar@GOTPCREL(%rip), %r20
+  sbbq    bar@GOTPCREL(%rip), %r21
+  subq    bar@GOTPCREL(%rip), %r22
+  xorq    bar@GOTPCREL(%rip), %r23
+  testq   %r24, bar@GOTPCREL(%rip)
diff --git a/lld/test/ELF/x86-64-gotpc-relax.s 
b/lld/test/ELF/x86-64-gotpc-relax.s
index 1fb3a3c76852ab..ee15738268d5a8 100644
--- a/lld/test/ELF/x86-64-gotpc-relax.s
+++ b/lld/test/ELF/x86-64-gotpc-relax.s
@@ -120,3 +120,16 @@ _start:
  jmp *hid@GOTPCREL(%rip)
  jmp *ifunc@GOTPCREL(%rip)
  jmp *ifunc@GOTPCREL(%rip)
+
+ movq foo@GOTPCREL(%rip), %r16
+ movq foo@GOTPCREL(%rip), %r16
+ movq hid@GOTPCREL(%rip), %r16
+ movq hid@GOTPCREL(%rip), %r16
+ movq ifunc@GOTPCREL(%rip), %r16
+ movq ifunc@GOTPCREL(%rip), %r16
+ movq foo@GOTPCREL(%rip), %r16
+ movq foo@GOTPCREL(%rip), %r16
+ movq hid@GOTPCREL(%rip), %r16
+ movq hid@GOTPCREL(%rip), %r16
+ movq ifunc@GOTPCREL(%rip), %r16
+ movq ifunc@GOTPCREL(%rip), %r16

>From 338a5650bec6d6f15cdbc9bf38a50f48400568b5 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen....@intel.com>
Date: Fri, 30 Aug 2024 17:56:53 +0800
Subject: [PATCH 5/8] disable clang-format

---
 llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp 
b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index d1fd274433804b..2f6b55b0d6023e 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -629,6 +629,7 @@ std::optional<MCFixupKind> 
X86AsmBackend::getFixupKind(StringRef Name) const {
 
 const MCFixupKindInfo &X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const 
{
   const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = {
+      // clang-format off
       {"reloc_riprel_4byte", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
       {"reloc_riprel_4byte_movq_load", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
       {"reloc_riprel_4byte_movq_load_rex2", 0, 32, 
MCFixupKindInfo::FKF_IsPCRel},
@@ -640,6 +641,7 @@ const MCFixupKindInfo 
&X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
       {"reloc_global_offset_table", 0, 32, 0},
       {"reloc_global_offset_table8", 0, 64, 0},
       {"reloc_branch_4byte_pcrel", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
+      // clang-format on
   };
 
   // Fixup kinds from .reloc directive are like R_386_NONE/R_X86_64_NONE. They

>From 4bf2ab00947052a4e24ad4826dcdf9c576a45fce Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen....@intel.com>
Date: Sun, 1 Sep 2024 13:55:38 +0800
Subject: [PATCH 6/8] Make test x86-64-gotpc-relax.s pass

---
 lld/ELF/Arch/X86_64.cpp           | 13 ++++++-----
 lld/test/ELF/x86-64-gotpc-relax.s | 39 ++++++++++++++++++++-----------
 2 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 1371cee410dc82..a02ba2f34ccf8f 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -862,12 +862,13 @@ void X86_64::relocate(uint8_t *loc, const Relocation 
&rel, uint64_t val) const {
 
 RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend,
                                 const uint8_t *loc) const {
-  // Only R_X86_64_[REX_]GOTPCRELX can be relaxed. GNU as may emit GOTPCRELX
-  // with addend != -4. Such an instruction does not load the full GOT entry, 
so
-  // we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip), %rax
-  // (addend=0) loads the high 32 bits of the GOT entry.
+  // Only R_X86_64_[REX_]|[REX2_]GOTPCRELX can be relaxed. GNU as may emit
+  // GOTPCRELX with addend != -4. Such an instruction does not load the full 
GOT
+  // entry, so we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip),
+  // %rax (addend=0) loads the high 32 bits of the GOT entry.
   if (!ctx.arg.relax || addend != -4 ||
-      (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX))
+      (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX &&
+       type != R_X86_64_REX2_GOTPCRELX))
     return R_GOT_PC;
   const uint8_t op = loc[-2];
   const uint8_t modRm = loc[-1];
@@ -883,7 +884,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t 
addend,
   if (op == 0xff && (modRm == 0x15 || modRm == 0x25))
     return R_RELAX_GOT_PC;
 
-  // We don't support test/binop instructions without a REX prefix.
+  // We don't support test/binop instructions without a REX/REX2 prefix.
   if (type == R_X86_64_GOTPCRELX)
     return R_GOT_PC;
 
diff --git a/lld/test/ELF/x86-64-gotpc-relax.s 
b/lld/test/ELF/x86-64-gotpc-relax.s
index ee15738268d5a8..b1ff995b3fc211 100644
--- a/lld/test/ELF/x86-64-gotpc-relax.s
+++ b/lld/test/ELF/x86-64-gotpc-relax.s
@@ -15,16 +15,16 @@
 
 ## In our implementation, .got is retained even if all GOT-generating 
relocations are optimized.
 # CHECK:      Name              Type            Address          Off    Size   
ES Flg Lk Inf Al
-# CHECK:      .iplt             PROGBITS        0000000000201280 000280 000010 
00  AX  0   0 16
-# CHECK-NEXT: .got              PROGBITS        0000000000202290 000290 000000 
00  WA  0   0  8
+# CHECK:      .iplt             PROGBITS        00000000002012e0 0002e0 000010 
00  AX  0   0 16
+# CHECK-NEXT: .got              PROGBITS        00000000002022f0 0002f0 000000 
00  WA  0   0  8
 
 ## There is one R_X86_64_IRELATIVE relocations.
 # RELOC-LABEL: Relocation section '.rela.dyn' at offset {{.*}} contains 1 
entry:
 # CHECK:           Offset             Info             Type               
Symbol's Value  Symbol's Name + Addend
-# CHECK:       0000000000203290  0000000000000025 R_X86_64_IRELATIVE           
             2011e2
+# CHECK:       00000000002032f0  0000000000000025 R_X86_64_IRELATIVE           
             2011e2
 # CHECK-LABEL: Hex dump of section '.got.plt':
-# NOAPPLY-NEXT:  0x00203290 00000000 00000000
-# APPLY-NEXT:    0x00203290 e2112000 00000000
+# NOAPPLY-NEXT:  0x002032f0 00000000 00000000
+# APPLY-NEXT:    0x002032f0 e2112000 00000000
 
 # 0x201173 + 7 - 10 = 0x201170
 # 0x20117a + 7 - 17 = 0x201170
@@ -43,20 +43,20 @@
 # DISASM-NEXT: leaq -17(%rip), %rax
 # DISASM-NEXT: leaq -23(%rip), %rax
 # DISASM-NEXT: leaq -30(%rip), %rax
-# DISASM-NEXT: movq 8330(%rip), %rax
-# DISASM-NEXT: movq 8323(%rip), %rax
+# DISASM-NEXT: movq 8426(%rip), %rax
+# DISASM-NEXT: movq 8419(%rip), %rax
 # DISASM-NEXT: leaq -52(%rip), %rax
 # DISASM-NEXT: leaq -59(%rip), %rax
 # DISASM-NEXT: leaq -65(%rip), %rax
 # DISASM-NEXT: leaq -72(%rip), %rax
-# DISASM-NEXT: movq 8288(%rip), %rax
-# DISASM-NEXT: movq 8281(%rip), %rax
+# DISASM-NEXT: movq 8384(%rip), %rax
+# DISASM-NEXT: movq 8377(%rip), %rax
 # DISASM-NEXT: callq 0x2011e0 <foo>
 # DISASM-NEXT: callq 0x2011e0 <foo>
 # DISASM-NEXT: callq 0x2011e1 <hid>
 # DISASM-NEXT: callq 0x2011e1 <hid>
-# DISASM-NEXT: callq *8251(%rip)
-# DISASM-NEXT: callq *8245(%rip)
+# DISASM-NEXT: callq *8347(%rip)
+# DISASM-NEXT: callq *8341(%rip)
 # DISASM-NEXT: jmp   0x2011e0 <foo>
 # DISASM-NEXT: nop
 # DISASM-NEXT: jmp   0x2011e0 <foo>
@@ -65,13 +65,26 @@
 # DISASM-NEXT: nop
 # DISASM-NEXT: jmp   0x2011e1 <hid>
 # DISASM-NEXT: nop
-# DISASM-NEXT: jmpq  *8215(%rip)
-# DISASM-NEXT: jmpq  *8209(%rip)
+# DISASM-NEXT: jmpq  *8311(%rip)
+# DISASM-NEXT: jmpq  *8305(%rip)
+# DISASM-NEXT: leaq -167(%rip), %r16
+# DISASM-NEXT: leaq -175(%rip), %r16
+# DISASM-NEXT: leaq -182(%rip), %r16
+# DISASM-NEXT: leaq -190(%rip), %r16
+# DISASM-NEXT: movq 8265(%rip), %r16
+# DISASM-NEXT: movq 8257(%rip), %r16
+# DISASM-NEXT: leaq -215(%rip), %r16
+# DISASM-NEXT: leaq -223(%rip), %r16
+# DISASM-NEXT: leaq -230(%rip), %r16
+# DISASM-NEXT: leaq -238(%rip), %r16
+# DISASM-NEXT: movq 8217(%rip), %r16
+# DISASM-NEXT: movq 8209(%rip), %r16
 
 # NORELAX-LABEL: <_start>:
 # NORELAX-COUNT-12: movq
 # NORELAX-COUNT-6:  callq *
 # NORELAX-COUNT-6:  jmpq *
+# NORELAX-COUNT-12: movq
 
 .text
 .globl foo

>From 62a5da253afbe09a55066d279ed6ff9629e04a03 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen....@intel.com>
Date: Sun, 1 Sep 2024 18:02:01 +0800
Subject: [PATCH 7/8] Make test x86-64-gotpc-relax-nopic.s pass

---
 lld/ELF/Arch/X86_64.cpp | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index a02ba2f34ccf8f..56e3b882b8b3c7 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -901,6 +901,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t 
addend,
 static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
                           uint8_t modRm) {
   const uint8_t rex = loc[-3];
+  const bool isRex2 = loc[-4] == 0xd5;
   // Convert "test %reg, foo@GOTPCREL(%rip)" to "test $foo, %reg".
   if (op == 0x85) {
     // See "TEST-Logical Compare" (4-428 Vol. 2B),
@@ -925,7 +926,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, 
uint8_t op,
     // See "TEST-Logical Compare" (4-428 Vol. 2B).
     loc[-2] = 0xf7;
 
-    // Move R bit to the B bit in REX byte.
+    // Move R bit to the B bit in REX/REX2 byte.
     // REX byte is encoded as 0100WRXB, where
     // 0100 is 4bit fixed pattern.
     // REX.W When 1, a 64-bit operand size is used. Otherwise, when 0, the
@@ -936,7 +937,18 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, 
uint8_t op,
     // REX.B This 1-bit value is an extension to the MODRM.rm field or the
     // SIB.base field.
     // See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A).
-    loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
+    //
+    // REX2 prefix is encoded as 0xd5|M|R2|X2|B2|WRXB, where
+    // 0xd5 is 1byte fixed pattern.
+    // REX2's [W,R,X,B] have the same meanings as REX's.
+    // REX2.M encodes the map id.
+    // R2/X2/B2 provides the fifth and most siginicant bits of the R/X/B
+    // register identifiers, each of which can now address all 32 GPRs.
+    // TODO: Add the section number here after APX SPEC is merged into SDM.
+    if (isRex2)
+      loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2;
+    else
+      loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
     write32le(loc, val);
     return;
   }
@@ -957,7 +969,10 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, 
uint8_t op,
   // "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for
   // descriptions about each operation.
   loc[-2] = 0x81;
-  loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
+  if (isRex2)
+    loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2;
+  else
+    loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
   write32le(loc, val);
 }
 

>From 42e150fde2638501d8a615f358f50fbcfddb1a5a Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen....@intel.com>
Date: Tue, 24 Sep 2024 16:06:21 +0800
Subject: [PATCH 8/8] Revert lld change

---
 lld/ELF/Arch/X86_64.cpp                  |  37 ++------
 lld/test/ELF/x86-64-gotpc-no-relax-err.s |  10 +--
 lld/test/ELF/x86-64-gotpc-relax-nopic.s  | 109 +++++++++--------------
 lld/test/ELF/x86-64-gotpc-relax.s        |  54 +++--------
 4 files changed, 66 insertions(+), 144 deletions(-)

diff --git a/lld/ELF/Arch/X86_64.cpp b/lld/ELF/Arch/X86_64.cpp
index 56e3b882b8b3c7..48f17718365e24 100644
--- a/lld/ELF/Arch/X86_64.cpp
+++ b/lld/ELF/Arch/X86_64.cpp
@@ -388,7 +388,6 @@ RelExpr X86_64::getRelExpr(RelType type, const Symbol &s,
   case R_X86_64_GOTPCREL:
   case R_X86_64_GOTPCRELX:
   case R_X86_64_REX_GOTPCRELX:
-  case R_X86_64_REX2_GOTPCRELX:
   case R_X86_64_GOTTPOFF:
     return R_GOT_PC;
   case R_X86_64_GOTOFF64:
@@ -726,7 +725,6 @@ int64_t X86_64::getImplicitAddend(const uint8_t *buf, 
RelType type) const {
   case R_X86_64_GOTPCREL:
   case R_X86_64_GOTPCRELX:
   case R_X86_64_REX_GOTPCRELX:
-  case R_X86_64_REX2_GOTPCRELX:
   case R_X86_64_PC32:
   case R_X86_64_GOTTPOFF:
   case R_X86_64_PLT32:
@@ -810,7 +808,6 @@ void X86_64::relocate(uint8_t *loc, const Relocation &rel, 
uint64_t val) const {
     break;
   case R_X86_64_GOTPCRELX:
   case R_X86_64_REX_GOTPCRELX:
-  case R_X86_64_REX2_GOTPCRELX:
     if (rel.expr != R_GOT_PC) {
       relaxGot(loc, rel, val);
     } else {
@@ -862,13 +859,12 @@ void X86_64::relocate(uint8_t *loc, const Relocation 
&rel, uint64_t val) const {
 
 RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend,
                                 const uint8_t *loc) const {
-  // Only R_X86_64_[REX_]|[REX2_]GOTPCRELX can be relaxed. GNU as may emit
-  // GOTPCRELX with addend != -4. Such an instruction does not load the full 
GOT
-  // entry, so we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip),
-  // %rax (addend=0) loads the high 32 bits of the GOT entry.
+  // Only R_X86_64_[REX_]GOTPCRELX can be relaxed. GNU as may emit GOTPCRELX
+  // with addend != -4. Such an instruction does not load the full GOT entry, 
so
+  // we cannot relax the relocation. E.g. movl x@GOTPCREL+4(%rip), %rax
+  // (addend=0) loads the high 32 bits of the GOT entry.
   if (!ctx.arg.relax || addend != -4 ||
-      (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX &&
-       type != R_X86_64_REX2_GOTPCRELX))
+      (type != R_X86_64_GOTPCRELX && type != R_X86_64_REX_GOTPCRELX))
     return R_GOT_PC;
   const uint8_t op = loc[-2];
   const uint8_t modRm = loc[-1];
@@ -884,7 +880,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t 
addend,
   if (op == 0xff && (modRm == 0x15 || modRm == 0x25))
     return R_RELAX_GOT_PC;
 
-  // We don't support test/binop instructions without a REX/REX2 prefix.
+  // We don't support test/binop instructions without a REX prefix.
   if (type == R_X86_64_GOTPCRELX)
     return R_GOT_PC;
 
@@ -901,7 +897,6 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t 
addend,
 static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
                           uint8_t modRm) {
   const uint8_t rex = loc[-3];
-  const bool isRex2 = loc[-4] == 0xd5;
   // Convert "test %reg, foo@GOTPCREL(%rip)" to "test $foo, %reg".
   if (op == 0x85) {
     // See "TEST-Logical Compare" (4-428 Vol. 2B),
@@ -926,7 +921,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, 
uint8_t op,
     // See "TEST-Logical Compare" (4-428 Vol. 2B).
     loc[-2] = 0xf7;
 
-    // Move R bit to the B bit in REX/REX2 byte.
+    // Move R bit to the B bit in REX byte.
     // REX byte is encoded as 0100WRXB, where
     // 0100 is 4bit fixed pattern.
     // REX.W When 1, a 64-bit operand size is used. Otherwise, when 0, the
@@ -937,18 +932,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, 
uint8_t op,
     // REX.B This 1-bit value is an extension to the MODRM.rm field or the
     // SIB.base field.
     // See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A).
-    //
-    // REX2 prefix is encoded as 0xd5|M|R2|X2|B2|WRXB, where
-    // 0xd5 is 1byte fixed pattern.
-    // REX2's [W,R,X,B] have the same meanings as REX's.
-    // REX2.M encodes the map id.
-    // R2/X2/B2 provides the fifth and most siginicant bits of the R/X/B
-    // register identifiers, each of which can now address all 32 GPRs.
-    // TODO: Add the section number here after APX SPEC is merged into SDM.
-    if (isRex2)
-      loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2;
-    else
-      loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
+    loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
     write32le(loc, val);
     return;
   }
@@ -969,10 +953,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, 
uint8_t op,
   // "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for
   // descriptions about each operation.
   loc[-2] = 0x81;
-  if (isRex2)
-    loc[-3] = (rex & ~0x44) | (rex & 0x44) >> 2;
-  else
-    loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
+  loc[-3] = (rex & ~0x4) | (rex & 0x4) >> 2;
   write32le(loc, val);
 }
 
diff --git a/lld/test/ELF/x86-64-gotpc-no-relax-err.s 
b/lld/test/ELF/x86-64-gotpc-no-relax-err.s
index 4280c8fd1dc97e..618dca47755f41 100644
--- a/lld/test/ELF/x86-64-gotpc-no-relax-err.s
+++ b/lld/test/ELF/x86-64-gotpc-no-relax-err.s
@@ -7,19 +7,15 @@
 ## `>>> defined in` for linker synthesized __stop_* symbols (there is no
 ## associated file or linker script line number).
 
-# CHECK:      error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of 
range: 2147483666 is not in [-2147483648, 2147483647]; references '__stop_data'
+# CHECK:      error: {{.*}}:(.text+0x2): relocation R_X86_64_GOTPCRELX out of 
range: 2147483658 is not in [-2147483648, 2147483647]; references '__stop_data'
 # CHECK-NEXT: >>> defined in <internal>
 # CHECK-EMPTY:
-# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out 
of range: 2147483659 is not in [-2147483648, 2147483647]; references 
'__stop_data'
-# CHECK-NEXT: >>> defined in <internal>
-# CHECK-EMPTY:
-# CHECK-NEXT: error: {{.*}}:(.text+0x11): relocation R_X86_64_REX2_GOTPCRELX 
out of range: 2147483651 is not in [-2147483648, 2147483647]; references 
'__stop_data'
+# CHECK-NEXT: error: {{.*}}:(.text+0x9): relocation R_X86_64_REX_GOTPCRELX out 
of range: 2147483651 is not in [-2147483648, 2147483647]; references 
'__stop_data'
 # CHECK-NEXT: >>> defined in <internal>
 
 #--- a.s
   movl __stop_data@GOTPCREL(%rip), %eax  # out of range
   movq __stop_data@GOTPCREL(%rip), %rax  # out of range
-  movq __stop_data@GOTPCREL(%rip), %r16  # out of range
   movq __stop_data@GOTPCREL(%rip), %rax  # in range
 
 .section data,"aw",@progbits
@@ -27,5 +23,5 @@
 #--- lds
 SECTIONS {
   .text 0x200000 : { *(.text) }
-  .got 0x80200016 : { *(.got) }
+  .got 0x80200010 : { *(.got) }
 }
diff --git a/lld/test/ELF/x86-64-gotpc-relax-nopic.s 
b/lld/test/ELF/x86-64-gotpc-relax-nopic.s
index e3cd93d1d57962..7481904d16f1b4 100644
--- a/lld/test/ELF/x86-64-gotpc-relax-nopic.s
+++ b/lld/test/ELF/x86-64-gotpc-relax-nopic.s
@@ -10,39 +10,30 @@
 # SYMRELOC:      Symbols [
 # SYMRELOC:       Symbol {
 # SYMRELOC:        Name: bar
-# SYMRELOC-NEXT:   Value: 0x203290
+# SYMRELOC-NEXT:   Value: 0x203248
 
 ## 2105751 = 0x202197 (bar)
 # DISASM:      Disassembly of section .text:
 # DISASM-EMPTY:
 # DISASM-NEXT: <_start>:
-# DISASM-NEXT:   2011c8:       adcl  {{.*}}(%rip), %eax  # 0x202288
-# DISASM-NEXT:                 addl  {{.*}}(%rip), %ebx  # 0x202288
-# DISASM-NEXT:                 andl  {{.*}}(%rip), %ecx  # 0x202288
-# DISASM-NEXT:                 cmpl  {{.*}}(%rip), %edx  # 0x202288
-# DISASM-NEXT:                 orl   {{.*}}(%rip), %edi  # 0x202288
-# DISASM-NEXT:                 sbbl  {{.*}}(%rip), %esi  # 0x202288
-# DISASM-NEXT:                 subl  {{.*}}(%rip), %ebp  # 0x202288
-# DISASM-NEXT:                 xorl  $0x203290, %r8d
-# DISASM-NEXT:                 testl $0x203290, %r15d
-# DISASM-NEXT:   201200:       adcq  $0x203290, %rax
-# DISASM-NEXT:                 addq  $0x203290, %rbx
-# DISASM-NEXT:                 andq  $0x203290, %rcx
-# DISASM-NEXT:                 cmpq  $0x203290, %rdx
-# DISASM-NEXT:                 orq   $0x203290, %rdi
-# DISASM-NEXT:                 sbbq  $0x203290, %rsi
-# DISASM-NEXT:                 subq  $0x203290, %rbp
-# DISASM-NEXT:                 xorq  $0x203290, %r8
-# DISASM-NEXT:                 testq $0x203290, %r15
-# DISASM-NEXT:   20123f:       adcq  $0x203290, %r16
-# DISASM-NEXT:                 addq  $0x203290, %r17
-# DISASM-NEXT:                 andq  $0x203290, %r18
-# DISASM-NEXT:                 cmpq  $0x203290, %r19
-# DISASM-NEXT:                 orq   $0x203290, %r20
-# DISASM-NEXT:                 sbbq  $0x203290, %r21
-# DISASM-NEXT:                 subq  $0x203290, %r22
-# DISASM-NEXT:                 xorq  $0x203290, %r23
-# DISASM-NEXT:                 testq $0x203290, %r24
+# DISASM-NEXT:   2011c8:       adcl  {{.*}}(%rip), %eax  # 0x202240
+# DISASM-NEXT:                 addl  {{.*}}(%rip), %ebx  # 0x202240
+# DISASM-NEXT:                 andl  {{.*}}(%rip), %ecx  # 0x202240
+# DISASM-NEXT:                 cmpl  {{.*}}(%rip), %edx  # 0x202240
+# DISASM-NEXT:                 orl   {{.*}}(%rip), %edi  # 0x202240
+# DISASM-NEXT:                 sbbl  {{.*}}(%rip), %esi  # 0x202240
+# DISASM-NEXT:                 subl  {{.*}}(%rip), %ebp  # 0x202240
+# DISASM-NEXT:                 xorl  $0x203248, %r8d
+# DISASM-NEXT:                 testl $0x203248, %r15d
+# DISASM-NEXT:   201200:       adcq  $0x203248, %rax
+# DISASM-NEXT:                 addq  $0x203248, %rbx
+# DISASM-NEXT:                 andq  $0x203248, %rcx
+# DISASM-NEXT:                 cmpq  $0x203248, %rdx
+# DISASM-NEXT:                 orq   $0x203248, %rdi
+# DISASM-NEXT:                 sbbq  $0x203248, %rsi
+# DISASM-NEXT:                 subq  $0x203248, %rbp
+# DISASM-NEXT:                 xorq  $0x203248, %r8
+# DISASM-NEXT:                 testq $0x203248, %r15
 
 # RUN: ld.lld --hash-style=sysv -shared %t.o -o %t2
 # RUN: llvm-readobj -S -r -d %t2 | FileCheck --check-prefix=SEC-PIC    %s
@@ -55,8 +46,8 @@
 # SEC-PIC-NEXT:     SHF_ALLOC
 # SEC-PIC-NEXT:     SHF_WRITE
 # SEC-PIC-NEXT:   ]
-# SEC-PIC-NEXT:   Address: 0x23C8
-# SEC-PIC-NEXT:   Offset: 0x3C8
+# SEC-PIC-NEXT:   Address: 0x2380
+# SEC-PIC-NEXT:   Offset: 0x380
 # SEC-PIC-NEXT:   Size: 8
 # SEC-PIC-NEXT:   Link:
 # SEC-PIC-NEXT:   Info:
@@ -66,7 +57,7 @@
 # SEC-PIC:      0x000000006FFFFFF9 RELACOUNT            1
 # SEC-PIC:      Relocations [
 # SEC-PIC-NEXT:   Section ({{.*}}) .rela.dyn {
-# SEC-PIC-NEXT:     0x23C8 R_X86_64_RELATIVE - 0x33D0
+# SEC-PIC-NEXT:     0x2380 R_X86_64_RELATIVE - 0x3388
 # SEC-PIC-NEXT:   }
 # SEC-PIC-NEXT: ]
 
@@ -74,33 +65,24 @@
 # DISASM-PIC:      Disassembly of section .text:
 # DISASM-PIC-EMPTY:
 # DISASM-PIC-NEXT: <_start>:
-# DISASM-PIC-NEXT: 1268:       adcl  {{.*}}(%rip), %eax  # 0x23c8
-# DISASM-PIC-NEXT:             addl  {{.*}}(%rip), %ebx  # 0x23c8
-# DISASM-PIC-NEXT:             andl  {{.*}}(%rip), %ecx  # 0x23c8
-# DISASM-PIC-NEXT:             cmpl  {{.*}}(%rip), %edx  # 0x23c8
-# DISASM-PIC-NEXT:             orl   {{.*}}(%rip), %edi  # 0x23c8
-# DISASM-PIC-NEXT:             sbbl  {{.*}}(%rip), %esi  # 0x23c8
-# DISASM-PIC-NEXT:             subl  {{.*}}(%rip), %ebp  # 0x23c8
-# DISASM-PIC-NEXT:             xorl  {{.*}}(%rip), %r8d  # 0x23c8
-# DISASM-PIC-NEXT:             testl %r15d, {{.*}}(%rip) # 0x23c8
-# DISASM-PIC-NEXT: 12a0:       adcq  {{.*}}(%rip), %rax  # 0x23c8
-# DISASM-PIC-NEXT:             addq  {{.*}}(%rip), %rbx  # 0x23c8
-# DISASM-PIC-NEXT:             andq  {{.*}}(%rip), %rcx  # 0x23c8
-# DISASM-PIC-NEXT:             cmpq  {{.*}}(%rip), %rdx  # 0x23c8
-# DISASM-PIC-NEXT:             orq   {{.*}}(%rip), %rdi  # 0x23c8
-# DISASM-PIC-NEXT:             sbbq  {{.*}}(%rip), %rsi  # 0x23c8
-# DISASM-PIC-NEXT:             subq  {{.*}}(%rip), %rbp  # 0x23c8
-# DISASM-PIC-NEXT:             xorq  {{.*}}(%rip), %r8   # 0x23c8
-# DISASM-PIC-NEXT:             testq %r15, {{.*}}(%rip)  # 0x23c8
-# DISASM-PIC-NEXT: 12df:       adcq  {{.*}}(%rip), %r16  # 0x23c8
-# DISASM-PIC-NEXT:             addq  {{.*}}(%rip), %r17  # 0x23c8
-# DISASM-PIC-NEXT:             andq  {{.*}}(%rip), %r18  # 0x23c8
-# DISASM-PIC-NEXT:             cmpq  {{.*}}(%rip), %r19  # 0x23c8
-# DISASM-PIC-NEXT:             orq   {{.*}}(%rip), %r20  # 0x23c8
-# DISASM-PIC-NEXT:             sbbq  {{.*}}(%rip), %r21  # 0x23c8
-# DISASM-PIC-NEXT:             subq  {{.*}}(%rip), %r22  # 0x23c8
-# DISASM-PIC-NEXT:             xorq  {{.*}}(%rip), %r23   # 0x23c8
-# DISASM-PIC-NEXT:             testq %r24, {{.*}}(%rip)  # 0x23c8
+# DISASM-PIC-NEXT: 1268:       adcl  {{.*}}(%rip), %eax  # 0x2380
+# DISASM-PIC-NEXT:             addl  {{.*}}(%rip), %ebx  # 0x2380
+# DISASM-PIC-NEXT:             andl  {{.*}}(%rip), %ecx  # 0x2380
+# DISASM-PIC-NEXT:             cmpl  {{.*}}(%rip), %edx  # 0x2380
+# DISASM-PIC-NEXT:             orl   {{.*}}(%rip), %edi  # 0x2380
+# DISASM-PIC-NEXT:             sbbl  {{.*}}(%rip), %esi  # 0x2380
+# DISASM-PIC-NEXT:             subl  {{.*}}(%rip), %ebp  # 0x2380
+# DISASM-PIC-NEXT:             xorl  {{.*}}(%rip), %r8d  # 0x2380
+# DISASM-PIC-NEXT:             testl %r15d, {{.*}}(%rip) # 0x2380
+# DISASM-PIC-NEXT: 12a0:       adcq  {{.*}}(%rip), %rax  # 0x2380
+# DISASM-PIC-NEXT:             addq  {{.*}}(%rip), %rbx  # 0x2380
+# DISASM-PIC-NEXT:             andq  {{.*}}(%rip), %rcx  # 0x2380
+# DISASM-PIC-NEXT:             cmpq  {{.*}}(%rip), %rdx  # 0x2380
+# DISASM-PIC-NEXT:             orq   {{.*}}(%rip), %rdi  # 0x2380
+# DISASM-PIC-NEXT:             sbbq  {{.*}}(%rip), %rsi  # 0x2380
+# DISASM-PIC-NEXT:             subq  {{.*}}(%rip), %rbp  # 0x2380
+# DISASM-PIC-NEXT:             xorq  {{.*}}(%rip), %r8   # 0x2380
+# DISASM-PIC-NEXT:             testq %r15, {{.*}}(%rip)  # 0x2380
 
 .data
 .type   bar, @object
@@ -133,14 +115,3 @@ _start:
   subq    bar@GOTPCREL(%rip), %rbp
   xorq    bar@GOTPCREL(%rip), %r8
   testq   %r15, bar@GOTPCREL(%rip)
-
-## R_X86_64_REX2_GOTPCRELX
-  adcq    bar@GOTPCREL(%rip), %r16
-  addq    bar@GOTPCREL(%rip), %r17
-  andq    bar@GOTPCREL(%rip), %r18
-  cmpq    bar@GOTPCREL(%rip), %r19
-  orq     bar@GOTPCREL(%rip), %r20
-  sbbq    bar@GOTPCREL(%rip), %r21
-  subq    bar@GOTPCREL(%rip), %r22
-  xorq    bar@GOTPCREL(%rip), %r23
-  testq   %r24, bar@GOTPCREL(%rip)
diff --git a/lld/test/ELF/x86-64-gotpc-relax.s 
b/lld/test/ELF/x86-64-gotpc-relax.s
index b1ff995b3fc211..5945bfc04a0225 100644
--- a/lld/test/ELF/x86-64-gotpc-relax.s
+++ b/lld/test/ELF/x86-64-gotpc-relax.s
@@ -1,5 +1,5 @@
 # REQUIRES: x86
-## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX/R_X86_64_REX2_GOTPCRELX 
GOT optimization.
+## Test R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX GOT optimization.
 
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
 # RUN: ld.lld %t.o -o %t1 --no-apply-dynamic-relocs
@@ -15,16 +15,16 @@
 
 ## In our implementation, .got is retained even if all GOT-generating 
relocations are optimized.
 # CHECK:      Name              Type            Address          Off    Size   
ES Flg Lk Inf Al
-# CHECK:      .iplt             PROGBITS        00000000002012e0 0002e0 000010 
00  AX  0   0 16
-# CHECK-NEXT: .got              PROGBITS        00000000002022f0 0002f0 000000 
00  WA  0   0  8
+# CHECK:      .iplt             PROGBITS        0000000000201280 000280 000010 
00  AX  0   0 16
+# CHECK-NEXT: .got              PROGBITS        0000000000202290 000290 000000 
00  WA  0   0  8
 
 ## There is one R_X86_64_IRELATIVE relocations.
 # RELOC-LABEL: Relocation section '.rela.dyn' at offset {{.*}} contains 1 
entry:
 # CHECK:           Offset             Info             Type               
Symbol's Value  Symbol's Name + Addend
-# CHECK:       00000000002032f0  0000000000000025 R_X86_64_IRELATIVE           
             2011e2
+# CHECK:       0000000000203290  0000000000000025 R_X86_64_IRELATIVE           
             2011e2
 # CHECK-LABEL: Hex dump of section '.got.plt':
-# NOAPPLY-NEXT:  0x002032f0 00000000 00000000
-# APPLY-NEXT:    0x002032f0 e2112000 00000000
+# NOAPPLY-NEXT:  0x00203290 00000000 00000000
+# APPLY-NEXT:    0x00203290 e2112000 00000000
 
 # 0x201173 + 7 - 10 = 0x201170
 # 0x20117a + 7 - 17 = 0x201170
@@ -43,20 +43,20 @@
 # DISASM-NEXT: leaq -17(%rip), %rax
 # DISASM-NEXT: leaq -23(%rip), %rax
 # DISASM-NEXT: leaq -30(%rip), %rax
-# DISASM-NEXT: movq 8426(%rip), %rax
-# DISASM-NEXT: movq 8419(%rip), %rax
+# DISASM-NEXT: movq 8330(%rip), %rax
+# DISASM-NEXT: movq 8323(%rip), %rax
 # DISASM-NEXT: leaq -52(%rip), %rax
 # DISASM-NEXT: leaq -59(%rip), %rax
 # DISASM-NEXT: leaq -65(%rip), %rax
 # DISASM-NEXT: leaq -72(%rip), %rax
-# DISASM-NEXT: movq 8384(%rip), %rax
-# DISASM-NEXT: movq 8377(%rip), %rax
+# DISASM-NEXT: movq 8288(%rip), %rax
+# DISASM-NEXT: movq 8281(%rip), %rax
 # DISASM-NEXT: callq 0x2011e0 <foo>
 # DISASM-NEXT: callq 0x2011e0 <foo>
 # DISASM-NEXT: callq 0x2011e1 <hid>
 # DISASM-NEXT: callq 0x2011e1 <hid>
-# DISASM-NEXT: callq *8347(%rip)
-# DISASM-NEXT: callq *8341(%rip)
+# DISASM-NEXT: callq *8251(%rip)
+# DISASM-NEXT: callq *8245(%rip)
 # DISASM-NEXT: jmp   0x2011e0 <foo>
 # DISASM-NEXT: nop
 # DISASM-NEXT: jmp   0x2011e0 <foo>
@@ -65,26 +65,13 @@
 # DISASM-NEXT: nop
 # DISASM-NEXT: jmp   0x2011e1 <hid>
 # DISASM-NEXT: nop
-# DISASM-NEXT: jmpq  *8311(%rip)
-# DISASM-NEXT: jmpq  *8305(%rip)
-# DISASM-NEXT: leaq -167(%rip), %r16
-# DISASM-NEXT: leaq -175(%rip), %r16
-# DISASM-NEXT: leaq -182(%rip), %r16
-# DISASM-NEXT: leaq -190(%rip), %r16
-# DISASM-NEXT: movq 8265(%rip), %r16
-# DISASM-NEXT: movq 8257(%rip), %r16
-# DISASM-NEXT: leaq -215(%rip), %r16
-# DISASM-NEXT: leaq -223(%rip), %r16
-# DISASM-NEXT: leaq -230(%rip), %r16
-# DISASM-NEXT: leaq -238(%rip), %r16
-# DISASM-NEXT: movq 8217(%rip), %r16
-# DISASM-NEXT: movq 8209(%rip), %r16
+# DISASM-NEXT: jmpq  *8215(%rip)
+# DISASM-NEXT: jmpq  *8209(%rip)
 
 # NORELAX-LABEL: <_start>:
 # NORELAX-COUNT-12: movq
 # NORELAX-COUNT-6:  callq *
 # NORELAX-COUNT-6:  jmpq *
-# NORELAX-COUNT-12: movq
 
 .text
 .globl foo
@@ -133,16 +120,3 @@ _start:
  jmp *hid@GOTPCREL(%rip)
  jmp *ifunc@GOTPCREL(%rip)
  jmp *ifunc@GOTPCREL(%rip)
-
- movq foo@GOTPCREL(%rip), %r16
- movq foo@GOTPCREL(%rip), %r16
- movq hid@GOTPCREL(%rip), %r16
- movq hid@GOTPCREL(%rip), %r16
- movq ifunc@GOTPCREL(%rip), %r16
- movq ifunc@GOTPCREL(%rip), %r16
- movq foo@GOTPCREL(%rip), %r16
- movq foo@GOTPCREL(%rip), %r16
- movq hid@GOTPCREL(%rip), %r16
- movq hid@GOTPCREL(%rip), %r16
- movq ifunc@GOTPCREL(%rip), %r16
- movq ifunc@GOTPCREL(%rip), %r16

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to