@@ -681,7 +681,9 @@ class MemorySanitizer {
681
681
FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
682
682
683
683
// / MSan runtime replacements for memset with address space.
684
- FunctionCallee MemsetOffloadFn[kNumberOfAddressSpace ];
684
+ FunctionCallee MemmoveOffloadFn[kNumberOfAddressSpace ][kNumberOfAddressSpace ],
685
+ MemcpyOffloadFn[kNumberOfAddressSpace ][kNumberOfAddressSpace ],
686
+ MemsetOffloadFn[kNumberOfAddressSpace ];
685
687
686
688
// / KMSAN callback for task-local function argument shadow.
687
689
StructType *MsanContextStateTy;
@@ -948,7 +950,7 @@ static Constant *getOrInsertGlobal(Module &M, StringRef Name, Type *Ty) {
948
950
// FIXME: spirv target doesn't support TLS, need to handle it later.
949
951
if (Triple (M.getTargetTriple ()).isSPIROrSPIRV ()) {
950
952
return M.getOrInsertGlobal (Name, Ty, [&] {
951
- return new GlobalVariable (M, Ty, false , GlobalVariable::ExternalLinkage ,
953
+ return new GlobalVariable (M, Ty, false , GlobalVariable::InternalLinkage ,
952
954
Constant::getNullValue (Ty), Name, nullptr ,
953
955
GlobalVariable::NotThreadLocal,
954
956
kSpirOffloadGlobalAS );
@@ -1088,11 +1090,23 @@ void MemorySanitizer::initializeCallbacks(Module &M,
1088
1090
} else {
1089
1091
for (unsigned FirstArgAS = 0 ; FirstArgAS < kNumberOfAddressSpace ;
1090
1092
FirstArgAS++) {
1091
- const std::string Suffix = " _p" + itostr (FirstArgAS);
1093
+ const std::string Suffix1 = " _p" + itostr (FirstArgAS);
1092
1094
PointerType *FirstArgPtrTy = IRB.getPtrTy (FirstArgAS);
1093
1095
MemsetOffloadFn[FirstArgAS] = M.getOrInsertFunction (
1094
- " __msan_memset" + Suffix , TLI.getAttrList (C, {1 }, /* Signed=*/ true ),
1096
+ " __msan_memset" + Suffix1 , TLI.getAttrList (C, {1 }, /* Signed=*/ true ),
1095
1097
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
+ }
1096
1110
}
1097
1111
}
1098
1112
@@ -1320,8 +1334,6 @@ static void setNoSanitizedMetadataSPIR(Instruction &I) {
1320
1334
Addr = XCHG->getPointerOperand ();
1321
1335
else if (const auto *ASC = dyn_cast<AddrSpaceCastInst>(&I))
1322
1336
Addr = ASC->getPointerOperand ();
1323
- else if (isa<MemCpyInst>(&I))
1324
- I.setNoSanitizeMetadata ();
1325
1337
else if (isa<AllocaInst>(&I))
1326
1338
I.setNoSanitizeMetadata ();
1327
1339
else if (const auto *CI = dyn_cast<CallInst>(&I)) {
@@ -3180,9 +3192,19 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
3180
3192
// /
3181
3193
// / Similar situation exists for memcpy and memset.
3182
3194
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
+
3183
3203
getShadow (I.getArgOperand (1 )); // Ensure shadow initialized
3184
3204
IRBuilder<> IRB (&I);
3185
- IRB.CreateCall (MS.MemmoveFn ,
3205
+ IRB.CreateCall (SpirOrSpirv ? MS.MemmoveOffloadFn [I.getDestAddressSpace ()]
3206
+ [I.getSourceAddressSpace ()]
3207
+ : MS.MemmoveFn ,
3186
3208
{I.getArgOperand (0 ), I.getArgOperand (1 ),
3187
3209
IRB.CreateIntCast (I.getArgOperand (2 ), MS.IntptrTy , false )});
3188
3210
I.eraseFromParent ();
@@ -3203,9 +3225,19 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
3203
3225
// / __msan_memcpy(). Should this be wrong, such as when implementing memcpy()
3204
3226
// / itself, instrumentation should be disabled with the no_sanitize attribute.
3205
3227
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
+
3206
3236
getShadow (I.getArgOperand (1 )); // Ensure shadow initialized
3207
3237
IRBuilder<> IRB (&I);
3208
- IRB.CreateCall (MS.MemcpyFn ,
3238
+ IRB.CreateCall (SpirOrSpirv ? MS.MemcpyOffloadFn [I.getDestAddressSpace ()]
3239
+ [I.getSourceAddressSpace ()]
3240
+ : MS.MemcpyFn ,
3209
3241
{I.getArgOperand (0 ), I.getArgOperand (1 ),
3210
3242
IRB.CreateIntCast (I.getArgOperand (2 ), MS.IntptrTy , false )});
3211
3243
I.eraseFromParent ();
@@ -3220,10 +3252,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
3220
3252
3221
3253
IRBuilder<> IRB (&I);
3222
3254
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 ,
3227
3256
{I.getArgOperand (0 ),
3228
3257
IRB.CreateIntCast (I.getArgOperand (1 ), IRB.getInt32Ty (), false ),
3229
3258
IRB.CreateIntCast (I.getArgOperand (2 ), MS.IntptrTy , false )});
0 commit comments