@@ -681,7 +681,9 @@ class MemorySanitizer {
681681 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
682682
683683 // / MSan runtime replacements for memset with address space.
684- FunctionCallee MemsetOffloadFn[kNumberOfAddressSpace ];
684+ FunctionCallee MemmoveOffloadFn[kNumberOfAddressSpace ][kNumberOfAddressSpace ],
685+ MemcpyOffloadFn[kNumberOfAddressSpace ][kNumberOfAddressSpace ],
686+ MemsetOffloadFn[kNumberOfAddressSpace ];
685687
686688 // / KMSAN callback for task-local function argument shadow.
687689 StructType *MsanContextStateTy;
@@ -948,7 +950,7 @@ static Constant *getOrInsertGlobal(Module &M, StringRef Name, Type *Ty) {
948950 // FIXME: spirv target doesn't support TLS, need to handle it later.
949951 if (Triple (M.getTargetTriple ()).isSPIROrSPIRV ()) {
950952 return M.getOrInsertGlobal (Name, Ty, [&] {
951- return new GlobalVariable (M, Ty, false , GlobalVariable::ExternalLinkage ,
953+ return new GlobalVariable (M, Ty, false , GlobalVariable::InternalLinkage ,
952954 Constant::getNullValue (Ty), Name, nullptr ,
953955 GlobalVariable::NotThreadLocal,
954956 kSpirOffloadGlobalAS );
@@ -1088,11 +1090,23 @@ void MemorySanitizer::initializeCallbacks(Module &M,
10881090 } else {
10891091 for (unsigned FirstArgAS = 0 ; FirstArgAS < kNumberOfAddressSpace ;
10901092 FirstArgAS++) {
1091- const std::string Suffix = " _p" + itostr (FirstArgAS);
1093+ const std::string Suffix1 = " _p" + itostr (FirstArgAS);
10921094 PointerType *FirstArgPtrTy = IRB.getPtrTy (FirstArgAS);
10931095 MemsetOffloadFn[FirstArgAS] = M.getOrInsertFunction (
1094- " __msan_memset" + Suffix , TLI.getAttrList (C, {1 }, /* Signed=*/ true ),
1096+ " __msan_memset" + Suffix1 , TLI.getAttrList (C, {1 }, /* Signed=*/ true ),
10951097 FirstArgPtrTy, FirstArgPtrTy, IRB.getInt32Ty (), IntptrTy);
1098+
1099+ for (unsigned SecondArgAS = 0 ; SecondArgAS < kNumberOfAddressSpace ;
1100+ SecondArgAS++) {
1101+ const std::string Suffix2 = Suffix1 + " _p" + itostr (SecondArgAS);
1102+ PointerType *SecondArgPtrTy = IRB.getPtrTy (SecondArgAS);
1103+ MemmoveOffloadFn[FirstArgAS][SecondArgAS] =
1104+ M.getOrInsertFunction (" __msan_memmove" + Suffix2, FirstArgPtrTy,
1105+ FirstArgPtrTy, SecondArgPtrTy, IntptrTy);
1106+ MemcpyOffloadFn[FirstArgAS][SecondArgAS] =
1107+ M.getOrInsertFunction (" __msan_memcpy" + Suffix2, FirstArgPtrTy,
1108+ FirstArgPtrTy, SecondArgPtrTy, IntptrTy);
1109+ }
10961110 }
10971111 }
10981112
@@ -1320,8 +1334,6 @@ static void setNoSanitizedMetadataSPIR(Instruction &I) {
13201334 Addr = XCHG->getPointerOperand ();
13211335 else if (const auto *ASC = dyn_cast<AddrSpaceCastInst>(&I))
13221336 Addr = ASC->getPointerOperand ();
1323- else if (isa<MemCpyInst>(&I))
1324- I.setNoSanitizeMetadata ();
13251337 else if (isa<AllocaInst>(&I))
13261338 I.setNoSanitizeMetadata ();
13271339 else if (const auto *CI = dyn_cast<CallInst>(&I)) {
@@ -3180,9 +3192,19 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
31803192 // /
31813193 // / Similar situation exists for memcpy and memset.
31823194 void visitMemMoveInst (MemMoveInst &I) {
3195+ if (SpirOrSpirv && ((isa<Instruction>(I.getArgOperand (0 )) &&
3196+ cast<Instruction>(I.getArgOperand (0 ))
3197+ ->getMetadata (LLVMContext::MD_nosanitize)) ||
3198+ (isa<Instruction>(I.getArgOperand (1 )) &&
3199+ cast<Instruction>(I.getArgOperand (1 ))
3200+ ->getMetadata (LLVMContext::MD_nosanitize))))
3201+ return ;
3202+
31833203 getShadow (I.getArgOperand (1 )); // Ensure shadow initialized
31843204 IRBuilder<> IRB (&I);
3185- IRB.CreateCall (MS.MemmoveFn ,
3205+ IRB.CreateCall (SpirOrSpirv ? MS.MemmoveOffloadFn [I.getDestAddressSpace ()]
3206+ [I.getSourceAddressSpace ()]
3207+ : MS.MemmoveFn ,
31863208 {I.getArgOperand (0 ), I.getArgOperand (1 ),
31873209 IRB.CreateIntCast (I.getArgOperand (2 ), MS.IntptrTy , false )});
31883210 I.eraseFromParent ();
@@ -3203,9 +3225,19 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
32033225 // / __msan_memcpy(). Should this be wrong, such as when implementing memcpy()
32043226 // / itself, instrumentation should be disabled with the no_sanitize attribute.
32053227 void visitMemCpyInst (MemCpyInst &I) {
3228+ if (SpirOrSpirv && ((isa<Instruction>(I.getArgOperand (0 )) &&
3229+ cast<Instruction>(I.getArgOperand (0 ))
3230+ ->getMetadata (LLVMContext::MD_nosanitize)) ||
3231+ (isa<Instruction>(I.getArgOperand (1 )) &&
3232+ cast<Instruction>(I.getArgOperand (1 ))
3233+ ->getMetadata (LLVMContext::MD_nosanitize))))
3234+ return ;
3235+
32063236 getShadow (I.getArgOperand (1 )); // Ensure shadow initialized
32073237 IRBuilder<> IRB (&I);
3208- IRB.CreateCall (MS.MemcpyFn ,
3238+ IRB.CreateCall (SpirOrSpirv ? MS.MemcpyOffloadFn [I.getDestAddressSpace ()]
3239+ [I.getSourceAddressSpace ()]
3240+ : MS.MemcpyFn ,
32093241 {I.getArgOperand (0 ), I.getArgOperand (1 ),
32103242 IRB.CreateIntCast (I.getArgOperand (2 ), MS.IntptrTy , false )});
32113243 I.eraseFromParent ();
@@ -3220,10 +3252,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
32203252
32213253 IRBuilder<> IRB (&I);
32223254 IRB.CreateCall (
3223- SpirOrSpirv ? MS.MemsetOffloadFn [cast<PointerType>(
3224- I.getArgOperand (0 )->getType ())
3225- ->getAddressSpace ()]
3226- : MS.MemsetFn ,
3255+ SpirOrSpirv ? MS.MemsetOffloadFn [I.getDestAddressSpace ()] : MS.MemsetFn ,
32273256 {I.getArgOperand (0 ),
32283257 IRB.CreateIntCast (I.getArgOperand (1 ), IRB.getInt32Ty (), false ),
32293258 IRB.CreateIntCast (I.getArgOperand (2 ), MS.IntptrTy , false )});
0 commit comments