[msan] Optimize -msan-check-constant-shadow.

The new code does not create new basic blocks in the case when shadow is a
compile-time constant; it generates either an unconditional __msan_warning
call or nothing instead.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226569 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evgeniy Stepanov 2015-01-20 15:21:35 +00:00
parent 68d992759a
commit d9434ef62f
2 changed files with 65 additions and 9 deletions

View File

@ -611,11 +611,15 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
OriginAlignment);
} else {
Value *ConvertedShadow = convertToShadowTyNoVec(Shadow, IRB);
// TODO(eugenis): handle non-zero constant shadow by inserting an
// unconditional check (can not simply fail compilation as this could
// be in the dead code).
if (!ClCheckConstantShadow)
if (isa<Constant>(ConvertedShadow)) return;
Constant *ConstantShadow = dyn_cast_or_null<Constant>(ConvertedShadow);
if (ConstantShadow) {
if (ClCheckConstantShadow && !ConstantShadow->isZeroValue())
IRB.CreateAlignedStore(updateOrigin(Origin, IRB),
getOriginPtr(Addr, IRB, Alignment),
OriginAlignment);
return;
}
unsigned TypeSizeInBits =
MS.DL->getTypeSizeInBits(ConvertedShadow->getType());
unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
@ -670,9 +674,23 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
DEBUG(dbgs() << " SHAD0 : " << *Shadow << "\n");
Value *ConvertedShadow = convertToShadowTyNoVec(Shadow, IRB);
DEBUG(dbgs() << " SHAD1 : " << *ConvertedShadow << "\n");
// See the comment in storeOrigin().
if (!ClCheckConstantShadow)
if (isa<Constant>(ConvertedShadow)) return;
Constant *ConstantShadow = dyn_cast_or_null<Constant>(ConvertedShadow);
if (ConstantShadow) {
if (ClCheckConstantShadow && !ConstantShadow->isZeroValue()) {
if (MS.TrackOrigins) {
IRB.CreateStore(Origin ? (Value *)Origin : (Value *)IRB.getInt32(0),
MS.OriginTLS);
}
IRB.CreateCall(MS.WarningFn);
IRB.CreateCall(MS.EmptyAsm);
// FIXME: Insert UnreachableInst if !ClKeepGoing?
// This may invalidate some of the following checks and needs to be done
// at the very end.
}
return;
}
unsigned TypeSizeInBits =
MS.DL->getTypeSizeInBits(ConvertedShadow->getType());
unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);

View File

@ -1,10 +1,11 @@
; RUN: opt < %s -msan -msan-check-constant-shadow=1 -S | FileCheck %s
; RUN: opt < %s -msan -msan-check-access-address=0 -msan-check-constant-shadow=1 -msan-track-origins=1 -S | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Test that returning a literal undef from main() triggers an MSan warning.
; main() is special: it inserts check for the return value
define i32 @main() nounwind uwtable sanitize_memory {
entry:
ret i32 undef
@ -13,3 +14,40 @@ entry:
; CHECK-LABEL: @main
; CHECK: call void @__msan_warning_noreturn
; CHECK: ret i32 undef
; This function stores known initialized value.
; Expect 2 stores: one for the shadow (0), one for the value (42), but no origin.
define void @StoreConstant(i32* nocapture %p) nounwind uwtable sanitize_memory {
entry:
store i32 42, i32* %p, align 4
ret void
}
; CHECK-LABEL: @StoreConstant
; CHECK-NOT: store i32
; CHECK: store i32 0,
; CHECK-NOT: store i32
; CHECK: store i32 42,
; CHECK-NOT: store i32
; CHECK: ret void
; This function stores known uninitialized value.
; Expect 3 stores: shadow, value and origin.
; Expect no icmp(s): everything here is unconditional.
define void @StoreUndef(i32* nocapture %p) nounwind uwtable sanitize_memory {
entry:
store i32 undef, i32* %p, align 4
ret void
}
; CHECK-LABEL: @StoreUndef
; CHECK-NOT: icmp
; CHECK: store i32
; CHECK-NOT: icmp
; CHECK: store i32
; CHECK-NOT: icmp
; CHECK: store i32
; CHECK-NOT: icmp
; CHECK: ret void