aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorClement Courbet <courbet@google.com>2021-10-11 09:49:00 +0200
committerClement Courbet <courbet@google.com>2021-10-11 10:04:22 +0200
commit83ded5d3239170a430e49cde80ea40e68b9af230 (patch)
tree53ee49f1a5518aaa1b58352034db66899e9382f3 /llvm/lib/Analysis/BasicAliasAnalysis.cpp
parentc63cb0c80ec7eb2dedad6e89fb9a3042b71d3b0f (diff)
downloadllvm-83ded5d3239170a430e49cde80ea40e68b9af230.zip
llvm-83ded5d3239170a430e49cde80ea40e68b9af230.tar.gz
llvm-83ded5d3239170a430e49cde80ea40e68b9af230.tar.bz2
re-land "[AA] Teach BasicAA to recognize basic GEP range information."
Now that PR52104 is fixed.
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp44
1 files changed, 39 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 84e7683..69f5cf0 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -31,6 +31,7 @@
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constant.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
@@ -312,6 +313,14 @@ struct ExtendedValue {
return N;
}
+ ConstantRange evaluateWith(ConstantRange N) const {
+ assert(N.getBitWidth() == V->getType()->getPrimitiveSizeInBits() &&
+ "Incompatible bit width");
+ if (SExtBits) N = N.signExtend(N.getBitWidth() + SExtBits);
+ if (ZExtBits) N = N.zeroExtend(N.getBitWidth() + ZExtBits);
+ return N;
+ }
+
bool canDistributeOver(bool NUW, bool NSW) const {
// zext(x op<nuw> y) == zext(x) op<nuw> zext(y)
// sext(x op<nsw> y) == sext(x) op<nsw> sext(y)
@@ -1291,13 +1300,24 @@ AliasResult BasicAAResult::aliasGEP(
return AliasResult::NoAlias;
if (V1Size.hasValue() && V2Size.hasValue()) {
- // Try to determine whether abs(VarIndex) > 0.
+ // Try to determine the range of values for VarIndex.
+ // VarIndexRange is such that:
+ // (VarIndex <= -MinAbsVarIndex || MinAbsVarIndex <= VarIndex) &&
+ // VarIndexRange.contains(VarIndex)
Optional<APInt> MinAbsVarIndex;
+ Optional<ConstantRange> VarIndexRange;
if (DecompGEP1.VarIndices.size() == 1) {
- // VarIndex = Scale*V. If V != 0 then abs(VarIndex) >= abs(Scale).
+ // VarIndex = Scale*V.
const VariableGEPIndex &Var = DecompGEP1.VarIndices[0];
- if (isKnownNonZero(Var.Val.V, DL, 0, &AC, Var.CxtI, DT))
+ if (isKnownNonZero(Var.Val.V, DL, 0, &AC, Var.CxtI, DT)) {
+ // 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())
+ .multiply(ConstantRange(Var.Scale));
} else if (DecompGEP1.VarIndices.size() == 2) {
// VarIndex = Scale*V0 + (-Scale)*V1.
// If V0 != V1 then abs(VarIndex) >= abs(Scale).
@@ -1316,12 +1336,26 @@ AliasResult BasicAAResult::aliasGEP(
// The constant offset will have added at least +/-MinAbsVarIndex to it.
APInt OffsetLo = DecompGEP1.Offset - *MinAbsVarIndex;
APInt OffsetHi = DecompGEP1.Offset + *MinAbsVarIndex;
- // Check that an access at OffsetLo or lower, and an access at OffsetHi
- // or higher both do not alias.
+ // We know that Offset <= OffsetLo || Offset >= OffsetHi
if (OffsetLo.isNegative() && (-OffsetLo).uge(V1Size.getValue()) &&
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))