[llvm] fe46688 - Verifier: Check ifunc resolver functions return a pointer

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 27 09:54:44 PST 2022


Author: Matt Arsenault
Date: 2022-11-27T12:42:08-05:00
New Revision: fe466887d1bd9a68fa2f82fda3b33b7a619c6082

URL: https://github.com/llvm/llvm-project/commit/fe466887d1bd9a68fa2f82fda3b33b7a619c6082
DIFF: https://github.com/llvm/llvm-project/commit/fe466887d1bd9a68fa2f82fda3b33b7a619c6082.diff

LOG: Verifier: Check ifunc resolver functions return a pointer

Clang and gcc both reject trying to use ifunc with a function which
doesn't return a pointer type. Some opaque pointer tests were using
this, apparently by accident.

Added: 
    

Modified: 
    llvm/lib/IR/Verifier.cpp
    llvm/test/Assembler/opaque-ptr-struct-types.ll
    llvm/test/Other/force-opaque-ptrs.ll
    llvm/test/Verifier/ifunc.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 67eabcac30c3..1f5d5d9c0324 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -888,6 +888,10 @@ void Verifier::visitGlobalIFunc(const GlobalIFunc &GI) {
   // Check that the immediate resolver operand (prior to any bitcasts) has the
   // correct type.
   const Type *ResolverTy = GI.getResolver()->getType();
+
+  Check(isa<PointerType>(Resolver->getFunctionType()->getReturnType()),
+        "IFunc resolver must return a pointer", &GI);
+
   const Type *ResolverFuncTy =
       GlobalIFunc::getResolverFunctionType(GI.getValueType());
   Check(ResolverTy == ResolverFuncTy->getPointerTo(GI.getAddressSpace()),

diff  --git a/llvm/test/Assembler/opaque-ptr-struct-types.ll b/llvm/test/Assembler/opaque-ptr-struct-types.ll
index 19d79ad3c820..55ece6fb2d6f 100644
--- a/llvm/test/Assembler/opaque-ptr-struct-types.ll
+++ b/llvm/test/Assembler/opaque-ptr-struct-types.ll
@@ -20,7 +20,7 @@
 
 @g = external global %T1
 
- at g.ifunc = ifunc %T8 (), ptr @f
+ at g.ifunc = ifunc %T8 (), ptr @f.resolver
 
 define %T2 @f(ptr %p) {
   alloca %T3
@@ -30,4 +30,12 @@ define %T2 @f(ptr %p) {
   unreachable
 }
 
+define %T2* @f.resolver(ptr %p) {
+  alloca %T3
+  getelementptr %T4, ptr %p, i64 1
+  call void @f(ptr sret(%T5) %p)
+  store ptr getelementptr (%T6, ptr @g, i64 1), ptr %p
+  unreachable
+}
+
 declare void @f2(ptr sret(%T7))

diff  --git a/llvm/test/Other/force-opaque-ptrs.ll b/llvm/test/Other/force-opaque-ptrs.ll
index 4f33169b56da..895bbdb06756 100644
--- a/llvm/test/Other/force-opaque-ptrs.ll
+++ b/llvm/test/Other/force-opaque-ptrs.ll
@@ -20,8 +20,15 @@
 ; CHECK: @ga2 = alias i19, ptr @g2
 @ga2 = alias i19, i19* bitcast (i18* @g2 to i19*)
 
-; CHECK: @gi = ifunc i20 (), ptr @f
- at gi = ifunc i20 (), i20 ()* ()* bitcast (void (i32*)* @f to i20 ()* ()*)
+; CHECK: @gi = ifunc i20 (), ptr @resolver
+ at gi = ifunc i20 (), i20 ()* ()* bitcast (i32* ()* @resolver to i20 ()* ()*)
+
+
+define i32* @resolver() {
+  %load = load i32, i32* @g.fwd
+  %ptr = inttoptr i32 %load to i32*
+  ret i32* %ptr
+}
 
 define void @f(i32* %p) {
 ; CHECK-LABEL: define {{[^@]+}}@f

diff  --git a/llvm/test/Verifier/ifunc.ll b/llvm/test/Verifier/ifunc.ll
index e2130370e8da..b9fb456ac7a2 100644
--- a/llvm/test/Verifier/ifunc.ll
+++ b/llvm/test/Verifier/ifunc.ll
@@ -27,3 +27,11 @@ define available_externally void ()* @resolver_linker_decl() {
 @inval_resolver_type = ifunc i32 (), void ()* ()* @resolver
 ; CHECK: IFunc resolver has incorrect type
 ; CHECK-NEXT: @inval_resolver_type
+
+ at ifunc_nonpointer_return_type = ifunc i32 (), i32 ()* @resolver_returns_nonpointer
+; CHECK: IFunc resolver must return a pointer
+; CHECK-NEXT: i32 ()* @ifunc_nonpointer_return_type
+
+define i32 @resolver_returns_nonpointer() {
+  ret i32 0
+}


        


More information about the llvm-commits mailing list