Author: Itay Bookstein Date: 2021-10-31T20:00:57-07:00 New Revision: 848812a55e530517191ed0f4f15c0c60752ea9c4
URL: https://github.com/llvm/llvm-project/commit/848812a55e530517191ed0f4f15c0c60752ea9c4 DIFF: https://github.com/llvm/llvm-project/commit/848812a55e530517191ed0f4f15c0c60752ea9c4.diff LOG: [Verifier] Add verification logic for GlobalIFuncs Verify that the resolver exists, that it is a defined Function, and that its return type matches the ifunc's type. Add corresponding check to BitcodeReader, change clang to emit the correct type, and fix tests to comply. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D112349 Added: Modified: clang/lib/CodeGen/CodeGenModule.cpp clang/test/CodeGen/ifunc.c clang/test/CodeGen/semantic-interposition.c llvm/include/llvm/IR/GlobalIFunc.h llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/IR/Globals.cpp llvm/lib/IR/Verifier.cpp llvm/test/Assembler/ifunc-asm.ll llvm/test/Assembler/ifunc-dsolocal.ll llvm/test/Assembler/ifunc-use-list-order.ll llvm/test/Bindings/llvm-c/echo.ll llvm/test/Bitcode/compatibility-3.9.ll llvm/test/Bitcode/compatibility-4.0.ll llvm/test/Bitcode/compatibility-5.0.ll llvm/test/Bitcode/compatibility-6.0.ll llvm/test/Bitcode/compatibility.ll llvm/test/Bitcode/dso_local_equivalent.ll llvm/test/Bitcode/dso_location.ll llvm/test/CodeGen/PowerPC/ifunc.ll llvm/test/CodeGen/X86/addrsig.ll llvm/test/CodeGen/X86/dso_local_equivalent.ll llvm/test/CodeGen/X86/ifunc-asm.ll llvm/test/CodeGen/X86/partition.ll llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll llvm/test/LTO/Resolution/X86/ifunc.ll llvm/test/LTO/Resolution/X86/ifunc2.ll llvm/test/Linker/ifunc.ll llvm/test/Object/X86/nm-ir.ll llvm/test/ThinLTO/X86/empty-module.ll llvm/test/Transforms/GlobalDCE/global-ifunc.ll Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 74c4490d5422e..9cedd9a9a35c0 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5013,8 +5013,9 @@ void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) { Aliases.push_back(GD); llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType()); + llvm::Type *ResolverTy = llvm::GlobalIFunc::getResolverFunctionType(DeclTy); llvm::Constant *Resolver = - GetOrCreateLLVMFunction(IFA->getResolver(), DeclTy, GD, + GetOrCreateLLVMFunction(IFA->getResolver(), ResolverTy, GD, /*ForVTable=*/false); llvm::GlobalIFunc *GIF = llvm::GlobalIFunc::create(DeclTy, 0, llvm::Function::ExternalLinkage, diff --git a/clang/test/CodeGen/ifunc.c b/clang/test/CodeGen/ifunc.c index a88bb1878f265..fee9cc3dee99e 100644 --- a/clang/test/CodeGen/ifunc.c +++ b/clang/test/CodeGen/ifunc.c @@ -34,8 +34,8 @@ extern void goo(void) __attribute__ ((ifunc("goo_ifunc"))); void* goo_ifunc(void) { return 0; } -// CHECK: @foo = ifunc i32 (i32), bitcast (i32 (i32)* ()* @foo_ifunc to i32 (i32)*) -// CHECK: @goo = ifunc void (), bitcast (i8* ()* @goo_ifunc to void ()*) +// CHECK: @foo = ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc +// CHECK: @goo = ifunc void (), bitcast (i8* ()* @goo_ifunc to void ()* ()*) // CHECK: call i32 @foo(i32 // CHECK: call void @goo() diff --git a/clang/test/CodeGen/semantic-interposition.c b/clang/test/CodeGen/semantic-interposition.c index 22923e1d494ed..3581312b8e27b 100644 --- a/clang/test/CodeGen/semantic-interposition.c +++ b/clang/test/CodeGen/semantic-interposition.c @@ -10,13 +10,13 @@ // CHECK: @var = global i32 0, align 4 // CHECK: @ext_var = external global i32, align 4 -// CHECK: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()*) +// CHECK: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()* ()*) // CHECK: define dso_local i32 @func() // CHECK: declare i32 @ext() // PREEMPT: @var = global i32 0, align 4 // PREEMPT: @ext_var = external global i32, align 4 -// PREEMPT: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()*) +// PREEMPT: @ifunc = ifunc i32 (), bitcast (i8* ()* @ifunc_resolver to i32 ()* ()*) // PREEMPT: define i32 @func() // PREEMPT: declare i32 @ext() diff --git a/llvm/include/llvm/IR/GlobalIFunc.h b/llvm/include/llvm/IR/GlobalIFunc.h index 4dc184c2336fe..10088ee2fff42 100644 --- a/llvm/include/llvm/IR/GlobalIFunc.h +++ b/llvm/include/llvm/IR/GlobalIFunc.h @@ -80,6 +80,10 @@ class GlobalIFunc final : public GlobalObject, public ilist_node<GlobalIFunc> { static_cast<const GlobalIFunc *>(this)->getResolverFunction()); } + static FunctionType *getResolverFunctionType(Type *IFuncValTy) { + return FunctionType::get(IFuncValTy->getPointerTo(), false); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Value *V) { return V->getValueID() == Value::GlobalIFuncVal; diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 9ba76022e6549..8b0846d6cb6d8 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2279,7 +2279,11 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { return error("Alias and aliasee types don't match"); GA->setAliasee(C); } else if (auto *GI = dyn_cast<GlobalIFunc>(GV)) { - GI->setResolver(C); + Type *ResolverFTy = + GlobalIFunc::getResolverFunctionType(GI->getValueType()); + // Transparently fix up the type for compatiblity with older bitcode + GI->setResolver( + ConstantExpr::getBitCast(C, ResolverFTy->getPointerTo())); } else { return error("Expected an alias or an ifunc"); } diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index 0aff4906bcf15..9f38288095e3a 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -541,5 +541,5 @@ void GlobalIFunc::eraseFromParent() { const Function *GlobalIFunc::getResolverFunction() const { DenseSet<const GlobalAlias *> Aliases; - return cast<Function>(findBaseObject(getResolver(), Aliases)); + return dyn_cast<Function>(findBaseObject(getResolver(), Aliases)); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index de092ec632f4c..a72c8bb119e2d 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -415,6 +415,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { for (const GlobalAlias &GA : M.aliases()) visitGlobalAlias(GA); + for (const GlobalIFunc &GI : M.ifuncs()) + visitGlobalIFunc(GI); + for (const NamedMDNode &NMD : M.named_metadata()) visitNamedMDNode(NMD); @@ -440,6 +443,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { void visitGlobalValue(const GlobalValue &GV); void visitGlobalVariable(const GlobalVariable &GV); void visitGlobalAlias(const GlobalAlias &GA); + void visitGlobalIFunc(const GlobalIFunc &GI); void visitAliaseeSubExpr(const GlobalAlias &A, const Constant &C); void visitAliaseeSubExpr(SmallPtrSetImpl<const GlobalAlias *> &Visited, const GlobalAlias &A, const Constant &C); @@ -823,6 +827,23 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) { visitGlobalValue(GA); } +void Verifier::visitGlobalIFunc(const GlobalIFunc &GI) { + // Pierce through ConstantExprs and GlobalAliases and check that the resolver + // is a Function definition + const Function *Resolver = GI.getResolverFunction(); + Assert(Resolver, "IFunc must have a Function resolver", &GI); + Assert(!Resolver->isDeclarationForLinker(), + "IFunc resolver must be a definition", &GI); + + // Check that the immediate resolver operand (prior to any bitcasts) has the + // correct type + const Type *ResolverTy = GI.getResolver()->getType(); + const Type *ResolverFuncTy = + GlobalIFunc::getResolverFunctionType(GI.getValueType()); + Assert(ResolverTy == ResolverFuncTy->getPointerTo(), + "IFunc resolver has incorrect type", &GI); +} + void Verifier::visitNamedMDNode(const NamedMDNode &NMD) { // There used to be various other llvm.dbg.* nodes, but we don't support // upgrading them and we want to reserve the namespace for future uses. diff --git a/llvm/test/Assembler/ifunc-asm.ll b/llvm/test/Assembler/ifunc-asm.ll index bef243a25dd0a..e32587fdc25a8 100644 --- a/llvm/test/Assembler/ifunc-asm.ll +++ b/llvm/test/Assembler/ifunc-asm.ll @@ -2,11 +2,20 @@ target triple = "x86_64-unknown-linux-gnu" -@foo = ifunc i32 (i32), i64 ()* @foo_ifunc -; CHECK: @foo = ifunc i32 (i32), i64 ()* @foo_ifunc +@foo = ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc +; CHECK: @foo = ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc -define internal i64 @foo_ifunc() { +@strlen = ifunc i64 (i8*), bitcast (i64 (i32*)* ()* @mistyped_strlen_resolver to i64 (i8*)* ()*) +; CHECK: strlen = ifunc i64 (i8*), bitcast (i64 (i32*)* ()* @mistyped_strlen_resolver to i64 (i8*)* ()*) + +define internal i32 (i32)* @foo_ifunc() { +entry: + ret i32 (i32)* null +} +; CHECK: define internal i32 (i32)* @foo_ifunc() + +define internal i64 (i32*)* @mistyped_strlen_resolver() { entry: - ret i64 0 + ret i64 (i32*)* null } -; CHECK: define internal i64 @foo_ifunc() +; CHECK: define internal i64 (i32*)* @mistyped_strlen_resolver() diff --git a/llvm/test/Assembler/ifunc-dsolocal.ll b/llvm/test/Assembler/ifunc-dsolocal.ll index 63242cb3f24fb..f8e2c3af1500e 100644 --- a/llvm/test/Assembler/ifunc-dsolocal.ll +++ b/llvm/test/Assembler/ifunc-dsolocal.ll @@ -1,9 +1,9 @@ ; RUN: llvm-as < %s | llvm-dis | FileCheck %s -@foo = dso_local ifunc i32 (i32), i64 ()* @foo_ifunc -; CHECK: @foo = dso_local ifunc i32 (i32), i64 ()* @foo_ifunc +@foo = dso_local ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc +; CHECK: @foo = dso_local ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc -define internal i64 @foo_ifunc() { +define internal i32 (i32)* @foo_ifunc() { entry: - ret i64 0 + ret i32 (i32)* null } diff --git a/llvm/test/Assembler/ifunc-use-list-order.ll b/llvm/test/Assembler/ifunc-use-list-order.ll index efd8dcc3f8791..167406a3be255 100644 --- a/llvm/test/Assembler/ifunc-use-list-order.ll +++ b/llvm/test/Assembler/ifunc-use-list-order.ll @@ -6,11 +6,11 @@ ; Alias for ifunc. @alias_foo = alias void (), void ()* @foo_ifunc -@foo_ifunc = ifunc void (), i8* ()* @foo_resolver +@foo_ifunc = ifunc void (), void ()* ()* @foo_resolver -define i8* @foo_resolver() { +define void ()* @foo_resolver() { entry: - ret i8* null + ret void ()* null } ; Function referencing ifunc. @@ -26,12 +26,11 @@ entry: ; Alias for function. @alias_bar = alias void (), void ()* @bar -@bar_ifunc = ifunc void (), i8* ()* @bar2_ifunc -@bar2_ifunc = ifunc i8* (), i8* ()* @bar_resolver +@bar_ifunc = ifunc void (), void ()* ()* @bar_resolver -define i8* @bar_resolver() { +define void ()* @bar_resolver() { entry: - ret i8* null + ret void ()* null } ; Function referencing bar. diff --git a/llvm/test/Bindings/llvm-c/echo.ll b/llvm/test/Bindings/llvm-c/echo.ll index 64e516c1970fc..c2fc7b108bf3b 100644 --- a/llvm/test/Bindings/llvm-c/echo.ll +++ b/llvm/test/Bindings/llvm-c/echo.ll @@ -29,11 +29,11 @@ module asm "classical GAS" @aliased4 = weak alias i32, i32* @var @aliased5 = weak_odr alias i32, i32* @var -@ifunc = ifunc i32 (i32), i64 ()* @ifunc_resolver +@ifunc = ifunc i32 (i32), i32 (i32)* ()* @ifunc_resolver -define i64 @ifunc_resolver() { +define i32 (i32)* @ifunc_resolver() { entry: - ret i64 0 + ret i32 (i32)* null } define { i64, %S* } @unpackrepack(%S %s) { diff --git a/llvm/test/Bitcode/compatibility-3.9.ll b/llvm/test/Bitcode/compatibility-3.9.ll index 6c0d827f80625..a203717993f21 100644 --- a/llvm/test/Bitcode/compatibility-3.9.ll +++ b/llvm/test/Bitcode/compatibility-3.9.ll @@ -256,19 +256,19 @@ declare void @g.f1() ; IFunc -- Linkage @ifunc.external = external ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.external = ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.external = ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.private = private ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.internal = internal ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) ; IFunc -- Visibility @ifunc.default = default ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.default = ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.default = ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.hidden = hidden ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.protected = protected ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) define i8* @ifunc_resolver() { entry: diff --git a/llvm/test/Bitcode/compatibility-4.0.ll b/llvm/test/Bitcode/compatibility-4.0.ll index c17ece7f5c899..c0953cbbbcdc7 100644 --- a/llvm/test/Bitcode/compatibility-4.0.ll +++ b/llvm/test/Bitcode/compatibility-4.0.ll @@ -256,19 +256,19 @@ declare void @g.f1() ; IFunc -- Linkage @ifunc.external = external ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.external = ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.external = ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.private = private ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.internal = internal ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) ; IFunc -- Visibility @ifunc.default = default ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.default = ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.default = ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.hidden = hidden ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.protected = protected ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) define i8* @ifunc_resolver() { entry: diff --git a/llvm/test/Bitcode/compatibility-5.0.ll b/llvm/test/Bitcode/compatibility-5.0.ll index 6da717f053971..abc3cb3ae9485 100644 --- a/llvm/test/Bitcode/compatibility-5.0.ll +++ b/llvm/test/Bitcode/compatibility-5.0.ll @@ -256,19 +256,19 @@ declare void @g.f1() ; IFunc -- Linkage @ifunc.external = external ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.external = ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.external = ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.private = private ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.internal = internal ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) ; IFunc -- Visibility @ifunc.default = default ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.default = ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.default = ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.hidden = hidden ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.protected = protected ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) define i8* @ifunc_resolver() { entry: diff --git a/llvm/test/Bitcode/compatibility-6.0.ll b/llvm/test/Bitcode/compatibility-6.0.ll index 467b75abd5a89..a9a114f577af3 100644 --- a/llvm/test/Bitcode/compatibility-6.0.ll +++ b/llvm/test/Bitcode/compatibility-6.0.ll @@ -255,19 +255,19 @@ declare void @g.f1() ; IFunc -- Linkage @ifunc.external = external ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.external = ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.external = ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.private = private ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.internal = internal ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) ; IFunc -- Visibility @ifunc.default = default ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.default = ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.default = ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.hidden = hidden ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver +; CHECK: @ifunc.protected = protected ifunc void (), bitcast (i8* ()* @ifunc_resolver to void ()* ()*) define i8* @ifunc_resolver() { entry: diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll index 2281938c6d834..2e73810380f65 100644 --- a/llvm/test/Bitcode/compatibility.ll +++ b/llvm/test/Bitcode/compatibility.ll @@ -264,28 +264,28 @@ declare void @g.f1() ; <ResolverTy>* @<Resolver> ; IFunc -- Linkage -@ifunc.external = external ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.external = ifunc void (), i8* ()* @ifunc_resolver -@ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver -@ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver +@ifunc.external = external ifunc void (), void ()* ()* @ifunc_resolver +; CHECK: @ifunc.external = ifunc void (), void ()* ()* @ifunc_resolver +@ifunc.private = private ifunc void (), void ()* ()* @ifunc_resolver +; CHECK: @ifunc.private = private ifunc void (), void ()* ()* @ifunc_resolver +@ifunc.internal = internal ifunc void (), void ()* ()* @ifunc_resolver +; CHECK: @ifunc.internal = internal ifunc void (), void ()* ()* @ifunc_resolver ; IFunc -- Visibility -@ifunc.default = default ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.default = ifunc void (), i8* ()* @ifunc_resolver -@ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver -@ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver -; CHECK: @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver +@ifunc.default = default ifunc void (), void ()* ()* @ifunc_resolver +; CHECK: @ifunc.default = ifunc void (), void ()* ()* @ifunc_resolver +@ifunc.hidden = hidden ifunc void (), void ()* ()* @ifunc_resolver +; CHECK: @ifunc.hidden = hidden ifunc void (), void ()* ()* @ifunc_resolver +@ifunc.protected = protected ifunc void (), void ()* ()* @ifunc_resolver +; CHECK: @ifunc.protected = protected ifunc void (), void ()* ()* @ifunc_resolver ; IFunc -- partition -; CHECK: @ifunc.partition = ifunc void (), i8* ()* @ifunc_resolver, partition "part" -@ifunc.partition = ifunc void (), i8* ()* @ifunc_resolver, partition "part" +; CHECK: @ifunc.partition = ifunc void (), void ()* ()* @ifunc_resolver, partition "part" +@ifunc.partition = ifunc void (), void ()* ()* @ifunc_resolver, partition "part" -define i8* @ifunc_resolver() { +define void ()* @ifunc_resolver() { entry: - ret i8* null + ret void ()* null } ;; Functions diff --git a/llvm/test/Bitcode/dso_local_equivalent.ll b/llvm/test/Bitcode/dso_local_equivalent.ll index 13eec78020b7c..819586ea6c531 100644 --- a/llvm/test/Bitcode/dso_local_equivalent.ll +++ b/llvm/test/Bitcode/dso_local_equivalent.ll @@ -65,12 +65,12 @@ define void @call_dso_local_alias_func() { ret void } -@ifunc_func = ifunc void (), i64 ()* @resolver -@dso_local_ifunc_func = dso_local ifunc void (), i64 ()* @resolver +@ifunc_func = ifunc void (), void ()* ()* @resolver +@dso_local_ifunc_func = dso_local ifunc void (), void ()* ()* @resolver -define internal i64 @resolver() { +define internal void ()* @resolver() { entry: - ret i64 0 + ret void ()* null } define void @call_ifunc_func() { diff --git a/llvm/test/Bitcode/dso_location.ll b/llvm/test/Bitcode/dso_location.ll index 3ad511bad430b..43f96780fbc20 100644 --- a/llvm/test/Bitcode/dso_location.ll +++ b/llvm/test/Bitcode/dso_location.ll @@ -27,8 +27,8 @@ @preemptable_alias = dso_preemptable alias i32, i32* @hidden_local_global ; CHECK-DAG: @preemptable_alias = alias i32, i32* @hidden_local_global -@preemptable_ifunc = dso_preemptable ifunc void (), i8* ()* @ifunc_resolver -; CHECK-DAG: @preemptable_ifunc = ifunc void (), i8* ()* @ifunc_resolver +@preemptable_ifunc = dso_preemptable ifunc void (), void ()* ()* @ifunc_resolver +; CHECK-DAG: @preemptable_ifunc = ifunc void (), void ()* ()* @ifunc_resolver declare dso_local default void @default_local() ; CHECK: declare dso_local void @default_local() @@ -41,7 +41,7 @@ entry: ret void } -define i8* @ifunc_resolver() { +define void ()* @ifunc_resolver() { entry: - ret i8* null + ret void ()* null } diff --git a/llvm/test/CodeGen/PowerPC/ifunc.ll b/llvm/test/CodeGen/PowerPC/ifunc.ll index a58601f8f32f6..23afc886a991f 100644 --- a/llvm/test/CodeGen/PowerPC/ifunc.ll +++ b/llvm/test/CodeGen/PowerPC/ifunc.ll @@ -7,10 +7,10 @@ ; RUN: llc %s -o - -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr10 \ ; RUN: -verify-machineinstrs | FileCheck --check-prefix=LEP10 %s -@ifunc1 = dso_local ifunc void(), i8*()* @resolver -@ifunc2 = ifunc void(), i8*()* @resolver +@ifunc1 = dso_local ifunc void(), void()* ()* @resolver +@ifunc2 = ifunc void(), void()* ()* @resolver -define i8* @resolver() { ret i8* null } +define void()* @resolver() { ret void()* null } define void @foo() #0 { ; REL-LABEL: foo diff --git a/llvm/test/CodeGen/X86/addrsig.ll b/llvm/test/CodeGen/X86/addrsig.ll index 957de7ec2a64c..f028e0a6b1905 100644 --- a/llvm/test/CodeGen/X86/addrsig.ll +++ b/llvm/test/CodeGen/X86/addrsig.ll @@ -6,9 +6,9 @@ ; CHECK: .addrsig ; CHECK: .addrsig_sym f1 -define void @f1() { - %f1 = bitcast void()* @f1 to i8* - %f2 = bitcast void()* @f2 to i8* +define void()* @f1() { + %f1 = bitcast void()* ()* @f1 to i8* + %f2 = bitcast void()* ()* @f2 to i8* %f3 = bitcast void()* @f3 to i8* %g1 = bitcast i32* @g1 to i8* %g2 = bitcast i32* @g2 to i8* @@ -34,7 +34,7 @@ declare void @metadata_f1() declare void @metadata_f2() ; CHECK-NOT: .addrsig_sym f2 -define internal void @f2() local_unnamed_addr { +define internal void()* @f2() local_unnamed_addr { unreachable } @@ -63,9 +63,9 @@ declare void @f3() unnamed_addr @a2 = internal local_unnamed_addr alias i32, i32* @g2 ; CHECK: .addrsig_sym i1 -@i1 = ifunc void(), void()* @f1 +@i1 = ifunc void(), void()* ()* @f1 ; CHECK-NOT: .addrsig_sym i2 -@i2 = internal local_unnamed_addr ifunc void(), void()* @f2 +@i2 = internal local_unnamed_addr ifunc void(), void()* ()* @f2 declare void @llvm.dbg.value(metadata, metadata, metadata) diff --git a/llvm/test/CodeGen/X86/dso_local_equivalent.ll b/llvm/test/CodeGen/X86/dso_local_equivalent.ll index e4a5fdfa9046f..9a8f163e0689d 100644 --- a/llvm/test/CodeGen/X86/dso_local_equivalent.ll +++ b/llvm/test/CodeGen/X86/dso_local_equivalent.ll @@ -74,12 +74,12 @@ define void @call_dso_local_alias_func() { ret void } -@ifunc_func = ifunc void (), i64 ()* @resolver -@dso_local_ifunc_func = dso_local ifunc void (), i64 ()* @resolver +@ifunc_func = ifunc void (), void ()* ()* @resolver +@dso_local_ifunc_func = dso_local ifunc void (), void ()* ()* @resolver -define internal i64 @resolver() { +define internal void ()* @resolver() { entry: - ret i64 0 + ret void ()* null } ; If an ifunc is not dso_local already, then we should still emit a stub for it diff --git a/llvm/test/CodeGen/X86/ifunc-asm.ll b/llvm/test/CodeGen/X86/ifunc-asm.ll index c1604882f3c2a..a37f4263fb504 100644 --- a/llvm/test/CodeGen/X86/ifunc-asm.ll +++ b/llvm/test/CodeGen/X86/ifunc-asm.ll @@ -2,13 +2,13 @@ target triple = "x86_64-unknown-linux-gnu" -define internal i64 @foo_ifunc() { +define internal i32 (i32)* @foo_ifunc() { entry: - ret i64 0 + ret i32 (i32)* null } ; CHECK: .type foo_ifunc,@function ; CHECK-NEXT: foo_ifunc: -@foo = ifunc i32 (i32), i64 ()* @foo_ifunc +@foo = ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc ; CHECK: .type foo,@gnu_indirect_function ; CHECK-NEXT: .set foo, foo_ifunc diff --git a/llvm/test/CodeGen/X86/partition.ll b/llvm/test/CodeGen/X86/partition.ll index cc8d44e399ef3..f83a4cf32f5bc 100644 --- a/llvm/test/CodeGen/X86/partition.ll +++ b/llvm/test/CodeGen/X86/partition.ll @@ -17,7 +17,7 @@ ; CHECK-NEXT: .zero 1 ; CHECK-NEXT: .quad i1 -define void @f1() partition "part1" { +define void ()* @f1() partition "part1" { unreachable } @@ -30,4 +30,4 @@ declare void @f3() partition "part3" @g1 = global i32 0, partition "part4" @a1 = alias i32, i32* @g1, partition "part5" -@i1 = ifunc void(), void()* @f1, partition "part6" +@i1 = ifunc void(), void()* ()* @f1, partition "part6" diff --git a/llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll b/llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll index a70325bebd61a..09403e47de58a 100644 --- a/llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll +++ b/llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll @@ -1,6 +1,6 @@ target datalayout = "e-p:64:64" target triple = "x86_64-unknown-linux-gnu" -define i32 @foo_resolver() { - ret i32 2 +define i32 ()* @foo_resolver() { + ret i32 ()* inttoptr (i32 2 to i32 ()*) } diff --git a/llvm/test/LTO/Resolution/X86/ifunc.ll b/llvm/test/LTO/Resolution/X86/ifunc.ll index afe7c8cd1e7e7..d4a2d5bd608fe 100644 --- a/llvm/test/LTO/Resolution/X86/ifunc.ll +++ b/llvm/test/LTO/Resolution/X86/ifunc.ll @@ -1,23 +1,15 @@ ; RUN: opt -module-summary -o %t.bc %s -; RUN: llvm-lto2 run %t.bc -r %t.bc,foo,pl -r %t.bc,strlen,pl -o %t2 +; RUN: llvm-lto2 run %t.bc -r %t.bc,foo,pl -o %t2 ; RUN: llvm-nm %t2.1 | FileCheck %s ; CHECK: i foo ; CHECK: t foo_resolver -; CHECK: i strlen -; CHECK: t strlen_resolver target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -@foo = ifunc i32 (i32), i64 ()* @foo_resolver -@strlen = ifunc i64 (i8*), bitcast (i64 (i8*)* ()* @strlen_resolver to i64 (i8*)*) +@foo = ifunc i32 (i32), i32 (i32)* ()* @foo_resolver -define internal i64 @foo_resolver() { +define internal i32 (i32)* @foo_resolver() { entry: - ret i64 0 -} - -define internal i64 (i8*)* @strlen_resolver() { -entry: - ret i64 (i8*)* null + ret i32 (i32)* null } diff --git a/llvm/test/LTO/Resolution/X86/ifunc2.ll b/llvm/test/LTO/Resolution/X86/ifunc2.ll index 6dd5e59831836..0d824f6f3b27c 100644 --- a/llvm/test/LTO/Resolution/X86/ifunc2.ll +++ b/llvm/test/LTO/Resolution/X86/ifunc2.ll @@ -6,14 +6,14 @@ target datalayout = "e-p:64:64" target triple = "x86_64-unknown-linux-gnu" -; CHECK: @foo = ifunc i32 (), i32 ()* @foo_resolver.2 -@foo = ifunc i32 (), i32 ()* @foo_resolver +; CHECK: @foo = ifunc i32 (), i32 ()* ()* @foo_resolver.2 +@foo = ifunc i32 (), i32 ()* ()* @foo_resolver -; CHECK: define internal i32 @foo_resolver.2() { -; CHECK-NEXT: ret i32 1 -define weak i32 @foo_resolver() { - ret i32 1 +; CHECK: define internal i32 ()* @foo_resolver.2() { +; CHECK-NEXT: ret i32 ()* inttoptr (i32 1 to i32 ()*) +define weak i32 ()* @foo_resolver() { + ret i32 ()* inttoptr (i32 1 to i32 ()*) } -; CHECK: define i32 @foo_resolver() { -; CHECK-NEXT: ret i32 2 +; CHECK: define i32 ()* @foo_resolver() { +; CHECK-NEXT: ret i32 ()* inttoptr (i32 2 to i32 ()*) diff --git a/llvm/test/Linker/ifunc.ll b/llvm/test/Linker/ifunc.ll index 1e5396ed5fed6..aaf5836a137da 100644 --- a/llvm/test/Linker/ifunc.ll +++ b/llvm/test/Linker/ifunc.ll @@ -3,18 +3,18 @@ ;; Check that ifuncs are linked in properly. -; CHECK-DAG: @foo = ifunc void (), bitcast (void ()* ()* @foo_resolve to void ()*) +; CHECK-DAG: @foo = ifunc void (), void ()* ()* @foo_resolve ; CHECK-DAG: define internal void ()* @foo_resolve() { -; CHECK-DAG: @bar = ifunc void (), bitcast (void ()* ()* @bar_resolve to void ()*) +; CHECK-DAG: @bar = ifunc void (), void ()* ()* @bar_resolve ; CHECK-DAG: define internal void ()* @bar_resolve() { ;--- a.ll declare void @bar() ;--- b.ll -@foo = ifunc void (), bitcast (void ()* ()* @foo_resolve to void ()*) -@bar = ifunc void (), bitcast (void ()* ()* @bar_resolve to void ()*) +@foo = ifunc void (), void ()* ()* @foo_resolve +@bar = ifunc void (), void ()* ()* @bar_resolve define internal void ()* @foo_resolve() { ret void ()* null diff --git a/llvm/test/Object/X86/nm-ir.ll b/llvm/test/Object/X86/nm-ir.ll index c90f67b15160d..e57c6d9a11c6e 100644 --- a/llvm/test/Object/X86/nm-ir.ll +++ b/llvm/test/Object/X86/nm-ir.ll @@ -32,12 +32,12 @@ module asm ".long undef_asm_sym" @a1 = alias i32, i32* @g1 @a2 = internal alias i32, i32* @g1 -define void @f1() { +define void ()* @f1() { call void @f5() - ret void + ret void ()* null } -@ifunc_f1 = ifunc void (), void ()* @f1 +@ifunc_f1 = ifunc void (), void ()* ()* @f1 define internal void @f2() { ret void diff --git a/llvm/test/ThinLTO/X86/empty-module.ll b/llvm/test/ThinLTO/X86/empty-module.ll index 3a63a65259da7..04bc0d5942e1a 100644 --- a/llvm/test/ThinLTO/X86/empty-module.ll +++ b/llvm/test/ThinLTO/X86/empty-module.ll @@ -10,9 +10,9 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -@foo = ifunc i32 (i32), i64 ()* @foo_ifunc +@foo = ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc -define internal i64 @foo_ifunc() { +define internal i32 (i32)* @foo_ifunc() { entry: - ret i64 0 + ret i32 (i32)* null } diff --git a/llvm/test/Transforms/GlobalDCE/global-ifunc.ll b/llvm/test/Transforms/GlobalDCE/global-ifunc.ll index 8022452c34856..e12cead897f91 100644 --- a/llvm/test/Transforms/GlobalDCE/global-ifunc.ll +++ b/llvm/test/Transforms/GlobalDCE/global-ifunc.ll @@ -2,12 +2,12 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -@if = ifunc void (), void ()* @fn +@if = ifunc void (), void ()* ()* @fn -define internal void @fn() { +define internal void ()* @fn() { entry: - ret void + ret void ()* null } -; CHECK-DAG: @if = ifunc void (), void ()* @fn -; CHECK-DAG: define internal void @fn( +; CHECK-DAG: @if = ifunc void (), void ()* ()* @fn +; CHECK-DAG: define internal void ()* @fn( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits