https://github.com/mtrofin updated https://github.com/llvm/llvm-project/pull/203171
>From 59609f00c1db40b5d665d18eb473112f012429e9 Mon Sep 17 00:00:00 2001 From: Mircea Trofin <[email protected]> Date: Wed, 10 Jun 2026 15:30:18 -0700 Subject: [PATCH] cfi creates alias --- .../llvm/Transforms/Coroutines/CoroInstr.h | 12 +++-- llvm/lib/IR/Verifier.cpp | 2 +- .../lib/Transforms/Coroutines/CoroCleanup.cpp | 6 ++- llvm/lib/Transforms/Coroutines/Coroutines.cpp | 9 ++-- llvm/lib/Transforms/IPO/LowerTypeTests.cpp | 16 ++++++ .../Transforms/IPO/ThinLTOBitcodeWriter.cpp | 53 +++++++------------ .../lib/Transforms/IPO/WholeProgramDevirt.cpp | 25 +++++++-- .../ThinLTO/X86/devirt_function_alias2.ll | 10 ++-- .../Transforms/Coroutines/coro-id-alias.ll | 13 +++++ .../cfi-icall-static-inline-asm.ll | 4 +- .../Transforms/ThinLTOBitcodeWriter/comdat.ll | 17 +++--- .../ThinLTOBitcodeWriter/split-internal1.ll | 3 +- .../ThinLTOBitcodeWriter/split-internal2.ll | 5 +- .../split-vfunc-internal.ll | 6 ++- 14 files changed, 114 insertions(+), 67 deletions(-) create mode 100644 llvm/test/Transforms/Coroutines/coro-id-alias.ll diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h b/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h index cfdf831709adc..71632a46dcde1 100644 --- a/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h +++ b/llvm/include/llvm/Transforms/Coroutines/CoroInstr.h @@ -215,7 +215,8 @@ class CoroIdInst : public AnyCoroIdInst { void setInfo(Constant *C) { setArgOperand(InfoArg, C); } Function *getCoroutine() const { - return cast<Function>(getArgOperand(CoroutineArg)->stripPointerCasts()); + return cast<Function>( + getArgOperand(CoroutineArg)->stripPointerCastsAndAliases()); } void setCoroutineSelf() { if (!isa<ConstantPointerNull>(getArgOperand(CoroutineArg))) @@ -254,17 +255,20 @@ class AnyCoroIdRetconInst : public AnyCoroIdInst { /// attributes, and calling convention of the continuation function(s) /// are taken from this declaration. Function *getPrototype() const { - return cast<Function>(getArgOperand(PrototypeArg)->stripPointerCasts()); + return cast<Function>( + getArgOperand(PrototypeArg)->stripPointerCastsAndAliases()); } /// Return the function to use for allocating memory. Function *getAllocFunction() const { - return cast<Function>(getArgOperand(AllocArg)->stripPointerCasts()); + return cast<Function>( + getArgOperand(AllocArg)->stripPointerCastsAndAliases()); } /// Return the function to use for deallocating memory. Function *getDeallocFunction() const { - return cast<Function>(getArgOperand(DeallocArg)->stripPointerCasts()); + return cast<Function>( + getArgOperand(DeallocArg)->stripPointerCastsAndAliases()); } // Methods to support type inquiry through isa, cast, and dyn_cast: diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index e247582bb57ea..f542a5e82c6fd 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -6276,7 +6276,7 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { Check(isa<ConstantPointerNull>(Promise) || isa<AllocaInst>(Promise), "promise argument must refer to an alloca"); - auto *CoroAddr = Call.getArgOperand(2)->stripPointerCasts(); + auto *CoroAddr = Call.getArgOperand(2)->stripPointerCastsAndAliases(); bool BeforeCoroEarly = isa<ConstantPointerNull>(CoroAddr); Check(BeforeCoroEarly || isa<Function>(CoroAddr), "coro argument must refer to a function"); diff --git a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp index 1078fbffb13e3..fc8a6277893a3 100644 --- a/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroCleanup.cpp @@ -140,10 +140,12 @@ bool Lowerer::lower(Function &F) { break; case Intrinsic::coro_async_size_replace: auto *Target = cast<ConstantStruct>( - cast<GlobalVariable>(II->getArgOperand(0)->stripPointerCasts()) + cast<GlobalVariable>( + II->getArgOperand(0)->stripPointerCastsAndAliases()) ->getInitializer()); auto *Source = cast<ConstantStruct>( - cast<GlobalVariable>(II->getArgOperand(1)->stripPointerCasts()) + cast<GlobalVariable>( + II->getArgOperand(1)->stripPointerCastsAndAliases()) ->getInitializer()); auto *TargetSize = Target->getOperand(1); auto *SourceSize = Source->getOperand(1); diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp index 9e798ccbaacee..a922099a1f43f 100644 --- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp +++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp @@ -555,7 +555,7 @@ void coro::Shape::emitDealloc(IRBuilder<> &Builder, Value *Ptr, /// Check that the given value is a well-formed prototype for the /// llvm.coro.id.retcon.* intrinsics. static void checkWFRetconPrototype(const AnyCoroIdRetconInst *I, Value *V) { - auto F = dyn_cast<Function>(V->stripPointerCasts()); + auto F = dyn_cast<Function>(V->stripPointerCastsAndAliases()); if (!F) fail(I, "llvm.coro.id.retcon.* prototype not a Function", V); @@ -591,7 +591,7 @@ static void checkWFRetconPrototype(const AnyCoroIdRetconInst *I, Value *V) { /// Check that the given value is a well-formed allocator. static void checkWFAlloc(const Instruction *I, Value *V) { - auto F = dyn_cast<Function>(V->stripPointerCasts()); + auto F = dyn_cast<Function>(V->stripPointerCastsAndAliases()); if (!F) fail(I, "llvm.coro.* allocator not a Function", V); @@ -606,7 +606,7 @@ static void checkWFAlloc(const Instruction *I, Value *V) { /// Check that the given value is a well-formed deallocator. static void checkWFDealloc(const Instruction *I, Value *V) { - auto F = dyn_cast<Function>(V->stripPointerCasts()); + auto F = dyn_cast<Function>(V->stripPointerCastsAndAliases()); if (!F) fail(I, "llvm.coro.* deallocator not a Function", V); @@ -637,7 +637,8 @@ void AnyCoroIdRetconInst::checkWellFormed() const { } static void checkAsyncFuncPointer(const Instruction *I, Value *V) { - auto *AsyncFuncPtrAddr = dyn_cast<GlobalVariable>(V->stripPointerCasts()); + auto *AsyncFuncPtrAddr = + dyn_cast<GlobalVariable>(V->stripPointerCastsAndAliases()); if (!AsyncFuncPtrAddr) fail(I, "llvm.coro.id.async async function pointer not a global", V); } diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp index 7c045c90ead5b..d399b6f9d1090 100644 --- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp +++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp @@ -2138,6 +2138,22 @@ bool LowerTypeTestsModule::lower() { report_fatal_error( "unexpected call to llvm.icall.branch.funnel during import phase"); + for (auto &A : llvm::make_early_inc_range(M.aliases())) { + if (A.hasLocalLinkage()) + continue; + if (ImportSummary->cfiFunctionDefs().contains(A.getName()) || + ImportSummary->cfiFunctionDecls().contains(A.getName())) { + if (auto *F = dyn_cast<Function>(A.getAliasee()->stripPointerCasts())) { + A.replaceAllUsesWith(F); + std::string Name = std::string(A.getName()); + A.eraseFromParent(); + F->setName(Name); + F->setLinkage(GlobalValue::ExternalLinkage); + F->setVisibility(GlobalValue::HiddenVisibility); + } + } + } + SmallVector<Function *, 8> Defs; SmallVector<Function *, 8> Decls; for (auto &F : M) { diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp index 40200a6554249..1f4dff0aae472 100644 --- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp +++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp @@ -30,23 +30,10 @@ using namespace llvm; namespace { -// Determine if a promotion alias should be created for a symbol name. -static bool allowPromotionAlias(const std::string &Name) { - // Promotion aliases are used only in inline assembly. It's safe to - // simply skip unusual names. Subset of MCAsmInfo::isAcceptableChar() - // and MCAsmInfoXCOFF::isAcceptableChar(). - for (const char &C : Name) { - if (isAlnum(C) || C == '_' || C == '.') - continue; - return false; - } - return true; -} - // Promote each local-linkage entity defined by ExportM and used by ImportM by // changing visibility and appending the given ModuleId. void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId, - const SetVector<GlobalValue *> &PromoteExtra) { + SetVector<GlobalValue *> *PromoteExtra = nullptr) { DenseMap<const Comdat *, Comdat *> RenamedComdats; for (auto &ExportGV : ExportM.global_values()) { if (!ExportGV.hasLocalLinkage()) @@ -54,7 +41,8 @@ void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId, auto Name = ExportGV.getName(); GlobalValue *ImportGV = nullptr; - if (!PromoteExtra.count(&ExportGV)) { + const bool MustPromote = PromoteExtra && PromoteExtra->count(&ExportGV); + if (!MustPromote) { ImportGV = ImportM.getNamedValue(Name); if (!ImportGV) continue; @@ -72,24 +60,24 @@ void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId, if (C->getName() == Name) RenamedComdats.try_emplace(C, ExportM.getOrInsertComdat(NewName)); - ExportGV.setName(NewName); - ExportGV.setLinkage(GlobalValue::ExternalLinkage); - ExportGV.setVisibility(GlobalValue::HiddenVisibility); - // TODO: remove this reassign and instead create an alias. - ExportGV.reassignGUID(); + auto *ExternalAlias = GlobalAlias::create( + ExportGV.getType(), ExportGV.getAddressSpace(), + GlobalValue::ExternalLinkage, NewName, &ExportGV, &ExportM); + ExternalAlias->setVisibility(GlobalValue::HiddenVisibility); + ExportGV.replaceUsesWithIf(ExternalAlias, [ExternalAlias](Use &U) { + return U.getUser() != ExternalAlias; + }); + + if (MustPromote) { + PromoteExtra->remove(&ExportGV); + PromoteExtra->insert(ExternalAlias); + } + if (ImportGV) { ImportGV->setName(NewName); ImportGV->setVisibility(GlobalValue::HiddenVisibility); ImportGV->reassignGUID(); } - - if (isa<Function>(&ExportGV) && allowPromotionAlias(OldName)) { - // Create a local alias with the original name to avoid breaking - // references from inline assembly. - std::string Alias = - ".lto_set_conditional " + OldName + "," + NewName + "\n"; - ExportM.appendModuleInlineAsm(Alias); - } } if (!RenamedComdats.empty()) @@ -191,9 +179,8 @@ void simplifyExternals(Module &M) { F.getName().starts_with("llvm.")) continue; - Function *NewF = - Function::Create(EmptyFT, GlobalValue::ExternalLinkage, - F.getAddressSpace(), "", &M); + Function *NewF = Function::Create(EmptyFT, GlobalValue::ExternalLinkage, + F.getAddressSpace(), "", &M); NewF->copyAttributesFrom(&F); // Only copy function attribtues. NewF->setAttributes(AttributeList::get(M.getContext(), @@ -419,8 +406,8 @@ void splitAndWriteThinLTOBitcode( // match values from its first argument (the "exporting module") in // CfiFunctions. So we only need CfiFunctions for the second promotion (M -> // MergedM) - promoteInternals(*MergedM, M, ModuleId, {}); - promoteInternals(M, *MergedM, ModuleId, CfiFunctions); + promoteInternals(*MergedM, M, ModuleId, nullptr); + promoteInternals(M, *MergedM, ModuleId, &CfiFunctions); auto &Ctx = MergedM->getContext(); SmallVector<MDNode *, 8> CfiFunctionMDs; diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp index f876d4f02bb15..2c199896e2fe3 100644 --- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp +++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp @@ -1147,6 +1147,8 @@ bool DevirtModule::tryFindVirtualCallTargets( // target. auto *GV = dyn_cast<GlobalValue>(C); assert(GV); + if (auto *GA = dyn_cast<GlobalAlias>(GV)) + GV = GA->getAliaseeObject(); TargetsForSlot.push_back({GV, &TM}); } @@ -1203,7 +1205,17 @@ bool DevirtIndex::tryFindVirtualCallTargets( if (mustBeUnreachableFunction(VTP.FuncVI)) continue; - TargetsForSlot.push_back(VTP.FuncVI); + ValueInfo TheFn = VTP.FuncVI; + // Internal linkage functions get an external linkage alias to them. + if (!TheFn.getSummaryList().empty()) + if (auto *AS = + dyn_cast<AliasSummary>(TheFn.getSummaryList()[0].get())) { + assert(TheFn.getSummaryList().size() == 1 && + "Aliases to internal linkage targets of indirect calls are " + "expected to point to exactly one definition."); + TheFn = AS->getAliaseeVI(); + } + TargetsForSlot.push_back(TheFn); } } @@ -2261,10 +2273,13 @@ void DevirtModule::importResolution(VTableSlot Slot, VTableSlotInfo &SlotInfo) { assert(!Res.SingleImplName.empty()); // The type of the function in the declaration is irrelevant because every // call site will cast it to the correct type. - Constant *SingleImpl = - cast<Constant>(M.getOrInsertFunction(Res.SingleImplName, - Type::getVoidTy(M.getContext())) - .getCallee()); + Value *SingleImplVal = + M.getOrInsertFunction(Res.SingleImplName, + Type::getVoidTy(M.getContext())) + .getCallee(); + if (auto *A = dyn_cast<GlobalAlias>(SingleImplVal->stripPointerCasts())) + SingleImplVal = A->getAliaseeObject(); + Constant *SingleImpl = cast<Constant>(SingleImplVal); // This is the import phase so we should not be exporting anything. bool IsExported = false; diff --git a/llvm/test/ThinLTO/X86/devirt_function_alias2.ll b/llvm/test/ThinLTO/X86/devirt_function_alias2.ll index 3b3208e300aa8..e4f93208fba54 100644 --- a/llvm/test/ThinLTO/X86/devirt_function_alias2.ll +++ b/llvm/test/ThinLTO/X86/devirt_function_alias2.ll @@ -24,8 +24,8 @@ ; RUN: 2>&1 | FileCheck %s --check-prefix=REMARK --check-prefix=PRINT ; RUN: llvm-dis %t2.1.4.opt.bc -o - | FileCheck %s --check-prefix=CHECK-IR1 -; PRINT-DAG: Devirtualized call to {{.*}} (_ZN1D1mEiAlias) -; REMARK-DAG: single-impl: devirtualized a call to _ZN1D1mEiAlias +; PRINT-DAG: Devirtualized call to {{.*}} (_ZN1D1mEi) +; REMARK-DAG: single-impl: devirtualized a call to _ZN1D1mEi ;; Test hybrid Thin/Regular LTO @@ -63,13 +63,15 @@ target triple = "x86_64-grtev4-linux-gnu" @_ZTV1D = constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr undef, ptr @_ZN1D1mEiAlias] }, !type !3 -define i32 @_ZN1D1mEi(ptr %this, i32 %a) { +define i32 @_ZN1D1mEi(ptr %this, i32 %a) #0 { ret i32 0; } @_ZN1D1mEiAlias = unnamed_addr alias i32 (ptr, i32), ptr @_ZN1D1mEi -; CHECK-IR1-LABEL: define i32 @test +attributes #0 = { noinline optnone } + +; CHECK-IR1-LABEL: define {{.*}}i32 @test define i32 @test(ptr %obj2, i32 %a) { entry: %vtable2 = load ptr, ptr %obj2 diff --git a/llvm/test/Transforms/Coroutines/coro-id-alias.ll b/llvm/test/Transforms/Coroutines/coro-id-alias.ll new file mode 100644 index 0000000000000..86381e58a58b4 --- /dev/null +++ b/llvm/test/Transforms/Coroutines/coro-id-alias.ll @@ -0,0 +1,13 @@ +; RUN: opt < %s -passes=coro-early -S | FileCheck %s + +declare token @llvm.coro.id(i32, ptr, ptr, ptr) + +@foo_alias = alias void (), ptr @foo + +define void @foo() presplitcoroutine { +entry: + %id = call token @llvm.coro.id(i32 0, ptr null, ptr @foo_alias, ptr null) + ret void +} +; CHECK-LABEL: define void @foo() +; CHECK: call token @llvm.coro.id(i32 0, ptr null, ptr @foo, ptr null) diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/cfi-icall-static-inline-asm.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/cfi-icall-static-inline-asm.ll index d8ebae17d4693..9d2ee425031ab 100644 --- a/llvm/test/Transforms/ThinLTOBitcodeWriter/cfi-icall-static-inline-asm.ll +++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/cfi-icall-static-inline-asm.ll @@ -3,7 +3,7 @@ target triple = "x86_64-unknown-linux-gnu" -; CHECK: module asm ".lto_set_conditional a,a.[[HASH:[0-9a-f]+]]" +; CHECK: @a.[[HASH:[0-9a-f]+]] = hidden alias define void @b() { %f = alloca ptr, align 8 @@ -14,7 +14,7 @@ define void @b() { ret void } -; CHECK: define{{.*}} @a.[[HASH]](){{.*}} !type +; CHECK: define internal void @a() {{.*}}!type define internal void @a() !type !0 { ret void } diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/comdat.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/comdat.ll index f9545e2010c10..48d371531ed7b 100644 --- a/llvm/test/Transforms/ThinLTOBitcodeWriter/comdat.ll +++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/comdat.ll @@ -25,9 +25,8 @@ $nt = comdat any ; MERGED-SAME: comdat(${{"?lwt[^ ]+}}) @lwt_aliasee = private unnamed_addr global [1 x ptr] [ptr null], comdat($lwt), !type !0 -; MERGED: {{@"?lwt_nl[^ ]+}} = hidden unnamed_addr global -; MERGED-SAME: comdat(${{"?lwt[^ ]+}}) -; THIN: {{@"?lwt_nl[^ ]+}} = external hidden +; MERGED: @lwt_nl = internal unnamed_addr global i32 0, comdat(${{"?lwt[^ ]+}}) +; THIN: {{@"?lwt_nl\.[^ ]+}} = external hidden unnamed_addr global i32 @lwt_nl = internal unnamed_addr global i32 0, comdat($lwt) ; MERGED: @nlwt_aliasee = private unnamed_addr global @@ -47,12 +46,16 @@ $nt = comdat any ; THIN-SAME: comdat($nt) @nt_nl = internal unnamed_addr global i32 0, comdat($nt) -; MERGED: {{@"?lwt[^ ]+}} = hidden unnamed_addr alias -; THIN: {{@"?lwt[^ ]+}} = external hidden +; MERGED: @lwt = internal unnamed_addr alias [1 x ptr], ptr @lwt_aliasee +; MERGED: @nlwt_nl = internal unnamed_addr alias [1 x ptr], ptr @nlwt_aliasee +; MERGED: {{@"?lwt_nl\.[^ ]+}} = hidden alias ptr, ptr @lwt_nl +; MERGED: {{@"?lwt\.[^ ]+}} = hidden alias ptr, ptr @lwt +; MERGED: {{@"?nlwt_nl\.[^ ]+}} = hidden alias ptr, ptr @nlwt_nl + +; THIN: {{@"?lwt\.[^ ]+}} = external hidden global [1 x ptr] @lwt = internal unnamed_addr alias [1 x ptr], ptr @lwt_aliasee -; MERGED: {{@"?nlwt_nl[^ ]+}} = hidden unnamed_addr alias -; THIN: {{@"?nlwt_nl[^ ]+}} = external hidden +; THIN: {{@"?nlwt_nl\.[^ ]+}} = external hidden global [1 x ptr] @nlwt_nl = internal unnamed_addr alias [1 x ptr], ptr @nlwt_aliasee ; The functions below exist just to make sure the globals are used. diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal1.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal1.ll index 1a6cbb7e7e84b..2c84ab86cac63 100644 --- a/llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal1.ll +++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal1.ll @@ -13,7 +13,8 @@ ; BCA1-NOT: <GLOBALVAL_SUMMARY_BLOCK ; M0: @g.581d7631532fa146ba4061179da39272 = external hidden global i8 -; M1: @g.581d7631532fa146ba4061179da39272 = hidden global i8 42, !type !0 +; M1: @g = internal global i8 42, !type !0 +; M1: @g.581d7631532fa146ba4061179da39272 = hidden alias ptr, ptr @g @g = internal global i8 42, !type !0 ; M0: define ptr @f() diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal2.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal2.ll index 1a7b1aba66576..d9d9f516015d9 100644 --- a/llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal2.ll +++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/split-internal2.ll @@ -20,8 +20,9 @@ target triple = "x86_64-unknown-linux-gnu" ; M1: @g = global ptr @f.13757e0fb71915e385efa4dc9d1e08fd, !type !0 @g = global ptr @f, !type !0 -; M0: define hidden void @f.13757e0fb71915e385efa4dc9d1e08fd() -; M1: declare !guid !4 hidden void @f.13757e0fb71915e385efa4dc9d1e08fd() +; M0: @f.13757e0fb71915e385efa4dc9d1e08fd = hidden alias ptr, ptr @f +; M0: define internal void @f() +; M1: declare !guid !{{[0-9]+}} hidden void @f.13757e0fb71915e385efa4dc9d1e08fd() define internal void @f() { call void @f2() ret void diff --git a/llvm/test/Transforms/ThinLTOBitcodeWriter/split-vfunc-internal.ll b/llvm/test/Transforms/ThinLTOBitcodeWriter/split-vfunc-internal.ll index 75932fd84d83e..1d17699be1c3c 100644 --- a/llvm/test/Transforms/ThinLTOBitcodeWriter/split-vfunc-internal.ll +++ b/llvm/test/Transforms/ThinLTOBitcodeWriter/split-vfunc-internal.ll @@ -10,12 +10,14 @@ define ptr @source() { } ; M0: @g.84f59439b469192440047efc8de357fb = external hidden constant [1 x ptr] -; M1: @g.84f59439b469192440047efc8de357fb = hidden constant [1 x ptr] [ptr @ok.84f59439b469192440047efc8de357fb] +; M1: @g = internal constant [1 x ptr] [ptr @ok.84f59439b469192440047efc8de357fb] +; M1: @g.84f59439b469192440047efc8de357fb = hidden alias ptr, ptr @g @g = internal constant [1 x ptr] [ ptr @ok ], !type !0 -; M0: define hidden i64 @ok.84f59439b469192440047efc8de357fb +; M0: @ok.84f59439b469192440047efc8de357fb = hidden alias ptr, ptr @ok +; M0: define internal i64 @ok(ptr %this) ; M1: define available_externally hidden i64 @ok.84f59439b469192440047efc8de357fb define internal i64 @ok(ptr %this) { ret i64 42 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
