@@ -6973,48 +6973,56 @@ bool TBAAVerifier::isValidScalarTBAANode(const MDNode *MD) {
6973
6973
return Result;
6974
6974
}
6975
6975
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.
6978
6979
// /
6979
6980
// / 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) {
6984
6983
assert (BaseNode->getNumOperands () >= 2 && " Invalid base node!" );
6985
6984
6986
6985
// Scalar nodes have only one possible "field" -- their parent in the access
6987
6986
// hierarchy. Offset must be zero at this point, but our caller is supposed
6988
6987
// to check that.
6989
6988
if (BaseNode->getNumOperands () == 2 )
6990
- return cast<MDNode>(BaseNode->getOperand (1 ));
6989
+ return { cast<MDNode>(BaseNode->getOperand (1 ))} ;
6991
6990
6992
6991
unsigned FirstFieldOpNo = IsNewFormat ? 3 : 1 ;
6993
6992
unsigned NumOpsPerField = IsNewFormat ? 3 : 2 ;
6993
+
6994
+ unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
6994
6995
for (unsigned Idx = FirstFieldOpNo; Idx < BaseNode->getNumOperands ();
6995
6996
Idx += NumOpsPerField) {
6996
6997
auto *OffsetEntryCI =
6997
6998
mdconst::extract<ConstantInt>(BaseNode->getOperand (Idx + 1 ));
6998
6999
if (OffsetEntryCI->getValue ().ugt (Offset)) {
6999
7000
if (Idx == FirstFieldOpNo) {
7000
- CheckFailed (" Could not find TBAA parent in struct type node" , &I,
7001
- BaseNode, &Offset);
7002
- return nullptr ;
7001
+ return {};
7003
7002
}
7004
7003
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 ;
7010
7006
}
7011
7007
}
7012
7008
7013
- unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
7014
7009
auto *LastOffsetEntryCI = mdconst::extract<ConstantInt>(
7015
7010
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;
7018
7026
}
7019
7027
7020
7028
static bool isNewFormatTBAATypeNode (llvm::MDNode *Type) {
@@ -7091,47 +7099,84 @@ bool TBAAVerifier::visitTBAAMetadata(Instruction &I, const MDNode *MD) {
7091
7099
CheckTBAA (OffsetCI, " Offset must be constant integer" , &I, MD);
7092
7100
7093
7101
APInt Offset = OffsetCI->getValue ();
7094
- bool SeenAccessTypeInPath = false ;
7095
7102
7096
- SmallPtrSet<MDNode *, 4 > StructPath;
7103
+ SmallPtrSet<const MDNode *, 4 > StructPath;
7097
7104
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);
7105
7107
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 ;
7110
7112
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
+ }
7115
7120
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
+ }
7117
7127
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 ;
7121
7134
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);
7127
7137
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 ;
7130
7165
}
7131
7166
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;
7135
7180
}
7136
7181
7137
7182
char VerifierLegacyPass::ID = 0 ;
0 commit comments