aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/Instrumentation/MemorySanitizer.cpp27
-rw-r--r--test/Instrumentation/MemorySanitizer/msan_basic.ll16
2 files changed, 37 insertions, 6 deletions
diff --git a/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 183403d..3427512 100644
--- a/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -1101,6 +1101,25 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
VAHelper->visitVACopyInst(I);
}
+ void handleBswap(IntrinsicInst &I) {
+ IRBuilder<> IRB(&I);
+ Value *Op = I.getArgOperand(0);
+ Type *OpType = Op->getType();
+ Function *BswapFunc = Intrinsic::getDeclaration(
+ F.getParent(), Intrinsic::bswap, ArrayRef<Type*>(&OpType, 1));
+ setShadow(&I, IRB.CreateCall(BswapFunc, getShadow(Op)));
+ setOrigin(&I, getOrigin(Op));
+ }
+
+ void visitIntrinsicInst(IntrinsicInst &I) {
+ switch (I.getIntrinsicID()) {
+ case llvm::Intrinsic::bswap:
+ handleBswap(I); break;
+ default:
+ visitInstruction(I); break;
+ }
+ }
+
void visitCallSite(CallSite CS) {
Instruction &I = *CS.getInstruction();
assert((CS.isCall() || CS.isInvoke()) && "Unknown type of CallSite");
@@ -1120,12 +1139,8 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// will get propagated to a void RetVal.
if (Call->isTailCall() && Call->getType() != Call->getParent()->getType())
Call->setTailCall(false);
- if (isa<IntrinsicInst>(&I)) {
- // All intrinsics we care about are handled in corresponding visit*
- // methods. Add checks for the arguments, mark retval as clean.
- visitInstruction(I);
- return;
- }
+
+ assert(!isa<IntrinsicInst>(&I) && "intrinsics are handled elsewhere");
}
IRBuilder<> IRB(&I);
unsigned ArgOffset = 0;
diff --git a/test/Instrumentation/MemorySanitizer/msan_basic.ll b/test/Instrumentation/MemorySanitizer/msan_basic.ll
index 05cdaa7..a62b600 100644
--- a/test/Instrumentation/MemorySanitizer/msan_basic.ll
+++ b/test/Instrumentation/MemorySanitizer/msan_basic.ll
@@ -351,3 +351,19 @@ define <4 x i32> @ShuffleVector(<4 x i32> %vec, <4 x i32> %vec1) {
; CHECK-NOT: call void @__msan_warning
; CHECK: shufflevector
; CHECK: ret <4 x i32>
+
+; Test bswap intrinsic instrumentation
+define i32 @BSwap(i32 %x) nounwind uwtable readnone {
+ %y = tail call i32 @llvm.bswap.i32(i32 %x)
+ ret i32 %y
+}
+
+declare i32 @llvm.bswap.i32(i32) nounwind readnone
+
+; CHECK: @BSwap
+; CHECK-NOT: call void @__msan_warning
+; CHECK: @llvm.bswap.i32
+; CHECK-NOT: call void @__msan_warning
+; CHECK: @llvm.bswap.i32
+; CHECK-NOT: call void @__msan_warning
+; CHECK: ret i32