Skip to content

Commit 5babe36

Browse files
committed
add func test
1 parent 805abc8 commit 5babe36

File tree

4 files changed

+58
-14
lines changed

4 files changed

+58
-14
lines changed

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,9 @@ static bool isUnsupportedDeviceGlobal(GlobalVariable *G) {
16661666
if (G->getName().starts_with("__Asan"))
16671667
return true;
16681668

1669+
if (G->getAddressSpace() == kSpirOffloadLocalAS)
1670+
return true;
1671+
16691672
Attribute Attr = G->getAttribute("sycl-device-image-scope");
16701673
return (!Attr.isStringAttribute() || Attr.getValueAsString() == "false");
16711674
}
@@ -3062,7 +3065,8 @@ void ModuleAddressSanitizer::instrumentSyclStaticLocalMemory(IRBuilder<> &IRB) {
30623065
// Get root spir_kernel of spir_func
30633066
initializeKernelCallerMap(F);
30643067
for (Function *Kernel : FuncToKernelCallerMap[F])
3065-
Instrument(G, Kernel);
3068+
if (!InstrumentedFunc.contains(Kernel))
3069+
Instrument(G, Kernel);
30663070
}
30673071
}
30683072
}
@@ -3945,9 +3949,9 @@ bool AddressSanitizer::instrumentFunction(Function &F,
39453949
if (ChangedStack || !NoReturnCalls.empty())
39463950
FunctionModified = true;
39473951

3948-
// We need to instrument dynamic/static local arguments after stack poisoner
3952+
// We need to instrument dynamic local arguments after stack poisoner
39493953
if (TargetTriple.isSPIROrSPIRV()) {
3950-
if (F.getCallingConv() == CallingConv::SPIR_KERNEL) {
3954+
if (ClSpirOffloadLocals && F.getCallingConv() == CallingConv::SPIR_KERNEL) {
39513955
FunctionModified |= instrumentSyclDynamicLocalMemory(F, FSP.RetVec);
39523956
}
39533957
}

llvm/test/Instrumentation/AddressSanitizer/SPIRV/instrument_local_addess_space.ll

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,20 @@ target triple = "spir64-unknown-unknown"
77
%"class.sycl::_V1::detail::array" = type { [1 x i64] }
88
%"class.sycl::_V1::id" = type { %"class.sycl::_V1::detail::array" }
99

10-
declare dso_local spir_func ptr addrspace(3) @__sycl_allocateLocalMemory(i64 noundef %0, i64 noundef %1) local_unnamed_addr #1
10+
@WGLocalMem = internal addrspace(3) global [64 x i8] poison, align 4
1111

12-
define spir_kernel void @kernel_static_local() #0 {
12+
define spir_kernel void @kernel_static_local() sanitize_address {
1313
; CHECK-LABEL: define spir_kernel void @kernel_static_local
1414
entry:
15-
%1 = tail call spir_func ptr addrspace(3) @__sycl_allocateLocalMemory(i64 noundef 16, i64 noundef 4)
16-
; CHECK: [[T0:%.*]] = call ptr addrspace(3) @__sycl_allocateLocalMemory(i64 32, i64 8)
17-
; CHECK-NEXT: [[T1:%.*]] = ptrtoint ptr addrspace(3) [[T0]] to i64
18-
; CHECK-NEXT: call void @__asan_set_shadow_static_local(i64 [[T1]], i64 16, i64 32)
19-
; CHECK-NEXT: call void @__asan_unpoison_shadow_static_local(i64 %1, i64 16, i64 32)
15+
store i32 0, ptr addrspace(3) @WGLocalMem
16+
; CHECK: store ptr addrspace(1) %__asan_launch, ptr addrspace(3) @__AsanLaunchInfo, align 8
17+
; CHECK-NEXT: call void @__asan_set_shadow_static_local(i64 ptrtoint (ptr addrspace(3) @WGLocalMem to i64), i64 64, i64 96)
18+
; CHECK-NEXT: store i32 0, ptr addrspace(3) @WGLocalMem, align 4
19+
; CHECK-NEXT: call void @__asan_unpoison_shadow_static_local(i64 ptrtoint (ptr addrspace(3) @WGLocalMem to i64), i64 64, i64 96)
2020
ret void
2121
}
2222

23-
define spir_kernel void @kernel_dynamic_local(ptr addrspace(3) noundef align 4 %_arg_acc, ptr noundef byval(%"class.sycl::_V1::range") align 8 %_arg_acc1, ptr noundef byval(%"class.sycl::_V1::range") align 8 %_arg_acc2, ptr noundef byval(%"class.sycl::_V1::id") align 8 %_arg_acc3) #0 {
23+
define spir_kernel void @kernel_dynamic_local(ptr addrspace(3) noundef align 4 %_arg_acc, ptr noundef byval(%"class.sycl::_V1::range") align 8 %_arg_acc1, ptr noundef byval(%"class.sycl::_V1::range") align 8 %_arg_acc2, ptr noundef byval(%"class.sycl::_V1::id") align 8 %_arg_acc3) sanitize_address {
2424
; CHECK-LABEL: define spir_kernel void @kernel_dynamic_local
2525
entry:
2626
; CHECK: %local_args = alloca i64, align 8
@@ -32,6 +32,3 @@ entry:
3232
; CHECK: call void @__asan_unpoison_shadow_dynamic_local(i64 %2, i32 1)
3333
ret void
3434
}
35-
36-
attributes #0 = { sanitize_address }
37-
attributes #1 = { convergent nounwind }

sycl/test-e2e/AddressSanitizer/out-of-bounds/local/group_local_memory.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ int main() {
3030
ptr = sycl::ext::oneapi::group_local_memory<int[N]>(
3131
item.get_group());
3232
auto &ref = *ptr;
33+
// NOTE: direct access will be optimized out
3334
data[0] = check(ref, item.get_local_linear_id() * 2 + 4);
3435
});
3536
});
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// REQUIRES: linux, cpu || (gpu && level_zero)
2+
// RUN: %{build} %device_asan_flags -g -O0 -o %t1.out
3+
// RUN: %{run} not %t1.out 2>&1 | FileCheck %s
4+
// RUN: %{build} %device_asan_flags -g -O1 -o %t2.out
5+
// RUN: %{run} not %t2.out 2>&1 | FileCheck %s
6+
// RUN: %{build} %device_asan_flags -g -O2 -o %t3.out
7+
// RUN: %{run} not %t3.out 2>&1 | FileCheck %s
8+
9+
#include <sycl/detail/core.hpp>
10+
11+
#include <sycl/ext/oneapi/group_local_memory.hpp>
12+
#include <sycl/usm.hpp>
13+
14+
constexpr std::size_t N = 16;
15+
constexpr std::size_t group_size = 8;
16+
17+
__attribute__((noinline)) int check(int *ref, int index) { return ref[index]; }
18+
// CHECK: ERROR: DeviceSanitizer: out-of-bounds-access on Local Memory
19+
// CHECK: READ of size 4 at kernel {{<.*MyKernel>}} LID({{.*}}, 0, 0) GID({{.*}}, 0, 0)
20+
// CHECK: #0 {{.*}} {{.*group_local_memory_func.cpp}}:[[@LINE-3]]
21+
22+
__attribute__((noinline)) int test_local(sycl::nd_item<1> &item) {
23+
auto local_mem = sycl::ext::oneapi::group_local_memory<int[group_size]>(item.get_group());
24+
// NOTE: direct access will be optimized out
25+
return check(*local_mem, group_size);
26+
}
27+
28+
int main() {
29+
sycl::queue Q;
30+
auto data = sycl::malloc_device<int>(N, Q);
31+
32+
Q.submit([&](sycl::handler &h) {
33+
h.parallel_for<class MyKernel>(
34+
sycl::nd_range<1>(N, group_size), [=](sycl::nd_item<1> item) {
35+
data[0] = test_local(item);
36+
});
37+
});
38+
Q.wait();
39+
40+
sycl::free(data, Q);
41+
return 0;
42+
}

0 commit comments

Comments
 (0)