[llvm] 9791667 - [IR] Support ifuncs in opaque pointer mode

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 27 04:01:41 PST 2022


Author: Nikita Popov
Date: 2022-01-27T13:01:33+01:00
New Revision: 97916673d402c1d4915e6d49386a9d7739aca002

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

LOG: [IR] Support ifuncs in opaque pointer mode

Relax the type assertion for opaque pointers, and enumerate the
value type in TypeFinder and ValueEnumerator.

Added: 
    

Modified: 
    llvm/lib/AsmParser/LLParser.cpp
    llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
    llvm/lib/IR/TypeFinder.cpp
    llvm/test/Assembler/opaque-ptr-struct-types.ll
    llvm/test/Assembler/opaque-ptr.ll
    llvm/test/Other/force-opaque-ptrs.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d93d41cd08467..432ec151cf8ae 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -985,17 +985,18 @@ bool LLParser::parseAliasOrIFunc(const std::string &Name, LocTy NameLoc,
     return error(AliaseeLoc, "An alias or ifunc must have pointer type");
   unsigned AddrSpace = PTy->getAddressSpace();
 
-  if (IsAlias && !PTy->isOpaqueOrPointeeTypeMatches(Ty)) {
-    return error(
-        ExplicitTypeLoc,
-        typeComparisonErrorMessage(
-            "explicit pointee type doesn't match operand's pointee type", Ty,
-            PTy->getNonOpaquePointerElementType()));
-  }
-
-  if (!IsAlias && !PTy->getPointerElementType()->isFunctionTy()) {
-    return error(ExplicitTypeLoc,
-                 "explicit pointee type should be a function type");
+  if (IsAlias) {
+    if (!PTy->isOpaqueOrPointeeTypeMatches(Ty))
+      return error(
+          ExplicitTypeLoc,
+          typeComparisonErrorMessage(
+              "explicit pointee type doesn't match operand's pointee type", Ty,
+              PTy->getNonOpaquePointerElementType()));
+  } else {
+    if (!PTy->isOpaque() &&
+        !PTy->getNonOpaquePointerElementType()->isFunctionTy())
+      return error(ExplicitTypeLoc,
+                   "explicit pointee type should be a function type");
   }
 
   GlobalValue *GVal = nullptr;

diff  --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
index df4f1a1873d7b..01f7e85bd60ed 100644
--- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
+++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp
@@ -386,8 +386,10 @@ ValueEnumerator::ValueEnumerator(const Module &M,
   }
 
   // Enumerate the ifuncs.
-  for (const GlobalIFunc &GIF : M.ifuncs())
+  for (const GlobalIFunc &GIF : M.ifuncs()) {
     EnumerateValue(&GIF);
+    EnumerateType(GIF.getValueType());
+  }
 
   // Remember what is the cutoff between globalvalue's and other constants.
   unsigned FirstConstant = Values.size();

diff  --git a/llvm/lib/IR/TypeFinder.cpp b/llvm/lib/IR/TypeFinder.cpp
index 248c33b7b8679..904af7e737ccf 100644
--- a/llvm/lib/IR/TypeFinder.cpp
+++ b/llvm/lib/IR/TypeFinder.cpp
@@ -48,6 +48,10 @@ void TypeFinder::run(const Module &M, bool onlyNamed) {
       incorporateValue(Aliasee);
   }
 
+  // Get types from ifuncs.
+  for (const auto &GI : M.ifuncs())
+    incorporateType(GI.getValueType());
+
   // Get types from functions.
   SmallVector<std::pair<unsigned, MDNode *>, 4> MDForInst;
   for (const Function &FI : M) {

diff  --git a/llvm/test/Assembler/opaque-ptr-struct-types.ll b/llvm/test/Assembler/opaque-ptr-struct-types.ll
index f9aaa5a609b55..19d79ad3c820d 100644
--- a/llvm/test/Assembler/opaque-ptr-struct-types.ll
+++ b/llvm/test/Assembler/opaque-ptr-struct-types.ll
@@ -1,12 +1,13 @@
 ; RUN: opt -S -opaque-pointers < %s | opt -S -opaque-pointers | FileCheck %s
 
-; CHECK: %T1 = type { i8 }
-; CHECK: %T2 = type { i8 }
-; CHECK: %T3 = type { i8 }
-; CHECK: %T4 = type { i8 }
-; CHECK: %T5 = type { i8 }
-; CHECK: %T6 = type { i8 }
-; CHECK: %T7 = type { i8 }
+; CHECK-DAG: %T1 = type { i8 }
+; CHECK-DAG: %T2 = type { i8 }
+; CHECK-DAG: %T3 = type { i8 }
+; CHECK-DAG: %T4 = type { i8 }
+; CHECK-DAG: %T5 = type { i8 }
+; CHECK-DAG: %T6 = type { i8 }
+; CHECK-DAG: %T7 = type { i8 }
+; CHECK-DAG: %T8 = type { i8 }
 
 %T1 = type { i8 }
 %T2 = type { i8 }
@@ -15,9 +16,12 @@
 %T5 = type { i8 }
 %T6 = type { i8 }
 %T7 = type { i8 }
+%T8 = type { i8 }
 
 @g = external global %T1
 
+ at g.ifunc = ifunc %T8 (), ptr @f
+
 define %T2 @f(ptr %p) {
   alloca %T3
   getelementptr %T4, ptr %p, i64 1

diff  --git a/llvm/test/Assembler/opaque-ptr.ll b/llvm/test/Assembler/opaque-ptr.ll
index 37544ac17e0c1..ad292f880c56d 100644
--- a/llvm/test/Assembler/opaque-ptr.ll
+++ b/llvm/test/Assembler/opaque-ptr.ll
@@ -11,6 +11,9 @@
 @fptr2 = external global ptr () addrspace(1)*
 @fptr3 = external global ptr () addrspace(1)* addrspace(2)*
 
+; CHECK: @ifunc = ifunc void (), ptr @f
+ at ifunc = ifunc void (), ptr @f
+
 ; CHECK: define ptr @f(ptr %a) {
 ; CHECK:     %b = bitcast ptr %a to ptr
 ; CHECK:     ret ptr %b

diff  --git a/llvm/test/Other/force-opaque-ptrs.ll b/llvm/test/Other/force-opaque-ptrs.ll
index cfd0a7609fbb6..d963c7072e207 100644
--- a/llvm/test/Other/force-opaque-ptrs.ll
+++ b/llvm/test/Other/force-opaque-ptrs.ll
@@ -19,6 +19,9 @@
 ; 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 ()* ()*)
+
 define void @f(i32* %p) {
 ; CHECK-LABEL: define {{[^@]+}}@f
 ; CHECK-SAME: (ptr [[P:%.*]]) {


        


More information about the llvm-commits mailing list