[llvm] [RelLookupTableConverter] Drop unnamed_addr to avoid generating GOTPCREL relocations (PR #142304)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 1 02:59:30 PDT 2025


https://github.com/dianqk updated https://github.com/llvm/llvm-project/pull/142304

>From ffa43434a1af50376e761ebcca69512fe2b822ab Mon Sep 17 00:00:00 2001
From: dianqk <dianqk at dianqk.net>
Date: Sun, 1 Jun 2025 15:44:01 +0800
Subject: [PATCH 1/2] Pre-commit test cases

---
 .../RelLookupTableConverter/unnamed_addr.ll   | 88 +++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll

diff --git a/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll b/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll
new file mode 100644
index 0000000000000..41941acb277bf
--- /dev/null
+++ b/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll
@@ -0,0 +1,88 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
+; RUN: opt < %s -passes=rel-lookup-table-converter -relocation-model=pic -mtriple=x86_64 -S | FileCheck -check-prefix=x86_64 %s
+; RUN: opt < %s -passes=rel-lookup-table-converter -relocation-model=pic -mtriple=aarch64 -S | FileCheck -check-prefix=aarch64 %s
+
+ at a0 = private unnamed_addr constant i32 0
+ at a1 = private unnamed_addr constant i32 1
+ at a2 = private unnamed_addr constant i32 2
+ at load_relative_1.table = private unnamed_addr constant [3 x ptr] [ptr @a0, ptr @a1, ptr @a2]
+
+ at x0 = internal unnamed_addr constant i64 0
+ at x1 = internal unnamed_addr constant i64 1
+ at x2 = internal unnamed_addr constant i64 2
+ at x3 = internal unnamed_addr constant i64 3
+ at y0 = internal unnamed_addr constant ptr @x3
+ at y1 = internal unnamed_addr constant ptr @x2
+ at y2 = internal unnamed_addr constant ptr @x1
+ at y3 = internal unnamed_addr constant ptr @x0
+ at load_relative_2.table = private unnamed_addr constant [4 x ptr] [ptr @y3, ptr @y2, ptr @y1, ptr @y0]
+
+;.
+; x86_64: @a0 = private unnamed_addr constant i32 0
+; x86_64: @a1 = private unnamed_addr constant i32 1
+; x86_64: @a2 = private unnamed_addr constant i32 2
+; x86_64: @load_relative_1.table.rel = private unnamed_addr constant [3 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @a0 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @a1 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @a2 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32)], align 4
+; x86_64: @x0 = internal unnamed_addr constant i64 0
+; x86_64: @x1 = internal unnamed_addr constant i64 1
+; x86_64: @x2 = internal unnamed_addr constant i64 2
+; x86_64: @x3 = internal unnamed_addr constant i64 3
+; x86_64: @y0 = internal unnamed_addr constant ptr @x3
+; x86_64: @y1 = internal unnamed_addr constant ptr @x2
+; x86_64: @y2 = internal unnamed_addr constant ptr @x1
+; x86_64: @y3 = internal unnamed_addr constant ptr @x0
+; x86_64: @load_relative_2.table.rel = private unnamed_addr constant [4 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @y3 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y2 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y1 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y0 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32)], align 4
+;.
+; aarch64: @a0 = private unnamed_addr constant i32 0
+; aarch64: @a1 = private unnamed_addr constant i32 1
+; aarch64: @a2 = private unnamed_addr constant i32 2
+; aarch64: @load_relative_1.table.rel = private unnamed_addr constant [3 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @a0 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @a1 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @a2 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32)], align 4
+; aarch64: @x0 = internal unnamed_addr constant i64 0
+; aarch64: @x1 = internal unnamed_addr constant i64 1
+; aarch64: @x2 = internal unnamed_addr constant i64 2
+; aarch64: @x3 = internal unnamed_addr constant i64 3
+; aarch64: @y0 = internal unnamed_addr constant ptr @x3
+; aarch64: @y1 = internal unnamed_addr constant ptr @x2
+; aarch64: @y2 = internal unnamed_addr constant ptr @x1
+; aarch64: @y3 = internal unnamed_addr constant ptr @x0
+; aarch64: @load_relative_2.table.rel = private unnamed_addr constant [4 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @y3 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y2 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y1 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y0 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32)], align 4
+;.
+define ptr @load_relative_1(i64 %offset) {
+; x86_64-LABEL: define ptr @load_relative_1(
+; x86_64-SAME: i64 [[OFFSET:%.*]]) {
+; x86_64-NEXT:    [[RELTABLE_SHIFT:%.*]] = shl i64 [[OFFSET]], 2
+; x86_64-NEXT:    [[RELTABLE_INTRINSIC:%.*]] = call ptr @llvm.load.relative.i64(ptr @load_relative_1.table.rel, i64 [[RELTABLE_SHIFT]])
+; x86_64-NEXT:    ret ptr [[RELTABLE_INTRINSIC]]
+;
+; aarch64-LABEL: define ptr @load_relative_1(
+; aarch64-SAME: i64 [[OFFSET:%.*]]) {
+; aarch64-NEXT:    [[RELTABLE_SHIFT:%.*]] = shl i64 [[OFFSET]], 2
+; aarch64-NEXT:    [[RELTABLE_INTRINSIC:%.*]] = call ptr @llvm.load.relative.i64(ptr @load_relative_1.table.rel, i64 [[RELTABLE_SHIFT]])
+; aarch64-NEXT:    ret ptr [[RELTABLE_INTRINSIC]]
+;
+  %gep = getelementptr inbounds [3 x ptr], ptr @load_relative_1.table, i64 0, i64 %offset
+  %load = load ptr, ptr %gep
+  ret ptr %load
+}
+
+define ptr @load_relative_2(i64 %offset) {
+; x86_64-LABEL: define ptr @load_relative_2(
+; x86_64-SAME: i64 [[OFFSET:%.*]]) {
+; x86_64-NEXT:    [[RELTABLE_SHIFT:%.*]] = shl i64 [[OFFSET]], 2
+; x86_64-NEXT:    [[RELTABLE_INTRINSIC:%.*]] = call ptr @llvm.load.relative.i64(ptr @load_relative_2.table.rel, i64 [[RELTABLE_SHIFT]])
+; x86_64-NEXT:    ret ptr [[RELTABLE_INTRINSIC]]
+;
+; aarch64-LABEL: define ptr @load_relative_2(
+; aarch64-SAME: i64 [[OFFSET:%.*]]) {
+; aarch64-NEXT:    [[RELTABLE_SHIFT:%.*]] = shl i64 [[OFFSET]], 2
+; aarch64-NEXT:    [[RELTABLE_INTRINSIC:%.*]] = call ptr @llvm.load.relative.i64(ptr @load_relative_2.table.rel, i64 [[RELTABLE_SHIFT]])
+; aarch64-NEXT:    ret ptr [[RELTABLE_INTRINSIC]]
+;
+  %gep = getelementptr inbounds [4 x ptr], ptr @load_relative_2.table, i64 0, i64 %offset
+  %load = load ptr, ptr %gep
+  ret ptr %load
+}
+;.
+; x86_64: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: read) }
+;.
+; aarch64: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: read) }
+;.

