Skip to content

[llvm][lld] Support R_AARCH64_GOTPCREL32 #72584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 10, 2024

Conversation

PiJoules
Copy link
Contributor

This is the follopw implementation to
ARM-software/abi-aa#223 that supports this relocation in llvm and lld.

@llvmbot
Copy link
Member

llvmbot commented Nov 16, 2023

@llvm/pr-subscribers-lld-elf
@llvm/pr-subscribers-llvm-binary-utilities

@llvm/pr-subscribers-mc

Author: None (PiJoules)

Changes

This is the follopw implementation to
ARM-software/abi-aa#223 that supports this relocation in llvm and lld.


Full diff: https://github.com/llvm/llvm-project/pull/72584.diff

5 Files Affected:

  • (modified) lld/ELF/Arch/AArch64.cpp (+3)
  • (added) lld/test/ELF/aarch64-reloc-gotpcrel32.s (+36)
  • (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def (+2)
  • (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp (+5-2)
  • (added) llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s (+14)
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 048f0ec30ebd283..32cff73955028e4 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -165,6 +165,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
   case R_AARCH64_ADR_GOT_PAGE:
   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     return R_AARCH64_GOT_PAGE_PC;
+  case R_AARCH64_GOTPCREL32:
+    return R_GOT_PC;
   case R_AARCH64_NONE:
     return R_NONE;
   default:
@@ -374,6 +376,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     write32(loc, val);
     break;
   case R_AARCH64_PLT32:
+  case R_AARCH64_GOTPCREL32:
     checkInt(loc, val, 32, rel);
     write32(loc, val);
     break;
diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..7ea55bfc5b00aad
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
@@ -0,0 +1,36 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -S %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
+
+
+// SEC:         Name: .got (58)
+// SEC-NEXT:    Type: SHT_PROGBITS (0x1)
+// SEC-NEXT:    Flags [ (0x3)
+// SEC-NEXT:      SHF_ALLOC (0x2)
+// SEC-NEXT:      SHF_WRITE (0x1)
+// SEC-NEXT:    ]
+// SEC-NEXT:    Address: 0x20350
+// SEC-NEXT:    Offset: 0x350
+// SEC-NEXT:    Size: 8
+// SEC-NEXT:    Link: 0
+// SEC-NEXT:    Info: 0
+// SEC-NEXT:    AddressAlignment: 8
+// SEC-NEXT:    EntrySize: 0
+
+  .section .data
+  .globl bar
+bar:
+
+  .globl _start
+_start:
+// bar@GOTPCREL   = 0x20350 (got entry for `bar`) - 0x30358 (.) = 0xfffefff8
+// bar@GOTPCREL+4 = 0x20350 (got entry for `bar`) - 0x3035c (.) + 4 = 0xfffefff8
+// bar@GOTPCREL-4 = 0x20350 (got entry for `bar`) - 0x30360 (.) + 4 = 0xfffeffec
+// CHECK: Contents of section .data:
+// CHECK:  30358 f8fffeff f8fffeff ecfffeff
+  .word bar@GOTPCREL
+  .word bar@GOTPCREL+4
+  .word bar@GOTPCREL-4
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index b507109b19e1b90..fcaea2aceed5209 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -59,6 +59,7 @@ ELF_RELOC(R_AARCH64_ADR_GOT_PAGE,                    0x137)
 ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC,                0x138)
 ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15,               0x139)
 ELF_RELOC(R_AARCH64_PLT32,                           0x13a)
+ELF_RELOC(R_AARCH64_GOTPCREL32,                      0x13b)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21,                0x200)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21,                0x201)
 ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC,               0x202)
@@ -166,6 +167,7 @@ ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE,                0x01a)
 ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC,            0x01b)
 ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14,           0x01c)
 ELF_RELOC(R_AARCH64_P32_PLT32,                       0x01d)
