aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Function.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-03-25 10:50:13 +0100
committerNikita Popov <npopov@redhat.com>2022-03-30 09:51:24 +0200
commit8a72391f609f016b0aef17e728aca65027a80cc4 (patch)
tree27b84859a3c0d8fd89dc6acd3aba41203fe53273 /llvm/lib/IR/Function.cpp
parentf54f448525e3c6ba39c9cea9f166192593c25133 (diff)
downloadllvm-8a72391f609f016b0aef17e728aca65027a80cc4.zip
llvm-8a72391f609f016b0aef17e728aca65027a80cc4.tar.gz
llvm-8a72391f609f016b0aef17e728aca65027a80cc4.tar.bz2
[IR] Require intrinsic struct return type to be anonymous
This is an alternative to D122376. Rather than working around the problem, this patch requires that struct return types in intrinsics are anonymous/literal and adds auto-upgrade code to convert existing uses of intrinsics with named struct types. This ensures that the mapping between intrinsic name and intrinsic function type is actually bijective, as it is supposed to be. This also fixes https://github.com/llvm/llvm-project/issues/37891. Differential Revision: https://reviews.llvm.org/D122471
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r--llvm/lib/IR/Function.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 3298591..87a0770 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -1475,9 +1475,19 @@ static bool matchIntrinsicType(
PointerType *PT = dyn_cast<PointerType>(Ty);
if (!PT || PT->getAddressSpace() != D.Pointer_AddressSpace)
return true;
- if (!PT->isOpaque())
+ if (!PT->isOpaque()) {
+ /* Manually consume a pointer to empty struct descriptor, which is
+ * used for externref. We don't want to enforce that the struct is
+ * anonymous in this case. (This renders externref intrinsics
+ * non-unique, but this will go away with opaque pointers anyway.) */
+ if (Infos.front().Kind == IITDescriptor::Struct &&
+ Infos.front().Struct_NumElements == 0) {
+ Infos = Infos.slice(1);
+ return false;
+ }
return matchIntrinsicType(PT->getNonOpaquePointerElementType(), Infos,
ArgTys, DeferredChecks, IsDeferredCheck);
+ }
// Consume IIT descriptors relating to the pointer element type.
// FIXME: Intrinsic type matching of nested single value types or even
// aggregates doesn't work properly with opaque pointers but hopefully
@@ -1491,7 +1501,8 @@ static bool matchIntrinsicType(
case IITDescriptor::Struct: {
StructType *ST = dyn_cast<StructType>(Ty);
- if (!ST || ST->getNumElements() != D.Struct_NumElements)
+ if (!ST || !ST->isLiteral() || ST->isPacked() ||
+ ST->getNumElements() != D.Struct_NumElements)
return true;
for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)