>From a1a209597d2b9ce6925a12cd6407e07906d735b9 Mon Sep 17 00:00:00 2001
From: dianqk <dianqk at dianqk.net>
Date: Sun, 1 Jun 2025 15:50:58 +0800
Subject: [PATCH 2/2] [RelLookupTableConverter] Drop unnamed_addr to avoid
 generating GOTPCREL relocations

---
 .../Utils/RelLookupTableConverter.cpp         |  5 ++++
 .../RelLookupTableConverter/unnamed_addr.ll   | 28 +++++++++----------
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp b/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp
index 2700b4307308c..88591fc11519a 100644
--- a/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp
+++ b/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp
@@ -110,6 +110,11 @@ static GlobalVariable *createRelLookupTable(Function &Func,
 
   for (Use &Operand : LookupTableArr->operands()) {
     Constant *Element = cast<Constant>(Operand);
+    // Drop unnamed_addr to avoid matching pattern in
+    // `handleIndirectSymViaGOTPCRel`, which generates GOTPCREL relocations not
+    // supported by the GNU linker and LLD versions below 18 on aarch64.
+    if (auto *GlobalElement = dyn_cast<GlobalValue>(Element))
+      GlobalElement->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
     Type *IntPtrTy = M.getDataLayout().getIntPtrType(M.getContext());
     Constant *Base = llvm::ConstantExpr::getPtrToInt(RelLookupTable, IntPtrTy);
     Constant *Target = llvm::ConstantExpr::getPtrToInt(Element, IntPtrTy);
diff --git a/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll b/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll
index 41941acb277bf..748d7522c1097 100644
--- a/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll
+++ b/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll
@@ -18,32 +18,32 @@
 @load_relative_2.table = private unnamed_addr constant [4 x ptr] [ptr @y3, ptr @y2, ptr @y1, ptr @y0]
 
 ;.
-; x86_64: @a0 = private unnamed_addr constant i32 0
-; x86_64: @a1 = private unnamed_addr constant i32 1
-; x86_64: @a2 = private unnamed_addr constant i32 2
+; x86_64: @a0 = private constant i32 0
+; x86_64: @a1 = private constant i32 1
+; x86_64: @a2 = private constant i32 2
 ; x86_64: @load_relative_1.table.rel = private unnamed_addr constant [3 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @a0 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @a1 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @a2 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32)], align 4
 ; x86_64: @x0 = internal unnamed_addr constant i64 0
 ; x86_64: @x1 = internal unnamed_addr constant i64 1
 ; x86_64: @x2 = internal unnamed_addr constant i64 2
 ; x86_64: @x3 = internal unnamed_addr constant i64 3
-; x86_64: @y0 = internal unnamed_addr constant ptr @x3
-; x86_64: @y1 = internal unnamed_addr constant ptr @x2
-; x86_64: @y2 = internal unnamed_addr constant ptr @x1
-; x86_64: @y3 = internal unnamed_addr constant ptr @x0
+; x86_64: @y0 = internal constant ptr @x3
+; x86_64: @y1 = internal constant ptr @x2
+; x86_64: @y2 = internal constant ptr @x1
+; x86_64: @y3 = internal constant ptr @x0
 ; x86_64: @load_relative_2.table.rel = private unnamed_addr constant [4 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @y3 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y2 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y1 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y0 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32)], align 4
 ;.
