[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