From 04e1efbae223d4afde370897636f8778beb6ef8c Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Mon, 15 Apr 2019 08:59:56 +0000 Subject: [PATCH] [Transforms][ASan] Move findAllocaForValue() to Utils/Local.cpp. NFC Summary: Factor out findAllocaForValue() from ASan so that we can use it in MSan to handle lifetime intrinsics. Reviewers: eugenis, pcc Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60615 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358380 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Utils/Local.h | 4 ++ .../Instrumentation/AddressSanitizer.cpp | 42 ++----------------- lib/Transforms/Utils/Local.cpp | 38 +++++++++++++++++ 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 641b645825f..15a6ac7a0a2 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -335,6 +335,10 @@ bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, void replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DIBuilder &Builder, int Offset = 0); +/// Finds alloca where the value comes from. +AllocaInst *findAllocaForValue(Value *V, + DenseMap &AllocaForValue); + /// Assuming the instruction \p I is going to be deleted, attempt to salvage /// debug users of \p I by writing the effect of \p I in a DIExpression. /// Returns true if any debug users were updated. diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index f3bebf38ba2..4c827aca20e 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1038,7 +1038,9 @@ struct FunctionStackPoisoner : public InstVisitor { !ConstantInt::isValueValidForType(IntptrTy, SizeValue)) return; // Find alloca instruction that corresponds to llvm.lifetime argument. - AllocaInst *AI = findAllocaForValue(II.getArgOperand(1)); + AllocaInst *AI = + llvm::findAllocaForValue(II.getArgOperand(1), AllocaForValue); + // We're interested only in allocas we can handle. if (!AI || !ASan.isInterestingAlloca(*AI)) return; bool DoPoison = (ID == Intrinsic::lifetime_end); @@ -1062,9 +1064,6 @@ struct FunctionStackPoisoner : public InstVisitor { // ---------------------- Helpers. void initializeCallbacks(Module &M); - /// Finds alloca where the value comes from. - AllocaInst *findAllocaForValue(Value *V); - // Copies bytes from ShadowBytes into shadow memory for indexes where // ShadowMask is not zero. If ShadowMask[i] is zero, we assume that // ShadowBytes[i] is constantly zero and doesn't need to be overwritten. @@ -3228,41 +3227,6 @@ void FunctionStackPoisoner::poisonAlloca(Value *V, uint64_t Size, // variable may go in and out of scope several times, e.g. in loops). // (3) if we poisoned at least one %alloca in a function, // unpoison the whole stack frame at function exit. - -AllocaInst *FunctionStackPoisoner::findAllocaForValue(Value *V) { - if (AllocaInst *AI = dyn_cast(V)) - // We're interested only in allocas we can handle. - return ASan.isInterestingAlloca(*AI) ? AI : nullptr; - // See if we've already calculated (or started to calculate) alloca for a - // given value. - AllocaForValueMapTy::iterator I = AllocaForValue.find(V); - if (I != AllocaForValue.end()) return I->second; - // Store 0 while we're calculating alloca for value V to avoid - // infinite recursion if the value references itself. - AllocaForValue[V] = nullptr; - AllocaInst *Res = nullptr; - if (CastInst *CI = dyn_cast(V)) - Res = findAllocaForValue(CI->getOperand(0)); - else if (PHINode *PN = dyn_cast(V)) { - for (Value *IncValue : PN->incoming_values()) { - // Allow self-referencing phi-nodes. - if (IncValue == PN) continue; - AllocaInst *IncValueAI = findAllocaForValue(IncValue); - // AI for incoming values should exist and should all be equal. - if (IncValueAI == nullptr || (Res != nullptr && IncValueAI != Res)) - return nullptr; - Res = IncValueAI; - } - } else if (GetElementPtrInst *EP = dyn_cast(V)) { - Res = findAllocaForValue(EP->getPointerOperand()); - } else { - LLVM_DEBUG(dbgs() << "Alloca search canceled on unknown instruction: " << *V - << "\n"); - } - if (Res) AllocaForValue[V] = Res; - return Res; -} - void FunctionStackPoisoner::handleDynamicAllocaCall(AllocaInst *AI) { IRBuilder<> IRB(AI); diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 7024c663e30..3110322b314 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -2886,3 +2886,41 @@ bool llvm::canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx) { return true; } } + +using AllocaForValueMapTy = DenseMap; +AllocaInst *llvm::findAllocaForValue(Value *V, + AllocaForValueMapTy &AllocaForValue) { + if (AllocaInst *AI = dyn_cast(V)) + return AI; + // See if we've already calculated (or started to calculate) alloca for a + // given value. + AllocaForValueMapTy::iterator I = AllocaForValue.find(V); + if (I != AllocaForValue.end()) + return I->second; + // Store 0 while we're calculating alloca for value V to avoid + // infinite recursion if the value references itself. + AllocaForValue[V] = nullptr; + AllocaInst *Res = nullptr; + if (CastInst *CI = dyn_cast(V)) + Res = findAllocaForValue(CI->getOperand(0), AllocaForValue); + else if (PHINode *PN = dyn_cast(V)) { + for (Value *IncValue : PN->incoming_values()) { + // Allow self-referencing phi-nodes. + if (IncValue == PN) + continue; + AllocaInst *IncValueAI = findAllocaForValue(IncValue, AllocaForValue); + // AI for incoming values should exist and should all be equal. + if (IncValueAI == nullptr || (Res != nullptr && IncValueAI != Res)) + return nullptr; + Res = IncValueAI; + } + } else if (GetElementPtrInst *EP = dyn_cast(V)) { + Res = findAllocaForValue(EP->getPointerOperand(), AllocaForValue); + } else { + LLVM_DEBUG(dbgs() << "Alloca search cancelled on unknown instruction: " + << *V << "\n"); + } + if (Res) + AllocaForValue[V] = Res; + return Res; +} -- 2.50.1