Index: lib/Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -718,14 +718,33 @@ IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()), Origin}); } else { - Value *Cmp = IRB.CreateICmpNE( - ConvertedShadow, getCleanShadow(ConvertedShadow), "_mscmp"); - Instruction *CheckTerm = SplitBlockAndInsertIfThen( - Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights); - IRBuilder<> IRBNew(CheckTerm); - paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), - getOriginPtr(Addr, IRBNew, Alignment), StoreSize, - OriginAlignment); + if (ArrayType *AT = dyn_cast(ConvertedShadow->getType())) { + // For ArrayType we need to apply the icmp to each element (since the + // the instruction does not support array types). + for (int i = 0, s = AT->getNumElements(); i < s; i++) { + Value *ConvertedShadowElem = IRB.CreateExtractValue( + ConvertedShadow, i); + Value *CleanShadowElem = getCleanShadow(ConvertedShadowElem); + Value *Cmp = IRB.CreateICmpNE( + ConvertedShadowElem, CleanShadowElem, "_mscmp"); + + Instruction *CheckTerm = SplitBlockAndInsertIfThen( + Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights); + IRB.SetInsertPoint(CheckTerm); + } + paintOrigin(IRB, updateOrigin(Origin, IRB), + getOriginPtr(Addr, IRB, Alignment), StoreSize, + OriginAlignment); + } else { + Value *Cmp = IRB.CreateICmpNE( + ConvertedShadow, getCleanShadow(ConvertedShadow), "_mscmp"); + Instruction *CheckTerm = SplitBlockAndInsertIfThen( + Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights); + IRBuilder<> IRBNew(CheckTerm); + paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), + getOriginPtr(Addr, IRBNew, Alignment), StoreSize, + OriginAlignment); + } } } } Index: test/Instrumentation/MemorySanitizer/origin-array.ll =================================================================== --- /dev/null +++ test/Instrumentation/MemorySanitizer/origin-array.ll @@ -0,0 +1,32 @@ +; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128" +target triple = "aarch64-unknown-linux-gnu" + +; Check origin handling of array types. Since the instrumentation will +; potentially creates icmp instruction to check origin values, it requires +; the intrumentation pass to create icmp for each element. + +define void @foo([2 x i64] %v, [2 x i64]* %p) sanitize_memory { +entry: + store [2 x i64] %v, [2 x i64]* %p, align 8 + ret void +} + +; CHECK-LABEL: @foo +; CHECK: load {{.*}} @__msan_param_tls +; CHECK: [[ORIGIN:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls + +; Extract and compare the first element. +; CHECK: {{.*}} extractvalue {{.*}}, 0 +; CHECK: icmp +; CHECK: br i1 {{.*}} +; CHECK: ;