diff --git a/llvm/include/llvm/IR/TypeFinder.h b/llvm/include/llvm/IR/TypeFinder.h index a83f85ea84c30..dd2b70c65c2d2 100644 --- a/llvm/include/llvm/IR/TypeFinder.h +++ b/llvm/include/llvm/IR/TypeFinder.h @@ -14,6 +14,7 @@ #define LLVM_IR_TYPEFINDER_H #include "llvm/ADT/DenseSet.h" +#include "llvm/IR/Attributes.h" #include #include @@ -32,6 +33,7 @@ class TypeFinder { // objects, we keep several helper maps. DenseSet VisitedConstants; DenseSet VisitedMetadata; + DenseSet VisitedAttributes; DenseSet VisitedTypes; std::vector StructTypes; @@ -74,6 +76,9 @@ class TypeFinder { /// incorporateMDNode - This method is used to walk the operands of an MDNode /// to find types hiding within. void incorporateMDNode(const MDNode *V); + + /// Incorporate types referenced by attributes. + void incorporateAttributes(AttributeList AL); }; } // end namespace llvm diff --git a/llvm/lib/IR/TypeFinder.cpp b/llvm/lib/IR/TypeFinder.cpp index 1f757d7dbf4e9..248c33b7b8679 100644 --- a/llvm/lib/IR/TypeFinder.cpp +++ b/llvm/lib/IR/TypeFinder.cpp @@ -18,8 +18,10 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" #include "llvm/IR/User.h" @@ -34,14 +36,14 @@ void TypeFinder::run(const Module &M, bool onlyNamed) { // Get types from global variables. for (const auto &G : M.globals()) { - incorporateType(G.getType()); + incorporateType(G.getValueType()); if (G.hasInitializer()) incorporateValue(G.getInitializer()); } // Get types from aliases. for (const auto &A : M.aliases()) { - incorporateType(A.getType()); + incorporateType(A.getValueType()); if (const Value *Aliasee = A.getAliasee()) incorporateValue(Aliasee); } @@ -49,7 +51,8 @@ void TypeFinder::run(const Module &M, bool onlyNamed) { // Get types from functions. SmallVector, 4> MDForInst; for (const Function &FI : M) { - incorporateType(FI.getType()); + incorporateType(FI.getFunctionType()); + incorporateAttributes(FI.getAttributes()); for (const Use &U : FI.operands()) incorporateValue(U.get()); @@ -69,6 +72,13 @@ void TypeFinder::run(const Module &M, bool onlyNamed) { if (&*O && !isa(&*O)) incorporateValue(&*O); + if (auto *GEP = dyn_cast(&I)) + incorporateType(GEP->getSourceElementType()); + if (auto *AI = dyn_cast(&I)) + incorporateType(AI->getAllocatedType()); + if (const auto *CB = dyn_cast(&I)) + incorporateAttributes(CB->getAttributes()); + // Incorporate types hiding in metadata. I.getAllMetadataOtherThanDebugLoc(MDForInst); for (const auto &MD : MDForInst) @@ -138,6 +148,9 @@ void TypeFinder::incorporateValue(const Value *V) { if (isa(V)) return; + if (auto *GEP = dyn_cast(V)) + incorporateType(GEP->getSourceElementType()); + // Look in operands for types. const User *U = cast(V); for (const auto &I : U->operands()) @@ -173,3 +186,13 @@ void TypeFinder::incorporateMDNode(const MDNode *V) { } } } + +void TypeFinder::incorporateAttributes(AttributeList AL) { + if (!VisitedAttributes.insert(AL).second) + return; + + for (AttributeSet AS : AL) + for (Attribute A : AS) + if (A.isTypeAttribute()) + incorporateType(A.getValueAsType()); +} diff --git a/llvm/test/Assembler/opaque-ptr-struct-types.ll b/llvm/test/Assembler/opaque-ptr-struct-types.ll new file mode 100644 index 0000000000000..f9aaa5a609b55 --- /dev/null +++ b/llvm/test/Assembler/opaque-ptr-struct-types.ll @@ -0,0 +1,29 @@ +; 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 } + +%T1 = type { i8 } +%T2 = type { i8 } +%T3 = type { i8 } +%T4 = type { i8 } +%T5 = type { i8 } +%T6 = type { i8 } +%T7 = type { i8 } + +@g = external global %T1 + +define %T2 @f(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))