Skip to content

Commit 9448e0f

Browse files
authored
[DevMSAN] Unpoison sret argument for builtin function to get spec constant (#19800)
* For builtin func like "__sycl_getComposite2020SpecConstantValue", if structs which are larger than 64b will be returned via sret arguments and will be initialized inside the function. So we need to unpoison the sret arguments. * Always set ZE_AFFINITY_MAST to 0 when running device sanitizer tests since device sanitizer only support one GPU card now.
1 parent 0040e71 commit 9448e0f

File tree

6 files changed

+95
-9
lines changed

6 files changed

+95
-9
lines changed

libdevice/sanitizer/msan_rtl.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ __msan_unpoison_shadow_dynamic_local(uptr ptr, uint32_t num_args) {
671671
"__msan_unpoison_shadow_dynamic_local"));
672672
}
673673

674-
static __SYCL_CONSTANT__ const char __msan_print_set_shadow_private[] =
674+
static __SYCL_CONSTANT__ const char __msan_print_set_shadow[] =
675675
"[kernel] __msan_set_value(beg=%p, end=%p, val=%02X)\n";
676676

677677
// We outline the function of setting shadow memory of private memory, because
@@ -684,8 +684,7 @@ DEVICE_EXTERN_C_NOINLINE void __msan_poison_stack(__SYCL_PRIVATE__ void *ptr,
684684
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_func_beg, "__msan_poison_stack"));
685685

686686
auto shadow_address = MemToShadow((uptr)ptr, ADDRESS_SPACE_PRIVATE);
687-
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_set_shadow_private,
688-
(void *)shadow_address,
687+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_set_shadow, (void *)shadow_address,
689688
(void *)(shadow_address + size), 0xff));
690689

691690
if (shadow_address != GetMsanLaunchInfo->CleanShadow) {
@@ -704,8 +703,7 @@ DEVICE_EXTERN_C_NOINLINE void __msan_unpoison_stack(__SYCL_PRIVATE__ void *ptr,
704703
__spirv_ocl_printf(__msan_print_func_beg, "__msan_unpoison_stack"));
705704

706705
auto shadow_address = MemToShadow((uptr)ptr, ADDRESS_SPACE_PRIVATE);
707-
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_set_shadow_private,
708-
(void *)shadow_address,
706+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_set_shadow, (void *)shadow_address,
709707
(void *)(shadow_address + size), 0x0));
710708

711709
if (shadow_address != GetMsanLaunchInfo->CleanShadow) {
@@ -716,6 +714,26 @@ DEVICE_EXTERN_C_NOINLINE void __msan_unpoison_stack(__SYCL_PRIVATE__ void *ptr,
716714
__spirv_ocl_printf(__msan_print_func_end, "__msan_unpoison_stack"));
717715
}
718716

