@@ -6945,48 +6945,56 @@ bool TBAAVerifier::isValidScalarTBAANode(const MDNode *MD) {
69456945 return Result;
69466946}
69476947
6948- // / Returns the field node at the offset \p Offset in \p BaseNode. Update \p
6949- // / Offset in place to be the offset within the field node returned.
6948+ // / Returns one or several field nodes at the offset \p Offset in \p BaseNode.
6949+ // / Returns empty vector if \p BaseNode has no fields with specified offset.
6950+ // / Update \p Offset in place to be the offset within the field node returned.
69506951// /
69516952// / We assume we've okayed \p BaseNode via \c verifyTBAABaseNode.
6952- MDNode *TBAAVerifier::getFieldNodeFromTBAABaseNode (Instruction &I,
6953- const MDNode *BaseNode,
6954- APInt &Offset,
6955- bool IsNewFormat) {
6953+ std::vector<MDNode *> TBAAVerifier::getFieldNodeFromTBAABaseNode (
6954+ Instruction &I, const MDNode *BaseNode, APInt &Offset, bool IsNewFormat) {
69566955 assert (BaseNode->getNumOperands () >= 2 && " Invalid base node!" );
69576956
69586957 // Scalar nodes have only one possible "field" -- their parent in the access
69596958 // hierarchy. Offset must be zero at this point, but our caller is supposed
69606959 // to check that.
69616960 if (BaseNode->getNumOperands () == 2 )
6962- return cast<MDNode>(BaseNode->getOperand (1 ));
6961+ return { cast<MDNode>(BaseNode->getOperand (1 ))} ;
69636962
69646963 unsigned FirstFieldOpNo = IsNewFormat ? 3 : 1 ;
69656964 unsigned NumOpsPerField = IsNewFormat ? 3 : 2 ;
6965+
6966+ unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
69666967 for (unsigned Idx = FirstFieldOpNo; Idx < BaseNode->getNumOperands ();
69676968 Idx += NumOpsPerField) {
69686969 auto *OffsetEntryCI =
69696970 mdconst::extract<ConstantInt>(BaseNode->getOperand (Idx + 1 ));
69706971 if (OffsetEntryCI->getValue ().ugt (Offset)) {
69716972 if (Idx == FirstFieldOpNo) {
6972- CheckFailed (" Could not find TBAA parent in struct type node" , &I,
6973- BaseNode, &Offset);
6974- return nullptr ;
6973+ return {};
69756974 }
69766975
6977- unsigned PrevIdx = Idx - NumOpsPerField;
6978- auto *PrevOffsetEntryCI =
6979- mdconst::extract<ConstantInt>(BaseNode->getOperand (PrevIdx + 1 ));
6980- Offset -= PrevOffsetEntryCI->getValue ();
6981- return cast<MDNode>(BaseNode->getOperand (PrevIdx));
6976+ LastIdx = Idx - NumOpsPerField;
6977+ break ;
69826978 }
69836979 }
69846980
6985- unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
69866981 auto *LastOffsetEntryCI = mdconst::extract<ConstantInt>(
69876982 BaseNode->getOperand (LastIdx + 1 ));
6988- Offset -= LastOffsetEntryCI->getValue ();
6989- return cast<MDNode>(BaseNode->getOperand (LastIdx));
6983+ auto LastOffsetVal = LastOffsetEntryCI->getValue ();
6984+ Offset -= LastOffsetVal;
6985+
6986+ std::vector<MDNode *> Ret;
6987+ Ret.emplace_back (cast<MDNode>(BaseNode->getOperand (LastIdx)));
6988+ while (LastIdx > FirstFieldOpNo) {
6989+ LastIdx -= NumOpsPerField;
6990+ LastOffsetEntryCI =
6991+ mdconst::extract<ConstantInt>(BaseNode->getOperand (LastIdx + 1 ));
6992+ if (LastOffsetEntryCI->getValue () != LastOffsetVal)
6993+ break ;
6994+ Ret.emplace_back (cast<MDNode>(BaseNode->getOperand (LastIdx)));
6995+ }
6996+
6997+ return Ret;
69906998}
69916999
69927000static bool isNewFormatTBAATypeNode (llvm::MDNode *Type) {
@@ -7063,47 +7071,84 @@ bool TBAAVerifier::visitTBAAMetadata(Instruction &I, const MDNode *MD) {
70637071 CheckTBAA (OffsetCI, " Offset must be constant integer" , &I, MD);
70647072
70657073 APInt Offset = OffsetCI->getValue ();
7066- bool SeenAccessTypeInPath = false ;
70677074
7068- SmallPtrSet<MDNode *, 4 > StructPath;
7075+ SmallPtrSet<const MDNode *, 4 > StructPath;
70697076
7070- for (/* empty */ ; BaseNode && !IsRootTBAANode (BaseNode);
7071- BaseNode = getFieldNodeFromTBAABaseNode (I, BaseNode, Offset,
7072- IsNewFormat)) {
7073- if (!StructPath.insert (BaseNode).second ) {
7074- CheckFailed (" Cycle detected in struct path" , &I, MD);
7075- return false ;
7076- }
7077+ auto &&[Invalid, BaseNodeBitWidth] =
7078+ verifyTBAABaseNode (I, BaseNode, IsNewFormat);
70777079
7078- bool Invalid;
7079- unsigned BaseNodeBitWidth;
7080- std::tie (Invalid, BaseNodeBitWidth) = verifyTBAABaseNode (I, BaseNode,
7081- IsNewFormat) ;
7080+ // If the base node is invalid in itself, then we've already printed all the
7081+ // errors we wanted to print.
7082+ if (Invalid)
7083+ return false ;
70827084
7083- // If the base node is invalid in itself, then we've already printed all the
7084- // errors we wanted to print.
7085- if (Invalid)
7086- return false ;
7085+ bool SeenAccessTypeInPath = BaseNode == AccessType;
7086+ if (SeenAccessTypeInPath) {
7087+ CheckTBAA (Offset == 0 , " Offset not zero at the point of scalar access" , &I,
7088+ MD, &Offset);
7089+ if (IsNewFormat)
7090+ return true ;
7091+ }
70877092
7088- SeenAccessTypeInPath |= BaseNode == AccessType;
7093+ CheckTBAA (findAccessTypeNode (I, StructPath, Offset, IsNewFormat, AccessType,
7094+ BaseNode, MD) ||
7095+ SeenAccessTypeInPath,
7096+ " Did not see access type in access path!" , &I, MD);
7097+ return true ;
7098+ }
70897099
7090- if (isValidScalarTBAANode (BaseNode) || BaseNode == AccessType)
7091- CheckTBAA (Offset == 0 , " Offset not zero at the point of scalar access" ,
7092- &I, MD, &Offset);
7100+ bool TBAAVerifier::findAccessTypeNode (
7101+ Instruction &I, SmallPtrSetImpl<const MDNode *> &StructPath, APInt Offset,
7102+ bool IsNewFormat, const MDNode *AccessType, const MDNode *BaseNode,
7103+ const MDNode *MD) {
7104+ if (!BaseNode || IsRootTBAANode (BaseNode))
7105+ return false ;
70937106
7094- CheckTBAA (BaseNodeBitWidth == Offset.getBitWidth () ||
7095- (BaseNodeBitWidth == 0 && Offset == 0 ) ||
7096- (IsNewFormat && BaseNodeBitWidth == ~0u ),
7097- " Access bit-width not the same as description bit-width" , &I, MD,
7098- BaseNodeBitWidth, Offset.getBitWidth ());
7107+ auto &&[Invalid, BaseNodeBitWidth] =
7108+ verifyTBAABaseNode (I, BaseNode, IsNewFormat);
70997109
7100- if (IsNewFormat && SeenAccessTypeInPath)
7101- break ;
7110+ // If the base node is invalid in itself, then we've already printed all the
7111+ // errors we wanted to print.
7112+ if (Invalid)
7113+ return false ;
7114+
7115+ // Offset at point of scalar access must be zero. Skip mismatched nodes.
7116+ if ((isValidScalarTBAANode (BaseNode) || BaseNode == AccessType) &&
7117+ Offset != 0 )
7118+ return false ;
7119+
7120+ CheckTBAA (BaseNodeBitWidth == Offset.getBitWidth () ||
7121+ (BaseNodeBitWidth == 0 && Offset == 0 ) ||
7122+ (IsNewFormat && BaseNodeBitWidth == ~0u ),
7123+ " Access bit-width not the same as description bit-width" , &I, MD,
7124+ BaseNodeBitWidth, Offset.getBitWidth ());
7125+
7126+ bool SeenAccessTypeInPath = (BaseNode == AccessType && Offset == 0 );
7127+
7128+ if (IsNewFormat && SeenAccessTypeInPath)
7129+ return true ;
7130+
7131+ auto ProbableNodes =
7132+ getFieldNodeFromTBAABaseNode (I, BaseNode, Offset, IsNewFormat);
7133+
7134+ if (!StructPath.insert (BaseNode).second ) {
7135+ CheckFailed (" Cycle detected in struct path" , &I, MD);
7136+ return false ;
71027137 }
71037138
7104- CheckTBAA (SeenAccessTypeInPath, " Did not see access type in access path!" , &I,
7105- MD);
7106- return true ;
7139+ for (auto *PN : ProbableNodes) {
7140+ if (!PN || IsRootTBAANode (PN))
7141+ continue ;
7142+
7143+ SmallPtrSet<const MDNode *, 4 > StructPathCopy;
7144+ StructPathCopy.insert (StructPath.begin (), StructPath.end ());
7145+
7146+ if (findAccessTypeNode (I, StructPathCopy, Offset, IsNewFormat, AccessType,
7147+ PN, MD))
7148+ return true ;
7149+ }
7150+
7151+ return SeenAccessTypeInPath;
71077152}
71087153
71097154char VerifierLegacyPass::ID = 0 ;
0 commit comments