Skip to content

Commit 5ede3e9

Browse files
committed
address comments
1 parent 221175c commit 5ede3e9

File tree

13 files changed

+555
-45
lines changed

13 files changed

+555
-45
lines changed

clang/lib/Driver/SanitizerArgs.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,11 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
11971197

11981198
CmdArgs.push_back("-mllvm");
11991199
CmdArgs.push_back("-asan-mapping-scale=4");
1200+
} else if (Sanitizers.has(SanitizerKind::Memory)) {
1201+
CmdArgs.push_back("-fsanitize=memory");
1202+
1203+
CmdArgs.push_back("-mllvm");
1204+
CmdArgs.push_back("-msan-instrumentation-with-call-threshold=0");
12001205
}
12011206
return;
12021207
}

clang/lib/Driver/ToolChains/SYCL.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
545545
{"libsycl-asan-cpu", "internal"},
546546
{"libsycl-asan-dg2", "internal"},
547547
{"libsycl-asan-pvc", "internal"}};
548+
const SYCLDeviceLibsList SYCLDeviceMsanLibs = {{"libsycl-msan", "internal"}};
548549
#endif
549550

550551
const SYCLDeviceLibsList SYCLNativeCpuDeviceLibs = {
@@ -695,6 +696,8 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
695696

696697
if (SanitizeVal == "address")
697698
addSingleLibrary(SYCLDeviceAsanLibs[sanitizer_lib_idx]);
699+
else if (SanitizeVal == "memory")
700+
addLibraries(SYCLDeviceMsanLibs);
698701

699702
#endif
700703

@@ -1634,7 +1637,7 @@ SYCLToolChain::SYCLToolChain(const Driver &D, const llvm::Triple &Triple,
16341637
if (A->getOption().getID() == options::OPT_fsanitize_EQ &&
16351638
A->getValues().size() == 1) {
16361639
std::string SanitizeVal = A->getValue();
1637-
if (SanitizeVal == "address")
1640+
if (SanitizeVal == "address" || SanitizeVal == "memory")
16381641
continue;
16391642
}
16401643
D.Diag(clang::diag::warn_drv_unsupported_option_for_target)
@@ -1672,7 +1675,7 @@ SYCLToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
16721675
if (Opt.getID() == options::OPT_fsanitize_EQ &&
16731676
A->getValues().size() == 1) {
16741677
std::string SanitizeVal = A->getValue();
1675-
if (SanitizeVal == "address") {
1678+
if (SanitizeVal == "address" || SanitizeVal == "memory") {
16761679
if (IsNewDAL)
16771680
DAL->append(A);
16781681
continue;
@@ -2081,5 +2084,5 @@ void SYCLToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args,
20812084
}
20822085

20832086
SanitizerMask SYCLToolChain::getSupportedSanitizers() const {
2084-
return SanitizerKind::Address;
2087+
return SanitizerKind::Address | SanitizerKind::Memory;
20852088
}

libdevice/cmake/modules/SYCLLibdevice.cmake

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,13 @@ if (NOT MSVC AND UR_SANITIZER_INCLUDE_DIR)
288288
${sanitizer_generic_compile_opts}
289289
${sycl_dg2_target_opt}
290290
-D__LIBDEVICE_DG2__)
291+
292+
set(msan_obj_deps
293+
device.h atomic.hpp spirv_vars.h
294+
${UR_SANITIZER_INCLUDE_DIR}/msan/msan_libdevice.hpp
295+
include/msan_rtl.hpp
296+
include/spir_global_var.hpp
297+
sycl-compiler)
291298
endif()
292299

293300
if("native_cpu" IN_LIST SYCL_ENABLE_BACKENDS)
@@ -373,6 +380,14 @@ else()
373380
OPTS ${asan_${asan_device}_compile_opts_${asan_ft}})
374381
endforeach()
375382
endforeach()
383+
384+
# msan jit
385+
add_devicelibs(libsycl-msan
386+
SRC sanitizer/msan_rtl.cpp
387+
DEPENDENCIES ${msan_obj_deps}
388+
EXTRA_OPTS -fno-sycl-instrument-device-code
389+
-I${UR_SANITIZER_INCLUDE_DIR}
390+
-I${CMAKE_CURRENT_SOURCE_DIR})
376391
endif()
377392
endif()
378393

libdevice/include/msan_rtl.hpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//==-- msan_rtl.hpp - Declaration for sanitizer global var ---==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#pragma once
9+
10+
#include "sanitizer_defs.hpp"
11+
#include "spir_global_var.hpp"
12+
13+
// Treat this header as system one to workaround frontend's restriction
14+
#pragma clang system_header

libdevice/sanitizer/msan_rtl.cpp

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
//==--- msan_rtl.cpp - device memory sanitizer runtime library -------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "include/msan_rtl.hpp"
10+
#include "atomic.hpp"
11+
#include "device.h"
12+
#include "msan/msan_libdevice.hpp"
13+
#include "spirv_vars.h"
14+
15+
DeviceGlobal<void *> __MsanLaunchInfo;
16+
17+
constexpr int MSAN_REPORT_NONE = 0;
18+
constexpr int MSAN_REPORT_START = 1;
19+
constexpr int MSAN_REPORT_FINISH = 2;
20+
21+
static const uint64_t CleanShadow[16] = {};
22+
23+
static const __SYCL_CONSTANT__ char __msan_print_warning_return[] =
24+
"[kernel] !!! msan warning return\n";
25+
26+
static const __SYCL_CONSTANT__ char __msan_print_shadow[] =
27+
"[kernel] __msan_get_shadow(addr=%p, as=%d) = %p: %02X\n";
28+
29+
static const __SYCL_CONSTANT__ char __msan_print_warning_nolaunchinfo[] =
30+
"[kernel] !!! __mem_warning_nolaunchinfo\n";
31+
32+
static const __SYCL_CONSTANT__ char __msan_print_launchinfo[] =
33+
"[kernel] !!! launchinfo %p (GlobalShadow=%p)\n";
34+
35+
static const __SYCL_CONSTANT__ char __msan_print_report[] =
36+
"[kernel] %d bytes uninitialized at kernel %s\n";
37+
38+
static const __SYCL_CONSTANT__ char __msan_print_unsupport_device_type[] =
39+
"[kernel] Unsupport device type: %d\n";
40+
41+
#if defined(__SPIR__) || defined(__SPIRV__)
42+
43+
#if defined(__SYCL_DEVICE_ONLY__)
44+
#define __USE_SPIR_BUILTIN__ 1
45+
#endif
46+
47+
#if __USE_SPIR_BUILTIN__
48+
extern SYCL_EXTERNAL int
49+
__spirv_ocl_printf(const __SYCL_CONSTANT__ char *Format, ...);
50+
extern "C" SYCL_EXTERNAL void __devicelib_exit();
51+
#endif
52+
53+
#define MSAN_DEBUG(X) \
54+
do { \
55+
auto launch_info = \
56+
(__SYCL_GLOBAL__ const MsanLaunchInfo *)__MsanLaunchInfo.get(); \
57+
if (launch_info->Debug) { \
58+
X; \
59+
} \
60+
} while (false)
61+
62+
namespace {
63+
64+
void __msan_internal_report_save(const uint32_t size,
65+
const char __SYCL_CONSTANT__ *file,
66+
const uint32_t line,
67+
const char __SYCL_CONSTANT__ *func) {
68+
const int Expected = MSAN_REPORT_NONE;
69+
int Desired = MSAN_REPORT_START;
70+
71+
if (UNLIKELY(!__MsanLaunchInfo)) {
72+
__spirv_ocl_printf(__msan_print_warning_nolaunchinfo);
73+
return;
74+
}
75+
76+
auto &SanitizerReport =
77+
((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())->Report;
78+
79+
if (atomicCompareAndSet(&SanitizerReport.Flag, Desired, Expected) ==
80+
Expected) {
81+
82+
int FileLength = 0;
83+
int FuncLength = 0;
84+
85+
if (file)
86+
for (auto *C = file; *C != '\0'; ++C, ++FileLength)
87+
;
88+
if (func)
89+
for (auto *C = func; *C != '\0'; ++C, ++FuncLength)
90+
;
91+
92+
int MaxFileIdx = sizeof(SanitizerReport.File) - 1;
93+
int MaxFuncIdx = sizeof(SanitizerReport.Func) - 1;
94+
95+
if (FileLength < MaxFileIdx)
96+
MaxFileIdx = FileLength;
97+
if (FuncLength < MaxFuncIdx)
98+
MaxFuncIdx = FuncLength;
99+
100+
for (int Idx = 0; Idx < MaxFileIdx; ++Idx)
101+
SanitizerReport.File[Idx] = file[Idx];
102+
SanitizerReport.File[MaxFileIdx] = '\0';
103+
104+
for (int Idx = 0; Idx < MaxFuncIdx; ++Idx)
105+
SanitizerReport.Func[Idx] = func[Idx];
106+
SanitizerReport.Func[MaxFuncIdx] = '\0';
107+
108+
SanitizerReport.AccessSize = size;
109+
SanitizerReport.Line = line;
110+
SanitizerReport.GID0 = __spirv_GlobalInvocationId_x();
111+
SanitizerReport.GID1 = __spirv_GlobalInvocationId_y();
112+
SanitizerReport.GID2 = __spirv_GlobalInvocationId_z();
113+
SanitizerReport.LID0 = __spirv_LocalInvocationId_x();
114+
SanitizerReport.LID1 = __spirv_LocalInvocationId_y();
115+
SanitizerReport.LID2 = __spirv_LocalInvocationId_z();
116+
117+
// Show we've done copying
118+
atomicStore(&SanitizerReport.Flag, MSAN_REPORT_FINISH);
119+
120+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_report, size, func));
121+
}
122+
}
123+
124+
void __msan_report_error(const uint32_t size,
125+
const char __SYCL_CONSTANT__ *file,
126+
const uint32_t line,
127+
const char __SYCL_CONSTANT__ *func) {
128+
__msan_internal_report_save(size, file, line, func);
129+
130+
auto launch = (__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get();
131+
if (!launch->IsRecover) {
132+
__devicelib_exit();
133+
}
134+
}
135+
136+
inline uptr __msan_get_shadow_cpu(uptr addr) {
137+
return addr ^ 0x500000000000ULL;
138+
}
139+
140+
inline uptr __msan_get_shadow_pvc(uptr addr, uint32_t as) {
141+
// Device USM only
142+
uptr shadow_ptr = ((__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get())
143+
->GlobalShadowOffset +
144+
(addr & 0x3FFF'FFFF'FFFFULL);
145+
return shadow_ptr;
146+
}
147+
148+
} // namespace
149+
150+
#define MSAN_MAYBE_WARNING(type, size) \
151+
DEVICE_EXTERN_C_NOINLINE void __msan_maybe_warning_##size( \
152+
type s, u32 o, const char __SYCL_CONSTANT__ *file, uint32_t line, \
153+
const char __SYCL_CONSTANT__ *func) { \
154+
if (UNLIKELY(s)) { \
155+
__msan_report_error(size, file, line, func); \
156+
} \
157+
}
158+
159+
MSAN_MAYBE_WARNING(u8, 1)
160+
MSAN_MAYBE_WARNING(u16, 2)
161+
MSAN_MAYBE_WARNING(u32, 4)
162+
MSAN_MAYBE_WARNING(u64, 8)
163+
164+
DEVICE_EXTERN_C_NOINLINE uptr __msan_get_shadow(uptr addr, uint32_t as) {
165+
if (UNLIKELY(!__MsanLaunchInfo)) {
166+
__spirv_ocl_printf(__msan_print_warning_nolaunchinfo);
167+
return 0;
168+
}
169+
170+
auto launch_info = (__SYCL_GLOBAL__ MsanLaunchInfo *)__MsanLaunchInfo.get();
171+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_launchinfo, (void *)launch_info,
172+
launch_info->GlobalShadowOffset));
173+
174+
// Return clean shadow (0s) by default
175+
uptr shadow_ptr = (uptr)CleanShadow;
176+
177+
if (LIKELY(launch_info->DeviceTy == DeviceType::CPU)) {
178+
shadow_ptr = __msan_get_shadow_cpu(addr);
179+
} else if (launch_info->DeviceTy == DeviceType::GPU_PVC) {
180+
shadow_ptr = __msan_get_shadow_pvc(addr, as);
181+
} else {
182+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_unsupport_device_type,
183+
launch_info->DeviceTy));
184+
}
185+
186+
MSAN_DEBUG(__spirv_ocl_printf(__msan_print_shadow, (void *)addr, as,
187+
(void *)shadow_ptr, *(u8 *)shadow_ptr));
188+
189+
return shadow_ptr;
190+
}
191+
192+
#endif // __SPIR__ || __SPIRV__

llvm/lib/SYCLLowerIR/ComputeModuleRuntimeInfo.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ bool isModuleUsingAsan(const Module &M) {
5858
return false;
5959
}
6060

61+
bool isModuleUsingMsan(const Module &M) {
62+
return M.getGlobalVariable("__MsanLaunchInfo") != nullptr;
63+
}
64+
6165
// This function traverses over reversed call graph by BFS algorithm.
6266
// It means that an edge links some function @func with functions
6367
// which contain call of function @func. It starts from
@@ -400,7 +404,9 @@ PropSetRegTy computeModuleProperties(const Module &M,
400404

401405
{
402406
if (isModuleUsingAsan(M))
403-
PropSet.add(PropSetRegTy::SYCL_MISC_PROP, "asanUsed", true);
407+
PropSet.add(PropSetRegTy::SYCL_MISC_PROP, "sanUsed", "asan");
408+
else if (isModuleUsingMsan(M))
409+
PropSet.add(PropSetRegTy::SYCL_MISC_PROP, "sanUsed", "msan");
404410
}
405411

406412
if (GlobProps.EmitDeviceGlobalPropSet) {

0 commit comments

Comments
 (0)