aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Value.cpp
diff options
context:
space:
mode:
authorKuter Dinel <kuterdinel@gmail.com>2020-05-13 12:49:15 -0500
committerJohannes Doerfert <johannes@jdoerfert.de>2020-05-13 16:44:15 -0500
commite57807769b5c21dd06ee293ed7ebaa13f8914ba2 (patch)
treecac7c86aa1a0dc9351dd741e86ec6c3e6cba4c97 /llvm/lib/IR/Value.cpp
parentd6e3e55c40a973e233b168c19b1f1718212b41a4 (diff)
downloadllvm-e57807769b5c21dd06ee293ed7ebaa13f8914ba2.zip
llvm-e57807769b5c21dd06ee293ed7ebaa13f8914ba2.tar.gz
llvm-e57807769b5c21dd06ee293ed7ebaa13f8914ba2.tar.bz2
[Attributor] Use AAValueConstantRange to infer dereferencability.
Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D76208
Diffstat (limited to 'llvm/lib/IR/Value.cpp')
-rw-r--r--llvm/lib/IR/Value.cpp23
1 files changed, 18 insertions, 5 deletions
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index 015bf20..cf54740 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -599,9 +599,9 @@ const Value *Value::stripPointerCastsAndInvariantGroups() const {
return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndInvariantGroups>(this);
}
-const Value *
-Value::stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset,
- bool AllowNonInbounds) const {
+const Value *Value::stripAndAccumulateConstantOffsets(
+ const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
+ function_ref<bool(Value &, APInt &)> ExternalAnalysis) const {
if (!getType()->isPtrOrPtrVectorTy())
return this;
@@ -627,7 +627,7 @@ Value::stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset,
// of GEP's pointer type rather than the size of the original
// pointer type.
APInt GEPOffset(DL.getIndexTypeSizeInBits(V->getType()), 0);
- if (!GEP->accumulateConstantOffset(DL, GEPOffset))
+ if (!GEP->accumulateConstantOffset(DL, GEPOffset, ExternalAnalysis))
return V;
// Stop traversal if the pointer offset wouldn't fit in the bit-width
@@ -636,7 +636,20 @@ Value::stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset,
if (GEPOffset.getMinSignedBits() > BitWidth)
return V;
- Offset += GEPOffset.sextOrTrunc(BitWidth);
+ // External Analysis can return a result higher/lower than the value
+ // represents. We need to detect overflow/underflow.
+ APInt GEPOffsetST = GEPOffset.sextOrTrunc(BitWidth);
+ if (!ExternalAnalysis) {
+ Offset += GEPOffsetST;
+ } else {
+ bool Overflow = false;
+ APInt OldOffset = Offset;
+ Offset = Offset.sadd_ov(GEPOffsetST, Overflow);
+ if (Overflow) {
+ Offset = OldOffset;
+ return V;
+ }
+ }
V = GEP->getPointerOperand();
} else if (Operator::getOpcode(V) == Instruction::BitCast ||
Operator::getOpcode(V) == Instruction::AddrSpaceCast) {