@@ -6945,48 +6945,56 @@ bool TBAAVerifier::isValidScalarTBAANode(const MDNode *MD) {
6945
6945
return Result;
6946
6946
}
6947
6947
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.
6950
6951
// /
6951
6952
// / 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) {
6956
6955
assert (BaseNode->getNumOperands () >= 2 && " Invalid base node!" );
6957
6956
6958
6957
// Scalar nodes have only one possible "field" -- their parent in the access
6959
6958
// hierarchy. Offset must be zero at this point, but our caller is supposed
6960
6959
// to check that.
6961
6960
if (BaseNode->getNumOperands () == 2 )
6962
- return cast<MDNode>(BaseNode->getOperand (1 ));
6961
+ return { cast<MDNode>(BaseNode->getOperand (1 ))} ;
6963
6962
6964
6963
unsigned FirstFieldOpNo = IsNewFormat ? 3 : 1 ;
6965
6964
unsigned NumOpsPerField = IsNewFormat ? 3 : 2 ;
6965
+
6966
+ unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
6966
6967
for (unsigned Idx = FirstFieldOpNo; Idx < BaseNode->getNumOperands ();
6967
6968
Idx += NumOpsPerField) {
6968
6969
auto *OffsetEntryCI =
6969
6970
mdconst::extract<ConstantInt>(BaseNode->getOperand (Idx + 1 ));
6970
6971
if (OffsetEntryCI->getValue ().ugt (Offset)) {
6971
6972
if (Idx == FirstFieldOpNo) {
6972
- CheckFailed (" Could not find TBAA parent in struct type node" , &I,
6973
- BaseNode, &Offset);
6974
- return nullptr ;
6973
+ return {};
6975
6974
}
6976
6975
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 ;
6982
6978
}
6983
6979
}
6984
6980
6985
- unsigned LastIdx = BaseNode->getNumOperands () - NumOpsPerField;
6986
6981
auto *LastOffsetEntryCI = mdconst::extract<ConstantInt>(
6987
6982
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;
6990
6998
}
6991
6999
6992
7000
static bool isNewFormatTBAATypeNode (llvm::MDNode *Type) {
@@ -7063,47 +7071,84 @@ bool TBAAVerifier::visitTBAAMetadata(Instruction &I, const MDNode *MD) {
7063
7071
CheckTBAA (OffsetCI, " Offset must be constant integer" , &I, MD);
7064
7072
7065
7073
APInt Offset = OffsetCI->getValue ();
7066
- bool SeenAccessTypeInPath = false ;
7067
7074
7068
- SmallPtrSet<MDNode *, 4 > StructPath;
7075
+ SmallPtrSet<const MDNode *, 4 > StructPath;
7069
7076
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);
7077
7079
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 ;
7082
7084
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
+ }
7087
7092
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
+ }
7089
7099
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 ;
7093
7106
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);
7099
7109
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 ;
7102
7137
}
7103
7138
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;
7107
7152
}
7108
7153
7109
7154
char VerifierLegacyPass::ID = 0 ;
0 commit comments