@@ -530,6 +530,8 @@ struct VariableGEPIndex {
530
530
return Scale == Other.Scale ;
531
531
}
532
532
533
+ bool isSubtracted () const { return IsNegated || Scale.isNegative (); }
534
+
533
535
void dump () const {
534
536
print (dbgs ());
535
537
dbgs () << " \n " ;
@@ -564,8 +566,8 @@ struct BasicAAResult::DecomposedGEP {
564
566
dbgs () << " \n " ;
565
567
}
566
568
void print (raw_ostream &OS) const {
567
- OS << " (DecomposedGEP Base=" << Base->getName ()
568
- << " , Offset =" << Offset
569
+ OS << " (DecomposedGEP Base=" << Base->getName () << " , Offset= " << Offset
570
+ << " , nuw =" << ((NWFlags && NWFlags-> hasNoUnsignedWrap ()) ? " 1 " : " 0 " )
569
571
<< " , VarIndices=[" ;
570
572
for (size_t i = 0 ; i < VarIndices.size (); i++) {
571
573
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