diff options
author | Davide Italiano <davide@freebsd.org> | 2016-12-07 21:47:32 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2016-12-07 21:47:32 +0000 |
commit | 1ed5396304ff6c29a043bed467f375efbff83d25 (patch) | |
tree | 1e1208133139937a51509c8ec9309699abef5a1b /llvm/lib | |
parent | 26d060fbf9fe5525f06f13c398ad1c564528fe57 (diff) | |
download | bcm5719-llvm-1ed5396304ff6c29a043bed467f375efbff83d25.tar.gz bcm5719-llvm-1ed5396304ff6c29a043bed467f375efbff83d25.zip |
[BDCE] Skip metadata while replacing uses.
The fix committed in r288851 doesn't cover all the cases.
In particular, if we have an instruction with side effects
which has a no non-dbg use not depending on the bits, we still
perform RAUW destroying the dbg.value's first argument.
Prevent metadata from being replaced here to avoid the issue.
Differential Revision: https://reviews.llvm.org/D27534
llvm-svn: 288987
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/IR/Value.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/BDCE.cpp | 5 |
2 files changed, 13 insertions, 4 deletions
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index 451cb09ea9f..91a999b5800 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -367,7 +367,7 @@ static bool contains(Value *Expr, Value *V) { } #endif // NDEBUG -void Value::replaceAllUsesWith(Value *New) { +void Value::doRAUW(Value *New, bool NoMetadata) { assert(New && "Value::replaceAllUsesWith(<null>) is invalid!"); assert(!contains(New, this) && "this->replaceAllUsesWith(expr(this)) is NOT valid!"); @@ -377,7 +377,7 @@ void Value::replaceAllUsesWith(Value *New) { // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsRAUWd(this, New); - if (isUsedByMetadata()) + if (!NoMetadata && isUsedByMetadata()) ValueAsMetadata::handleRAUW(this, New); while (!use_empty()) { @@ -398,6 +398,14 @@ void Value::replaceAllUsesWith(Value *New) { BB->replaceSuccessorsPhiUsesWith(cast<BasicBlock>(New)); } +void Value::replaceAllUsesWith(Value *New) { + doRAUW(New, false /* NoMetadata */); +} + +void Value::replaceNonMetadataUsesWith(Value *New) { + doRAUW(New, true /* NoMetadata */); +} + // Like replaceAllUsesWith except it does not handle constants or basic blocks. // This routine leaves uses within BB. void Value::replaceUsesOutsideBlock(Value *New, BasicBlock *BB) { diff --git a/llvm/lib/Transforms/Scalar/BDCE.cpp b/llvm/lib/Transforms/Scalar/BDCE.cpp index 1baade43e85..251b3870776 100644 --- a/llvm/lib/Transforms/Scalar/BDCE.cpp +++ b/llvm/lib/Transforms/Scalar/BDCE.cpp @@ -40,7 +40,8 @@ static bool bitTrackingDCE(Function &F, DemandedBits &DB) { bool Changed = false; for (Instruction &I : instructions(F)) { // If the instruction has side effects and no non-dbg uses, - // BDCE should skip it. + // skip it. This way we avoid computing known bits on an instruction + // that will not help us. if (I.mayHaveSideEffects() && I.use_empty()) continue; @@ -55,7 +56,7 @@ static bool bitTrackingDCE(Function &F, DemandedBits &DB) { // undef, poison, etc. Value *Zero = ConstantInt::get(I.getType(), 0); ++NumSimplified; - I.replaceAllUsesWith(Zero); + I.replaceNonMetadataUsesWith(Zero); Changed = true; } if (!DB.isInstructionDead(&I)) |