@@ -6968,48 +6968,56 @@ bool TBAAVerifier::isValidScalarTBAANode(const MDNode *MD) {
6968
6968
return Result;
6969
6969
}
6970
6970
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.
6973
6974
// /
6974
6975
// / 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) {
6979
6978
assert (BaseNode->getNumOperands () >= 2 && " Invalid base node!" );
6980
6979
6981
6980
// Scalar nodes have only one possible "field" -- their parent in the access
6982
6981
// hierarchy. Offset must be zero at this point, but our caller is supposed
6983
6982
// to check that.
6984
6983
if (BaseNode->getNumOperands () == 2 )
6985
- return cast<MDNode>(BaseNode->getOperand (1 ));
6984
+ return { cast<MDNode>(BaseNode->getOperand (1 ))} ;
6986
6985
6987
6986
unsigned FirstFieldOpNo = IsNewFormat ? 3 : 1 ;
6988
6987
unsigned NumOpsPerField = IsNewFormat ? 3 : 2 ;
6988
+
6989
+ unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
6989
6990
for (unsigned Idx = FirstFieldOpNo; Idx < BaseNode->getNumOperands ();
6990
6991
Idx += NumOpsPerField) {
6991
6992
auto *OffsetEntryCI =
6992
6993
mdconst::extract<ConstantInt>(BaseNode->getOperand (Idx + 1 ));
6993
6994
if (OffsetEntryCI->getValue ().ugt (Offset)) {
6994
6995
if (Idx == FirstFieldOpNo) {
6995
- CheckFailed (" Could not find TBAA parent in struct type node" , &I,
6996
- BaseNode, &Offset);
6997
- return nullptr ;
6996
+ return {};
6998
6997
}
6999
6998
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 ;
7005
7001
}
7006
7002
}
7007
7003
7008
- unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
7009
7004
auto *LastOffsetEntryCI = mdconst::extract<ConstantInt>(
7010
7005
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;
7013
7021
}
7014
7022
7015
7023
static bool isNewFormatTBAATypeNode (llvm::MDNode *Type) {
@@ -7086,47 +7094,84 @@ bool TBAAVerifier::visitTBAAMetadata(Instruction &I, const MDNode *MD) {
7086
7094
CheckTBAA (OffsetCI, " Offset must be constant integer" , &I, MD);
7087
7095
7088
7096
APInt Offset = OffsetCI->getValue ();
7089
- bool SeenAccessTypeInPath = false ;
7090
7097
7091
- SmallPtrSet<MDNode *, 4 > StructPath;
7098
+ SmallPtrSet<const MDNode *, 4 > StructPath;
7092
7099
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);
7100
7102
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 ;
7105
7107
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
+ }
7110
7115
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
+ }
7112
7122
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 ;
7116
7129
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);
7122
7132
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 ;
7125
7160
}
7126
7161
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;
7130
7175
}
7131
7176
7132
7177
char VerifierLegacyPass::ID = 0 ;
0 commit comments