Skip to content

Commit 40e247d

Browse files
[SYCL] Fix linkage adjustment of kernels (#19915)
This is a cherry-pick of #19771 This patch resolves #19409 Two main changes were done: 1. Corrected method of detection that kernel is defined as an inline function. The original code detecting this was introduced in #338, but by some reason we looked into a headers-provided wrapper that calls a kernel instead of a kernel itself. Alongside with fixing this, a dedicated clang-level test was added to check this behavior 2. Fixed a bug introduced by incorrect conflict resolution (commit fcd95a9) with llvm/llvm-project#137882. Specifically, when deciding if a function (that is expected to be a SYCL kernel) linkage should be promoted to non-discardable we used to check for OpenCL kernel attribute. That attribute is not present in SYCL headers and therefore was only generated for actual SYCL kernels emitted by front-end. However, with kernel attributes unified, we now promote linkage of non-kernel wrapper function that has `sycl_kernel` attribute attached to it explicitly by SYCL headers. The fix here is to only react to the kernel attribute if it was added implicitly, to preserve original behavior.
1 parent 48609f5 commit 40e247d

26 files changed

+128
-53
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12895,7 +12895,8 @@ static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context,
1289512895
if (Context.shouldExternalize(D))
1289612896
return GVA_StrongExternal;
1289712897
} else if (Context.getLangOpts().SYCLIsDevice &&
12898-
D->hasAttr<DeviceKernelAttr>()) {
12898+
(D->hasAttr<DeviceKernelAttr>() &&
12899+
D->getAttr<DeviceKernelAttr>()->isImplicit())) {
1289912900
if (L == GVA_DiscardableODR)
1290012901
return GVA_StrongODR;
1290112902
}

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5442,9 +5442,13 @@ void SemaSYCL::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
54425442
ESIMDKernelDiagnostics esimdKernel(*this, KernelObj->getLocation(),
54435443
IsSIMDKernel);
54445444

5445-
SyclKernelDeclCreator kernel_decl(*this, KernelObj->getLocation(),
5446-
KernelCallerFunc->isInlined(), IsSIMDKernel,
5447-
KernelCallerFunc);
5445+
// In case of syntax errors in input programs we are not able to access
5446+
// CallOperator. In this case the value of IsInlined doesn't matter, because
5447+
// compilation will fail with errors anyways.
5448+
const bool IsInlined =
5449+
CallOperator ? CallOperator->isInlined() : /* placeholder */ false;
5450+
SyclKernelDeclCreator kernel_decl(*this, KernelObj->getLocation(), IsInlined,
5451+
IsSIMDKernel, KernelCallerFunc);
54485452
SyclKernelBodyCreator kernel_body(*this, kernel_decl, KernelObj,
54495453
KernelCallerFunc, IsSIMDKernel,
54505454
CallOperator);

clang/test/CodeGenSYCL/device_has.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
using namespace sycl;
77
queue q;
88

9-
// CHECK-DAG: define dso_local spir_kernel void @{{.*}}kernel_name_1{{.*}} !sycl_declared_aspects ![[ASPECTS1:[0-9]+]] !srcloc ![[SRCLOC1:[0-9]+]]
9+
// CHECK-DAG: define {{.*}}spir_kernel void @{{.*}}kernel_name_1{{.*}} !sycl_declared_aspects ![[ASPECTS1:[0-9]+]] !srcloc ![[SRCLOC1:[0-9]+]]
1010

1111
// CHECK-DAG: define {{.*}}spir_func void @{{.*}}func1{{.*}} !sycl_declared_aspects ![[ASPECTS1]] !srcloc ![[SRCLOC2:[0-9]+]] {
1212
[[sycl::device_has(sycl::aspect::cpu)]] void func1() {}
@@ -67,7 +67,7 @@ void foo() {
6767
q.submit([&](handler &h) {
6868
KernelFunctor f1;
6969
h.single_task<class kernel_name_1>(f1);
70-
// CHECK-DAG: define dso_local spir_kernel void @{{.*}}kernel_name_2{{.*}} !sycl_declared_aspects ![[ASPECTS4:[0-9]+]] !srcloc ![[SRCLOC8:[0-9]+]]
70+
// CHECK-DAG: define {{.*}}spir_kernel void @{{.*}}kernel_name_2{{.*}} !sycl_declared_aspects ![[ASPECTS4:[0-9]+]] !srcloc ![[SRCLOC8:[0-9]+]]
7171
h.single_task<class kernel_name_2>([]() [[sycl::device_has(sycl::aspect::gpu)]] {});
7272
});
7373
}

clang/test/CodeGenSYCL/dynamic_local_accessor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// The first two RUN commands verify that the init call is generated with the correct arguments in LLVM IR
88
// and the second two RUN commands verify the contents of the integration header produced by the frontend.
99
//
10-
// CHECK-IR: define dso_local spir_kernel void @
10+
// CHECK-IR: define {{.*}}spir_kernel void @
1111
// CHECK-IR-SAME: ptr addrspace(3) noundef align 4 [[PTR:%[a-zA-Z0-9_]+]]
1212
//
1313
// CHECK-IR: [[PTR]].addr = alloca ptr addrspace(3), align 8

