Skip to content

Commit 0b6ed92

Browse files
committed
[BasicAA] Use early returns (NFC)
Reduce nesting in aliasGEP() a bit by returning early.
1 parent 53900a1 commit 0b6ed92

File tree

1 file changed

+108
-109
lines changed

1 file changed

+108
-109
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 108 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,7 @@ AliasResult BasicAAResult::aliasGEP(
11861186
// is less than the size of the associated memory object, then we know
11871187
// that the objects are partially overlapping. If the difference is
11881188
// greater, we know they do not overlap.
1189-
if (DecompGEP1.Offset != 0 && DecompGEP1.VarIndices.empty()) {
1189+
if (DecompGEP1.VarIndices.empty()) {
11901190
APInt &Off = DecompGEP1.Offset;
11911191

11921192
// Initialize for Off >= 0 (V2 <= GEP1) case.
@@ -1208,126 +1208,125 @@ AliasResult BasicAAResult::aliasGEP(
12081208
Off = -Off;
12091209
}
12101210

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);
12261226
}
1227-
return AliasResult::NoAlias;
1227+
return AR;
12281228
}
1229+
return AliasResult::NoAlias;
12291230
}
12301231

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+
}
12771263

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;
12891277

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+
}
13151289

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();
13241301
}
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();
13251314
}
13261315

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+
}
13291325
}
13301326

1327+
if (constantOffsetHeuristic(DecompGEP1, V1Size, V2Size, &AC, DT))
1328+
return AliasResult::NoAlias;
1329+
13311330
// Statically, we can see that the base objects are the same, but the
13321331
// pointers have dynamic offsets which we can't resolve. And none of our
13331332
// little tricks above worked.

0 commit comments

Comments
 (0)