aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorPiotr Padlewski <piotr.padlewski@gmail.com>2018-05-23 09:16:44 +0000
committerPiotr Padlewski <piotr.padlewski@gmail.com>2018-05-23 09:16:44 +0000
commitd6f7346a4b4bdbdfef9ba7a5b8619e42091e2440 (patch)
tree9c009d37ea6f02879925ab71d94ac81a32701753 /llvm/lib/Analysis/ValueTracking.cpp
parenteb13d3d22e9bd303b4065b372a692cd04e4b8cc1 (diff)
downloadllvm-d6f7346a4b4bdbdfef9ba7a5b8619e42091e2440.zip
llvm-d6f7346a4b4bdbdfef9ba7a5b8619e42091e2440.tar.gz
llvm-d6f7346a4b4bdbdfef9ba7a5b8619e42091e2440.tar.bz2
Fix aliasing of launder.invariant.group
Summary: Patch for capture tracking broke bootstrap of clang with -fstict-vtable-pointers which resulted in debbugging nightmare. It was fixed https://reviews.llvm.org/D46900 but as it turned out, there were other parts like inliner (computing of noalias metadata) that I found after bootstraping with enabled assertions. Reviewers: hfinkel, rsmith, chandlerc, amharc, kuhar Subscribers: JDevlieghere, eraman, llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D47088 llvm-svn: 333070
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp34
1 files changed, 29 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 0b0dfde..7f33c67 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1956,8 +1956,8 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) {
if (auto CS = ImmutableCallSite(V)) {
if (CS.isReturnNonNull())
return true;
- if (CS.getIntrinsicID() == Intrinsic::ID::launder_invariant_group)
- return isKnownNonZero(CS->getOperand(0), Depth + 1, Q);
+ if (const auto *RP = getArgumentAliasingToReturnedPointer(CS))
+ return isKnownNonZero(RP, Depth + 1, Q);
}
}
@@ -3385,6 +3385,22 @@ uint64_t llvm::GetStringLength(const Value *V, unsigned CharSize) {
return Len == ~0ULL ? 1 : Len;
}
+const Value *llvm::getArgumentAliasingToReturnedPointer(ImmutableCallSite CS) {
+ assert(CS &&
+ "getArgumentAliasingToReturnedPointer only works on nonnull CallSite");
+ if (const Value *RV = CS.getReturnedArgOperand())
+ return RV;
+ // This can be used only as a aliasing property.
+ if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(CS))
+ return CS.getArgOperand(0);
+ return nullptr;
+}
+
+bool llvm::isIntrinsicReturningPointerAliasingArgumentWithoutCapturing(
+ ImmutableCallSite CS) {
+ return CS.getIntrinsicID() == Intrinsic::launder_invariant_group;
+}
+
/// \p PN defines a loop-variant pointer to an object. Check if the
/// previous iteration of the loop was referring to the same object as \p PN.
static bool isSameUnderlyingObjectInLoop(const PHINode *PN,
@@ -3430,11 +3446,19 @@ Value *llvm::GetUnderlyingObject(Value *V, const DataLayout &DL,
// An alloca can't be further simplified.
return V;
} else {
- if (auto CS = CallSite(V))
- if (Value *RV = CS.getReturnedArgOperand()) {
- V = RV;
+ if (auto CS = CallSite(V)) {
+ // Note: getArgumentAliasingToReturnedPointer keeps it in sync with
+ // CaptureTracking, which is needed for correctness. This is because
+ // some intrinsics like launder.invariant.group returns pointers that
+ // are aliasing it's argument, which is known to CaptureTracking.
+ // If AliasAnalysis does not use the same information, it could assume
+ // that pointer returned from launder does not alias it's argument
+ // because launder could not return it if the pointer was not captured.
+ if (auto *RP = getArgumentAliasingToReturnedPointer(CS)) {
+ V = RP;
continue;
}
+ }
// See if InstructionSimplify knows any relevant tricks.
if (Instruction *I = dyn_cast<Instruction>(V))