diff options
author | Piotr Padlewski <piotr.padlewski@gmail.com> | 2018-05-23 09:16:44 +0000 |
---|---|---|
committer | Piotr Padlewski <piotr.padlewski@gmail.com> | 2018-05-23 09:16:44 +0000 |
commit | d6f7346a4b4bdbdfef9ba7a5b8619e42091e2440 (patch) | |
tree | 9c009d37ea6f02879925ab71d94ac81a32701753 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | eb13d3d22e9bd303b4065b372a692cd04e4b8cc1 (diff) | |
download | llvm-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.cpp | 34 |
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)) |