diff options
author | Jessica Clarke <jrtc27@jrtc27.com> | 2024-08-28 17:11:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-28 17:11:15 +0100 |
commit | 73e0aa58666f235bef091735a5f189882acc1148 (patch) | |
tree | bb070fc4f2229fd5c61c7a4f54812f5e2684cece /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | 82113a432c5bffe026682ea117a3e2cd67a2fed0 (diff) | |
download | llvm-73e0aa58666f235bef091735a5f189882acc1148.zip llvm-73e0aa58666f235bef091735a5f189882acc1148.tar.gz llvm-73e0aa58666f235bef091735a5f189882acc1148.tar.bz2 |
[CodeGen] Create IFUNCs in the program address space, not hard-coded 0 (#105726)
Commit 0d527e56a5ee ("GlobalIFunc: Make ifunc respect function address
spaces") added support for this within LLVM, but Clang does not properly
honour the target's address spaces when creating IFUNCs, crashing with
RAUW and verifier assertion failures when compiling C code on a target
with a non-zero program address space, so fix this.
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 42742ae..df4c13c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4455,12 +4455,13 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { if (getTarget().supportsIFunc()) { llvm::GlobalValue::LinkageTypes Linkage = getMultiversionLinkage(*this, GD); auto *IFunc = cast<llvm::GlobalValue>(GetOrCreateMultiVersionResolver(GD)); + unsigned AS = IFunc->getType()->getPointerAddressSpace(); // Fix up function declarations that were created for cpu_specific before // cpu_dispatch was known if (!isa<llvm::GlobalIFunc>(IFunc)) { - auto *GI = llvm::GlobalIFunc::create(DeclTy, 0, Linkage, "", ResolverFunc, - &getModule()); + auto *GI = llvm::GlobalIFunc::create(DeclTy, AS, Linkage, "", + ResolverFunc, &getModule()); replaceDeclarationWith(IFunc, GI); IFunc = GI; } @@ -4469,8 +4470,8 @@ void CodeGenModule::emitCPUDispatchDefinition(GlobalDecl GD) { *this, GD, FD, /*OmitMultiVersionMangling=*/true); llvm::Constant *AliasFunc = GetGlobalValue(AliasName); if (!AliasFunc) { - auto *GA = llvm::GlobalAlias::create(DeclTy, 0, Linkage, AliasName, IFunc, - &getModule()); + auto *GA = llvm::GlobalAlias::create(DeclTy, AS, Linkage, AliasName, + IFunc, &getModule()); SetCommonAttributes(GD, GA); } } @@ -4542,15 +4543,14 @@ llvm::Constant *CodeGenModule::GetOrCreateMultiVersionResolver(GlobalDecl GD) { // For cpu_specific, don't create an ifunc yet because we don't know if the // cpu_dispatch will be emitted in this translation unit. if (getTarget().supportsIFunc() && !FD->isCPUSpecificMultiVersion()) { - llvm::Type *ResolverType = llvm::FunctionType::get( - llvm::PointerType::get(DeclTy, - getTypes().getTargetAddressSpace(FD->getType())), - false); + unsigned AS = getTypes().getTargetAddressSpace(FD->getType()); + llvm::Type *ResolverType = + llvm::FunctionType::get(llvm::PointerType::get(DeclTy, AS), false); llvm::Constant *Resolver = GetOrCreateLLVMFunction( MangledName + ".resolver", ResolverType, GlobalDecl{}, /*ForVTable=*/false); llvm::GlobalIFunc *GIF = - llvm::GlobalIFunc::create(DeclTy, 0, getMultiversionLinkage(*this, GD), + llvm::GlobalIFunc::create(DeclTy, AS, getMultiversionLinkage(*this, GD), "", Resolver, &getModule()); GIF->setName(ResolverName); SetCommonAttributes(FD, GIF); @@ -6160,9 +6160,9 @@ void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) { GetOrCreateLLVMFunction(IFA->getResolver(), VoidTy, {}, /*ForVTable=*/false); llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType()); - llvm::GlobalIFunc *GIF = - llvm::GlobalIFunc::create(DeclTy, 0, llvm::Function::ExternalLinkage, - "", Resolver, &getModule()); + unsigned AS = getTypes().getTargetAddressSpace(D->getType()); + llvm::GlobalIFunc *GIF = llvm::GlobalIFunc::create( + DeclTy, AS, llvm::Function::ExternalLinkage, "", Resolver, &getModule()); if (Entry) { if (GIF->getResolver() == Entry) { Diags.Report(IFA->getLocation(), diag::err_cyclic_alias) << 1; |