Skip to content

Commit c43282a

Browse files
authored
[RelLookupTableConverter] Drop unnamed_addr for GVs in entries to avoid generating GOTPCREL relocations (#146068)
The entry in a relative lookup table is a global variable with a constant offset, such as `@gv`, `GEP @gv, 1`, and so on. We cannot only consider the case of a trivial global variable. This PR handles all cases using the existing `IsConstantOffsetFromGlobal` function.
1 parent 75175e7 commit c43282a

File tree

2 files changed

+66
-16
lines changed

2 files changed

+66
-16
lines changed

llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,20 @@ static bool shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV) {
6666
if (!ElemType->isPointerTy() || DL.getPointerTypeSizeInBits(ElemType) != 64)
6767
return false;
6868

69+
SmallVector<GlobalVariable *, 4> GVOps;
70+
Triple TT = M.getTargetTriple();
71+
// FIXME: This should be removed in the future.
72+
bool ShouldDropUnnamedAddr =
73+
// Drop unnamed_addr to avoid matching pattern in
74+
// `handleIndirectSymViaGOTPCRel`, which generates GOTPCREL relocations
75+
// not supported by the GNU linker and LLD versions below 18 on aarch64.
76+
TT.isAArch64()
77+
// Apple's ld64 (and ld-prime on Xcode 15.2) miscompile something on
78+
// x86_64-apple-darwin. See
79+
// https://github.com/rust-lang/rust/issues/140686 and
80+
// https://github.com/rust-lang/rust/issues/141306.
81+
|| (TT.isX86() && TT.isOSDarwin());
82+
6983
for (const Use &Op : Array->operands()) {
7084
Constant *ConstOp = cast<Constant>(&Op);
7185
GlobalValue *GVOp;
@@ -85,8 +99,15 @@ static bool shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV) {
8599
!GlovalVarOp->isDSOLocal() ||
86100
!GlovalVarOp->isImplicitDSOLocal())
87101
return false;
102+
103+
if (ShouldDropUnnamedAddr)
104+
GVOps.push_back(GlovalVarOp);
88105
}
89106

107+
if (ShouldDropUnnamedAddr)
108+
for (auto *GVOp : GVOps)
109+
GVOp->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
110+
90111
return true;
91112
}
92113

