Skip to content

Commit 1e1ffc0

Browse files
AllanZynepbalcer
andauthored
[DeviceAsan][NFC] Code Restructure (#15843)
UR: oneapi-src/unified-runtime#2232 Code refactoring for implementing MemorySanitizer --------- Co-authored-by: Piotr Balcer <[email protected]>
1 parent db59b4f commit 1e1ffc0

File tree

7 files changed

+119
-93
lines changed

7 files changed

+119
-93
lines changed

.github/CODEOWNERS

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,12 @@ sycl/test-e2e/LLVMIntrinsicLowering/ @intel/dpcpp-spirv-reviewers
169169

170170
# Sanitizer
171171
clang/lib/Driver/SanitizerArgs.cpp @intel/dpcpp-sanitizers-review
172-
libdevice/sanitizer_utils.cpp @intel/dpcpp-sanitizers-review
173-
libdevice/include/asan_libdevice.hpp @intel/dpcpp-sanitizers-review
174-
libdevice/include/sanitizer_utils.hpp @intel/dpcpp-sanitizers-review
172+
libdevice/include/asan_rtl.hpp @intel/dpcpp-sanitizers-review
173+
libdevice/include/sanitizer_defs.hpp @intel/dpcpp-sanitizers-review
174+
libdevice/sanitizer/ @intel/dpcpp-sanitizers-review
175+
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h @intel/dpcpp-sanitizers-review
176+
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h @intel/dpcpp-sanitizers-review
177+
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerOptions.h @intel/dpcpp-sanitizers-review
175178
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @intel/dpcpp-sanitizers-review
176-
sycl/test-e2e/AddressSanitizer/ @intel/dpcpp-sanitizers-review
177179
llvm/test/Instrumentation/AddressSanitizer/ @intel/dpcpp-sanitizers-review
178-
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerOptions.h @intel/dpcpp-sanitizers-review
179-
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h @intel/dpcpp-sanitizers-review
180-
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h @intel/dpcpp-sanitizers-review
180+
sycl/test-e2e/AddressSanitizer/ @intel/dpcpp-sanitizers-review

clang/lib/Driver/ToolChains/SYCL.cpp

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -658,43 +658,44 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
658658
addLibraries(SYCLDeviceAnnotationLibs);
659659

660660
#if !defined(_WIN32)
661+
std::string SanitizeVal;
661662
size_t sanitizer_lib_idx = getSingleBuildTarget();
662663
if (Arg *A = Args.getLastArg(options::OPT_fsanitize_EQ,
663664
options::OPT_fno_sanitize_EQ)) {
664665
if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
665-
A->getValues().size() == 1) {
666-
std::string SanitizeVal = A->getValue();
667-
if (SanitizeVal == "address")
668-
addSingleLibrary(SYCLDeviceAsanLibs[sanitizer_lib_idx]);
669-
}
666+
A->getValues().size() == 1)
667+
SanitizeVal = A->getValue();
670668
} else {
671669
// User can pass -fsanitize=address to device compiler via
672670
// -Xsycl-target-frontend, sanitize device library must be
673671
// linked with user's device image if so.
674-
bool IsDeviceAsanEnabled = false;
675-
auto SyclFEArg = Args.getAllArgValues(options::OPT_Xsycl_frontend);
676-
IsDeviceAsanEnabled = (std::count(SyclFEArg.begin(), SyclFEArg.end(),
677-
"-fsanitize=address") > 0);
678-
if (!IsDeviceAsanEnabled) {
679-
auto SyclFEArgEq = Args.getAllArgValues(options::OPT_Xsycl_frontend_EQ);
680-
IsDeviceAsanEnabled = (std::count(SyclFEArgEq.begin(), SyclFEArgEq.end(),
681-
"-fsanitize=address") > 0);
682-
}
683-
684-
// User can also enable asan for SYCL device via -Xarch_device option.
685-
if (!IsDeviceAsanEnabled) {
686-
auto DeviceArchVals = Args.getAllArgValues(options::OPT_Xarch_device);
687-
for (auto DArchVal : DeviceArchVals) {
688-
if (DArchVal.find("-fsanitize=address") != std::string::npos) {
689-
IsDeviceAsanEnabled = true;
690-
break;
691-
}
672+
std::vector<std::string> EnabledDeviceSanitizers;
673+
674+
// NOTE: "-fsanitize=" applies to all device targets
675+
auto SyclFEArgVals = Args.getAllArgValues(options::OPT_Xsycl_frontend);
676+
auto SyclFEEQArgVals = Args.getAllArgValues(options::OPT_Xsycl_frontend_EQ);
677+
auto ArchDeviceVals = Args.getAllArgValues(options::OPT_Xarch_device);
678+
679+
std::vector<std::string> ArgVals(
680+
SyclFEArgVals.size() + SyclFEEQArgVals.size() + ArchDeviceVals.size());
681+
ArgVals.insert(ArgVals.end(), SyclFEArgVals.begin(), SyclFEArgVals.end());
682+
ArgVals.insert(ArgVals.end(), SyclFEEQArgVals.begin(),
683+
SyclFEEQArgVals.end());
684+
ArgVals.insert(ArgVals.end(), ArchDeviceVals.begin(), ArchDeviceVals.end());
685+
686+
// Driver will report error if address sanitizer and memory sanitizer are
687+
// both enabled, so we only need to check first one here.
688+
for (const std::string &Arg : ArgVals) {
689+
if (Arg.find("-fsanitize=address") != std::string::npos) {
690+
SanitizeVal = "address";
691+
break;
692692
}
693693
}
694-
695-
if (IsDeviceAsanEnabled)
696-
addSingleLibrary(SYCLDeviceAsanLibs[sanitizer_lib_idx]);
697694
}
695+
696+
if (SanitizeVal == "address")
697+
addSingleLibrary(SYCLDeviceAsanLibs[sanitizer_lib_idx]);
698+
698699
#endif
699700

700701
if (isNativeCPU)

libdevice/cmake/modules/SYCLLibdevice.cmake

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ function(add_devicelibs filename)
197197
cmake_parse_arguments(ARG
198198
""
199199
""
200-
"SRC;EXTRA_OPTS;DEPENDENCIES"
200+
"SRC;EXTRA_OPTS;DEPENDENCIES;SKIP_ARCHS"
201201
${ARGN})
202202

203203
foreach(filetype IN LISTS filetypes)
@@ -209,6 +209,9 @@ function(add_devicelibs filename)
209209
endforeach()
210210

211211
foreach(arch IN LISTS devicelib_arch)
212+
if(arch IN_LIST ARG_SKIP_ARCHS)
213+
continue()
214+
endif()
212215
compile_lib(${filename}-${arch}
213216
FILETYPE bc
214217
SRC ${ARG_SRC}
@@ -229,16 +232,17 @@ set(imf_obj_deps device_imf.hpp imf_half.hpp imf_bf16.hpp imf_rounding_op.hpp im
229232
set(itt_obj_deps device_itt.h spirv_vars.h device.h sycl-compiler)
230233
set(bfloat16_obj_deps sycl-headers sycl-compiler)
231234
if (NOT MSVC AND UR_SANITIZER_INCLUDE_DIR)
232-
set(sanitizer_obj_deps
235+
set(asan_obj_deps
233236
device.h atomic.hpp spirv_vars.h
234-
${UR_SANITIZER_INCLUDE_DIR}/asan_libdevice.hpp
235-
include/sanitizer_utils.hpp
237+
${UR_SANITIZER_INCLUDE_DIR}/asan/asan_libdevice.hpp
238+
include/asan_rtl.hpp
236239
include/spir_global_var.hpp
237240
sycl-compiler)
238241

239242
set(sanitizer_generic_compile_opts ${compile_opts}
240243
-fno-sycl-instrument-device-code
241-
-I${UR_SANITIZER_INCLUDE_DIR})
244+
-I${UR_SANITIZER_INCLUDE_DIR}
245+
-I${CMAKE_CURRENT_SOURCE_DIR})
242246

243247
set(asan_pvc_compile_opts_obj -fsycl -c
244248
${sanitizer_generic_compile_opts}
@@ -346,19 +350,27 @@ if(MSVC)
346350
DEPENDENCIES ${cmath_obj_deps})
347351
else()
348352
if(UR_SANITIZER_INCLUDE_DIR)
353+
# asan jit
349354
add_devicelibs(libsycl-asan
350-
SRC sanitizer_utils.cpp
351-
DEPENDENCIES ${sanitizer_obj_deps}
352-
EXTRA_OPTS -fno-sycl-instrument-device-code -I${UR_SANITIZER_INCLUDE_DIR})
355+
SRC sanitizer/asan_rtl.cpp
356+
DEPENDENCIES ${asan_obj_deps}
357+
SKIP_ARCHS nvptx64-nvidia-cuda
358+
amdgcn-amd-amdhsa
359+
EXTRA_OPTS -fno-sycl-instrument-device-code
360+
-I${UR_SANITIZER_INCLUDE_DIR}
361+
-I${CMAKE_CURRENT_SOURCE_DIR})
362+
363+
# asan aot
353364
set(asan_filetypes obj obj-new-offload bc)
354365
set(asan_devicetypes pvc cpu dg2)
366+
355367
foreach(asan_ft IN LISTS asan_filetypes)
356368
foreach(asan_device IN LISTS asan_devicetypes)
357369
compile_lib_ext(libsycl-asan-${asan_device}
358-
SRC sanitizer_utils.cpp
359-
FILETYPE ${asan_ft}
360-
DEPENDENCIES ${sanitizer_obj_deps}
361-
OPTS ${asan_${asan_device}_compile_opts_${asan_ft}})
370+
SRC sanitizer/asan_rtl.cpp
371+
FILETYPE ${asan_ft}
372+
DEPENDENCIES ${asan_obj_deps}
373+
OPTS ${asan_${asan_device}_compile_opts_${asan_ft}})
362374
endforeach()
363375
endforeach()
364376
endif()

libdevice/include/sanitizer_utils.hpp renamed to libdevice/include/asan_rtl.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//==-- sanitizer_device_utils.hpp - Declaration for sanitizer global var ---==//
1+
//==-- asan_rtl.hpp - Declaration for sanitizer global var ---==//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88
#pragma once
99

10+
#include "sanitizer_defs.hpp"
1011
#include "spir_global_var.hpp"
1112
#include <cstdint>
1213

libdevice/include/sanitizer_defs.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//==-- sanitizer_defs.hpp - common macros shared by sanitizers ---==//
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 <cstdint>
11+
12+
using uptr = uintptr_t;
13+
using u8 = uint8_t;
14+
using u16 = uint16_t;
15+
using u32 = uint32_t;
16+
using u64 = uint64_t;
17+
using s8 = int8_t;
18+
using s16 = int16_t;
19+
using s32 = int32_t;
20+
using s64 = int64_t;
21+
22+
#define LIKELY(x) __builtin_expect(!!(x), 1)
23+
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
24+
#define NORETURN __declspec(noreturn)

libdevice/sanitizer_utils.cpp renamed to libdevice/sanitizer/asan_rtl.cpp

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
1-
//==--- sanitizer_utils.cpp - device sanitizer util inserted by compiler ---==//
1+
//==--- asan_rtl.cpp - device address sanitizer runtime library ------------==//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "asan_libdevice.hpp"
9+
#include "include/asan_rtl.hpp"
10+
#include "asan/asan_libdevice.hpp"
1011
#include "atomic.hpp"
1112
#include "device.h"
1213
#include "spirv_vars.h"
1314

14-
#include "include/sanitizer_utils.hpp"
15-
16-
using uptr = uintptr_t;
17-
using s8 = char;
18-
using u8 = unsigned char;
19-
using s16 = short;
20-
using u16 = unsigned short;
21-
2215
// Save the pointer to LaunchInfo
2316
__SYCL_GLOBAL__ uptr *__SYCL_LOCAL__ __AsanLaunchInfo;
2417

@@ -375,7 +368,7 @@ bool MemIsZero(__SYCL_GLOBAL__ const char *beg, uptr size) {
375368
static __SYCL_CONSTANT__ const char __mem_sanitizer_report[] =
376369
"[kernel] SanitizerReport (ErrorType=%d, IsRecover=%d)\n";
377370

378-
void __asan_internal_report_save(DeviceSanitizerErrorType error_type) {
371+
void __asan_internal_report_save(ErrorType error_type) {
379372
const int Expected = ASAN_REPORT_NONE;
380373
int Desired = ASAN_REPORT_START;
381374

@@ -387,21 +380,21 @@ void __asan_internal_report_save(DeviceSanitizerErrorType error_type) {
387380
__spirv_BuiltInWorkgroupId.z;
388381

389382
auto &SanitizerReport = ((__SYCL_GLOBAL__ LaunchInfo *)__AsanLaunchInfo)
390-
->SanitizerReport[WG_LID % ASAN_MAX_NUM_REPORTS];
383+
->Report[WG_LID % ASAN_MAX_NUM_REPORTS];
391384

392385
if (atomicCompareAndSet(
393386
&(((__SYCL_GLOBAL__ LaunchInfo *)__AsanLaunchInfo)->ReportFlag), 1,
394387
0) == 0 &&
395388
atomicCompareAndSet(&SanitizerReport.Flag, Desired, Expected) ==
396389
Expected) {
397-
SanitizerReport.ErrorType = error_type;
390+
SanitizerReport.ErrorTy = error_type;
398391
SanitizerReport.IsRecover = false;
399392

400393
// Show we've done copying
401394
atomicStore(&SanitizerReport.Flag, ASAN_REPORT_FINISH);
402395

403396
ASAN_DEBUG(__spirv_ocl_printf(__mem_sanitizer_report,
404-
SanitizerReport.ErrorType,
397+
SanitizerReport.ErrorTy,
405398
SanitizerReport.IsRecover));
406399
}
407400
__devicelib_exit();
@@ -410,8 +403,7 @@ void __asan_internal_report_save(DeviceSanitizerErrorType error_type) {
410403
void __asan_internal_report_save(
411404
uptr ptr, uint32_t as, const char __SYCL_CONSTANT__ *file, uint32_t line,
412405
const char __SYCL_CONSTANT__ *func, bool is_write, uint32_t access_size,
413-
DeviceSanitizerMemoryType memory_type, DeviceSanitizerErrorType error_type,
414-
bool is_recover = false) {
406+
MemoryType memory_type, ErrorType error_type, bool is_recover = false) {
415407

416408
const int Expected = ASAN_REPORT_NONE;
417409
int Desired = ASAN_REPORT_START;
@@ -424,7 +416,7 @@ void __asan_internal_report_save(
424416
__spirv_BuiltInWorkgroupId.z;
425417

426418
auto &SanitizerReport = ((__SYCL_GLOBAL__ LaunchInfo *)__AsanLaunchInfo)
427-
->SanitizerReport[WG_LID % ASAN_MAX_NUM_REPORTS];
419+
->Report[WG_LID % ASAN_MAX_NUM_REPORTS];
428420

429421
if ((is_recover ||
430422
atomicCompareAndSet(
@@ -470,15 +462,15 @@ void __asan_internal_report_save(
470462
SanitizerReport.Address = ptr;
471463
SanitizerReport.IsWrite = is_write;
472464
SanitizerReport.AccessSize = access_size;
473-
SanitizerReport.ErrorType = error_type;
474-
SanitizerReport.MemoryType = memory_type;
465+
SanitizerReport.ErrorTy = error_type;
466+
SanitizerReport.MemoryTy = memory_type;
475467
SanitizerReport.IsRecover = is_recover;
476468

477469
// Show we've done copying
478470
atomicStore(&SanitizerReport.Flag, ASAN_REPORT_FINISH);
479471

480472
ASAN_DEBUG(__spirv_ocl_printf(__mem_sanitizer_report,
481-
SanitizerReport.ErrorType,
473+
SanitizerReport.ErrorTy,
482474
SanitizerReport.IsRecover));
483475
}
484476
__devicelib_exit();
@@ -488,29 +480,29 @@ void __asan_internal_report_save(
488480
/// ASAN Error Reporters
489481
///
490482

491-
DeviceSanitizerMemoryType GetMemoryTypeByShadowValue(int shadow_value) {
483+
MemoryType GetMemoryTypeByShadowValue(int shadow_value) {
492484
switch (shadow_value) {
493485
case kUsmDeviceRedzoneMagic:
494486
case kUsmDeviceDeallocatedMagic:
495-
return DeviceSanitizerMemoryType::USM_DEVICE;
487+
return MemoryType::USM_DEVICE;
496488
case kUsmHostRedzoneMagic:
497489
case kUsmHostDeallocatedMagic:
498-
return DeviceSanitizerMemoryType::USM_HOST;
490+
return MemoryType::USM_HOST;
499491
case kUsmSharedRedzoneMagic:
500492
case kUsmSharedDeallocatedMagic:
501-
return DeviceSanitizerMemoryType::USM_SHARED;
493+
return MemoryType::USM_SHARED;
502494
case kPrivateLeftRedzoneMagic:
503495
case kPrivateMidRedzoneMagic:
504496
case kPrivateRightRedzoneMagic:
505-
return DeviceSanitizerMemoryType::PRIVATE;
497+
return MemoryType::PRIVATE;
506498
case kMemBufferRedzoneMagic:
507-
return DeviceSanitizerMemoryType::MEM_BUFFER;
499+
return MemoryType::MEM_BUFFER;
508500
case kSharedLocalRedzoneMagic:
509-
return DeviceSanitizerMemoryType::LOCAL;
501+
return MemoryType::LOCAL;
510502
case kDeviceGlobalRedzoneMagic:
511-
return DeviceSanitizerMemoryType::DEVICE_GLOBAL;
503+
return MemoryType::DEVICE_GLOBAL;
512504
default:
513-
return DeviceSanitizerMemoryType::UNKNOWN;
505+
return MemoryType::UNKNOWN;
514506
}
515507
}
516508

@@ -528,9 +520,8 @@ void __asan_report_access_error(uptr addr, uint32_t as, size_t size,
528520
}
529521
// FIXME: check if shadow_address out-of-bound
530522

531-
DeviceSanitizerMemoryType memory_type =
532-
GetMemoryTypeByShadowValue(shadow_value);
533-
DeviceSanitizerErrorType error_type;
523+
MemoryType memory_type = GetMemoryTypeByShadowValue(shadow_value);
524+
ErrorType error_type;
534525

535526
switch (shadow_value) {
536527
case kUsmDeviceRedzoneMagic:
@@ -542,18 +533,18 @@ void __asan_report_access_error(uptr addr, uint32_t as, size_t size,
542533
case kMemBufferRedzoneMagic:
543534
case kSharedLocalRedzoneMagic:
544535
case kDeviceGlobalRedzoneMagic:
545-
error_type = DeviceSanitizerErrorType::OUT_OF_BOUNDS;
536+
error_type = ErrorType::OUT_OF_BOUNDS;
546537
break;
547538
case kUsmDeviceDeallocatedMagic:
548539
case kUsmHostDeallocatedMagic:
549540
case kUsmSharedDeallocatedMagic:
550-
error_type = DeviceSanitizerErrorType::USE_AFTER_FREE;
541+
error_type = ErrorType::USE_AFTER_FREE;
551542
break;
552543
case kNullPointerRedzoneMagic:
553-
error_type = DeviceSanitizerErrorType::NULL_POINTER;
544+
error_type = ErrorType::NULL_POINTER;
554545
break;
555546
default:
556-
error_type = DeviceSanitizerErrorType::UNKNOWN;
547+
error_type = ErrorType::UNKNOWN;
557548
}
558549

559550
__asan_internal_report_save(addr, as, file, line, func, is_write, size,
@@ -573,16 +564,15 @@ void __asan_report_misalign_error(uptr addr, uint32_t as, size_t size,
573564
}
574565
int shadow_value = *shadow;
575566

576-
DeviceSanitizerErrorType error_type = DeviceSanitizerErrorType::MISALIGNED;
577-
DeviceSanitizerMemoryType memory_type =
578-
GetMemoryTypeByShadowValue(shadow_value);
567+
ErrorType error_type = ErrorType::MISALIGNED;
568+
MemoryType memory_type = GetMemoryTypeByShadowValue(shadow_value);
579569

580570
__asan_internal_report_save(addr, as, file, line, func, is_write, size,
581571
memory_type, error_type, is_recover);
582572
}
583573

584574
void __asan_report_unknown_device() {
585-
__asan_internal_report_save(DeviceSanitizerErrorType::UNKNOWN_DEVICE);
575+
__asan_internal_report_save(ErrorType::UNKNOWN_DEVICE);
586576
}
587577

588578
///

0 commit comments

Comments
 (0)