mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 21:32:39 +00:00
[msan] Transform memcpy and memset to library calls.
This was already done for memmove, where it is required for correctness. This change improves performance by avoiding copyingthe same memory twice. Also, the library functions are given __msan_ prefix to prevent instcombine pass from converting them back to intrinsics. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168876 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8564dc67b5
commit
2e815e7cf4
@ -170,8 +170,8 @@ private:
|
||||
Value *MsanSetAllocaOriginFn;
|
||||
/// \brief Run-time helper that poisons stack on function entry.
|
||||
Value *MsanPoisonStackFn;
|
||||
/// \brief The actual "memmove" function.
|
||||
Value *MemmoveFn;
|
||||
/// \brief MSan runtime replacements for memmove, memcpy and memset.
|
||||
Value *MemmoveFn, *MemcpyFn, *MemsetFn;
|
||||
|
||||
/// \brief Address mask used in application-to-shadow address calculation.
|
||||
/// ShadowAddr is computed as ApplicationAddr & ~ShadowMask.
|
||||
@ -266,7 +266,13 @@ bool MemorySanitizer::doInitialization(Module &M) {
|
||||
MsanPoisonStackFn = M.getOrInsertFunction(
|
||||
"__msan_poison_stack", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy, NULL);
|
||||
MemmoveFn = M.getOrInsertFunction(
|
||||
"memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
"__msan_memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IntptrTy, NULL);
|
||||
MemcpyFn = M.getOrInsertFunction(
|
||||
"__msan_memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
|
||||
IntptrTy, NULL);
|
||||
MemsetFn = M.getOrInsertFunction(
|
||||
"__msan_memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(),
|
||||
IntptrTy, NULL);
|
||||
|
||||
// Create globals.
|
||||
@ -969,35 +975,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||
void visitAShr(BinaryOperator &I) { handleShift(I); }
|
||||
void visitLShr(BinaryOperator &I) { handleShift(I); }
|
||||
|
||||
void visitMemSetInst(MemSetInst &I) {
|
||||
IRBuilder<> IRB(&I);
|
||||
Value *Ptr = I.getArgOperand(0);
|
||||
Value *Val = I.getArgOperand(1);
|
||||
Value *ShadowPtr = getShadowPtr(Ptr, Val->getType(), IRB);
|
||||
Value *ShadowVal = getCleanShadow(Val);
|
||||
Value *Size = I.getArgOperand(2);
|
||||
unsigned Align = I.getAlignment();
|
||||
bool isVolatile = I.isVolatile();
|
||||
|
||||
IRB.CreateMemSet(ShadowPtr, ShadowVal, Size, Align, isVolatile);
|
||||
}
|
||||
|
||||
void visitMemCpyInst(MemCpyInst &I) {
|
||||
IRBuilder<> IRB(&I);
|
||||
Value *Dst = I.getArgOperand(0);
|
||||
Value *Src = I.getArgOperand(1);
|
||||
Type *ElementType = dyn_cast<PointerType>(Dst->getType())->getElementType();
|
||||
Value *ShadowDst = getShadowPtr(Dst, ElementType, IRB);
|
||||
Value *ShadowSrc = getShadowPtr(Src, ElementType, IRB);
|
||||
Value *Size = I.getArgOperand(2);
|
||||
unsigned Align = I.getAlignment();
|
||||
bool isVolatile = I.isVolatile();
|
||||
|
||||
IRB.CreateMemCpy(ShadowDst, ShadowSrc, Size, Align, isVolatile);
|
||||
if (ClTrackOrigins)
|
||||
IRB.CreateCall3(MS.MsanCopyOriginFn, Dst, Src, Size);
|
||||
}
|
||||
|
||||
/// \brief Instrument llvm.memmove
|
||||
///
|
||||
/// At this point we don't know if llvm.memmove will be inlined or not.
|
||||
@ -1007,8 +984,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||
/// we will memove the shadow twice: which is bad in case
|
||||
/// of overlapping regions. So, we simply lower the intrinsic to a call.
|
||||
///
|
||||
/// Similar situation exists for memcpy and memset, but for those functions
|
||||
/// calling instrumentation twice does not lead to incorrect results.
|
||||
/// Similar situation exists for memcpy and memset.
|
||||
void visitMemMoveInst(MemMoveInst &I) {
|
||||
IRBuilder<> IRB(&I);
|
||||
IRB.CreateCall3(
|
||||
@ -1019,6 +995,31 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
|
||||
I.eraseFromParent();
|
||||
}
|
||||
|
||||
// Similar to memmove: avoid copying shadow twice.
|
||||
// This is somewhat unfortunate as it may slowdown small constant memcpys.
|
||||
// FIXME: consider doing manual inline for small constant sizes and proper
|
||||
// alignment.
|
||||
void visitMemCpyInst(MemCpyInst &I) {
|
||||
IRBuilder<> IRB(&I);
|
||||
IRB.CreateCall3(
|
||||
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();
|
||||
}
|
||||
|
||||
// Same as memcpy.
|
||||
void visitMemSetInst(MemSetInst &I) {
|
||||
IRBuilder<> IRB(&I);
|
||||
IRB.CreateCall3(
|
||||
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();
|
||||
}
|
||||
|
||||
void visitVAStartInst(VAStartInst &I) {
|
||||
VAHelper->visitVAStartInst(I);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user