diff options
author | Clement Courbet <courbet@google.com> | 2021-10-11 09:49:00 +0200 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2021-10-11 10:04:22 +0200 |
commit | 83ded5d3239170a430e49cde80ea40e68b9af230 (patch) | |
tree | 53ee49f1a5518aaa1b58352034db66899e9382f3 /llvm/lib/Analysis/BasicAliasAnalysis.cpp | |
parent | c63cb0c80ec7eb2dedad6e89fb9a3042b71d3b0f (diff) | |
download | llvm-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.cpp | 44 |
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)) |