@@ -108,24 +129,8 @@ static GlobalVariable *createRelLookupTable(Function &Func,
108129
uint64_t Idx = 0;
109130
SmallVector<Constant *, 64> RelLookupTableContents(NumElts);
110131

111-
Triple TT = M.getTargetTriple();
112-
// FIXME: This should be removed in the future.
113-
bool ShouldDropUnnamedAddr =
114-
// Drop unnamed_addr to avoid matching pattern in
115-
// `handleIndirectSymViaGOTPCRel`, which generates GOTPCREL relocations
116-
// not supported by the GNU linker and LLD versions below 18 on aarch64.
117-
TT.isAArch64()
118-
// Apple's ld64 (and ld-prime on Xcode 15.2) miscompile something on
119-
// x86_64-apple-darwin. See
120-
// https://github.com/rust-lang/rust/issues/140686 and
121-
// https://github.com/rust-lang/rust/issues/141306.
122-
|| (TT.isX86() && TT.isOSDarwin());
123-
124132
for (Use &Operand : LookupTableArr->operands()) {
125133
Constant *Element = cast<Constant>(Operand);
126-
if (ShouldDropUnnamedAddr)
127-
if (auto *GlobalElement = dyn_cast<GlobalValue>(Element))
128-
GlobalElement->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
129134
Type *IntPtrTy = M.getDataLayout().getIntPtrType(M.getContext());
130135
Constant *Base = llvm::ConstantExpr::getPtrToInt(RelLookupTable, IntPtrTy);
131136
Constant *Target = llvm::ConstantExpr::getPtrToInt(Element, IntPtrTy);

llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
@y3 = internal unnamed_addr constant ptr @x0
2121
@load_relative_2.table = private unnamed_addr constant [4 x ptr] [ptr @y3, ptr @y2, ptr @y1, ptr @y0]
2222

23+
@b0 = private unnamed_addr constant [8 x i8] c"00000000"
24+
@b1 = private unnamed_addr constant [8 x i8] c"11111111"
25+
@b2 = private unnamed_addr constant [8 x i8] c"22222222"
26+
@load_relative_3.table = private unnamed_addr constant [3 x ptr] [
27+
ptr getelementptr inbounds (i8, ptr @b0, i64 8),
28+
ptr getelementptr inbounds (i8, ptr @b1, i64 8),
29+
ptr getelementptr inbounds (i8, ptr @b2, i64 8)]
30+
2331
;.
2432
; x86_64-apple-darwin: @a0 = private constant i32 0
2533
; x86_64-apple-darwin: @a1 = private constant i32 1
@@ -34,6 +42,10 @@
3442
; x86_64-apple-darwin: @y2 = internal constant ptr @x1
3543
; x86_64-apple-darwin: @y3 = internal constant ptr @x0
3644
; x86_64-apple-darwin: @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
45+
; x86_64-apple-darwin: @b0 = private constant [8 x i8] c"00000000"
46+
; x86_64-apple-darwin: @b1 = private constant [8 x i8] c"11111111"
47+
; x86_64-apple-darwin: @b2 = private constant [8 x i8] c"22222222"
48+
; x86_64-apple-darwin: @load_relative_3.table.rel = private unnamed_addr constant [3 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @b0, i64 8) to i64), i64 ptrtoint (ptr @load_relative_3.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @b1, i64 8) to i64), i64 ptrtoint (ptr @load_relative_3.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @b2, i64 8) to i64), i64 ptrtoint (ptr @load_relative_3.table.rel to i64)) to i32)], align 4
3749
;.
3850
; aarch64: @a0 = private constant i32 0
3951
; aarch64: @a1 = private constant i32 1
@@ -48,6 +60,10 @@
4860
; aarch64: @y2 = internal constant ptr @x1
4961
; aarch64: @y3 = internal constant ptr @x0
5062
; 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
63+
; aarch64: @b0 = private constant [8 x i8] c"00000000"
64+
; aarch64: @b1 = private constant [8 x i8] c"11111111"
65+
; aarch64: @b2 = private constant [8 x i8] c"22222222"
66+
; aarch64: @load_relative_3.table.rel = private unnamed_addr constant [3 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @b0, i64 8) to i64), i64 ptrtoint (ptr @load_relative_3.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @b1, i64 8) to i64), i64 ptrtoint (ptr @load_relative_3.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @b2, i64 8) to i64), i64 ptrtoint (ptr @load_relative_3.table.rel to i64)) to i32)], align 4
5167
;.
5268
; x86_64: @a0 = private unnamed_addr constant i32 0
5369
; x86_64: @a1 = private unnamed_addr constant i32 1
@@ -62,6 +78,10 @@
6278
; x86_64: @y2 = internal unnamed_addr constant ptr @x1
6379
; x86_64: @y3 = internal unnamed_addr constant ptr @x0
6480
; 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
81+
; x86_64: @b0 = private unnamed_addr constant [8 x i8] c"00000000"
82+
; x86_64: @b1 = private unnamed_addr constant [8 x i8] c"11111111"
83+
; x86_64: @b2 = private unnamed_addr constant [8 x i8] c"22222222"
84+
; x86_64: @load_relative_3.table.rel = private unnamed_addr constant [3 x i32] [i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @b0, i64 8) to i64), i64 ptrtoint (ptr @load_relative_3.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @b1, i64 8) to i64), i64 ptrtoint (ptr @load_relative_3.table.rel to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr getelementptr inbounds (i8, ptr @b2, i64 8) to i64), i64 ptrtoint (ptr @load_relative_3.table.rel to i64)) to i32)], align 4
6585
;.
6686
define ptr @load_relative_1(i64 %offset) {
6787
; x86_64-apple-darwin-LABEL: define ptr @load_relative_1(
@@ -110,6 +130,31 @@ define ptr @load_relative_2(i64 %offset) {
110130
%load = load ptr, ptr %gep
111131
ret ptr %load
112132
}
133+
134+
define ptr @load_relative_3(i64 %offset) {
135+
; x86_64-apple-darwin-LABEL: define ptr @load_relative_3(
136+
; x86_64-apple-darwin-SAME: i64 [[OFFSET:%.*]]) {
137+
; x86_64-apple-darwin-NEXT: [[RELTABLE_SHIFT:%.*]] = shl i64 [[OFFSET]], 2
138+
; x86_64-apple-darwin-NEXT: [[RELTABLE_INTRINSIC:%.*]] = call ptr @llvm.load.relative.i64(ptr @load_relative_3.table.rel, i64 [[RELTABLE_SHIFT]])
139+
; x86_64-apple-darwin-NEXT: ret ptr [[RELTABLE_INTRINSIC]]
140+
;
141+
; aarch64-LABEL: define ptr @load_relative_3(
142+
; aarch64-SAME: i64 [[OFFSET:%.*]]) {
143+
; aarch64-NEXT: [[RELTABLE_SHIFT:%.*]] = shl i64 [[OFFSET]], 2
144+
; aarch64-NEXT: [[RELTABLE_INTRINSIC:%.*]] = call ptr @llvm.load.relative.i64(ptr @load_relative_3.table.rel, i64 [[RELTABLE_SHIFT]])
145+
; aarch64-NEXT: ret ptr [[RELTABLE_INTRINSIC]]
146+
;
147+
; x86_64-LABEL: define ptr @load_relative_3(
148+
; x86_64-SAME: i64 [[OFFSET:%.*]]) {
149+
; x86_64-NEXT: [[RELTABLE_SHIFT:%.*]] = shl i64 [[OFFSET]], 2
150+
; x86_64-NEXT: [[RELTABLE_INTRINSIC:%.*]] = call ptr @llvm.load.relative.i64(ptr @load_relative_3.table.rel, i64 [[RELTABLE_SHIFT]])
151+
; x86_64-NEXT: ret ptr [[RELTABLE_INTRINSIC]]
152+
;
153+
%gep = getelementptr inbounds [3 x ptr], ptr @load_relative_3.table, i64 0, i64 %offset
154+
%load = load ptr, ptr %gep
155+
ret ptr %load
156+
}
157+
113158
;.
114159
; x86_64-apple-darwin: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: read) }
115160
;.

0 commit comments

Comments
 (0)