clang/test/CodeGenSYCL/dynamic_work_group_memory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// The first two RUN commands verify that the init call is generated with the correct arguments in LLVM IR
88
// and the second two RUN commands verify the contents of the integration header produced by the frontend.
99
//
10-
// CHECK-IR: define dso_local spir_kernel void @
10+
// CHECK-IR: define {{.*}}spir_kernel void @
1111
// CHECK-IR-SAME: ptr addrspace(3) noundef align 4 [[PTR:%[a-zA-Z0-9_]+]]
1212
//
1313
// CHECK-IR: [[PTR]].addr = alloca ptr addrspace(3), align 8

clang/test/CodeGenSYCL/generated-types-initialization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ int main() {
3838
});
3939
return 0;
4040
}
41-
// CHECK: define dso_local spir_kernel void @{{.*}}basic(ptr noundef byval(%struct.__generated_B) align 8 %_arg_Obj)
41+
// CHECK: define {{.*}}spir_kernel void @{{.*}}basic(ptr noundef byval(%struct.__generated_B) align 8 %_arg_Obj)
4242
//
4343
// Kernel object clone.
4444
// CHECK: %[[K:[a-zA-Z0-9_.]+]] = alloca %class.anon
@@ -54,7 +54,7 @@ int main() {
5454
// Kernel body call.
5555
// CHECK: call spir_func void @_ZZZ4mainENKUlRN4sycl3_V17handlerEE_clES2_ENKUlvE_clEv(ptr addrspace(4) noundef align 8 dereferenceable_or_null(16) %[[K_as_cast]])
5656

57-
// CHECK: define dso_local spir_kernel void @{{.*}}nns(ptr noundef byval(%struct.__generated_B.0) align 8 %_arg_NNSObj)
57+
// CHECK: define {{.*}}spir_kernel void @{{.*}}nns(ptr noundef byval(%struct.__generated_B.0) align 8 %_arg_NNSObj)
5858
//
5959
// Kernel object clone.
6060
// CHECK: %[[NNSK:[a-zA-Z0-9_.]+]] = alloca %class.anon.2

clang/test/CodeGenSYCL/kernel-handler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ void test(int val) {
2222
});
2323
}
2424

25-
// ALL: define dso_local{{ spir_kernel | ptx_kernel | }}void @{{.*}}test_kernel_handler{{[^(]*}}
25+
// ALL: define {{.*}}{{ spir_kernel | ptx_kernel | }}void @{{.*}}test_kernel_handler{{[^(]*}}
2626
// NONATIVESUPPORT-SAME: (ptr noundef byval(%class.anon) align 4 %_arg__sycl_functor, ptr addrspace(1) noundef align 1 %_arg__specialization_constants_buffer)
2727
// NATIVESUPPORT-SAME: (i32 noundef %_arg_a, ptr addrspace(1) noundef align 1 %_arg__specialization_constants_buffer)
2828
// ALL: %kh = alloca %"class.sycl::_V1::kernel_handler", align 1

clang/test/CodeGenSYCL/kernel-op-calls.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,46 +14,46 @@ class Functor1 {
1414
[[sycl::reqd_sub_group_size(4)]] void operator()(sycl::id<1> id) const {}
1515

1616
[[sycl::work_group_size_hint(1, 2, 3)]] void operator()(sycl::id<2> id) const {}
17-
1817
};
1918

2019
class ESIMDFunctor {
2120
public:
22-
ESIMDFunctor(){}
21+
ESIMDFunctor(){}
2322

2423
[[intel::sycl_explicit_simd]] void operator()(sycl::id<2> id) const {}
2524

26-
[[sycl::work_group_size_hint(1, 2, 3)]][[intel::sycl_explicit_simd]] void operator()(sycl::id<1> id) const {}
27-
25+
[[sycl::work_group_size_hint(1, 2, 3)]] [[intel::sycl_explicit_simd]]
26+
void operator()(sycl::id<1> id) const {}
2827
};
2928

3029
// Check templated 'operator()()' call works.
3130
class kernels {
32-
public:
31+
public:
3332
kernels(){}
3433

35-
template<int Dimensions = 1>
36-
[[sycl::work_group_size_hint(1, 2, 3)]] void operator()(sycl::id<Dimensions> item) const {}
37-
34+
template<int Dimensions = 1>
35+
[[sycl::work_group_size_hint(1, 2, 3)]]
36+
void operator()(sycl::id<Dimensions> item) const {}
3837
};
3938

4039
int main() {
4140

4241
Q.submit([&](sycl::handler& cgh) {
4342
Functor1 F;
44-
// CHECK: define dso_local spir_kernel void @_ZTS8Functor1() {{.*}} !kernel_arg_buffer_location !{{[0-9]+}} !intel_reqd_sub_group_size !{{[0-9]+}} !sycl_fixed_targets !{{[0-9]+}} {
43+
// CHECK: define weak_odr spir_kernel void @_ZTS8Functor1() {{.*}} !intel_reqd_sub_group_size
4544
cgh.parallel_for(sycl::range<1>(10), F);
4645
});
4746

4847
Q.submit([&](sycl::handler& cgh) {
4948
kernels K;
50-
// CHECK: define dso_local spir_kernel void @_ZTS7kernels() {{.*}} !kernel_arg_buffer_location !{{[0-9]+}} !work_group_size_hint !{{[0-9]+}} !sycl_fixed_targets !{{[0-9]+}} {
49+
// CHECK: define weak_odr spir_kernel void @_ZTS7kernels() {{.*}} !work_group_size_hint !{{[0-9]+}}
5150
cgh.parallel_for(sycl::range<1>(10), K);
5251
});
5352

5453
Q.submit([&](sycl::handler& cgh) {
5554
ESIMDFunctor EF;
56-
// CHECK: define dso_local spir_kernel void @_ZTS12ESIMDFunctor() {{.*}} !sycl_explicit_simd !{{[0-9]+}} !intel_reqd_sub_group_size !{{[0-9]+}} !work_group_size_hint !{{[0-9]+}} !kernel_arg_accessor_ptr !{{[0-9]+}} !sycl_fixed_targets !{{[0-9]+}} {
55+
// CHECK: define weak_odr spir_kernel void @_ZTS12ESIMDFunctor() {{.*}} !work_group_size_hint
56+
// CHECK-SAME: !sycl_explicit_simd
5757
cgh.parallel_for(sycl::range<1>(10), EF);
5858
});
5959

clang/test/CodeGenSYCL/kernel-param-acc-array.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ int main() {
2424
acc[1].use();
2525
});
2626
}
27-
// CHECK-LABEL: define dso_local spir_kernel void @_ZTSZ4mainE8kernel_A(
27+
// CHECK-LABEL: define {{.*}}spir_kernel void @_ZTSZ4mainE8kernel_A(
2828
// CHECK-SAME: ptr addrspace(1) noundef align 4 [[_ARG_ACC:%.*]], ptr noundef byval(%"struct.sycl::_V1::range") align 4 [[_ARG_ACC1:%.*]], ptr noundef byval(%"struct.sycl::_V1::range") align 4 [[_ARG_ACC2:%.*]], ptr noundef byval(%"struct.sycl::_V1::id") align 4 [[_ARG_ACC3:%.*]], ptr addrspace(1) noundef align 4 [[_ARG_ACC4:%.*]], ptr noundef byval(%"struct.sycl::_V1::range") align 4 [[_ARG_ACC6:%.*]], ptr noundef byval(%"struct.sycl::_V1::range") align 4 [[_ARG_ACC7:%.*]], ptr noundef byval(%"struct.sycl::_V1::id") align 4 [[_ARG_ACC8:%.*]]) #[[ATTR0:[0-9]+]]
2929
// CHECK-NEXT: [[ENTRY:.*:]]
3030
// CHECK-NEXT: [[_ARG_ACC_ADDR:%.*]] = alloca ptr addrspace(1), align 8

clang/test/CodeGenSYCL/kernel-param-member-acc-array.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ int main() {
2828
});
2929
}
3030

31-
// CHECK-LABEL: define dso_local spir_kernel void @_ZTSZ4mainE8kernel_C(
31+
// CHECK-LABEL: define {{.*}}spir_kernel void @_ZTSZ4mainE8kernel_C(
3232
// CHECK-SAME: ptr addrspace(1) noundef align 4 [[_ARG_MEMBER_ACC:%.*]], ptr noundef byval(%"struct.sycl::_V1::range") align 4 [[_ARG_MEMBER_ACC1:%.*]], ptr noundef byval(%"struct.sycl::_V1::range") align 4 [[_ARG_MEMBER_ACC2:%.*]], ptr noundef byval(%"struct.sycl::_V1::id") align 4 [[_ARG_MEMBER_ACC3:%.*]], ptr addrspace(1) noundef align 4 [[_ARG_MEMBER_ACC4:%.*]], ptr noundef byval(%"struct.sycl::_V1::range") align 4 [[_ARG_MEMBER_ACC6:%.*]], ptr noundef byval(%"struct.sycl::_V1::range") align 4 [[_ARG_MEMBER_ACC7:%.*]], ptr noundef byval(%"struct.sycl::_V1::id") align 4 [[_ARG_MEMBER_ACC8:%.*]]) #[[ATTR0:[0-9]+]]
3333
// CHECK-NEXT: [[ENTRY:.*:]]
3434
// CHECK-NEXT: [[_ARG_MEMBER_ACC_ADDR:%.*]] = alloca ptr addrspace(1), align 8

0 commit comments

Comments
 (0)