aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2021-10-25 18:47:51 +0200
committerNikita Popov <nikita.ppv@gmail.com>2021-10-27 12:40:58 +0200
commit9bc7e543b4ef5eef2be2325204db20073fc18e36 (patch)
tree07eae588b91008192875657627023a5834f54b37 /llvm/lib/Analysis/BasicAliasAnalysis.cpp
parentdb848fbf671d99256b2840e19ed3b0b349069e48 (diff)
downloadllvm-9bc7e543b4ef5eef2be2325204db20073fc18e36.zip
llvm-9bc7e543b4ef5eef2be2325204db20073fc18e36.tar.gz
llvm-9bc7e543b4ef5eef2be2325204db20073fc18e36.tar.bz2
[BasicAA] Make range check more precise
Make the range check more precise by calculating the range of potentially accessed bytes for both accesses and checking whether their intersection is empty. In that case there can be no overlap between the accesses and the result is NoAlias. This is more powerful than the previous approach, because it can deal with sign-wrapped ranges. In the test case the original range is [-1, INT_MAX] but becomes [0, INT_MIN] after applying the offset. This is a wrapping range, so getSignedMin/getSignedMax will treat it as a full range. However, the range excludes the elements [INT_MIN+1, -1], which is enough to prove NoAlias with an access at offset -1. Differential Revision: https://reviews.llvm.org/D112486
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp26
1 files changed, 13 insertions, 13 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index f0e5d65..0305732 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1252,7 +1252,7 @@ AliasResult BasicAAResult::aliasGEP(
APInt GCD;
bool AllNonNegative = DecompGEP1.Offset.isNonNegative();
bool AllNonPositive = DecompGEP1.Offset.isNonPositive();
- ConstantRange Range = ConstantRange(DecompGEP1.Offset);
+ ConstantRange OffsetRange = ConstantRange(DecompGEP1.Offset);
for (unsigned i = 0, e = DecompGEP1.VarIndices.size(); i != e; ++i) {
const VariableGEPIndex &Index = DecompGEP1.VarIndices[i];
const APInt &Scale = Index.Scale;
@@ -1277,12 +1277,12 @@ AliasResult BasicAAResult::aliasGEP(
(SignKnownOne && Scale.isNonNegative());
}
- assert(Range.getBitWidth() == Scale.getBitWidth() &&
+ assert(OffsetRange.getBitWidth() == Scale.getBitWidth() &&
"Bit widths are normalized to MaxPointerSize");
- Range = Range.add(Index.Val
+ OffsetRange = OffsetRange.add(Index.Val
.evaluateWith(computeConstantRange(
Index.Val.V, true, &AC, Index.CxtI))
- .sextOrTrunc(Range.getBitWidth())
+ .sextOrTrunc(OffsetRange.getBitWidth())
.smul_fast(ConstantRange(Scale)));
}
@@ -1315,15 +1315,15 @@ AliasResult BasicAAResult::aliasGEP(
(-DecompGEP1.Offset).uge(V1Size.getValue()))
return AliasResult::NoAlias;
- if (!Range.isEmptySet()) {
- // We know that Offset >= MinOffset.
- // (MinOffset >= V2Size) => (Offset >= V2Size) => NoAlias.
- if (V2Size.hasValue() && Range.getSignedMin().sge(V2Size.getValue()))
- return AliasResult::NoAlias;
-
- // We know that Offset <= MaxOffset.
- // (MaxOffset <= -V1Size) => (Offset <= -V1Size) => NoAlias.
- if (V1Size.hasValue() && Range.getSignedMax().sle(-V1Size.getValue()))
+ if (V1Size.hasValue() && V2Size.hasValue()) {
+ // Compute ranges of potentially accessed bytes for both accesses. If the
+ // interseciton is empty, there can be no overlap.
+ unsigned BW = OffsetRange.getBitWidth();
+ ConstantRange Range1 = OffsetRange.add(
+ ConstantRange(APInt(BW, 0), APInt(BW, V1Size.getValue())));
+ ConstantRange Range2 =
+ ConstantRange(APInt(BW, 0), APInt(BW, V2Size.getValue()));
+ if (Range1.intersectWith(Range2).isEmptySet())
return AliasResult::NoAlias;
}