diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -2507,6 +2507,12 @@ void visitAShr(BinaryOperator &I) { handleShift(I); } void visitLShr(BinaryOperator &I) { handleShift(I); } + void replaceInst(Instruction *Old, Instruction *New) { + if (Old == ActualFnStart) + ActualFnStart = New; + Old->eraseFromParent(); + } + /// Instrument llvm.memmove /// /// At this point we don't know if llvm.memmove will be inlined or not. @@ -2519,12 +2525,12 @@ /// Similar situation exists for memcpy and memset. void visitMemMoveInst(MemMoveInst &I) { IRBuilder<> IRB(&I); - IRB.CreateCall( + Instruction *NewInst = IRB.CreateCall( MS.MemmoveFn, {IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()), IRB.CreatePointerCast(I.getArgOperand(1), IRB.getInt8PtrTy()), IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)}); - I.eraseFromParent(); + replaceInst(&I, NewInst); } // Similar to memmove: avoid copying shadow twice. @@ -2533,23 +2539,23 @@ // alignment. void visitMemCpyInst(MemCpyInst &I) { IRBuilder<> IRB(&I); - IRB.CreateCall( + Instruction *NewInst = IRB.CreateCall( MS.MemcpyFn, {IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()), IRB.CreatePointerCast(I.getArgOperand(1), IRB.getInt8PtrTy()), IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)}); - I.eraseFromParent(); + replaceInst(&I, NewInst); } // Same as memcpy. void visitMemSetInst(MemSetInst &I) { IRBuilder<> IRB(&I); - IRB.CreateCall( + Instruction *NewInst = IRB.CreateCall( MS.MemsetFn, {IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()), IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false), IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)}); - I.eraseFromParent(); + replaceInst(&I, NewInst); } void visitVAStartInst(VAStartInst &I) {