-; aarch64: @a0 = private unnamed_addr constant i32 0
-; aarch64: @a1 = private unnamed_addr constant i32 1
-; aarch64: @a2 = private unnamed_addr constant i32 2
+; aarch64: @a0 = private constant i32 0
+; aarch64: @a1 = private constant i32 1
+; aarch64: @a2 = private constant i32 2
 ; aarch64: @load_relative_1.table.rel = private unnamed_addr constant [3 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @a0 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @a1 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @a2 to i64), i64 ptrtoint (ptr @load_relative_1.table.rel to i64)) to i32)], align 4
 ; aarch64: @x0 = internal unnamed_addr constant i64 0
 ; aarch64: @x1 = internal unnamed_addr constant i64 1
 ; aarch64: @x2 = internal unnamed_addr constant i64 2
 ; aarch64: @x3 = internal unnamed_addr constant i64 3
-; aarch64: @y0 = internal unnamed_addr constant ptr @x3
-; aarch64: @y1 = internal unnamed_addr constant ptr @x2
-; aarch64: @y2 = internal unnamed_addr constant ptr @x1
-; aarch64: @y3 = internal unnamed_addr constant ptr @x0
+; aarch64: @y0 = internal constant ptr @x3
+; aarch64: @y1 = internal constant ptr @x2
+; aarch64: @y2 = internal constant ptr @x1
+; aarch64: @y3 = internal constant ptr @x0
 ; aarch64: @load_relative_2.table.rel = private unnamed_addr constant [4 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr @y3 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y2 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y1 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr @y0 to i64), i64 ptrtoint (ptr @load_relative_2.table.rel to i64)) to i32)], align 4
 ;.
 define ptr @load_relative_1(i64 %offset) {



More information about the llvm-commits mailing list