diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5013,8 +5013,9 @@ 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 --- a/clang/test/CodeGen/ifunc.c +++ b/clang/test/CodeGen/ifunc.c @@ -34,8 +34,8 @@ 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 --- 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 --- a/llvm/include/llvm/IR/GlobalIFunc.h +++ b/llvm/include/llvm/IR/GlobalIFunc.h @@ -80,6 +80,10 @@ static_cast(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 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2279,7 +2279,11 @@ return error("Alias and aliasee types don't match"); GA->setAliasee(C); } else if (auto *GI = dyn_cast(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 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -541,5 +541,5 @@ const Function *GlobalIFunc::getResolverFunction() const { DenseSet Aliases; - return cast(findBaseObject(getResolver(), Aliases)); + return dyn_cast(findBaseObject(getResolver(), Aliases)); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -415,6 +415,9 @@ 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 @@ 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 &Visited, const GlobalAlias &A, const Constant &C); @@ -823,6 +827,23 @@ 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 --- 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 --- 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 --- 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 @@ ; 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 --- a/llvm/test/Bindings/llvm-c/echo.ll +++ b/llvm/test/Bindings/llvm-c/echo.ll @@ -29,11 +29,11 @@ @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 --- a/llvm/test/Bitcode/compatibility-3.9.ll +++ b/llvm/test/Bitcode/compatibility-3.9.ll @@ -256,19 +256,19 @@ ; 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 --- a/llvm/test/Bitcode/compatibility-4.0.ll +++ b/llvm/test/Bitcode/compatibility-4.0.ll @@ -256,19 +256,19 @@ ; 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 --- a/llvm/test/Bitcode/compatibility-5.0.ll +++ b/llvm/test/Bitcode/compatibility-5.0.ll @@ -256,19 +256,19 @@ ; 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 --- a/llvm/test/Bitcode/compatibility-6.0.ll +++ b/llvm/test/Bitcode/compatibility-6.0.ll @@ -255,19 +255,19 @@ ; 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 --- a/llvm/test/Bitcode/compatibility.ll +++ b/llvm/test/Bitcode/compatibility.ll @@ -264,28 +264,28 @@ ; * @ ; 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 --- a/llvm/test/Bitcode/dso_local_equivalent.ll +++ b/llvm/test/Bitcode/dso_local_equivalent.ll @@ -65,12 +65,12 @@ 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 --- 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 @@ 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 --- 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 --- 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_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 @@ @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 --- a/llvm/test/CodeGen/X86/dso_local_equivalent.ll +++ b/llvm/test/CodeGen/X86/dso_local_equivalent.ll @@ -74,12 +74,12 @@ 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 --- 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 --- 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 @@ @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 --- 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 --- 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 --- 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 --- 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 --- a/llvm/test/Object/X86/nm-ir.ll +++ b/llvm/test/Object/X86/nm-ir.ll @@ -32,12 +32,12 @@ @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 --- 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 --- 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(