From 1b8176919d6dd379dfb26050ba909fd3a74679d5 Mon Sep 17 00:00:00 2001 From: dianqk Date: Fri, 27 Jun 2025 19:46:36 +0800 Subject: [PATCH 1/3] Pre-commit test cases --- .../RelLookupTableConverter/unnamed_addr.ll | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll b/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll index 78b8a4aa126c9..106b9b108bccc 100644 --- a/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll +++ b/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll @@ -20,6 +20,14 @@ @y3 = internal unnamed_addr constant ptr @x0 @load_relative_2.table = private unnamed_addr constant [4 x ptr] [ptr @y3, ptr @y2, ptr @y1, ptr @y0] +@b0 = private unnamed_addr constant [8 x i8] c"00000000" +@b1 = private unnamed_addr constant [8 x i8] c"11111111" +@b2 = private unnamed_addr constant [8 x i8] c"22222222" +@load_relative_3.table = private unnamed_addr constant [3 x ptr] [ + ptr getelementptr inbounds (i8, ptr @b0, i64 8), + ptr getelementptr inbounds (i8, ptr @b1, i64 8), + ptr getelementptr inbounds (i8, ptr @b2, i64 8)] + ;. ; x86_64-apple-darwin: @a0 = private constant i32 0 ; x86_64-apple-darwin: @a1 = private constant i32 1 @@ -34,6 +42,10 @@ ; x86_64-apple-darwin: @y2 = internal constant ptr @x1 ; x86_64-apple-darwin: @y3 = internal constant ptr @x0 ; 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 +; x86_64-apple-darwin: @b0 = private unnamed_addr constant [8 x i8] c"00000000" +; x86_64-apple-darwin: @b1 = private unnamed_addr constant [8 x i8] c"11111111" +; x86_64-apple-darwin: @b2 = private unnamed_addr constant [8 x i8] c"22222222" +; 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 ;. ; aarch64: @a0 = private constant i32 0 ; aarch64: @a1 = private constant i32 1 @@ -48,6 +60,10 @@ ; 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 +; aarch64: @b0 = private unnamed_addr constant [8 x i8] c"00000000" +; aarch64: @b1 = private unnamed_addr constant [8 x i8] c"11111111" +; aarch64: @b2 = private unnamed_addr constant [8 x i8] c"22222222" +; 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 ;. ; x86_64: @a0 = private unnamed_addr constant i32 0 ; x86_64: @a1 = private unnamed_addr constant i32 1 @@ -62,6 +78,10 @@ ; 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 +; x86_64: @b0 = private unnamed_addr constant [8 x i8] c"00000000" +; x86_64: @b1 = private unnamed_addr constant [8 x i8] c"11111111" +; x86_64: @b2 = private unnamed_addr constant [8 x i8] c"22222222" +; 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 ;. define ptr @load_relative_1(i64 %offset) { ; x86_64-apple-darwin-LABEL: define ptr @load_relative_1( @@ -110,6 +130,31 @@ define ptr @load_relative_2(i64 %offset) { %load = load ptr, ptr %gep ret ptr %load } + +define ptr @load_relative_3(i64 %offset) { +; x86_64-apple-darwin-LABEL: define ptr @load_relative_3( +; x86_64-apple-darwin-SAME: i64 [[OFFSET:%.*]]) { +; x86_64-apple-darwin-NEXT: [[RELTABLE_SHIFT:%.*]] = shl i64 [[OFFSET]], 2 +; x86_64-apple-darwin-NEXT: [[RELTABLE_INTRINSIC:%.*]] = call ptr @llvm.load.relative.i64(ptr @load_relative_3.table.rel, i64 [[RELTABLE_SHIFT]]) +; x86_64-apple-darwin-NEXT: ret ptr [[RELTABLE_INTRINSIC]] +; +; aarch64-LABEL: define ptr @load_relative_3( +; 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_3.table.rel, i64 [[RELTABLE_SHIFT]]) +; aarch64-NEXT: ret ptr [[RELTABLE_INTRINSIC]] +; +; x86_64-LABEL: define ptr @load_relative_3( +; 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_3.table.rel, i64 [[RELTABLE_SHIFT]]) +; x86_64-NEXT: ret ptr [[RELTABLE_INTRINSIC]] +; + %gep = getelementptr inbounds [3 x ptr], ptr @load_relative_3.table, i64 0, i64 %offset + %load = load ptr, ptr %gep + ret ptr %load +} + ;. ; x86_64-apple-darwin: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: read) } ;. From cdb91fff5c097f7a3d58103fbe7d7954512e0e99 Mon Sep 17 00:00:00 2001 From: dianqk Date: Fri, 27 Jun 2025 20:34:52 +0800 Subject: [PATCH 2/3] [RelLookupTableConverter] Drop unnamed_addr for GVs in operands to avoid generating GOTPCREL relocations --- .../Utils/RelLookupTableConverter.cpp | 44 +++++++++++-------- .../RelLookupTableConverter/unnamed_addr.ll | 12 ++--- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp b/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp index af0f516f7b002..e38c657e8a32c 100644 --- a/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp +++ b/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp @@ -21,7 +21,10 @@ using namespace llvm; -static bool shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV) { +static bool +shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV, + SmallVectorImpl &GVOps, + bool ShouldDropUnnamedAddr) { // If lookup table has more than one user, // do not generate a relative lookup table. // 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) { !GlovalVarOp->isDSOLocal() || !GlovalVarOp->isImplicitDSOLocal()) return false; + + if (ShouldDropUnnamedAddr) + GVOps.push_back(GlovalVarOp); } return true; @@ -108,24 +114,8 @@ static GlobalVariable *createRelLookupTable(Function &Func, uint64_t Idx = 0; SmallVector RelLookupTableContents(NumElts); - Triple TT = M.getTargetTriple(); - // FIXME: This should be removed in the future. - bool ShouldDropUnnamedAddr = - // 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. - TT.isAArch64() - // Apple's ld64 (and ld-prime on Xcode 15.2) miscompile something on - // x86_64-apple-darwin. See - // https://github.com/rust-lang/rust/issues/140686 and - // https://github.com/rust-lang/rust/issues/141306. - || (TT.isX86() && TT.isOSDarwin()); - for (Use &Operand : LookupTableArr->operands()) { Constant *Element = cast(Operand); - if (ShouldDropUnnamedAddr) - if (auto *GlobalElement = dyn_cast(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); @@ -199,10 +189,28 @@ static bool convertToRelativeLookupTables( bool Changed = false; + Triple TT = M.getTargetTriple(); + // FIXME: This should be removed in the future. + bool ShouldDropUnnamedAddr = + // 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. + TT.isAArch64() + // Apple's ld64 (and ld-prime on Xcode 15.2) miscompile something on + // x86_64-apple-darwin. See + // https://github.com/rust-lang/rust/issues/140686 and + // https://github.com/rust-lang/rust/issues/141306. + || (TT.isX86() && TT.isOSDarwin()); for (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) { - if (!shouldConvertToRelLookupTable(M, GV)) + SmallVector GVOps; + + if (!shouldConvertToRelLookupTable(M, GV, GVOps, ShouldDropUnnamedAddr)) continue; + if (ShouldDropUnnamedAddr) + for (auto *GVOp : GVOps) + GVOp->setUnnamedAddr(GlobalValue::UnnamedAddr::None); + convertToRelLookupTable(GV); // Remove the original lookup table. diff --git a/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll b/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll index 106b9b108bccc..322c38d090fe1 100644 --- a/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll +++ b/llvm/test/Transforms/RelLookupTableConverter/unnamed_addr.ll @@ -42,9 +42,9 @@ ; x86_64-apple-darwin: @y2 = internal constant ptr @x1 ; x86_64-apple-darwin: @y3 = internal constant ptr @x0 ; 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 -; x86_64-apple-darwin: @b0 = private unnamed_addr constant [8 x i8] c"00000000" -; x86_64-apple-darwin: @b1 = private unnamed_addr constant [8 x i8] c"11111111" -; x86_64-apple-darwin: @b2 = private unnamed_addr constant [8 x i8] c"22222222" +; x86_64-apple-darwin: @b0 = private constant [8 x i8] c"00000000" +; x86_64-apple-darwin: @b1 = private constant [8 x i8] c"11111111" +; x86_64-apple-darwin: @b2 = private constant [8 x i8] c"22222222" ; 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 ;. ; aarch64: @a0 = private constant i32 0 @@ -60,9 +60,9 @@ ; 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 -; aarch64: @b0 = private unnamed_addr constant [8 x i8] c"00000000" -; aarch64: @b1 = private unnamed_addr constant [8 x i8] c"11111111" -; aarch64: @b2 = private unnamed_addr constant [8 x i8] c"22222222" +; aarch64: @b0 = private constant [8 x i8] c"00000000" +; aarch64: @b1 = private constant [8 x i8] c"11111111" +; aarch64: @b2 = private constant [8 x i8] c"22222222" ; 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 ;. ; x86_64: @a0 = private unnamed_addr constant i32 0 From 9920aab95d11a85bda2cd54ada3da27a900b1210 Mon Sep 17 00:00:00 2001 From: dianqk Date: Fri, 27 Jun 2025 20:39:59 +0800 Subject: [PATCH 3/3] [RelLookupTableConverter] Drop unnamed_addr for GVs in operands to avoid generating GOTPCREL relocations (Style 2) --- .../Utils/RelLookupTableConverter.cpp | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp b/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp index e38c657e8a32c..d53a3144bf57d 100644 --- a/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp +++ b/llvm/lib/Transforms/Utils/RelLookupTableConverter.cpp @@ -21,10 +21,7 @@ using namespace llvm; -static bool -shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV, - SmallVectorImpl &GVOps, - bool ShouldDropUnnamedAddr) { +static bool shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV) { // If lookup table has more than one user, // do not generate a relative lookup table. // This is to simplify the analysis that needs to be done for this pass. @@ -69,6 +66,20 @@ shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV, if (!ElemType->isPointerTy() || DL.getPointerTypeSizeInBits(ElemType) != 64) return false; + SmallVector GVOps; + Triple TT = M.getTargetTriple(); + // FIXME: This should be removed in the future. + bool ShouldDropUnnamedAddr = + // 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. + TT.isAArch64() + // Apple's ld64 (and ld-prime on Xcode 15.2) miscompile something on + // x86_64-apple-darwin. See + // https://github.com/rust-lang/rust/issues/140686 and + // https://github.com/rust-lang/rust/issues/141306. + || (TT.isX86() && TT.isOSDarwin()); + for (const Use &Op : Array->operands()) { Constant *ConstOp = cast(&Op); GlobalValue *GVOp; @@ -93,6 +104,10 @@ shouldConvertToRelLookupTable(Module &M, GlobalVariable &GV, GVOps.push_back(GlovalVarOp); } + if (ShouldDropUnnamedAddr) + for (auto *GVOp : GVOps) + GVOp->setUnnamedAddr(GlobalValue::UnnamedAddr::None); + return true; } @@ -189,28 +204,10 @@ static bool convertToRelativeLookupTables( bool Changed = false; - Triple TT = M.getTargetTriple(); - // FIXME: This should be removed in the future. - bool ShouldDropUnnamedAddr = - // 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. - TT.isAArch64() - // Apple's ld64 (and ld-prime on Xcode 15.2) miscompile something on - // x86_64-apple-darwin. See - // https://github.com/rust-lang/rust/issues/140686 and - // https://github.com/rust-lang/rust/issues/141306. - || (TT.isX86() && TT.isOSDarwin()); for (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) { - SmallVector GVOps; - - if (!shouldConvertToRelLookupTable(M, GV, GVOps, ShouldDropUnnamedAddr)) + if (!shouldConvertToRelLookupTable(M, GV)) continue; - if (ShouldDropUnnamedAddr) - for (auto *GVOp : GVOps) - GVOp->setUnnamedAddr(GlobalValue::UnnamedAddr::None); - convertToRelLookupTable(GV); // Remove the original lookup table.