+ELF_RELOC(R_AARCH64_P32_GOTPCREL32,                  0x01e)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PREL21,            0x050)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PAGE21,            0x051)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADD_LO12_NC,           0x052)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 9de40661298ccad..996fd1614d19f57 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -120,7 +120,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
 
   assert((!Target.getSymA() ||
           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
-          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) &&
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
          "Should only be expression-level modifiers here");
 
   assert((!Target.getSymB() ||
@@ -202,7 +203,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
     case FK_Data_2:
       return R_CLS(ABS16);
     case FK_Data_4:
-      return R_CLS(ABS32);
+      return Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL
+                 ? R_CLS(GOTPCREL32)
+                 : R_CLS(ABS32);
     case FK_Data_8:
       if (IsILP32) {
         Ctx.reportError(Fixup.getLoc(),
diff --git a/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..afbcaad9e1dfdcc
--- /dev/null
+++ b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | \
+// RUN:   llvm-readobj -r - | FileCheck %s
+
+        .section .data
+this:
+        .word this@GOTPCREL
+        .word extern_sym@GOTPCREL+4
+        .word negative_offset@GOTPCREL-4
+
+// CHECK:      Section ({{.*}}) .rela.data
+// CHECK-NEXT:   0x0 R_AARCH64_GOTPCREL32 this 0x0
+// CHECK-NEXT:   0x4 R_AARCH64_GOTPCREL32 extern_sym 0x4
+// CHECK-NEXT:   0x8 R_AARCH64_GOTPCREL32 negative_offset 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: }

@llvmbot
Copy link
Member

llvmbot commented Nov 16, 2023

@llvm/pr-subscribers-backend-aarch64

Author: None (PiJoules)

Changes

This is the follopw implementation to
ARM-software/abi-aa#223 that supports this relocation in llvm and lld.


Full diff: https://github.com/llvm/llvm-project/pull/72584.diff

5 Files Affected:

  • (modified) lld/ELF/Arch/AArch64.cpp (+3)
  • (added) lld/test/ELF/aarch64-reloc-gotpcrel32.s (+36)
  • (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def (+2)
  • (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp (+5-2)
  • (added) llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s (+14)
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 048f0ec30ebd283..32cff73955028e4 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -165,6 +165,8 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
   case R_AARCH64_ADR_GOT_PAGE:
   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     return R_AARCH64_GOT_PAGE_PC;
+  case R_AARCH64_GOTPCREL32:
+    return R_GOT_PC;
   case R_AARCH64_NONE:
     return R_NONE;
   default:
@@ -374,6 +376,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     write32(loc, val);
     break;
   case R_AARCH64_PLT32:
+  case R_AARCH64_GOTPCREL32:
     checkInt(loc, val, 32, rel);
     write32(loc, val);
     break;
diff --git a/lld/test/ELF/aarch64-reloc-gotpcrel32.s b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..7ea55bfc5b00aad
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-gotpcrel32.s
@@ -0,0 +1,36 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %S/Inputs/abs255.s -o %t255.o
+// RUN: ld.lld %t.o -o %t.so -shared
+// RUN: llvm-readobj -S %t.so | FileCheck --check-prefix=SEC %s
+// RUN: llvm-objdump --no-print-imm-hex -s -d %t.so | FileCheck %s
+
+
+// SEC:         Name: .got (58)
+// SEC-NEXT:    Type: SHT_PROGBITS (0x1)
+// SEC-NEXT:    Flags [ (0x3)
+// SEC-NEXT:      SHF_ALLOC (0x2)
+// SEC-NEXT:      SHF_WRITE (0x1)
+// SEC-NEXT:    ]
+// SEC-NEXT:    Address: 0x20350
+// SEC-NEXT:    Offset: 0x350
+// SEC-NEXT:    Size: 8
+// SEC-NEXT:    Link: 0
+// SEC-NEXT:    Info: 0
+// SEC-NEXT:    AddressAlignment: 8
+// SEC-NEXT:    EntrySize: 0
+
+  .section .data
+  .globl bar
+bar:
+
+  .globl _start
+_start:
+// bar@GOTPCREL   = 0x20350 (got entry for `bar`) - 0x30358 (.) = 0xfffefff8
+// bar@GOTPCREL+4 = 0x20350 (got entry for `bar`) - 0x3035c (.) + 4 = 0xfffefff8
+// bar@GOTPCREL-4 = 0x20350 (got entry for `bar`) - 0x30360 (.) + 4 = 0xfffeffec
+// CHECK: Contents of section .data:
+// CHECK:  30358 f8fffeff f8fffeff ecfffeff
+  .word bar@GOTPCREL
+  .word bar@GOTPCREL+4
+  .word bar@GOTPCREL-4
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index b507109b19e1b90..fcaea2aceed5209 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -59,6 +59,7 @@ ELF_RELOC(R_AARCH64_ADR_GOT_PAGE,                    0x137)
 ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC,                0x138)
 ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15,               0x139)
 ELF_RELOC(R_AARCH64_PLT32,                           0x13a)
+ELF_RELOC(R_AARCH64_GOTPCREL32,                      0x13b)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21,                0x200)
 ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21,                0x201)
 ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC,               0x202)
@@ -166,6 +167,7 @@ ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE,                0x01a)
 ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC,            0x01b)
 ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14,           0x01c)
 ELF_RELOC(R_AARCH64_P32_PLT32,                       0x01d)
