@@ -6968,48 +6968,56 @@ bool TBAAVerifier::isValidScalarTBAANode(const MDNode *MD) {
69686968 return Result;
69696969}
69706970
6971- // / Returns the field node at the offset \p Offset in \p BaseNode. Update \p
6972- // / Offset in place to be the offset within the field node returned.
6971+ // / Returns one or several field nodes at the offset \p Offset in \p BaseNode.
6972+ // / Returns empty vector if \p BaseNode has no fields with specified offset.
6973+ // / Update \p Offset in place to be the offset within the field node returned.
69736974// /
69746975// / We assume we've okayed \p BaseNode via \c verifyTBAABaseNode.
6975- MDNode *TBAAVerifier::getFieldNodeFromTBAABaseNode (Instruction &I,
6976- const MDNode *BaseNode,
6977- APInt &Offset,
6978- bool IsNewFormat) {
6976+ std::vector<MDNode *> TBAAVerifier::getFieldNodeFromTBAABaseNode (
6977+ Instruction &I, const MDNode *BaseNode, APInt &Offset, bool IsNewFormat) {
69796978 assert (BaseNode->getNumOperands () >= 2 && " Invalid base node!" );
69806979
69816980 // Scalar nodes have only one possible "field" -- their parent in the access
69826981 // hierarchy. Offset must be zero at this point, but our caller is supposed
69836982 // to check that.
69846983 if (BaseNode->getNumOperands () == 2 )
6985- return cast<MDNode>(BaseNode->getOperand (1 ));
6984+ return { cast<MDNode>(BaseNode->getOperand (1 ))} ;
69866985
69876986 unsigned FirstFieldOpNo = IsNewFormat ? 3 : 1 ;
69886987 unsigned NumOpsPerField = IsNewFormat ? 3 : 2 ;
6988+
6989+ unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
69896990 for (unsigned Idx = FirstFieldOpNo; Idx < BaseNode->getNumOperands ();
69906991 Idx += NumOpsPerField) {
69916992 auto *OffsetEntryCI =
69926993 mdconst::extract<ConstantInt>(BaseNode->getOperand (Idx + 1 ));
69936994 if (OffsetEntryCI->getValue ().ugt (Offset)) {
69946995 if (Idx == FirstFieldOpNo) {
6995- CheckFailed (" Could not find TBAA parent in struct type node" , &I,
6996- BaseNode, &Offset);
6997- return nullptr ;
6996+ return {};
69986997 }
69996998
7000- unsigned PrevIdx = Idx - NumOpsPerField;
7001- auto *PrevOffsetEntryCI =
7002- mdconst::extract<ConstantInt>(BaseNode->getOperand (PrevIdx + 1 ));
7003- Offset -= PrevOffsetEntryCI->getValue ();
7004- return cast<MDNode>(BaseNode->getOperand (PrevIdx));
6999+ LastIdx = Idx - NumOpsPerField;
7000+ break ;
70057001 }
70067002 }
70077003
7008- unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
70097004 auto *LastOffsetEntryCI = mdconst::extract<ConstantInt>(
70107005 BaseNode->getOperand (LastIdx + 1 ));
7011- Offset -= LastOffsetEntryCI->getValue ();
7012- return cast<MDNode>(BaseNode->getOperand (LastIdx));
7006+ auto LastOffsetVal = LastOffsetEntryCI->getValue ();
7007+ Offset -= LastOffsetVal;
7008+
7009+ std::vector<MDNode *> Ret;
7010+ Ret.emplace_back (cast<MDNode>(BaseNode->getOperand (LastIdx)));
7011+ while (LastIdx > FirstFieldOpNo) {
7012+ LastIdx -= NumOpsPerField;
7013+ LastOffsetEntryCI =
7014+ mdconst::extract<ConstantInt>(BaseNode->getOperand (LastIdx + 1 ));
7015+ if (LastOffsetEntryCI->getValue () != LastOffsetVal)
7016+ break ;
7017+ Ret.emplace_back (cast<MDNode>(BaseNode->getOperand (LastIdx)));
7018+ }
7019+
7020+ return Ret;
70137021}
70147022
70157023static bool isNewFormatTBAATypeNode (llvm::MDNode *Type) {
@@ -7086,47 +7094,84 @@ bool TBAAVerifier::visitTBAAMetadata(Instruction &I, const MDNode *MD) {
70867094 CheckTBAA (OffsetCI, " Offset must be constant integer" , &I, MD);
70877095
70887096 APInt Offset = OffsetCI->getValue ();
7089- bool SeenAccessTypeInPath = false ;
70907097
7091- SmallPtrSet<MDNode *, 4 > StructPath;
7098+ SmallPtrSet<const MDNode *, 4 > StructPath;
70927099
7093- for (/* empty */ ; BaseNode && !IsRootTBAANode (BaseNode);
7094- BaseNode = getFieldNodeFromTBAABaseNode (I, BaseNode, Offset,
7095- IsNewFormat)) {
7096- if (!StructPath.insert (BaseNode).second ) {
7097- CheckFailed (" Cycle detected in struct path" , &I, MD);
7098- return false ;
7099- }
7100+ auto &&[Invalid, BaseNodeBitWidth] =
7101+ verifyTBAABaseNode (I, BaseNode, IsNewFormat);
71007102
7101- bool Invalid;
7102- unsigned BaseNodeBitWidth;
7103- std::tie (Invalid, BaseNodeBitWidth) = verifyTBAABaseNode (I, BaseNode,
7104- IsNewFormat) ;
7103+ // If the base node is invalid in itself, then we've already printed all the
7104+ // errors we wanted to print.
7105+ if (Invalid)
7106+ return false ;
71057107
7106- // If the base node is invalid in itself, then we've already printed all the
7107- // errors we wanted to print.
7108- if (Invalid)
7109- return false ;
7108+ bool SeenAccessTypeInPath = BaseNode == AccessType;
7109+ if (SeenAccessTypeInPath) {
7110+ CheckTBAA (Offset == 0 , " Offset not zero at the point of scalar access" , &I,
7111+ MD, &Offset);
7112+ if (IsNewFormat)
7113+ return true ;
7114+ }
71107115
7111- SeenAccessTypeInPath |= BaseNode == AccessType;
7116+ CheckTBAA (findAccessTypeNode (I, StructPath, Offset, IsNewFormat, AccessType,
7117+ BaseNode, MD) ||
7118+ SeenAccessTypeInPath,
7119+ " Did not see access type in access path!" , &I, MD);
7120+ return true ;
7121+ }
71127122
7113- if (isValidScalarTBAANode (BaseNode) || BaseNode == AccessType)
7114- CheckTBAA (Offset == 0 , " Offset not zero at the point of scalar access" ,
7115- &I, MD, &Offset);
7123+ bool TBAAVerifier::findAccessTypeNode (
7124+ Instruction &I, SmallPtrSetImpl<const MDNode *> &StructPath, APInt Offset,
7125+ bool IsNewFormat, const MDNode *AccessType, const MDNode *BaseNode,
7126+ const MDNode *MD) {
7127+ if (!BaseNode || IsRootTBAANode (BaseNode))
7128+ return false ;
71167129
7117- CheckTBAA (BaseNodeBitWidth == Offset.getBitWidth () ||
7118- (BaseNodeBitWidth == 0 && Offset == 0 ) ||
7119- (IsNewFormat && BaseNodeBitWidth == ~0u ),
7120- " Access bit-width not the same as description bit-width" , &I, MD,
7121- BaseNodeBitWidth, Offset.getBitWidth ());
7130+ auto &&[Invalid, BaseNodeBitWidth] =
7131+ verifyTBAABaseNode (I, BaseNode, IsNewFormat);
71227132
7123- if (IsNewFormat && SeenAccessTypeInPath)
7124- break ;
7133+ // If the base node is invalid in itself, then we've already printed all the
7134+ // errors we wanted to print.
7135+ if (Invalid)
7136+ return false ;
7137+
7138+ // Offset at point of scalar access must be zero. Skip mismatched nodes.
7139+ if ((isValidScalarTBAANode (BaseNode) || BaseNode == AccessType) &&
7140+ Offset != 0 )
7141+ return false ;
7142+
7143+ CheckTBAA (BaseNodeBitWidth == Offset.getBitWidth () ||
7144+ (BaseNodeBitWidth == 0 && Offset == 0 ) ||
7145+ (IsNewFormat && BaseNodeBitWidth == ~0u ),
7146+ " Access bit-width not the same as description bit-width" , &I, MD,
7147+ BaseNodeBitWidth, Offset.getBitWidth ());
7148+
7149+ bool SeenAccessTypeInPath = (BaseNode == AccessType && Offset == 0 );
7150+
7151+ if (IsNewFormat && SeenAccessTypeInPath)
7152+ return true ;
7153+
7154+ auto ProbableNodes =
7155+ getFieldNodeFromTBAABaseNode (I, BaseNode, Offset, IsNewFormat);
7156+
7157+ if (!StructPath.insert (BaseNode).second ) {
7158+ CheckFailed (" Cycle detected in struct path" , &I, MD);
7159+ return false ;
71257160 }
71267161
7127- CheckTBAA (SeenAccessTypeInPath, " Did not see access type in access path!" , &I,
7128- MD);
7129- return true ;
7162+ for (auto *PN : ProbableNodes) {
7163+ if (!PN || IsRootTBAANode (PN))
7164+ continue ;
7165+
7166+ SmallPtrSet<const MDNode *, 4 > StructPathCopy;
7167+ StructPathCopy.insert (StructPath.begin (), StructPath.end ());
7168+
7169+ if (findAccessTypeNode (I, StructPathCopy, Offset, IsNewFormat, AccessType,
7170+ PN, MD))
7171+ return true ;
7172+ }
7173+
7174+ return SeenAccessTypeInPath;
71307175}
71317176
71327177char VerifierLegacyPass::ID = 0 ;
0 commit comments