Index: lib/Transforms/NaCl/SimplifyAllocas.cpp |
diff --git a/lib/Transforms/NaCl/SimplifyAllocas.cpp b/lib/Transforms/NaCl/SimplifyAllocas.cpp |
index 906b38606efdce907b7d6fc4c54dafa092adc07f..ba25b5f961ad5ca28254e67de200b003bb2558e8 100644 |
--- a/lib/Transforms/NaCl/SimplifyAllocas.cpp |
+++ b/lib/Transforms/NaCl/SimplifyAllocas.cpp |
@@ -15,9 +15,10 @@ |
#include "llvm/IR/DataLayout.h" |
#include "llvm/IR/Function.h" |
#include "llvm/IR/Instructions.h" |
+#include "llvm/IR/IntrinsicInst.h" |
#include "llvm/IR/Module.h" |
#include "llvm/Transforms/NaCl.h" |
- |
+#include "llvm/Support/raw_ostream.h" |
using namespace llvm; |
namespace { |
class SimplifyAllocas : public BasicBlockPass { |
@@ -40,7 +41,7 @@ private: |
bool doInitialization(Function &F) override { |
if (!Initialized) { |
M = F.getParent(); |
- DL = M->getDataLayout(); |
+ DL = &M->getDataLayout(); |
IntPtrType = DL->getIntPtrType(M->getContext()); |
Int8Type = Type::getInt8Ty(M->getContext()); |
Initialized = true; |
@@ -53,7 +54,8 @@ private: |
bool Changed = false; |
for (BasicBlock::iterator I = BB.getFirstInsertionPt(), E = BB.end(); |
I != E;) { |
- if (AllocaInst *Alloca = dyn_cast<AllocaInst>(I++)) { |
+ Instruction *Inst = &*I++; |
+ if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Inst)) { |
Changed = true; |
Type *ElementTy = Alloca->getType()->getPointerElementType(); |
Constant *ElementSize = |
@@ -93,6 +95,28 @@ private: |
Alloca->replaceAllUsesWith(BC); |
Alloca->eraseFromParent(); |
} |
+ else if (auto *Call = dyn_cast<IntrinsicInst>(Inst)) { |
+ if (Call->getIntrinsicID() == Intrinsic::dbg_declare) { |
+ // dbg.declare's first argument is a special metadata that wraps a |
+ // value, and RAUW works on those. It is supposed to refer to the |
+ // alloca that represents the variable's storage, but the alloca |
+ // simplification may have RAUWed it to use the bitcast. |
+ // Fix it up here by recreating the metadata to use the new alloca. |
+ auto *MV = cast<MetadataAsValue>(Call->getArgOperand(0)); |
+ // Sometimes dbg.declare points to an argument instead of an alloca. |
+ if (auto *VM = dyn_cast<ValueAsMetadata>(MV->getMetadata())) { |
+ if (auto *BCInst = dyn_cast<BitCastInst>(VM->getValue())) { |
+ Value *CastSrc = BCInst->getOperand(0); |
+ assert(isa<AllocaInst>(CastSrc)); |
+ Call->setArgOperand( |
+ 0, |
+ MetadataAsValue::get(Inst->getContext(), |
+ ValueAsMetadata::get(CastSrc))); |
+ Changed = true; |
+ } |
+ } |
+ } |
+ } |
} |
return Changed; |
} |