[llvm] 0d20ebf - [BasicAA] Use ranges for more than one index
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 25 06:31:00 PDT 2021
Author: Nikita Popov
Date: 2021-10-25T15:30:50+02:00
New Revision: 0d20ebf6862f77ce0913187c05c02ba5df175f29
URL: https://github.com/llvm/llvm-project/commit/0d20ebf6862f77ce0913187c05c02ba5df175f29
DIFF: https://github.com/llvm/llvm-project/commit/0d20ebf6862f77ce0913187c05c02ba5df175f29.diff
LOG: [BasicAA] Use ranges for more than one index
D109746 made BasicAA use range information to determine the
minimum/maximum GEP offset. However, it was limited to the case of
a single variable index. This patch extends support to multiple
indices by adding all the ranges together.
Differential Revision: https://reviews.llvm.org/D112378
Added:
Modified:
llvm/lib/Analysis/BasicAliasAnalysis.cpp
llvm/test/Analysis/BasicAA/range.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 25b6d9bc73847..f0e5d65f961d1 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1252,6 +1252,7 @@ AliasResult BasicAAResult::aliasGEP(
APInt GCD;
bool AllNonNegative = DecompGEP1.Offset.isNonNegative();
bool AllNonPositive = DecompGEP1.Offset.isNonPositive();
+ ConstantRange Range = 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;
@@ -1275,6 +1276,14 @@ AliasResult BasicAAResult::aliasGEP(
AllNonPositive &= (SignKnownZero && Scale.isNonPositive()) ||
(SignKnownOne && Scale.isNonNegative());
}
+
+ assert(Range.getBitWidth() == Scale.getBitWidth() &&
+ "Bit widths are normalized to MaxPointerSize");
+ Range = Range.add(Index.Val
+ .evaluateWith(computeConstantRange(
+ Index.Val.V, true, &AC, Index.CxtI))
+ .sextOrTrunc(Range.getBitWidth())
+ .smul_fast(ConstantRange(Scale)));
}
// We now have accesses at two offsets from the same base:
@@ -1306,13 +1315,22 @@ 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()))
+ return AliasResult::NoAlias;
+ }
+
if (V1Size.hasValue() && V2Size.hasValue()) {
- // Try to determine the range of values for VarIndex.
- // VarIndexRange is such that:
- // (VarIndex <= -MinAbsVarIndex || MinAbsVarIndex <= VarIndex) &&
- // VarIndexRange.contains(VarIndex)
+ // Try to determine the range of values for VarIndex such that
+ // VarIndex <= -MinAbsVarIndex || MinAbsVarIndex <= VarIndex.
Optional<APInt> MinAbsVarIndex;
- Optional<ConstantRange> VarIndexRange;
if (DecompGEP1.VarIndices.size() == 1) {
// VarIndex = Scale*V.
const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
@@ -1321,11 +1339,6 @@ AliasResult BasicAAResult::aliasGEP(
// If V != 0 then abs(VarIndex) >= abs(Scale).
MinAbsVarIndex = Var.Scale.abs();
}
- ConstantRange R = Var.Val.evaluateWith(
- computeConstantRange(Var.Val.V, true, &AC, Var.CxtI));
- if (!R.isFullSet() && !R.isEmptySet())
- VarIndexRange = R.sextOrTrunc(Var.Scale.getBitWidth())
- .smul_fast(ConstantRange(Var.Scale));
} else if (DecompGEP1.VarIndices.size() == 2) {
// VarIndex = Scale*V0 + (-Scale)*V1.
// If V0 != V1 then abs(VarIndex) >= abs(Scale).
@@ -1349,21 +1362,6 @@ AliasResult BasicAAResult::aliasGEP(
OffsetHi.isNonNegative() && OffsetHi.uge(V2Size.getValue()))
return AliasResult::NoAlias;
}
-
- if (VarIndexRange) {
- ConstantRange OffsetRange =
- VarIndexRange->add(ConstantRange(DecompGEP1.Offset));
-
- // We know that Offset >= MinOffset.
- // (MinOffset >= V2Size) => (Offset >= V2Size) => NoAlias.
- if (OffsetRange.getSignedMin().sge(V2Size.getValue()))
- return AliasResult::NoAlias;
-
- // We know that Offset <= MaxOffset.
- // (MaxOffset <= -V1Size) => (Offset <= -V1Size) => NoAlias.
- if (OffsetRange.getSignedMax().sle(-V1Size.getValue()))
- return AliasResult::NoAlias;
- }
}
if (constantOffsetHeuristic(DecompGEP1, V1Size, V2Size, &AC, DT))
diff --git a/llvm/test/Analysis/BasicAA/range.ll b/llvm/test/Analysis/BasicAA/range.ll
index d1847d618e948..78e6add0f50fa 100644
--- a/llvm/test/Analysis/BasicAA/range.ll
+++ b/llvm/test/Analysis/BasicAA/range.ll
@@ -185,8 +185,7 @@ define void @zeroext_index([256 x i32]* %s, i8* %q) {
; CHECK: NoAlias: i32* %p.01, i32* %p.2
; CHECK: MayAlias: i32* %p.02, i32* %p.2
; CHECK: NoAlias: i32* %p.01, i32* %p.3
-; TODO: This can be NoAlias.
-; CHECK: MayAlias: i32* %p.02, i32* %p.3
+; CHECK: NoAlias: i32* %p.02, i32* %p.3
define void @multiple(i32* %p, i32* %o1_ptr, i32* %o2_ptr) {
%o1 = load i32, i32* %o1_ptr, !range !0
%o2 = load i32, i32* %o2_ptr, !range !0
More information about the llvm-commits
mailing list