Skip to content

Commit cdb91ff

Browse files
committed
[RelLookupTableConverter] Drop unnamed_addr for GVs in operands to avoid generating GOTPCREL relocations
1 parent 1b81769 commit cdb91ff

File tree

2 files changed

+32
-24
lines changed

2 files changed

+32
-24
lines changed

llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121

2222
using namespace llvm;
2323

24-
static bool shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV) {
24+
static bool
25+
shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV,
26+
SmallVectorImpl<GlobalVariable *> &GVOps,
27+
bool ShouldDropUnnamedAddr) {
2528
// If lookup table has more than one user,
2629
// do not generate a relative lookup table.
2730
// This is to simplify the analysis that needs to be done for this pass.
@@ -85,6 +88,9 @@ static bool shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV) {
8588
!GlovalVarOp->isDSOLocal() ||
8689
!GlovalVarOp->isImplicitDSOLocal())
8790
return false;
91+
92+
if (ShouldDropUnnamedAddr)
93+
GVOps.push_back(GlovalVarOp);
8894
}
8995

9096
return true;
@@ -108,24 +114,8 @@ static GlobalVariable *createRelLookupTable(Function &Func,
108114
uint64_t Idx = 0;
109115
SmallVector<Constant *, 64> RelLookupTableContents(NumElts);
110116

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-
124117
for (Use &Operand : LookupTableArr->operands()) {
125118
Constant *Element = cast<Constant>(Operand);
126-
if (ShouldDropUnnamedAddr)
127-
if (auto *GlobalElement = dyn_cast<GlobalValue>(Element))
128-
GlobalElement->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
129119
Type *IntPtrTy = M.getDataLayout().getIntPtrType(M.getContext());
130120
Constant *Base = llvm::ConstantExpr::getPtrToInt(RelLookupTable, IntPtrTy);
131121
Constant *Target = llvm::ConstantExpr::getPtrToInt(Element, IntPtrTy);
@@ -199,10 +189,28 @@ static bool convertToRelativeLookupTables(
199189

200190
bool Changed = false;
201191

192+
Triple TT = M.getTargetTriple();
193+
// FIXME: This should be removed in the future.
194+
bool ShouldDropUnnamedAddr =
195+
// Drop unnamed_addr to avoid matching pattern in
196+
// `handleIndirectSymViaGOTPCRel`, which generates GOTPCREL relocations
197+
// not supported by the GNU linker and LLD versions below 18 on aarch64.
198+
TT.isAArch64()
199+
// Apple's ld64 (and ld-prime on Xcode 15.2) miscompile something on
200+
// x86_64-apple-darwin. See
201+
// https://github.com/rust-lang/rust/issues/140686 and
202+
// https://github.com/rust-lang/rust/issues/141306.
203+
|| (TT.isX86() && TT.isOSDarwin());
202204
for (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) {
203-
if (!shouldConvertToRelLookupTable(M, GV))
205+
SmallVector<GlobalVariable *, 4> GVOps;
206+
207+
if (!shouldConvertToRelLookupTable(M, GV, GVOps, ShouldDropUnnamedAddr))
204208
continue;
205209

210+
if (ShouldDropUnnamedAddr)
211+
for (auto *GVOp : GVOps)
212+
GVOp->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
213+
206214
convertToRelLookupTable(GV);
207215

208216
// Remove the original lookup table.

llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@
4242
; x86_64-apple-darwin: @y2 = internal constant ptr @x1
4343
; x86_64-apple-darwin: @y3 = internal constant ptr @x0
4444
; 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 unnamed_addr constant [8 x i8] c"00000000"
46-
; x86_64-apple-darwin: @b1 = private unnamed_addr constant [8 x i8] c"11111111"
47-
; x86_64-apple-darwin: @b2 = private unnamed_addr constant [8 x i8] c"22222222"
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"
4848
; 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
4949
;.
5050
; aarch64: @a0 = private constant i32 0
@@ -60,9 +60,9 @@
6060
; aarch64: @y2 = internal constant ptr @x1
6161
; aarch64: @y3 = internal constant ptr @x0
6262
; 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 unnamed_addr constant [8 x i8] c"00000000"
64-
; aarch64: @b1 = private unnamed_addr constant [8 x i8] c"11111111"
65-
; aarch64: @b2 = private unnamed_addr constant [8 x i8] c"22222222"
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"
6666
; 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
6767
;.
6868
; x86_64: @a0 = private unnamed_addr constant i32 0

0 commit comments

Comments
 (0)