@@ -6973,48 +6973,56 @@ bool TBAAVerifier::isValidScalarTBAANode(const MDNode *MD) {
69736973 return Result;
69746974}
69756975
6976- // / Returns the field node at the offset \p Offset in \p BaseNode. Update \p
6977- // / Offset in place to be the offset within the field node returned.
6976+ // / Returns one or several field nodes at the offset \p Offset in \p BaseNode.
6977+ // / Returns empty vector if \p BaseNode has no fields with specified offset.
6978+ // / Update \p Offset in place to be the offset within the field node returned.
69786979// /
69796980// / We assume we've okayed \p BaseNode via \c verifyTBAABaseNode.
6980- MDNode *TBAAVerifier::getFieldNodeFromTBAABaseNode (Instruction &I,
6981- const MDNode *BaseNode,
6982- APInt &Offset,
6983- bool IsNewFormat) {
6981+ std::vector<MDNode *> TBAAVerifier::getFieldNodeFromTBAABaseNode (
6982+ Instruction &I, const MDNode *BaseNode, APInt &Offset, bool IsNewFormat) {
69846983 assert (BaseNode->getNumOperands () >= 2 && " Invalid base node!" );
69856984
69866985 // Scalar nodes have only one possible "field" -- their parent in the access
69876986 // hierarchy. Offset must be zero at this point, but our caller is supposed
69886987 // to check that.
69896988 if (BaseNode->getNumOperands () == 2 )
6990- return cast<MDNode>(BaseNode->getOperand (1 ));
6989+ return { cast<MDNode>(BaseNode->getOperand (1 ))} ;
69916990
69926991 unsigned FirstFieldOpNo = IsNewFormat ? 3 : 1 ;
69936992 unsigned NumOpsPerField = IsNewFormat ? 3 : 2 ;
6993+
6994+ unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
69946995 for (unsigned Idx = FirstFieldOpNo; Idx < BaseNode->getNumOperands ();
69956996 Idx += NumOpsPerField) {
69966997 auto *OffsetEntryCI =
69976998 mdconst::extract<ConstantInt>(BaseNode->getOperand (Idx + 1 ));
69986999 if (OffsetEntryCI->getValue ().ugt (Offset)) {
69997000 if (Idx == FirstFieldOpNo) {
7000- CheckFailed (" Could not find TBAA parent in struct type node" , &I,
7001- BaseNode, &Offset);
7002- return nullptr ;
7001+ return {};
70037002 }
70047003
7005- unsigned PrevIdx = Idx - NumOpsPerField;
7006- auto *PrevOffsetEntryCI =
7007- mdconst::extract<ConstantInt>(BaseNode->getOperand (PrevIdx + 1 ));
7008- Offset -= PrevOffsetEntryCI->getValue ();
7009- return cast<MDNode>(BaseNode->getOperand (PrevIdx));
7004+ LastIdx = Idx - NumOpsPerField;
7005+ break ;
70107006 }
70117007 }
70127008
7013- unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
70147009 auto *LastOffsetEntryCI = mdconst::extract<ConstantInt>(
70157010 BaseNode->getOperand (LastIdx + 1 ));
7016- Offset -= LastOffsetEntryCI->getValue ();
7017- return cast<MDNode>(BaseNode->getOperand (LastIdx));
7011+ auto LastOffsetVal = LastOffsetEntryCI->getValue ();
7012+ Offset -= LastOffsetVal;
7013+
7014+ std::vector<MDNode *> Ret;
7015+ Ret.emplace_back (cast<MDNode>(BaseNode->getOperand (LastIdx)));
7016+ while (LastIdx > FirstFieldOpNo) {
7017+ LastIdx -= NumOpsPerField;
7018+ LastOffsetEntryCI =
7019+ mdconst::extract<ConstantInt>(BaseNode->getOperand (LastIdx + 1 ));
7020+ if (LastOffsetEntryCI->getValue () != LastOffsetVal)
7021+ break ;
7022+ Ret.emplace_back (cast<MDNode>(BaseNode->getOperand (LastIdx)));
7023+ }
7024+
7025+ return Ret;
70187026}
70197027
70207028static bool isNewFormatTBAATypeNode (llvm::MDNode *Type) {
@@ -7091,47 +7099,84 @@ bool TBAAVerifier::visitTBAAMetadata(Instruction &I, const MDNode *MD) {
70917099 CheckTBAA (OffsetCI, " Offset must be constant integer" , &I, MD);
70927100
70937101 APInt Offset = OffsetCI->getValue ();
7094- bool SeenAccessTypeInPath = false ;
70957102
7096- SmallPtrSet<MDNode *, 4 > StructPath;
7103+ SmallPtrSet<const MDNode *, 4 > StructPath;
70977104
7098- for (/* empty */ ; BaseNode && !IsRootTBAANode (BaseNode);
7099- BaseNode = getFieldNodeFromTBAABaseNode (I, BaseNode, Offset,
7100- IsNewFormat)) {
7101- if (!StructPath.insert (BaseNode).second ) {
7102- CheckFailed (" Cycle detected in struct path" , &I, MD);
7103- return false ;
7104- }
7105+ auto &&[Invalid, BaseNodeBitWidth] =
7106+ verifyTBAABaseNode (I, BaseNode, IsNewFormat);
71057107
7106- bool Invalid;
7107- unsigned BaseNodeBitWidth;
7108- std::tie (Invalid, BaseNodeBitWidth) = verifyTBAABaseNode (I, BaseNode,
7109- IsNewFormat) ;
7108+ // If the base node is invalid in itself, then we've already printed all the
7109+ // errors we wanted to print.
7110+ if (Invalid)
7111+ return false ;
71107112
7111- // If the base node is invalid in itself, then we've already printed all the
7112- // errors we wanted to print.
7113- if (Invalid)
7114- return false ;
7113+ bool SeenAccessTypeInPath = BaseNode == AccessType;
7114+ if (SeenAccessTypeInPath) {
7115+ CheckTBAA (Offset == 0 , " Offset not zero at the point of scalar access" , &I,
7116+ MD, &Offset);
7117+ if (IsNewFormat)
7118+ return true ;
7119+ }
71157120
7116- SeenAccessTypeInPath |= BaseNode == AccessType;
7121+ CheckTBAA (findAccessTypeNode (I, StructPath, Offset, IsNewFormat, AccessType,
7122+ BaseNode, MD) ||
7123+ SeenAccessTypeInPath,
7124+ " Did not see access type in access path!" , &I, MD);
7125+ return true ;
7126+ }
71177127
7118- if (isValidScalarTBAANode (BaseNode) || BaseNode == AccessType)
7119- CheckTBAA (Offset == 0 , " Offset not zero at the point of scalar access" ,
7120- &I, MD, &Offset);
7128+ bool TBAAVerifier::findAccessTypeNode (
7129+ Instruction &I, SmallPtrSetImpl<const MDNode *> &StructPath, APInt Offset,
7130+ bool IsNewFormat, const MDNode *AccessType, const MDNode *BaseNode,
7131+ const MDNode *MD) {
7132+ if (!BaseNode || IsRootTBAANode (BaseNode))
7133+ return false ;
71217134
7122- CheckTBAA (BaseNodeBitWidth == Offset.getBitWidth () ||
7123- (BaseNodeBitWidth == 0 && Offset == 0 ) ||
7124- (IsNewFormat && BaseNodeBitWidth == ~0u ),
7125- " Access bit-width not the same as description bit-width" , &I, MD,
7126- BaseNodeBitWidth, Offset.getBitWidth ());
7135+ auto &&[Invalid, BaseNodeBitWidth] =
7136+ verifyTBAABaseNode (I, BaseNode, IsNewFormat);
71277137
7128- if (IsNewFormat && SeenAccessTypeInPath)
7129- break ;
7138+ // If the base node is invalid in itself, then we've already printed all the
7139+ // errors we wanted to print.
7140+ if (Invalid)
7141+ return false ;
7142+
7143+ // Offset at point of scalar access must be zero. Skip mismatched nodes.
7144+ if ((isValidScalarTBAANode (BaseNode) || BaseNode == AccessType) &&
7145+ Offset != 0 )
7146+ return false ;
7147+
7148+ CheckTBAA (BaseNodeBitWidth == Offset.getBitWidth () ||
7149+ (BaseNodeBitWidth == 0 && Offset == 0 ) ||
7150+ (IsNewFormat && BaseNodeBitWidth == ~0u ),
7151+ " Access bit-width not the same as description bit-width" , &I, MD,
7152+ BaseNodeBitWidth, Offset.getBitWidth ());
7153+
7154+ bool SeenAccessTypeInPath = (BaseNode == AccessType && Offset == 0 );
7155+
7156+ if (IsNewFormat && SeenAccessTypeInPath)
7157+ return true ;
7158+
7159+ auto ProbableNodes =
7160+ getFieldNodeFromTBAABaseNode (I, BaseNode, Offset, IsNewFormat);
7161+
7162+ if (!StructPath.insert (BaseNode).second ) {
7163+ CheckFailed (" Cycle detected in struct path" , &I, MD);
7164+ return false ;
71307165 }
71317166
7132- CheckTBAA (SeenAccessTypeInPath, " Did not see access type in access path!" , &I,
7133- MD);
7134- return true ;
7167+ for (auto *PN : ProbableNodes) {
7168+ if (!PN || IsRootTBAANode (PN))
7169+ continue ;
7170+
7171+ SmallPtrSet<const MDNode *, 4 > StructPathCopy;
7172+ StructPathCopy.insert (StructPath.begin (), StructPath.end ());
7173+
7174+ if (findAccessTypeNode (I, StructPathCopy, Offset, IsNewFormat, AccessType,
7175+ PN, MD))
7176+ return true ;
7177+ }
7178+
7179+ return SeenAccessTypeInPath;
71357180}
71367181
71377182char VerifierLegacyPass::ID = 0 ;
0 commit comments