@@ -233,6 +233,8 @@ static const unsigned kRetvalTLSSize = 800;
233233// Accesses sizes are powers of two: 1, 2, 4, 8.
234234static const size_t kNumberOfAccessSizes = 4 ;
235235
236+ static constexpr unsigned kNumberOfAddressSpace = 5 ;
237+
236238// / Track origins of uninitialized values.
237239// /
238240// / Adds a section to MemorySanitizer report that points to the allocation
@@ -678,6 +680,9 @@ class MemorySanitizer {
678680 // / MSan runtime replacements for memmove, memcpy and memset.
679681 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
680682
683+ // / MSan runtime replacements for memset with address space.
684+ FunctionCallee MemsetOffloadFn[kNumberOfAddressSpace ];
685+
681686 // / KMSAN callback for task-local function argument shadow.
682687 StructType *MsanContextStateTy;
683688 FunctionCallee MsanGetContextStateFn;
@@ -964,7 +969,19 @@ void MemorySanitizer::createUserspaceApi(Module &M,
964969 } else {
965970 StringRef WarningFnName =
966971 Recover ? " __msan_warning" : " __msan_warning_noreturn" ;
967- WarningFn = M.getOrInsertFunction (WarningFnName, IRB.getVoidTy ());
972+ if (!TargetTriple.isSPIROrSPIRV ()) {
973+ WarningFn = M.getOrInsertFunction (WarningFnName, IRB.getVoidTy ());
974+ } else {
975+ // __msan_warning[_noreturn](
976+ // char* file,
977+ // unsigned int line,
978+ // char* func
979+ // )
980+ WarningFn = M.getOrInsertFunction (
981+ WarningFnName, IRB.getVoidTy (),
982+ IRB.getInt8PtrTy (kSpirOffloadConstantAS ), IRB.getInt32Ty (),
983+ IRB.getInt8PtrTy (kSpirOffloadConstantAS ));
984+ }
968985 }
969986
970987 // Create the global TLS variables.
@@ -1050,13 +1067,24 @@ void MemorySanitizer::initializeCallbacks(Module &M,
10501067 MsanSetOriginFn = M.getOrInsertFunction (
10511068 " __msan_set_origin" , TLI.getAttrList (C, {2 }, /* Signed=*/ false ),
10521069 IRB.getVoidTy (), PtrTy, IntptrTy, IRB.getInt32Ty ());
1053- MemmoveFn =
1054- M.getOrInsertFunction (" __msan_memmove" , PtrTy, PtrTy, PtrTy, IntptrTy);
1055- MemcpyFn =
1056- M.getOrInsertFunction (" __msan_memcpy" , PtrTy, PtrTy, PtrTy, IntptrTy);
1057- MemsetFn = M.getOrInsertFunction (" __msan_memset" ,
1058- TLI.getAttrList (C, {1 }, /* Signed=*/ true ),
1059- PtrTy, PtrTy, IRB.getInt32Ty (), IntptrTy);
1070+ if (!TargetTriple.isSPIROrSPIRV ()) {
1071+ MemmoveFn =
1072+ M.getOrInsertFunction (" __msan_memmove" , PtrTy, PtrTy, PtrTy, IntptrTy);
1073+ MemcpyFn =
1074+ M.getOrInsertFunction (" __msan_memcpy" , PtrTy, PtrTy, PtrTy, IntptrTy);
1075+ MemsetFn = M.getOrInsertFunction (" __msan_memset" ,
1076+ TLI.getAttrList (C, {1 }, /* Signed=*/ true ),
1077+ PtrTy, PtrTy, IRB.getInt32Ty (), IntptrTy);
1078+ } else {
1079+ for (unsigned FirstArgAS = 0 ; FirstArgAS < kNumberOfAddressSpace ;
1080+ FirstArgAS++) {
1081+ const std::string Suffix = " _p" + itostr (FirstArgAS);
1082+ PointerType *FirstArgPtrTy = IRB.getPtrTy (FirstArgAS);
1083+ MemsetOffloadFn[FirstArgAS] = M.getOrInsertFunction (
1084+ " __msan_memset" + Suffix, TLI.getAttrList (C, {1 }, /* Signed=*/ true ),
1085+ FirstArgPtrTy, FirstArgPtrTy, IRB.getInt32Ty (), IntptrTy);
1086+ }
1087+ }
10601088
10611089 MsanInstrumentAsmStoreFn = M.getOrInsertFunction (
10621090 " __msan_instrument_asm_store" , IRB.getVoidTy (), PtrTy, IntptrTy);
@@ -1560,6 +1588,35 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
15601588 return LazyWarningDebugLocationCount[DebugLoc] >= ClDisambiguateWarning;
15611589 }
15621590
1591+ void appendDebugInfoToArgs (IRBuilder<> &IRB, SmallVectorImpl<Value *> &Args) {
1592+ auto *M = F.getParent ();
1593+ auto &C = IRB.getContext ();
1594+ auto DebugLoc = IRB.getCurrentDebugLocation ();
1595+
1596+ // SPIR constant address space
1597+ auto *ConstASPtrTy =
1598+ PointerType::get (Type::getInt8Ty (C), kSpirOffloadConstantAS );
1599+
1600+ // file name and line number
1601+ if (DebugLoc) {
1602+ llvm::SmallString<128 > Source = DebugLoc->getDirectory ();
1603+ sys::path::append (Source, DebugLoc->getFilename ());
1604+ auto *FileNameGV = getOrCreateGlobalString (*M, " __msan_file" , Source,
1605+ kSpirOffloadConstantAS );
1606+ Args.push_back (ConstantExpr::getPointerCast (FileNameGV, ConstASPtrTy));
1607+ Args.push_back (ConstantInt::get (Type::getInt32Ty (C), DebugLoc.getLine ()));
1608+ } else {
1609+ Args.push_back (ConstantPointerNull::get (ConstASPtrTy));
1610+ Args.push_back (ConstantInt::get (Type::getInt32Ty (C), 0 ));
1611+ }
1612+
1613+ // function name
1614+ auto FuncName = F.getName ();
1615+ auto *FuncNameGV = getOrCreateGlobalString (
1616+ *M, " __msan_func" , demangle (FuncName), kSpirOffloadConstantAS );
1617+ Args.push_back (ConstantExpr::getPointerCast (FuncNameGV, ConstASPtrTy));
1618+ }
1619+
15631620 // / Helper function to insert a warning at IRB's current insert point.
15641621 void insertWarningFn (IRBuilder<> &IRB, Value *Origin) {
15651622 if (!Origin)
@@ -1584,10 +1641,16 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
15841641 }
15851642 }
15861643
1587- if (MS.CompileKernel || MS.TrackOrigins )
1588- IRB.CreateCall (MS.WarningFn , Origin)->setCannotMerge ();
1589- else
1590- IRB.CreateCall (MS.WarningFn )->setCannotMerge ();
1644+ if (!SpirOrSpirv) {
1645+ if (MS.CompileKernel || MS.TrackOrigins )
1646+ IRB.CreateCall (MS.WarningFn , Origin)->setCannotMerge ();
1647+ else
1648+ IRB.CreateCall (MS.WarningFn )->setCannotMerge ();
1649+ } else { // SPIR or SPIR-V
1650+ SmallVector<Value *, 3 > Args;
1651+ appendDebugInfoToArgs (IRB, Args);
1652+ IRB.CreateCall (MS.WarningFn , Args)->setCannotMerge ();
1653+ }
15911654 // FIXME: Insert UnreachableInst if !MS.Recover?
15921655 // This may invalidate some of the following checks and needs to be done
15931656 // at the very end.
@@ -1617,43 +1680,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
16171680 ConvertedShadow2,
16181681 MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32 (0 )};
16191682
1620- {
1621- auto *M = F.getParent ();
1622- auto *ConstASPtrTy = IRB.getInt8PtrTy (kSpirOffloadConstantAS );
1623-
1624- // file name and line number
1625- {
1626- bool HasDebugLoc = false ;
1627- auto *ConvertedShadowInst = dyn_cast<Instruction>(ConvertedShadow);
1628-
1629- if (ConvertedShadowInst) {
1630- if (auto &Loc = ConvertedShadowInst->getDebugLoc ()) {
1631- llvm::SmallString<128 > Source = Loc->getDirectory ();
1632- sys::path::append (Source, Loc->getFilename ());
1633- auto *FileNameGV = getOrCreateGlobalString (
1634- *M, " __asan_file" , Source, kSpirOffloadConstantAS );
1635- Args.push_back (
1636- ConstantExpr::getPointerCast (FileNameGV, ConstASPtrTy));
1637- Args.push_back (
1638- ConstantInt::get (IRB.getInt32Ty (), Loc.getLine ()));
1639-
1640- HasDebugLoc = true ;
1641- }
1642- }
1643-
1644- if (!HasDebugLoc) {
1645- Args.push_back (ConstantPointerNull::get (ConstASPtrTy));
1646- Args.push_back (ConstantInt::get (IRB.getInt32Ty (), 0 ));
1647- }
1648- }
1649-
1650- // function name
1651- auto FuncName = F.getName ();
1652- auto *FuncNameGV = getOrCreateGlobalString (
1653- *M, " __asan_func" , demangle (FuncName), kSpirOffloadConstantAS );
1654- Args.push_back (
1655- ConstantExpr::getPointerCast (FuncNameGV, ConstASPtrTy));
1656- }
1683+ appendDebugInfoToArgs (IRB, Args);
16571684
16581685 CallBase *CB = IRB.CreateCall (Fn, Args);
16591686 CB->addParamAttr (0 , Attribute::ZExt);
@@ -3160,7 +3187,10 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
31603187 void visitMemSetInst (MemSetInst &I) {
31613188 IRBuilder<> IRB (&I);
31623189 IRB.CreateCall (
3163- MS.MemsetFn ,
3190+ SpirOrSpirv ? MS.MemsetOffloadFn [cast<PointerType>(
3191+ I.getArgOperand (0 )->getType ())
3192+ ->getAddressSpace ()]
3193+ : MS.MemsetFn ,
31643194 {I.getArgOperand (0 ),
31653195 IRB.CreateIntCast (I.getArgOperand (1 ), IRB.getInt32Ty (), false ),
31663196 IRB.CreateIntCast (I.getArgOperand (2 ), MS.IntptrTy , false )});
0 commit comments