@@ -1186,7 +1186,7 @@ AliasResult BasicAAResult::aliasGEP(
1186
1186
// is less than the size of the associated memory object, then we know
1187
1187
// that the objects are partially overlapping. If the difference is
1188
1188
// greater, we know they do not overlap.
1189
- if (DecompGEP1.Offset != 0 && DecompGEP1. VarIndices .empty ()) {
1189
+ if (DecompGEP1.VarIndices .empty ()) {
1190
1190
APInt &Off = DecompGEP1.Offset ;
1191
1191
1192
1192
// Initialize for Off >= 0 (V2 <= GEP1) case.
@@ -1208,126 +1208,125 @@ AliasResult BasicAAResult::aliasGEP(
1208
1208
Off = -Off;
1209
1209
}
1210
1210
1211
- if (VLeftSize.hasValue ()) {
1212
- const uint64_t LSize = VLeftSize. getValue () ;
1213
- if (Off. ult (LSize)) {
1214
- // Conservatively drop processing if a phi was visited and/or offset is
1215
- // too big.
1216
- AliasResult AR = AliasResult::PartialAlias;
1217
- if (VRightSize. hasValue () && Off. ule (INT32_MAX) &&
1218
- (Off + VRightSize. getValue ()). ule (LSize)) {
1219
- // Memory referenced by right pointer is nested. Save the offset in
1220
- // cache. Note that originally offset estimated as GEP1-V2, but
1221
- // AliasResult contains the shift that represents GEP1+Offset=V2.
1222
- AR. setOffset (-Off. getSExtValue ());
1223
- AR. swap (Swapped);
1224
- }
1225
- return AR ;
1211
+ if (! VLeftSize.hasValue ())
1212
+ return AliasResult::MayAlias ;
1213
+
1214
+ const uint64_t LSize = VLeftSize. getValue ();
1215
+ if (Off. ult (LSize)) {
1216
+ // Conservatively drop processing if a phi was visited and/or offset is
1217
+ // too big.
1218
+ AliasResult AR = AliasResult::PartialAlias;
1219
+ if (VRightSize. hasValue () && Off. ule (INT32_MAX) &&
1220
+ (Off + VRightSize. getValue ()). ule (LSize)) {
1221
+ // Memory referenced by right pointer is nested. Save the offset in
1222
+ // cache. Note that originally offset estimated as GEP1-V2, but
1223
+ // AliasResult contains the shift that represents GEP1+Offset=V2.
1224
+ AR. setOffset (-Off. getSExtValue ());
1225
+ AR. swap (Swapped) ;
1226
1226
}
1227
- return AliasResult::NoAlias ;
1227
+ return AR ;
1228
1228
}
1229
+ return AliasResult::NoAlias;
1229
1230
}
1230
1231
1231
- if (!DecompGEP1.VarIndices .empty ()) {
1232
- APInt GCD;
1233
- ConstantRange OffsetRange = ConstantRange (DecompGEP1.Offset );
1234
- for (unsigned i = 0 , e = DecompGEP1.VarIndices .size (); i != e; ++i) {
1235
- const VariableGEPIndex &Index = DecompGEP1.VarIndices [i];
1236
- const APInt &Scale = Index.Scale ;
1237
- APInt ScaleForGCD = Scale;
1238
- if (!Index.IsNSW )
1239
- ScaleForGCD = APInt::getOneBitSet (Scale.getBitWidth (),
1240
- Scale.countTrailingZeros ());
1241
-
1242
- if (i == 0 )
1243
- GCD = ScaleForGCD.abs ();
1244
- else
1245
- GCD = APIntOps::GreatestCommonDivisor (GCD, ScaleForGCD.abs ());
1246
-
1247
- ConstantRange CR =
1248
- computeConstantRange (Index.Val .V , true , &AC, Index.CxtI );
1249
- KnownBits Known =
1250
- computeKnownBits (Index.Val .V , DL, 0 , &AC, Index.CxtI , DT);
1251
- CR = CR.intersectWith (
1252
- ConstantRange::fromKnownBits (Known, /* Signed */ true ),
1253
- ConstantRange::Signed);
1254
- CR = Index.Val .evaluateWith (CR).sextOrTrunc (OffsetRange.getBitWidth ());
1255
-
1256
- assert (OffsetRange.getBitWidth () == Scale.getBitWidth () &&
1257
- " Bit widths are normalized to MaxPointerSize" );
1258
- if (Index.IsNSW )
1259
- OffsetRange = OffsetRange.add (CR.smul_sat (ConstantRange (Scale)));
1260
- else
1261
- OffsetRange = OffsetRange.add (CR.smul_fast (ConstantRange (Scale)));
1262
- }
1263
-
1264
- // We now have accesses at two offsets from the same base:
1265
- // 1. (...)*GCD + DecompGEP1.Offset with size V1Size
1266
- // 2. 0 with size V2Size
1267
- // Using arithmetic modulo GCD, the accesses are at
1268
- // [ModOffset..ModOffset+V1Size) and [0..V2Size). If the first access fits
1269
- // into the range [V2Size..GCD), then we know they cannot overlap.
1270
- APInt ModOffset = DecompGEP1.Offset .srem (GCD);
1271
- if (ModOffset.isNegative ())
1272
- ModOffset += GCD; // We want mod, not rem.
1273
- if (V1Size.hasValue () && V2Size.hasValue () &&
1274
- ModOffset.uge (V2Size.getValue ()) &&
1275
- (GCD - ModOffset).uge (V1Size.getValue ()))
1276
- return AliasResult::NoAlias;
1232
+ APInt GCD;
1233
+ ConstantRange OffsetRange = ConstantRange (DecompGEP1.Offset );
1234
+ for (unsigned i = 0 , e = DecompGEP1.VarIndices .size (); i != e; ++i) {
1235
+ const VariableGEPIndex &Index = DecompGEP1.VarIndices [i];
1236
+ const APInt &Scale = Index.Scale ;
1237
+ APInt ScaleForGCD = Scale;
1238
+ if (!Index.IsNSW )
1239
+ ScaleForGCD = APInt::getOneBitSet (Scale.getBitWidth (),
1240
+ Scale.countTrailingZeros ());
1241
+
1242
+ if (i == 0 )
1243
+ GCD = ScaleForGCD.abs ();
1244
+ else
1245
+ GCD = APIntOps::GreatestCommonDivisor (GCD, ScaleForGCD.abs ());
1246
+
1247
+ ConstantRange CR =
1248
+ computeConstantRange (Index.Val .V , true , &AC, Index.CxtI );
1249
+ KnownBits Known =
1250
+ computeKnownBits (Index.Val .V , DL, 0 , &AC, Index.CxtI , DT);
1251
+ CR = CR.intersectWith (
1252
+ ConstantRange::fromKnownBits (Known, /* Signed */ true ),
1253
+ ConstantRange::Signed);
1254
+ CR = Index.Val .evaluateWith (CR).sextOrTrunc (OffsetRange.getBitWidth ());
1255
+
1256
+ assert (OffsetRange.getBitWidth () == Scale.getBitWidth () &&
1257
+ " Bit widths are normalized to MaxPointerSize" );
1258
+ if (Index.IsNSW )
1259
+ OffsetRange = OffsetRange.add (CR.smul_sat (ConstantRange (Scale)));
1260
+ else
1261
+ OffsetRange = OffsetRange.add (CR.smul_fast (ConstantRange (Scale)));
1262
+ }
1277
1263
1278
- if (V1Size.hasValue () && V2Size.hasValue ()) {
1279
- // Compute ranges of potentially accessed bytes for both accesses. If the
1280
- // interseciton is empty, there can be no overlap.
1281
- unsigned BW = OffsetRange.getBitWidth ();
1282
- ConstantRange Range1 = OffsetRange.add (
1283
- ConstantRange (APInt (BW, 0 ), APInt (BW, V1Size.getValue ())));
1284
- ConstantRange Range2 =
1285
- ConstantRange (APInt (BW, 0 ), APInt (BW, V2Size.getValue ()));
1286
- if (Range1.intersectWith (Range2).isEmptySet ())
1287
- return AliasResult::NoAlias;
1288
- }
1264
+ // We now have accesses at two offsets from the same base:
1265
+ // 1. (...)*GCD + DecompGEP1.Offset with size V1Size
1266
+ // 2. 0 with size V2Size
1267
+ // Using arithmetic modulo GCD, the accesses are at
1268
+ // [ModOffset..ModOffset+V1Size) and [0..V2Size). If the first access fits
1269
+ // into the range [V2Size..GCD), then we know they cannot overlap.
1270
+ APInt ModOffset = DecompGEP1.Offset .srem (GCD);
1271
+ if (ModOffset.isNegative ())
1272
+ ModOffset += GCD; // We want mod, not rem.
1273
+ if (V1Size.hasValue () && V2Size.hasValue () &&
1274
+ ModOffset.uge (V2Size.getValue ()) &&
1275
+ (GCD - ModOffset).uge (V1Size.getValue ()))
1276
+ return AliasResult::NoAlias;
1289
1277
1290
- if (V1Size.hasValue () && V2Size.hasValue ()) {
1291
- // Try to determine the range of values for VarIndex such that
1292
- // VarIndex <= -MinAbsVarIndex || MinAbsVarIndex <= VarIndex.
1293
- Optional<APInt> MinAbsVarIndex;
1294
- if (DecompGEP1.VarIndices .size () == 1 ) {
1295
- // VarIndex = Scale*V.
1296
- const VariableGEPIndex &Var = DecompGEP1.VarIndices [0 ];
1297
- if (Var.Val .TruncBits == 0 &&
1298
- isKnownNonZero (Var.Val .V , DL, 0 , &AC, Var.CxtI , DT)) {
1299
- // If V != 0 then abs(VarIndex) >= abs(Scale).
1300
- MinAbsVarIndex = Var.Scale .abs ();
1301
- }
1302
- } else if (DecompGEP1.VarIndices .size () == 2 ) {
1303
- // VarIndex = Scale*V0 + (-Scale)*V1.
1304
- // If V0 != V1 then abs(VarIndex) >= abs(Scale).
1305
- // Check that VisitedPhiBBs is empty, to avoid reasoning about
1306
- // inequality of values across loop iterations.
1307
- const VariableGEPIndex &Var0 = DecompGEP1.VarIndices [0 ];
1308
- const VariableGEPIndex &Var1 = DecompGEP1.VarIndices [1 ];
1309
- if (Var0.Scale == -Var1.Scale && Var0.Val .TruncBits == 0 &&
1310
- Var0.Val .hasSameCastsAs (Var1.Val ) && VisitedPhiBBs.empty () &&
1311
- isKnownNonEqual (Var0.Val .V , Var1.Val .V , DL, &AC, /* CxtI */ nullptr ,
1312
- DT))
1313
- MinAbsVarIndex = Var0.Scale .abs ();
1314
- }
1278
+ if (V1Size.hasValue () && V2Size.hasValue ()) {
1279
+ // Compute ranges of potentially accessed bytes for both accesses. If the
1280
+ // interseciton is empty, there can be no overlap.
1281
+ unsigned BW = OffsetRange.getBitWidth ();
1282
+ ConstantRange Range1 = OffsetRange.add (
1283
+ ConstantRange (APInt (BW, 0 ), APInt (BW, V1Size.getValue ())));
1284
+ ConstantRange Range2 =
1285
+ ConstantRange (APInt (BW, 0 ), APInt (BW, V2Size.getValue ()));
1286
+ if (Range1.intersectWith (Range2).isEmptySet ())
1287
+ return AliasResult::NoAlias;
1288
+ }
1315
1289
1316
- if (MinAbsVarIndex) {
1317
- // The constant offset will have added at least +/-MinAbsVarIndex to it.
1318
- APInt OffsetLo = DecompGEP1.Offset - *MinAbsVarIndex;
1319
- APInt OffsetHi = DecompGEP1.Offset + *MinAbsVarIndex;
1320
- // We know that Offset <= OffsetLo || Offset >= OffsetHi
1321
- if (OffsetLo.isNegative () && (-OffsetLo).uge (V1Size.getValue ()) &&
1322
- OffsetHi.isNonNegative () && OffsetHi.uge (V2Size.getValue ()))
1323
- return AliasResult::NoAlias;
1290
+ if (V1Size.hasValue () && V2Size.hasValue ()) {
1291
+ // Try to determine the range of values for VarIndex such that
1292
+ // VarIndex <= -MinAbsVarIndex || MinAbsVarIndex <= VarIndex.
1293
+ Optional<APInt> MinAbsVarIndex;
1294
+ if (DecompGEP1.VarIndices .size () == 1 ) {
1295
+ // VarIndex = Scale*V.
1296
+ const VariableGEPIndex &Var = DecompGEP1.VarIndices [0 ];
1297
+ if (Var.Val .TruncBits == 0 &&
1298
+ isKnownNonZero (Var.Val .V , DL, 0 , &AC, Var.CxtI , DT)) {
1299
+ // If V != 0 then abs(VarIndex) >= abs(Scale).
1300
+ MinAbsVarIndex = Var.Scale .abs ();
1324
1301
}
1302
+ } else if (DecompGEP1.VarIndices .size () == 2 ) {
1303
+ // VarIndex = Scale*V0 + (-Scale)*V1.
1304
+ // If V0 != V1 then abs(VarIndex) >= abs(Scale).
1305
+ // Check that VisitedPhiBBs is empty, to avoid reasoning about
1306
+ // inequality of values across loop iterations.
1307
+ const VariableGEPIndex &Var0 = DecompGEP1.VarIndices [0 ];
1308
+ const VariableGEPIndex &Var1 = DecompGEP1.VarIndices [1 ];
1309
+ if (Var0.Scale == -Var1.Scale && Var0.Val .TruncBits == 0 &&
1310
+ Var0.Val .hasSameCastsAs (Var1.Val ) && VisitedPhiBBs.empty () &&
1311
+ isKnownNonEqual (Var0.Val .V , Var1.Val .V , DL, &AC, /* CxtI */ nullptr ,
1312
+ DT))
1313
+ MinAbsVarIndex = Var0.Scale .abs ();
1325
1314
}
1326
1315
1327
- if (constantOffsetHeuristic (DecompGEP1, V1Size, V2Size, &AC, DT))
1328
- return AliasResult::NoAlias;
1316
+ if (MinAbsVarIndex) {
1317
+ // The constant offset will have added at least +/-MinAbsVarIndex to it.
1318
+ APInt OffsetLo = DecompGEP1.Offset - *MinAbsVarIndex;
1319
+ APInt OffsetHi = DecompGEP1.Offset + *MinAbsVarIndex;
1320
+ // We know that Offset <= OffsetLo || Offset >= OffsetHi
1321
+ if (OffsetLo.isNegative () && (-OffsetLo).uge (V1Size.getValue ()) &&
1322
+ OffsetHi.isNonNegative () && OffsetHi.uge (V2Size.getValue ()))
1323
+ return AliasResult::NoAlias;
1324
+ }
1329
1325
}
1330
1326
1327
+ if (constantOffsetHeuristic (DecompGEP1, V1Size, V2Size, &AC, DT))
1328
+ return AliasResult::NoAlias;
1329
+
1331
1330
// Statically, we can see that the base objects are the same, but the
1332
1331
// pointers have dynamic offsets which we can't resolve. And none of our
1333
1332
// little tricks above worked.
0 commit comments