717+
DEVICE_EXTERN_C_NOINLINE void __msan_unpoison_shadow(uptr ptr, uint32_t as,
718+
uptr size) {
719+
if (!GetMsanLaunchInfo)
720+
return;
721+
722+
MSAN_DEBUG(
723+
__spirv_ocl_printf(__msan_print_func_beg, "__msan_unpoison_shadow"));
724+
725+
auto shadow_address = MemToShadow(ptr, as);
726+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_set_shadow, (void *)shadow_address,
727+
(void *)(shadow_address + size), 0x0));
728+
729+
if (shadow_address != GetMsanLaunchInfo->CleanShadow) {
730+
Memset((__SYCL_GLOBAL__ char *)shadow_address, 0, size);
731+
}
732+
733+
MSAN_DEBUG(
734+
__spirv_ocl_printf(__msan_print_func_end, "__msan_unpoison_shadow"));
735+
}
736+
719737
static __SYCL_CONSTANT__ const char __msan_print_private_base[] =
720738
"[kernel] __msan_set_private_base(sid=%llu): %p\n";
721739

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,8 @@ class MemorySanitizerOnSpirv {
813813
Constant *getOrCreateGlobalString(StringRef Name, StringRef Value,
814814
unsigned AddressSpace);
815815

816+
static bool isSupportedBuiltIn(StringRef Name);
817+
816818
operator bool() const { return IsSPIRV; }
817819

818820
private:
@@ -823,7 +825,6 @@ class MemorySanitizerOnSpirv {
823825
void instrumentKernelsMetadata(int TrackOrigins);
824826
void instrumentPrivateArguments(Function &F, Instruction *FnPrologueEnd);
825827
void instrumentPrivateBase(Function &F);
826-
827828
void initializeRetVecMap(Function *F);
828829
void initializeKernelCallerMap(Function *F);
829830

@@ -856,6 +857,7 @@ class MemorySanitizerOnSpirv {
856857
FunctionCallee MsanUnpoisonShadowDynamicLocalFunc;
857858
FunctionCallee MsanBarrierFunc;
858859
FunctionCallee MsanUnpoisonStackFunc;
860+
FunctionCallee MsanUnpoisonShadowFunc;
859861
FunctionCallee MsanSetPrivateBaseFunc;
860862
FunctionCallee MsanUnpoisonStridedCopyFunc;
861863
};
@@ -949,6 +951,14 @@ void MemorySanitizerOnSpirv::initializeCallbacks() {
949951
MsanUnpoisonStackFunc = M.getOrInsertFunction(
950952
"__msan_unpoison_stack", IRB.getVoidTy(), PtrTy, IntptrTy);
951953

954+
// __msan_unpoison_(
955+
// uptr ptr,
956+
// uint32_t as,
957+
// size_t size
958+
// )
959+
MsanUnpoisonShadowFunc = M.getOrInsertFunction(
960+
"__msan_unpoison_shadow", IRB.getVoidTy(), IntptrTy, Int32Ty, IntptrTy);
961+
952962
// __msan_set_private_base(
953963
// as(0) void * ptr
954964
// )
@@ -987,9 +997,16 @@ void MemorySanitizerOnSpirv::instrumentGlobalVariables() {
987997
G.setName("nameless_global");
988998

989999
if (isUnsupportedDeviceGlobal(&G)) {
990-
for (auto *User : G.users())
991-
if (auto *Inst = dyn_cast<Instruction>(User))
992-
Inst->setNoSanitizeMetadata();
1000+
for (auto *User : G.users()) {
1001+
if (!isa<Instruction>(User))
1002+
continue;
1003+
if (auto *CI = dyn_cast<CallInst>(User)) {
1004+
Function *Callee = CI->getCalledFunction();
1005+
if (Callee && isSupportedBuiltIn(Callee->getName()))
1006+
continue;
1007+
}
1008+
cast<Instruction>(User)->setNoSanitizeMetadata();
1009+
}
9931010
continue;
9941011
}
9951012

@@ -1150,6 +1167,10 @@ void MemorySanitizerOnSpirv::instrumentPrivateBase(Function &F) {
11501167
IRB.CreateCall(MsanSetPrivateBaseFunc, {PrivateBase});
11511168
}
11521169

1170+
bool MemorySanitizerOnSpirv::isSupportedBuiltIn(StringRef Name) {
1171+
return Name.contains("__sycl_getComposite2020SpecConstantValue");
1172+
}
1173+
11531174
void MemorySanitizerOnSpirv::instrumentPrivateArguments(
11541175
Function &F, Instruction *FnPrologueEnd) {
11551176
if (!ClSpirOffloadPrivates)
@@ -6994,6 +7015,25 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
69947015
IRB.CreatePointerCast(Src, MS.Spirv.IntptrTy),
69957016
IRB.getInt32(Src->getType()->getPointerAddressSpace()),
69967017
IRB.getInt32(ElementSize), NumElements, Stride});
7018+
} else if (FuncName.contains(
7019+
"__sycl_getComposite2020SpecConstantValue")) {
7020+
// clang-format off
7021+
// Handle builtin functions like "_Z40__sycl_getComposite2020SpecConstantValue"
7022+
// Structs which are larger than 64b will be returned via sret arguments
7023+
// and will be initialized inside the function. So we need to unpoison
7024+
// the sret arguments.
7025+
// clang-format on
7026+
if (Func->hasStructRetAttr()) {
7027+
Type *SCTy = Func->getParamStructRetType(0);
7028+
unsigned Size = Func->getDataLayout().getTypeStoreSize(SCTy);
7029+
auto *Addr = CB.getArgOperand(0);
7030+
IRB.CreateCall(
7031+
MS.Spirv.MsanUnpoisonShadowFunc,
7032+
{IRB.CreatePointerCast(Addr, MS.Spirv.IntptrTy),
7033+
ConstantInt::get(MS.Spirv.Int32Ty,
7034+
Addr->getType()->getPointerAddressSpace()),
7035+
ConstantInt::get(MS.Spirv.IntptrTy, Size)});
7036+
}
69977037
}
69987038
}
69997039
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; RUN: opt < %s -passes=msan -msan-instrumentation-with-call-threshold=0 -msan-eager-checks=1 -msan-poison-stack-with-call=1 -S | FileCheck %s
2+
3+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1"
4+
target triple = "spir64-unknown-unknown"
5+
6+
%"class.sycl::_V1::specialization_id" = type { %"struct.user_def_types::no_cnstr" }
7+
%"struct.user_def_types::no_cnstr" = type { float, i32, i8 }
8+
9+
@__usid_str = external addrspace(4) constant [57 x i8]
10+
@_Z19spec_const_externalIN14user_def_types8no_cnstrELi1EE = external addrspace(1) constant %"class.sycl::_V1::specialization_id"
11+
12+
define spir_func i1 @_Z50check_kernel_handler_by_reference_external_handlerRN4sycl3_V114kernel_handlerEN14user_def_types8no_cnstrE() {
13+
entry:
14+
%ref.tmp.i = alloca %"struct.user_def_types::no_cnstr", align 4
15+
%ref.tmp.ascast.i = addrspacecast ptr %ref.tmp.i to ptr addrspace(4)
16+
; CHECK: [[REG1:%[0-9]+]] = ptrtoint ptr addrspace(4) %ref.tmp.ascast.i to i64
17+
; CHECK: call void @__msan_unpoison_shadow(i64 [[REG1]], i32 4, i64 12)
18+
call spir_func void @_Z40__sycl_getComposite2020SpecConstantValueIN14user_def_types8no_cnstrEET_PKcPKvS6_(ptr addrspace(4) dead_on_unwind writable sret(%"struct.user_def_types::no_cnstr") align 4 %ref.tmp.ascast.i, ptr addrspace(4) noundef @__usid_str, ptr addrspace(4) noundef addrspacecast (ptr addrspace(1) @_Z19spec_const_externalIN14user_def_types8no_cnstrELi1EE to ptr addrspace(4)), ptr addrspace(4) noundef null)
19+
ret i1 false
20+
}
21+
22+
declare spir_func void @_Z40__sycl_getComposite2020SpecConstantValueIN14user_def_types8no_cnstrEET_PKcPKvS6_(ptr addrspace(4) sret(%"struct.user_def_types::no_cnstr"), ptr addrspace(4), ptr addrspace(4), ptr addrspace(4))

sycl/test-e2e/AddressSanitizer/lit.local.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ unsupported_san_flags = [
2828
]
2929
if any(flag in config.cxx_flags for flag in unsupported_san_flags):
3030
config.unsupported=True
31+
32+
config.environment["ZE_AFFINITY_MASK"] = "0"

sycl/test-e2e/MemorySanitizer/lit.local.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,5 @@ unsupported_san_flags = [
3535
]
3636
if any(flag in config.cxx_flags for flag in unsupported_san_flags):
3737
config.unsupported=True
38+
39+
config.environment["ZE_AFFINITY_MASK"] = "0"

sycl/test-e2e/ThreadSanitizer/lit.local.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,5 @@ unsupported_san_flags = [
3333
]
3434
if any(flag in config.cxx_flags for flag in unsupported_san_flags):
3535
config.unsupported=True
36+
37+
config.environment["ZE_AFFINITY_MASK"] = "0"

0 commit comments

Comments
 (0)