[llvm] 848812a - [Verifier] Add verification logic for GlobalIFuncs
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 31 20:01:05 PDT 2021
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"
- at foo = ifunc i32 (i32), i64 ()* @foo_ifunc
-; CHECK: @foo = ifunc i32 (i32), i64 ()* @foo_ifunc
+ at foo = ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc
+; CHECK: @foo = ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc
-define internal i64 @foo_ifunc() {
+ at 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
- at foo = dso_local ifunc i32 (i32), i64 ()* @foo_ifunc
-; CHECK: @foo = dso_local ifunc i32 (i32), i64 ()* @foo_ifunc
+ at 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
- at foo_ifunc = ifunc void (), i8* ()* @foo_resolver
+ at 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
- at bar_ifunc = ifunc void (), i8* ()* @bar2_ifunc
- at bar2_ifunc = ifunc i8* (), i8* ()* @bar_resolver
+ at 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
- at ifunc = ifunc i32 (i32), i64 ()* @ifunc_resolver
+ at 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
- at ifunc.external = external ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.external = ifunc void (), i8* ()* @ifunc_resolver
- at ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver
- at ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver
+ at ifunc.external = external ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.external = ifunc void (), void ()* ()* @ifunc_resolver
+ at ifunc.private = private ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.private = private ifunc void (), void ()* ()* @ifunc_resolver
+ at ifunc.internal = internal ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.internal = internal ifunc void (), void ()* ()* @ifunc_resolver
; IFunc -- Visibility
- at ifunc.default = default ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.default = ifunc void (), i8* ()* @ifunc_resolver
- at ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver
- at ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver
+ at ifunc.default = default ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.default = ifunc void (), void ()* ()* @ifunc_resolver
+ at ifunc.hidden = hidden ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.hidden = hidden ifunc void (), void ()* ()* @ifunc_resolver
+ at 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"
- at ifunc.partition = ifunc void (), i8* ()* @ifunc_resolver, partition "part"
+; CHECK: @ifunc.partition = ifunc void (), void ()* ()* @ifunc_resolver, partition "part"
+ at 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
}
- at ifunc_func = ifunc void (), i64 ()* @resolver
- at dso_local_ifunc_func = dso_local ifunc void (), i64 ()* @resolver
+ at ifunc_func = ifunc void (), void ()* ()* @resolver
+ at 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
- at preemptable_ifunc = dso_preemptable ifunc void (), i8* ()* @ifunc_resolver
-; CHECK-DAG: @preemptable_ifunc = ifunc void (), i8* ()* @ifunc_resolver
+ at 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
- at ifunc1 = dso_local ifunc void(), i8*()* @resolver
- at ifunc2 = ifunc void(), i8*()* @resolver
+ at ifunc1 = dso_local ifunc void(), void()* ()* @resolver
+ at 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
- at i1 = ifunc void(), void()* @f1
+ at i1 = ifunc void(), void()* ()* @f1
; CHECK-NOT: .addrsig_sym i2
- at i2 = internal local_unnamed_addr ifunc void(), void()* @f2
+ at 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
}
- at ifunc_func = ifunc void (), i64 ()* @resolver
- at dso_local_ifunc_func = dso_local ifunc void (), i64 ()* @resolver
+ at ifunc_func = ifunc void (), void ()* ()* @resolver
+ at 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, at function
; CHECK-NEXT: foo_ifunc:
- at foo = ifunc i32 (i32), i64 ()* @foo_ifunc
+ at foo = ifunc i32 (i32), i32 (i32)* ()* @foo_ifunc
; CHECK: .type foo, at 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"
- at i1 = ifunc void(), void()* @f1, partition "part6"
+ at 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"
- at foo = ifunc i32 (i32), i64 ()* @foo_resolver
- at strlen = ifunc i64 (i8*), bitcast (i64 (i8*)* ()* @strlen_resolver to i64 (i8*)*)
+ at 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
- at foo = ifunc i32 (), i32 ()* @foo_resolver
+; CHECK: @foo = ifunc i32 (), i32 ()* ()* @foo_resolver.2
+ at 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
- at foo = ifunc void (), bitcast (void ()* ()* @foo_resolve to void ()*)
- at bar = ifunc void (), bitcast (void ()* ()* @bar_resolve to void ()*)
+ at foo = ifunc void (), void ()* ()* @foo_resolve
+ at 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
}
- at ifunc_f1 = ifunc void (), void ()* @f1
+ at 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"
- at foo = ifunc i32 (i32), i64 ()* @foo_ifunc
+ at 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"
- at if = ifunc void (), void ()* @fn
+ at 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(
More information about the llvm-commits
mailing list