+ELF_RELOC(R_AARCH64_P32_GOTPCREL32,                  0x01e)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PREL21,            0x050)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PAGE21,            0x051)
 ELF_RELOC(R_AARCH64_P32_TLSGD_ADD_LO12_NC,           0x052)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 9de40661298ccad..996fd1614d19f57 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -120,7 +120,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
 
   assert((!Target.getSymA() ||
           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
-          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT) &&
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_PLT ||
+          Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOTPCREL) &&
          "Should only be expression-level modifiers here");
 
   assert((!Target.getSymB() ||
@@ -202,7 +203,9 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
     case FK_Data_2:
       return R_CLS(ABS16);
     case FK_Data_4:
-      return R_CLS(ABS32);
+      return Target.getAccessVariant() == MCSymbolRefExpr::VK_GOTPCREL
+                 ? R_CLS(GOTPCREL32)
+                 : R_CLS(ABS32);
     case FK_Data_8:
       if (IsILP32) {
         Ctx.reportError(Fixup.getLoc(),
diff --git a/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
new file mode 100644
index 000000000000000..afbcaad9e1dfdcc
--- /dev/null
+++ b/llvm/test/MC/AArch64/elf-reloc-gotpcrel32.s
@@ -0,0 +1,14 @@
+// RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | \
+// RUN:   llvm-readobj -r - | FileCheck %s
+
+        .section .data
+this:
+        .word this@GOTPCREL
+        .word extern_sym@GOTPCREL+4
+        .word negative_offset@GOTPCREL-4
+
+// CHECK:      Section ({{.*}}) .rela.data
+// CHECK-NEXT:   0x0 R_AARCH64_GOTPCREL32 this 0x0
+// CHECK-NEXT:   0x4 R_AARCH64_GOTPCREL32 extern_sym 0x4
+// CHECK-NEXT:   0x8 R_AARCH64_GOTPCREL32 negative_offset 0xFFFFFFFFFFFFFFFC
+// CHECK-NEXT: }

@PiJoules
Copy link
Contributor Author

I only discovered the R_AARCH64_P32_* relocations just now. Not sure if I need another rfc for R_AARCH64_P32_GOTPCREL32.

Copy link
Collaborator

@smithp35 smithp35 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than one line about the ILP32 code LGTM.

Please do tell us if you need ILP32 support and we can add the code to the ABI.

@MaskRay MaskRay changed the title [llvm][lld] Support R_<CLS>_GOTREL32 [llvm][lld] Support R_AARCH64_GOTPCREL32 Nov 27, 2023
@PiJoules PiJoules requested review from smithp35 and MaskRay November 29, 2023 00:04
@@ -0,0 +1,11 @@
// REQUIRES: aarch64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newer tests place overflow tests (RUN: not ld.lld ...) and regular tests (RUN: ld.lld ...) in one file so that the boundary is clearer.

aarch64-reloc-plt32.s is a good example

Copy link
Contributor Author

@PiJoules PiJoules Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For PLT32 I can put all the tests in one file since foo@PLT can be relaxed to foo if it's defined in one of the other input files, but I don't think the same can work for foo@GOTPCREL since this can't be relaxed to anything that could be defined in a separate input file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you perhaps have another example I can follow?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you can use more than one symbol in a test.

Since the error message contains the bounds (in [-2147483648, 2147483647]), I think we don't need to make an extreme test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated tests

@smithp35
Copy link
Collaborator

I don't have any more comments, thanks for making the earlier changes. Happy for MaskRay to approve when his comments have been addressed.

@PiJoules PiJoules requested a review from MaskRay November 29, 2023 19:24
Copy link
Member

@MaskRay MaskRay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is mostly good, just needing some test changes.

This is the follopw implementation to
ARM-software/abi-aa#223 that supports this
relocation in llvm and lld.
@PiJoules PiJoules merged commit 04a906e into llvm:main Jan 10, 2024
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
This is the follopw implementation to
ARM-software/abi-aa#223 that supports this
relocation in llvm and lld.
bnbarham added a commit to bnbarham/llvm-project that referenced this pull request Sep 24, 2024
This reverts the MC changes from commit
04a906e, which cause failures when
linking with gold on arm64.
bnbarham added a commit to swiftlang/llvm-project that referenced this pull request Sep 25, 2024
Partially revert "[llvm][lld] Support R_AARCH64_GOTPCREL32 (llvm#72584)"
bnbarham added a commit to bnbarham/llvm-project that referenced this pull request Sep 26, 2024
…lvm#72584)""

This reverts commit f1cbfe9, which
ended up causing other failures.
bnbarham added a commit to swiftlang/llvm-project that referenced this pull request Sep 26, 2024
Revert "Partially revert "[llvm][lld] Support R_AARCH64_GOTPCREL32 (llvm#72584)""
@dianqk
Copy link
Member

dianqk commented May 31, 2025

We have identified that some Rust projects are broken from here, such as rust-lang/rust#141737 and tikv/tikv#18465. Can we revert this until the GNU linker also supports R_AARCH64_GOTPCREL32?

@nikic
Copy link
Contributor

nikic commented May 31, 2025

We have identified that some Rust projects are broken from here, such as rust-lang/rust#141737 and tikv/tikv#18465. Can we revert this until the GNU linker also supports R_AARCH64_GOTPCREL32?

You're suggesting to only revert the AArch64ELFObjectWriter part, right?

@MaskRay
Copy link
Member

MaskRay commented May 31, 2025

We have identified that some Rust projects are broken from here, such as rust-lang/rust#141737 and tikv/tikv#18465. Can we revert this until the GNU linker also supports R_AARCH64_GOTPCREL32?

I don't think it's reasonable to request reverting the lld/ELF or AArch64 assembler changes. The affected code path is only used when the input IR is in a specific form. If Rust needs compatibility with GNU ld or older lld, it should stop emitting IR that triggers this path.

Additionally, the linked rust-lang/rust#141737 does not explain why you assert this is an LLVM issue rather than a Rust one.

@nikic
Copy link
Contributor

nikic commented May 31, 2025

@MaskRay Rust is not generating this pattern, LLVM is. Are you suggesting that the RelLookupTableConverter pass should be disabled on aarch64?

@dianqk
Copy link
Member

dianqk commented May 31, 2025

@MaskRay Rust is not generating this pattern, LLVM is. Are you suggesting that the RelLookupTableConverter pass should be disabled on aarch64?

Just a question: is it reasonable, like https://github.com/rust-lang/llvm-project/pull/181/files removes unnamed_addr in the RelLookupTableConverter pass? I don't see any problem with retaining unnamed_addr on IR.

@MaskRay
Copy link
Member

MaskRay commented May 31, 2025

I don't have a Rust development environment, but these components are likely involved:

  • Rust LLVM IR producer
  • llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp
  • llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:handleIndirectSymViaGOTPCRel This converts GOT-equivalent Constant uses to GOTPCREL style fixups.
  • llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp lowers GOTPCREL style fixups to relocations, where R_AARCH64_GOTPCREL32 is not supported by GNU ld or older LLD.

Implementing a workaround in LLVM's Transforms or CodeGen sections might seem appealing for broader IR producer support, but we generally aim to avoid adding linker compatibility checks...
I'm currently leaning towards Rust implementing the workaround within its IR producer...

@nikic
Copy link
Contributor

nikic commented May 31, 2025

@MaskRay Rust is not generating this pattern, LLVM is. Are you suggesting that the RelLookupTableConverter pass should be disabled on aarch64?

Just a question: is it reasonable, like https://github.com/rust-lang/llvm-project/pull/181/files removes unnamed_addr in the RelLookupTableConverter pass? I don't see any problem with retaining unnamed_addr on IR.

It looks like removing unnamed_addr avoids the use of the GOTPCREL relocations: https://llvm.godbolt.org/z/js9vx39ar

@nikic
Copy link
Contributor

nikic commented May 31, 2025

@MaskRay I don't think this can be worked around by changing the IR Rust produces. The IR that Rust generates is very boring. All the decisions that ultimately lead to the use of this unsupported relocation are made by LLVM, so this needs to be fixed in LLVM, either by not using this relocation at all, or by never producing IR that can lead to the use of this relocation. The former seems cleaner to me, but I'm ok with either variant.

@MaskRay
Copy link
Member

MaskRay commented May 31, 2025

Disabling RelLookupTableConverter.cpp looks good to me. It's a tradeoff between dynamic relocations/startup time and slightly more instructions at the single user.

@nikic
Copy link
Contributor

nikic commented May 31, 2025

Okay, in that case I think doing something along the lines of @dianqk's workaround in https://github.com/rust-lang/llvm-project/pull/181/files would be best. That allows RelLookupTableConverter to still generally work, but prevents it from generating GOTPCREL relocations.

dianqk added a commit that referenced this pull request Jun 1, 2025
…REL relocations (#142304)

Follow
#72584 (comment),
the patch will drop the `unnamed_addr` attribute when generating
relative lookup tables. I'm not very confident about this patch, but it
does resolve rust-lang/rust#140686,
rust-lang/rust#141306 and
rust-lang/rust#141737.

But I don't think this will result in worse problems.

> LLVM provides that the calculation of such a constant initializer will
not overflow at link time under the medium code model if x is an
unnamed_addr function. However, it does not provide this guarantee for a
constant initializer folded into a function body. This intrinsic can be
used to avoid the possibility of overflows when loading from such a
constant. ([‘llvm.load.relative’
Intrinsic](https://llvm.org/docs/LangRef.html#id2592))

This is my concern. I'm not sure how unnamed_addr provides this
guarantee, and I haven't found any test cases.
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Jun 1, 2025
…ating GOTPCREL relocations (#142304)

Follow
llvm/llvm-project#72584 (comment),
the patch will drop the `unnamed_addr` attribute when generating
relative lookup tables. I'm not very confident about this patch, but it
does resolve rust-lang/rust#140686,
rust-lang/rust#141306 and
rust-lang/rust#141737.

But I don't think this will result in worse problems.

> LLVM provides that the calculation of such a constant initializer will
not overflow at link time under the medium code model if x is an
unnamed_addr function. However, it does not provide this guarantee for a
constant initializer folded into a function body. This intrinsic can be
used to avoid the possibility of overflows when loading from such a
constant. ([‘llvm.load.relative’
Intrinsic](https://llvm.org/docs/LangRef.html#id2592))

This is my concern. I'm not sure how unnamed_addr provides this
guarantee, and I haven't found any test cases.
dianqk added a commit to dianqk/llvm-project that referenced this pull request Jun 1, 2025
…REL relocations (llvm#142304)

Follow
llvm#72584 (comment),
the patch will drop the `unnamed_addr` attribute when generating
relative lookup tables. I'm not very confident about this patch, but it
does resolve rust-lang/rust#140686,
rust-lang/rust#141306 and
rust-lang/rust#141737.

But I don't think this will result in worse problems.

> LLVM provides that the calculation of such a constant initializer will
not overflow at link time under the medium code model if x is an
unnamed_addr function. However, it does not provide this guarantee for a
constant initializer folded into a function body. This intrinsic can be
used to avoid the possibility of overflows when loading from such a
constant. ([‘llvm.load.relative’
Intrinsic](https://llvm.org/docs/LangRef.html#id2592))

This is my concern. I'm not sure how unnamed_addr provides this
guarantee, and I haven't found any test cases.

(cherry picked from commit aa09dbb)
swift-ci pushed a commit to swiftlang/llvm-project that referenced this pull request Jun 3, 2025
…REL relocations (llvm#142304)

Follow
llvm#72584 (comment),
the patch will drop the `unnamed_addr` attribute when generating
relative lookup tables. I'm not very confident about this patch, but it
does resolve rust-lang/rust#140686,
rust-lang/rust#141306 and
rust-lang/rust#141737.

But I don't think this will result in worse problems.

> LLVM provides that the calculation of such a constant initializer will
not overflow at link time under the medium code model if x is an
unnamed_addr function. However, it does not provide this guarantee for a
constant initializer folded into a function body. This intrinsic can be
used to avoid the possibility of overflows when loading from such a
constant. ([‘llvm.load.relative’
Intrinsic](https://llvm.org/docs/LangRef.html#id2592))

This is my concern. I'm not sure how unnamed_addr provides this
guarantee, and I haven't found any test cases.

(cherry picked from commit aa09dbb)
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Jun 3, 2025
…ating GOTPCREL relocations (#142304)

Follow
llvm/llvm-project#72584 (comment),
the patch will drop the `unnamed_addr` attribute when generating
relative lookup tables. I'm not very confident about this patch, but it
does resolve rust-lang/rust#140686,
rust-lang/rust#141306 and
rust-lang/rust#141737.

But I don't think this will result in worse problems.

> LLVM provides that the calculation of such a constant initializer will
not overflow at link time under the medium code model if x is an
unnamed_addr function. However, it does not provide this guarantee for a
constant initializer folded into a function body. This intrinsic can be
used to avoid the possibility of overflows when loading from such a
constant. ([‘llvm.load.relative’
Intrinsic](https://llvm.org/docs/LangRef.html#id2592))

This is my concern. I'm not sure how unnamed_addr provides this
guarantee, and I haven't found any test cases.

(cherry picked from commit aa09dbb)
DhruvSrivastavaX pushed a commit to DhruvSrivastavaX/lldb-for-aix that referenced this pull request Jun 12, 2025
…REL relocations (llvm#142304)

Follow
llvm#72584 (comment),
the patch will drop the `unnamed_addr` attribute when generating
relative lookup tables. I'm not very confident about this patch, but it
does resolve rust-lang/rust#140686,
rust-lang/rust#141306 and
rust-lang/rust#141737.

But I don't think this will result in worse problems.

> LLVM provides that the calculation of such a constant initializer will
not overflow at link time under the medium code model if x is an
unnamed_addr function. However, it does not provide this guarantee for a
constant initializer folded into a function body. This intrinsic can be
used to avoid the possibility of overflows when loading from such a
constant. ([‘llvm.load.relative’
Intrinsic](https://llvm.org/docs/LangRef.html#id2592))

This is my concern. I'm not sure how unnamed_addr provides this
guarantee, and I haven't found any test cases.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants