ibookstein updated this revision to Diff 381754.
ibookstein added a comment.
Now using arcanist because commit includes change to binary file.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112349/new/
https://reviews.llvm.org/D112349
Files:
clang/lib/CodeGen/CodeGenModule.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-6.0.ll
llvm/test/Bitcode/compatibility-6.0.ll.bc
llvm/test/Bitcode/compatibility.ll
llvm/test/Bitcode/dso_local_equivalent.ll
llvm/test/Bitcode/dso_location.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
Index: llvm/test/Transforms/GlobalDCE/global-ifunc.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/global-ifunc.ll
+++ 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(
Index: llvm/test/ThinLTO/X86/empty-module.ll
===================================================================
--- llvm/test/ThinLTO/X86/empty-module.ll
+++ 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
}
Index: llvm/test/Object/X86/nm-ir.ll
===================================================================
--- llvm/test/Object/X86/nm-ir.ll
+++ 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
Index: llvm/test/Linker/ifunc.ll
===================================================================
--- llvm/test/Linker/ifunc.ll
+++ 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
Index: llvm/test/LTO/Resolution/X86/ifunc2.ll
===================================================================
--- llvm/test/LTO/Resolution/X86/ifunc2.ll
+++ 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 ()*)
Index: llvm/test/LTO/Resolution/X86/ifunc.ll
===================================================================
--- llvm/test/LTO/Resolution/X86/ifunc.ll
+++ 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
}
Index: llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll
===================================================================
--- llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll
+++ 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 ()*)
}
Index: llvm/test/CodeGen/X86/partition.ll
===================================================================
--- llvm/test/CodeGen/X86/partition.ll
+++ 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"
Index: llvm/test/CodeGen/X86/ifunc-asm.ll
===================================================================
--- llvm/test/CodeGen/X86/ifunc-asm.ll
+++ 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
Index: llvm/test/CodeGen/X86/dso_local_equivalent.ll
===================================================================
--- llvm/test/CodeGen/X86/dso_local_equivalent.ll
+++ 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
Index: llvm/test/CodeGen/X86/addrsig.ll
===================================================================
--- llvm/test/CodeGen/X86/addrsig.ll
+++ 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)
Index: llvm/test/Bitcode/dso_location.ll
===================================================================
--- llvm/test/Bitcode/dso_location.ll
+++ 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
}
Index: llvm/test/Bitcode/dso_local_equivalent.ll
===================================================================
--- llvm/test/Bitcode/dso_local_equivalent.ll
+++ 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() {
Index: llvm/test/Bitcode/compatibility.ll
===================================================================
--- llvm/test/Bitcode/compatibility.ll
+++ llvm/test/Bitcode/compatibility.ll
@@ -264,28 +264,28 @@
; <ResolverTy>* @<Resolver>
; IFunc -- Linkage
[email protected] = external ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.external = ifunc void (), i8* ()* @ifunc_resolver
[email protected] = private ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver
[email protected] = internal ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver
[email protected] = external ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.external = ifunc void (), void ()* ()* @ifunc_resolver
[email protected] = private ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.private = private ifunc void (), void ()* ()* @ifunc_resolver
[email protected] = internal ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.internal = internal ifunc void (), void ()* ()* @ifunc_resolver
; IFunc -- Visibility
[email protected] = default ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.default = ifunc void (), i8* ()* @ifunc_resolver
[email protected] = hidden ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver
[email protected] = protected ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver
[email protected] = default ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.default = ifunc void (), void ()* ()* @ifunc_resolver
[email protected] = hidden ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.hidden = hidden ifunc void (), void ()* ()* @ifunc_resolver
[email 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"
[email protected] = ifunc void (), i8* ()* @ifunc_resolver, partition "part"
+; CHECK: @ifunc.partition = ifunc void (), void ()* ()* @ifunc_resolver, partition "part"
[email protected] = ifunc void (), void ()* ()* @ifunc_resolver, partition "part"
-define i8* @ifunc_resolver() {
+define void ()* @ifunc_resolver() {
entry:
- ret i8* null
+ ret void ()* null
}
;; Functions
Index: llvm/test/Bitcode/compatibility-6.0.ll
===================================================================
--- llvm/test/Bitcode/compatibility-6.0.ll
+++ llvm/test/Bitcode/compatibility-6.0.ll
@@ -254,24 +254,24 @@
; <ResolverTy>* @<Resolver>
; IFunc -- Linkage
[email protected] = external ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.external = ifunc void (), i8* ()* @ifunc_resolver
[email protected] = private ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver
[email protected] = internal ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver
[email protected] = external ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.external = ifunc void (), void ()* ()* @ifunc_resolver
[email protected] = private ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.private = private ifunc void (), void ()* ()* @ifunc_resolver
[email protected] = internal ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.internal = internal ifunc void (), void ()* ()* @ifunc_resolver
; IFunc -- Visibility
[email protected] = default ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.default = ifunc void (), i8* ()* @ifunc_resolver
[email protected] = hidden ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver
[email protected] = protected ifunc void (), i8* ()* @ifunc_resolver
-; CHECK: @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver
-
-define i8* @ifunc_resolver() {
[email protected] = default ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.default = ifunc void (), void ()* ()* @ifunc_resolver
[email protected] = hidden ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.hidden = hidden ifunc void (), void ()* ()* @ifunc_resolver
[email protected] = protected ifunc void (), void ()* ()* @ifunc_resolver
+; CHECK: @ifunc.protected = protected ifunc void (), void ()* ()* @ifunc_resolver
+
+define void ()* @ifunc_resolver() {
entry:
- ret i8* null
+ ret void ()* null
}
;; Functions
Index: llvm/test/Bindings/llvm-c/echo.ll
===================================================================
--- llvm/test/Bindings/llvm-c/echo.ll
+++ 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) {
Index: llvm/test/Assembler/ifunc-use-list-order.ll
===================================================================
--- llvm/test/Assembler/ifunc-use-list-order.ll
+++ 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.
Index: llvm/test/Assembler/ifunc-dsolocal.ll
===================================================================
--- llvm/test/Assembler/ifunc-dsolocal.ll
+++ 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
}
Index: llvm/test/Assembler/ifunc-asm.ll
===================================================================
--- llvm/test/Assembler/ifunc-asm.ll
+++ 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()
Index: llvm/lib/IR/Verifier.cpp
===================================================================
--- llvm/lib/IR/Verifier.cpp
+++ 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<const GlobalAlias *> &Visited,
const GlobalAlias &A, const Constant &C);
@@ -821,6 +825,24 @@
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 a
+ // pointer-to-function type whose return type matches the ifunc
+ const auto *ResTy = dyn_cast<PointerType>(GI.getResolver()->getType());
+ Assert(ResTy, "IFunc resolver must have a pointer type", &GI);
+ const auto *ResFuncTy = dyn_cast<FunctionType>(ResTy->getElementType());
+ Assert(ResFuncTy, "IFunc resolver type must be pointer to function", &GI);
+ Assert(GI.getType() == ResFuncTy->getReturnType(),
+ "IFunc resolver return type must match IFunc 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.
Index: llvm/lib/IR/Globals.cpp
===================================================================
--- llvm/lib/IR/Globals.cpp
+++ llvm/lib/IR/Globals.cpp
@@ -541,5 +541,5 @@
const Function *GlobalIFunc::getResolverFunction() const {
DenseSet<const GlobalAlias *> Aliases;
- return cast<Function>(findBaseObject(getResolver(), Aliases));
+ return dyn_cast<Function>(findBaseObject(getResolver(), Aliases));
}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -5013,8 +5013,10 @@
Aliases.push_back(GD);
llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
+ llvm::Type *ResolverTy =
+ llvm::FunctionType::get(DeclTy->getPointerTo(), false);
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,
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits