Skip to content

Commit ade1870

Browse files
authored
[SYCL][HIP] Add assert support (#6424)
This patch adds an implementation of `__assert_fail` for HIP. It is implemented in IR because the function needs to take pointers with no address space and OpenCL compilation makes them private. It is implemented using the OCKL printf functions provided by HIP. In addition this patch also fixes `SYCL_EXTERNAL` for HIP, the AMDGPU backend runs some dead code elimination and would simply delete `SYCL_EXTERNAL` functions, and so this patch prevents the AMDGPU backend from deleting `SYCL_EXTERNAL` functions, identifying them through the `sycl-module-id` attribute (as done in other places such as `sycl-post-link`). This issue showed up in some of the assert tests that use multiple translation units, and this patch also fixes the `sycl-external.cpp` test. Matching `llvm-test-suite` update: intel/llvm-test-suite#1083
1 parent 7057f7a commit ade1870

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

libclc/amdgcn-amdhsa/libspirv/SOURCES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ workitem/get_sub_group_local_id.cl
6565
workitem/get_sub_group_size.cl
6666
misc/sub_group_shuffle.cl
6767
async/wait_group_events.cl
68+
assert/__assert_fail.ll
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
;;===----------------------------------------------------------------------===//
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+
#if __clang_major__ >= 7
10+
target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
11+
#else
12+
target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"
13+
#endif
14+
15+
@.assert_fmt = private unnamed_addr constant [79 x i8] c"%s:%u: %s: global id: [%u,%u,%u], local id: [%u,%u,%u] Assertion `%s` failed.\0A\00", align 1
16+
17+
declare void @llvm.trap() cold noreturn nounwind
18+
19+
declare i64 @__ockl_fprintf_stderr_begin() local_unnamed_addr
20+
declare i64 @__ockl_fprintf_append_string_n(i64, i8* readonly, i64, i32) local_unnamed_addr
21+
declare i64 @__ockl_fprintf_append_args(i64, i32, i64, i64, i64, i64, i64, i64, i64, i32) local_unnamed_addr
22+
23+
declare dso_local i64 @_Z28__spirv_GlobalInvocationId_xv() local_unnamed_addr
24+
declare dso_local i64 @_Z28__spirv_GlobalInvocationId_yv() local_unnamed_addr
25+
declare dso_local i64 @_Z28__spirv_GlobalInvocationId_zv() local_unnamed_addr
26+
27+
declare dso_local i64 @_Z27__spirv_LocalInvocationId_xv() local_unnamed_addr
28+
declare dso_local i64 @_Z27__spirv_LocalInvocationId_yv() local_unnamed_addr
29+
declare dso_local i64 @_Z27__spirv_LocalInvocationId_zv() local_unnamed_addr
30+
31+
define dso_local hidden noundef i64 @__strlen_assert(i8* noundef %str) local_unnamed_addr {
32+
entry:
33+
br label %while.cond
34+
35+
while.cond:
36+
%tmp.0 = phi i8* [ %str, %entry ], [ %incdec.ptr, %while.cond ]
37+
%incdec.ptr = getelementptr inbounds i8, i8* %tmp.0, i64 1
38+
%0 = load i8, i8* %tmp.0, align 1
39+
%tobool.not = icmp eq i8 %0, 0
40+
br i1 %tobool.not, label %while.end, label %while.cond
41+
42+
while.end:
43+
%sub.ptr.lhs.cast = ptrtoint i8* %incdec.ptr to i64
44+
%sub.ptr.rhs.cast = ptrtoint i8* %str to i64
45+
%sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
46+
ret i64 %sub.ptr.sub
47+
}
48+
49+
define hidden void @__assert_fail(i8* %assertion, i8* %file, i32 %line, i8* %function) nounwind alwaysinline {
50+
entry:
51+
%msg = call i64 @__ockl_fprintf_stderr_begin()
52+
%msg.1 = call i64 @__ockl_fprintf_append_string_n(i64 %msg, i8* readonly getelementptr inbounds ([79 x i8], [79 x i8]* @.assert_fmt, i64 0, i64 0), i64 79, i32 0)
53+
%len.file = call i64 @__strlen_assert(i8* %file)
54+
%msg.2 = call i64 @__ockl_fprintf_append_string_n(i64 %msg.1, i8* readonly %file, i64 %len.file, i32 0)
55+
%line.i64 = sext i32 %line to i64
56+
%msg.3 = call i64 @__ockl_fprintf_append_args(i64 %msg.2, i32 1, i64 %line.i64, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i32 0)
57+
%len.func = call i64 @__strlen_assert(i8* %function)
58+
%msg.4 = call i64 @__ockl_fprintf_append_string_n(i64 %msg.3, i8* readonly %function, i64 %len.func, i32 0)
59+
%gidx = tail call i64 @_Z28__spirv_GlobalInvocationId_xv()
60+
%gidy = tail call i64 @_Z28__spirv_GlobalInvocationId_yv()
61+
%gidz = tail call i64 @_Z28__spirv_GlobalInvocationId_zv()
62+
%lidx = tail call i64 @_Z27__spirv_LocalInvocationId_xv()
63+
%lidy = tail call i64 @_Z27__spirv_LocalInvocationId_yv()
64+
%lidz = tail call i64 @_Z27__spirv_LocalInvocationId_zv()
65+
%msg.5 = call i64 @__ockl_fprintf_append_args(i64 %msg.4, i32 6, i64 %gidx, i64 %gidy, i64 %gidz, i64 %lidx, i64 %lidy, i64 %lidz, i64 0, i32 0)
66+
%len.assertion = call i64 @__strlen_assert(i8* %assertion)
67+
%msg.6 = call i64 @__ockl_fprintf_append_string_n(i64 %msg.4, i8* readonly %assertion, i64 %len.assertion, i32 1)
68+
tail call void @llvm.trap()
69+
unreachable
70+
}

llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,11 +555,14 @@ StringRef AMDGPUTargetMachine::getFeatureString(const Function &F) const {
555555
}
556556

557557
/// Predicate for Internalize pass.
558+
/// Functions with the 'sycl-module-id' attribute are SYCL_EXTERNAL functions
559+
/// and must be preserved.
558560
static bool mustPreserveGV(const GlobalValue &GV) {
559561
if (const Function *F = dyn_cast<Function>(&GV))
560562
return F->isDeclaration() || F->getName().startswith("__asan_") ||
561563
F->getName().startswith("__sanitizer_") ||
562-
AMDGPU::isEntryFunctionCC(F->getCallingConv());
564+
AMDGPU::isEntryFunctionCC(F->getCallingConv()) ||
565+
F->hasFnAttribute("sycl-module-id");
563566

564567
GV.removeDeadConstantUsers();
565568
return !GV.use_empty();

0 commit comments

Comments
 (0)