@@ -527,6 +527,8 @@ struct VariableGEPIndex {
527
527
return Scale == Other.Scale ;
528
528
}
529
529
530
+ bool isSubtracted () const { return IsNegated || Scale.isNegative (); }
531
+
530
532
void dump () const {
531
533
print (dbgs ());
532
534
dbgs () << " \n " ;
@@ -561,8 +563,8 @@ struct BasicAAResult::DecomposedGEP {
561
563
dbgs () << " \n " ;
562
564
}
563
565
void print (raw_ostream &OS) const {
564
- OS << " (DecomposedGEP Base=" << Base->getName ()
565
- << " , Offset =" << Offset
566
+ OS << " (DecomposedGEP Base=" << Base->getName () << " , Offset= " << Offset
567
+ << " , nuw =" << ((NWFlags && NWFlags-> hasNoUnsignedWrap ()) ? " 1 " : " 0 " )
566
568
<< " , VarIndices=[" ;
567
569
for (size_t i = 0 ; i < VarIndices.size (); i++) {
568
570
if (i != 0 )
@@ -1238,27 +1240,26 @@ AliasResult BasicAAResult::aliasGEP(
1238
1240
}
1239
1241
}
1240
1242
1241
- // If the difference between pointers is Offset +<nuw> Indices (the variable
1242
- // indices all come from nuw GEPs) then we know that the addition does not
1243
- // wrap the pointer index type (add nuw) and the constant Offset is a lower
1244
- // bound on the distance between the pointers. We can then prove NoAlias via
1245
- // Offset u>= VLeftSize.
1243
+ // If the difference between pointers is Offset +<nuw> Indices then we know
1244
+ // that the addition does not wrap the pointer index type (add nuw) and the
1245
+ // constant Offset is a lower bound on the distance between the pointers. We
1246
+ // can then prove NoAlias via Offset u>= VLeftSize.
1246
1247
// + + +
1247
1248
// | BaseOffset | +<nuw> Indices |
1248
1249
// ---------------->|-------------------->|
1249
1250
// |-->VLeftSize | |-------> VRightSize
1250
1251
// LHS RHS
1251
1252
if (!DecompGEP1.VarIndices .empty () &&
1252
1253
llvm::all_of (DecompGEP1.VarIndices , [&](const VariableGEPIndex &V) {
1253
- return V.IsNegated == DecompGEP1.VarIndices .front ().IsNegated ;
1254
+ return V.isSubtracted () == DecompGEP1.VarIndices .front ().isSubtracted () ;
1254
1255
})) {
1255
- APInt Off = DecompGEP1.Offset ;
1256
+ const APInt & Off = DecompGEP1.Offset ;
1256
1257
bool Swapped = Off.isNegative ();
1257
1258
LocationSize VLeftSize = Swapped ? V1Size : V2Size;
1258
- DecomposedGEP &DecompRight = Swapped ? DecompGEP2 : DecompGEP1;
1259
+ const DecomposedGEP &DecompRight = Swapped ? DecompGEP2 : DecompGEP1;
1259
1260
1260
- bool IndicesFromRight = DecompGEP1.VarIndices .front ().IsNegated == Swapped;
1261
- if (IndicesFromRight && DecompRight.NWFlags ->hasNoUnsignedWrap ())
1261
+ bool IndicesAdded = DecompGEP1.VarIndices .front ().isSubtracted () == Swapped;
1262
+ if (IndicesAdded && DecompRight.NWFlags ->hasNoUnsignedWrap ())
1262
1263
if (VLeftSize.hasValue () && !VLeftSize.isScalable () &&
1263
1264
Off.abs ().uge (VLeftSize.getValue ()))
1264
1265
return AliasResult::NoAlias;
@@ -1866,8 +1867,15 @@ bool BasicAAResult::isValueEqualInPotentialCycles(const Value *V,
1866
1867
1867
1868
// / Computes the symbolic difference between two de-composed GEPs.
1868
1869
void BasicAAResult::subtractDecomposedGEPs (DecomposedGEP &DestGEP,
1869
- const DecomposedGEP &SrcGEP,
1870
+ DecomposedGEP &SrcGEP,
1870
1871
const AAQueryInfo &AAQI) {
1872
+ // Drop nuw flag from GEP if subtraction of constant offsets overflows in an
1873
+ // unsigned sense.
1874
+ if (DestGEP.Offset .ult (SrcGEP.Offset ))
1875
+ DestGEP.NWFlags = DestGEP.NWFlags ->withoutNoUnsignedWrap ();
1876
+ else if (SrcGEP.Offset .ult (DestGEP.Offset ) && SrcGEP.NWFlags )
1877
+ SrcGEP.NWFlags = SrcGEP.NWFlags ->withoutNoUnsignedWrap ();
1878
+
1871
1879
DestGEP.Offset -= SrcGEP.Offset ;
1872
1880
for (const VariableGEPIndex &Src : SrcGEP.VarIndices ) {
1873
1881
// Find V in Dest. This is N^2, but pointer indices almost never have more
@@ -1890,6 +1898,13 @@ void BasicAAResult::subtractDecomposedGEPs(DecomposedGEP &DestGEP,
1890
1898
// If we found it, subtract off Scale V's from the entry in Dest. If it
1891
1899
// goes to zero, remove the entry.
1892
1900
if (Dest.Scale != Src.Scale ) {
1901
+ // Drop nuw flag from GEP if subtraction of V's Scale overflows in an
1902
+ // unsigned sense.
1903
+ if (Dest.Scale .ult (Src.Scale ))
1904
+ DestGEP.NWFlags = DestGEP.NWFlags ->withoutNoUnsignedWrap ();
1905
+ else if (SrcGEP.NWFlags )
1906
+ SrcGEP.NWFlags = SrcGEP.NWFlags ->withoutNoUnsignedWrap ();
1907
+
1893
1908
Dest.Scale -= Src.Scale ;
1894
1909
Dest.IsNSW = false ;
1895
1910
} else {
0 commit comments