aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2021-03-03 08:43:32 -0800
committerPhilip Reames <listmail@philipreames.com>2021-03-03 08:43:32 -0800
commite6e5ef40cbc239754003c93c46df644dad8a8272 (patch)
treea832264246f96ec7497cbcc0df3a6d66e892609b /llvm/lib/Analysis/BasicAliasAnalysis.cpp
parentdd9922c487f34896f142778d4caa55a7d54c3cf4 (diff)
downloadllvm-e6e5ef40cbc239754003c93c46df644dad8a8272.zip
llvm-e6e5ef40cbc239754003c93c46df644dad8a8272.tar.gz
llvm-e6e5ef40cbc239754003c93c46df644dad8a8272.tar.bz2
[basicaa] Fix a latent bug in isGEPBaseAtNegativeOffset
This was pointed out in review of D97520 by Nikita, but existed in the original code as well. The basic issue is that a decomposed GEP expression describes (potentially) more than one getelementptr. The "inbounds" derived UB which justifies this aliasing rule requires that the entire offset be composed of "inbounds" geps. Otherwise, as can be seen in the recently added and changes in this patch test, we can end up with a large commulative offset with only a small sub-offset actually being "inbounds". If that small sub-offset lies within the object, the result was unsound. We could potentially be fancier here, but for the moment, simply be conservative when any of the GEPs parsed aren't inbounds.
Diffstat (limited to 'llvm/lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/BasicAliasAnalysis.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index d954810..f20baad 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -477,6 +477,13 @@ BasicAAResult::DecomposeGEPExpression(const Value *V, const DataLayout &DL,
return Decomposed;
}
+ // Track whether we've seen at least one in bounds gep, and if so, whether
+ // all geps parsed were in bounds.
+ if (Decomposed.InBounds == None)
+ Decomposed.InBounds = GEPOp->isInBounds();
+ else if (!GEPOp->isInBounds())
+ Decomposed.InBounds = false;
+
// Don't attempt to analyze GEPs over unsized objects.
if (!GEPOp->getSourceElementType()->isSized()) {
Decomposed.Base = V;
@@ -1051,7 +1058,7 @@ bool BasicAAResult::isGEPBaseAtNegativeOffset(const GEPOperator *GEPOp,
const DecomposedGEP &DecompGEP, const DecomposedGEP &DecompObject,
LocationSize MaybeObjectAccessSize) {
// If the object access size is unknown, or the GEP isn't inbounds, bail.
- if (!MaybeObjectAccessSize.hasValue() || !GEPOp->isInBounds())
+ if (!MaybeObjectAccessSize.hasValue() || !*DecompGEP.InBounds)
return false;
const uint64_t ObjectAccessSize = MaybeObjectAccessSize.getValue();