diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 79947ff892a1..73e7867d0a34 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -715,6 +715,7 @@ struct MemorySanitizerVisitor : public InstVisitor { ValueMap ShadowMap, OriginMap; std::unique_ptr VAHelper; const TargetLibraryInfo *TLI; + BasicBlock *ActualFnStart; // The following flags disable parts of MSan instrumentation based on // blacklist contents and command-line options. @@ -747,6 +748,9 @@ struct MemorySanitizerVisitor : public InstVisitor { CheckReturnValue = SanitizeFunction && (F.getName() == "main"); TLI = &MS.getAnalysis().getTLI(); + MS.initializeCallbacks(*F.getParent()); + ActualFnStart = &F.getEntryBlock(); + DEBUG(if (!InsertChecks) dbgs() << "MemorySanitizer is not inserting checks into '" << F.getName() << "'\n"); @@ -931,8 +935,6 @@ struct MemorySanitizerVisitor : public InstVisitor { /// \brief Add MemorySanitizer instrumentation to a function. bool runOnFunction() { - MS.initializeCallbacks(*F.getParent()); - // In the presence of unreachable blocks, we may see Phi nodes with // incoming nodes from such blocks. Since InstVisitor skips unreachable // blocks, such nodes will not have any shadow value associated with them. @@ -942,7 +944,7 @@ struct MemorySanitizerVisitor : public InstVisitor { // Iterate all BBs in depth-first order and create shadow instructions // for all instructions (where applicable). // For PHI nodes we create dummy shadow PHIs which will be finalized later. - for (BasicBlock *BB : depth_first(&F.getEntryBlock())) + for (BasicBlock *BB : depth_first(ActualFnStart)) visit(*BB); // Finalize PHI nodes. @@ -1216,7 +1218,7 @@ struct MemorySanitizerVisitor : public InstVisitor { if (*ShadowPtr) return *ShadowPtr; Function *F = A->getParent(); - IRBuilder<> EntryIRB(F->getEntryBlock().getFirstNonPHI()); + IRBuilder<> EntryIRB(ActualFnStart->getFirstNonPHI()); unsigned ArgOffset = 0; const DataLayout &DL = F->getParent()->getDataLayout(); for (auto &FArg : F->args()) { @@ -3214,7 +3216,7 @@ struct VarArgAMD64Helper : public VarArgHelper { if (!VAStartInstrumentationList.empty()) { // If there is a va_start in this function, make a backup copy of // va_arg_tls somewhere in the function entry block. - IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); + IRBuilder<> IRB(MSV.ActualFnStart->getFirstNonPHI()); VAArgOverflowSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS); Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), @@ -3336,7 +3338,7 @@ struct VarArgMIPS64Helper : public VarArgHelper { void finalizeInstrumentation() override { assert(!VAArgSize && !VAArgTLSCopy && "finalizeInstrumentation called twice"); - IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); + IRBuilder<> IRB(MSV.ActualFnStart->getFirstNonPHI()); VAArgSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS); Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize); @@ -3521,7 +3523,7 @@ struct VarArgAArch64Helper : public VarArgHelper { if (!VAStartInstrumentationList.empty()) { // If there is a va_start in this function, make a backup copy of // va_arg_tls somewhere in the function entry block. - IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); + IRBuilder<> IRB(MSV.ActualFnStart->getFirstNonPHI()); VAArgOverflowSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS); Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), @@ -3757,7 +3759,7 @@ struct VarArgPowerPC64Helper : public VarArgHelper { void finalizeInstrumentation() override { assert(!VAArgSize && !VAArgTLSCopy && "finalizeInstrumentation called twice"); - IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); + IRBuilder<> IRB(MSV.ActualFnStart->getFirstNonPHI()); VAArgSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS); Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize);