diff options
author | David Green <david.green@arm.com> | 2024-02-05 11:20:50 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-05 11:20:50 +0000 |
commit | 84ea236af9f36d409d2c45c66f8a8b6eb027935d (patch) | |
tree | ff6e0a59682ced9a431e3ccf75d0d3729e191340 /llvm/lib/Analysis/BasicAliasAnalysis.cpp | |
parent | 13e52b32790e3c3d2fb16139f082a588b4e0f4db (diff) | |
download | llvm-84ea236af9f36d409d2c45c66f8a8b6eb027935d.zip llvm-84ea236af9f36d409d2c45c66f8a8b6eb027935d.tar.gz llvm-84ea236af9f36d409d2c45c66f8a8b6eb027935d.tar.bz2 |
[BasicAA] Handle scalable type sizes with constant offsets (#80445)
This is a separate, but related issue to #69152 that was attempting to improve
AA with scalable dependency distances. This patch attempts to improve when
there are scalable accesses with a constant offset between them. We happen to
get a report of such a thing recently, where so long as the vscale_range is
known, the maximum size of the access can be assessed and better aliasing
results can be returned.
The Upper range of the vscale_range, along with known part of the typesize are
used to prove that Off >= CR.upper * LSize. It does not try to produce
PartialAlias results at the moment from the lower vscale_range. It also enables
the added benefit of allowing better alias analysis when the RHS of the two
values is scalable, but the LHS is normal and can be treated like any other
aliasing query.
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 1028b52..19c4393 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -1113,10 +1113,6 @@ AliasResult BasicAAResult::aliasGEP( return BaseAlias; } - // Bail on analysing scalable LocationSize - if (V1Size.isScalable() || V2Size.isScalable()) - return AliasResult::MayAlias; - // If there is a constant difference between the pointers, but the difference // is less than the size of the associated memory object, then we know // that the objects are partially overlapping. If the difference is @@ -1146,24 +1142,38 @@ AliasResult BasicAAResult::aliasGEP( if (!VLeftSize.hasValue()) return AliasResult::MayAlias; - const uint64_t LSize = VLeftSize.getValue(); - if (Off.ult(LSize)) { - // Conservatively drop processing if a phi was visited and/or offset is - // too big. - AliasResult AR = AliasResult::PartialAlias; - if (VRightSize.hasValue() && Off.ule(INT32_MAX) && - (Off + VRightSize.getValue()).ule(LSize)) { - // Memory referenced by right pointer is nested. Save the offset in - // cache. Note that originally offset estimated as GEP1-V2, but - // AliasResult contains the shift that represents GEP1+Offset=V2. - AR.setOffset(-Off.getSExtValue()); - AR.swap(Swapped); + const TypeSize LSize = VLeftSize.getValue(); + if (!LSize.isScalable()) { + if (Off.ult(LSize)) { + // Conservatively drop processing if a phi was visited and/or offset is + // too big. + AliasResult AR = AliasResult::PartialAlias; + if (VRightSize.hasValue() && !VRightSize.isScalable() && + Off.ule(INT32_MAX) && (Off + VRightSize.getValue()).ule(LSize)) { + // Memory referenced by right pointer is nested. Save the offset in + // cache. Note that originally offset estimated as GEP1-V2, but + // AliasResult contains the shift that represents GEP1+Offset=V2. + AR.setOffset(-Off.getSExtValue()); + AR.swap(Swapped); + } + return AR; } - return AR; + return AliasResult::NoAlias; + } else { + // We can use the getVScaleRange to prove that Off >= (CR.upper * LSize). + ConstantRange CR = getVScaleRange(&F, Off.getBitWidth()); + bool Overflow; + APInt UpperRange = CR.getUnsignedMax().umul_ov( + APInt(Off.getBitWidth(), LSize.getKnownMinValue()), Overflow); + if (!Overflow && Off.uge(UpperRange)) + return AliasResult::NoAlias; } - return AliasResult::NoAlias; } + // Bail on analysing scalable LocationSize + if (V1Size.isScalable() || V2Size.isScalable()) + return AliasResult::MayAlias; + // We need to know both acess sizes for all the following heuristics. if (!V1Size.hasValue() || !V2Size.hasValue()) return AliasResult::MayAlias; |