Skip to content

Commit a3ec083

Browse files
committed
Merge branch 'sycl' into throw_get_profiling_info_exception
2 parents b11a4d9 + 270e78d commit a3ec083

File tree

24 files changed

+408
-220
lines changed

24 files changed

+408
-220
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3039,9 +3039,12 @@ def WorkGroupSizeHint : InheritableAttr {
30393039
let Spellings = [GNU<"work_group_size_hint">,
30403040
CXX11<"sycl", "work_group_size_hint">];
30413041
let Args = [ExprArgument<"XDim">,
3042-
ExprArgument<"YDim">,
3043-
ExprArgument<"ZDim">];
3042+
ExprArgument<"YDim", /*optional*/1>,
3043+
ExprArgument<"ZDim", /*optional*/1>];
30443044
let Subjects = SubjectList<[Function], ErrorDiag>;
3045+
// In OpenCL C this attribute takes no default values whereas in SYCL it does.
3046+
// To avoid confusing diagnostics, the checks are deferred to "handleWorkGroupSizeHint".
3047+
let HasCustomParsing = 1;
30453048
let AdditionalMembers = [{
30463049
Optional<llvm::APSInt> getXDimVal() const {
30473050
if (const auto *CE = dyn_cast<ConstantExpr>(getXDim()))

clang/include/clang/Basic/AttrDocs.td

Lines changed: 7 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2848,77 +2848,23 @@ The GNU spelling is deprecated in SYCL mode.
28482848
[[sycl::work_group_size_hint(2, 2, 2)]] void operator()() const {}
28492849
};
28502850

2851-
The arguments to ``reqd_work_group_size`` are ordered based on which index
2851+
The arguments to ``work_group_size_hint`` are ordered based on which index
28522852
increments the fastest. In OpenCL, the first argument is the index that
28532853
increments the fastest, and in SYCL, the last argument is the index that
28542854
increments the fastest.
28552855

2856-
In OpenCL, all three arguments are required.
2856+
In OpenCL C, this attribute is available with the GNU spelling
2857+
(``__attribute__((work_group_size_hint(X, Y, Z)))``) and all
2858+
three arguments are required.
28572859

28582860
In SYCL, the attribute accepts either one, two, or three arguments; in each
28592861
form, the last (or only) argument is the index that increments fastest. The
28602862
number of arguments passed to the attribute must match the dimensionality of
28612863
the kernel the attribute is applied to.
28622864

2863-
If the ``reqd_work_group_size attribute`` is specified on a declaration along
2864-
with ``num_simd_work_items``, the required work group size specified by
2865-
``num_simd_work_items`` must evenly divide the index that increments fastest
2866-
in the ``reqd_work_group_size`` attribute.
2867-
2868-
.. code-block:: c++
2869-
2870-
// Note, '64' is evenly divisible by '4'; in SYCL, the last
2871-
// argument to the attribute is the one which increments fastest.
2872-
struct func {
2873-
[[intel::num_simd_work_items(4)]]
2874-
[[sycl::reqd_work_group_size(7, 4, 64)]]
2875-
void operator()() const {}
2876-
};
2877-
2878-
// Note, '8' is evenly divisible by '8'; in SYCL, the last
2879-
// argument to the attribute is the one which increments fastest.
2880-
struct bar {
2881-
[[sycl::reqd_work_group_size(1, 1, 8)]]
2882-
[[intel::num_simd_work_items(8)]]
2883-
void operator()() const {}
2884-
};
2885-
2886-
// Note, '10' is evenly divisible by '5'; in SYCL, the last
2887-
// argument to the attribute is the one which increments fastest.
2888-
[[cl::reqd_work_group_size(7, 5, 10)]]
2889-
[[intel::num_simd_work_items(5)]] void fun2() {}
2890-
2891-
// Note, '8' is evenly divisible by '4'; in SYCL, the last
2892-
// argument to the attribute is the one which increments fastest.
2893-
[[intel::num_simd_work_items(4)]]
2894-
[[cl::reqd_work_group_size(5, 4, 8)]] void fun3() {}
2895-
2896-
// Note, '8' is evenly divisible by '8'; in SYCL, the last
2897-
// argument to the attribute is the one which increments fastest.
2898-
struct func1 {
2899-
[[intel::num_simd_work_items(8)]]
2900-
[[cl::reqd_work_group_size(1, 1, 8)]]
2901-
void operator()() const {}
2902-
};
2903-
2904-
// Note, '8' is evenly divisible by '4'; in SYCL, the last
2905-
// argument to the attribute is the one which increments fastest.
2906-
struct bar1 {
2907-
[[cl::reqd_work_group_size(7, 4, 8)]]
2908-
[[intel::num_simd_work_items(4)]]
2909-
void operator()() const {}
2910-
};
2911-
2912-
// Note, '4' is evenly divisible by '2'; in SYCL, the last
2913-
// argument to the attribute is the one which increments fastest.
2914-
[[intel::num_simd_work_items(2)]]
2915-
__attribute__((reqd_work_group_size(3, 2, 4))) void test();
2916-
2917-
// Note, '8' is evenly divisible by '2'; in SYCL, the last
2918-
// argument to the attribute is the one which increments fastest.
2919-
__attribute__((reqd_work_group_size(3, 2, 8)))
2920-
[intel::num_simd_work_items(2)]] void test();
2921-
2865+
In SYCL 1.2.1 mode, the ``sycl::work_group_size_hint`` attribute is propagated
2866+
from the function it is applied to onto the kernel which calls the function.
2867+
In SYCL 2020 mode, the attribute is not propagated to the kernel.
29222868
}];
29232869
}
29242870

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3510,8 +3510,32 @@ Sema::MergeWorkGroupSizeHintAttr(Decl *D, const WorkGroupSizeHintAttr &A) {
35103510
static void handleWorkGroupSizeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
35113511
S.CheckDeprecatedSYCLAttributeSpelling(AL);
35123512

3513-
S.AddWorkGroupSizeHintAttr(D, AL, AL.getArgAsExpr(0), AL.getArgAsExpr(1),
3514-
AL.getArgAsExpr(2));
3513+
// __attribute__((work_group_size_hint) requires exactly three arguments.
3514+
if (AL.getSyntax() == ParsedAttr::AS_GNU || !AL.hasScope() ||
3515+
(AL.hasScope() && !AL.getScopeName()->isStr("sycl"))) {
3516+
if (!AL.checkExactlyNumArgs(S, 3))
3517+
return;
3518+
}
3519+
3520+
// FIXME: NumArgs checking is disabled in Attr.td to keep consistent
3521+
// disgnostics with OpenCL C that does not have optional values here.
3522+
if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3))
3523+
return;
3524+
3525+
// Handles default arguments in [[sycl::work_group_size_hint]] attribute.
3526+
auto SetDefaultValue = [](Sema &S, const ParsedAttr &AL) {
3527+
assert(AL.getKind() == ParsedAttr::AT_WorkGroupSizeHint && AL.hasScope() &&
3528+
AL.getScopeName()->isStr("sycl"));
3529+
return IntegerLiteral::Create(S.Context, llvm::APInt(32, 1),
3530+
S.Context.IntTy, AL.getLoc());
3531+
};
3532+
3533+
Expr *XDimExpr = AL.getArgAsExpr(0);
3534+
Expr *YDimExpr =
3535+
AL.isArgExpr(1) ? AL.getArgAsExpr(1) : SetDefaultValue(S, AL);
3536+
Expr *ZDimExpr =
3537+
AL.isArgExpr(2) ? AL.getArgAsExpr(2) : SetDefaultValue(S, AL);
3538+
S.AddWorkGroupSizeHintAttr(D, AL, XDimExpr, YDimExpr, ZDimExpr);
35153539
}
35163540

35173541
// Handles max_work_group_size attribute.

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,8 @@ static void collectSYCLAttributes(Sema &S, FunctionDecl *FD,
561561
llvm::copy_if(FD->getAttrs(), std::back_inserter(Attrs), [](Attr *A) {
562562
// FIXME: Make this list self-adapt as new SYCL attributes are added.
563563
return isa<IntelReqdSubGroupSizeAttr, IntelNamedSubGroupSizeAttr,
564-
ReqdWorkGroupSizeAttr, SYCLIntelKernelArgsRestrictAttr,
565-
SYCLIntelNumSimdWorkItemsAttr,
564+
ReqdWorkGroupSizeAttr, WorkGroupSizeHintAttr,
565+
SYCLIntelKernelArgsRestrictAttr, SYCLIntelNumSimdWorkItemsAttr,
566566
SYCLIntelSchedulerTargetFmaxMhzAttr,
567567
SYCLIntelMaxWorkGroupSizeAttr, SYCLIntelMaxGlobalWorkDimAttr,
568568
SYCLIntelNoGlobalWorkOffsetAttr, SYCLSimdAttr>(A);
@@ -3927,6 +3927,22 @@ static void PropagateAndDiagnoseDeviceAttr(
39273927
}
39283928
break;
39293929
}
3930+
case attr::Kind::WorkGroupSizeHint: {
3931+
auto *WGSH = cast<WorkGroupSizeHintAttr>(A);
3932+
if (auto *Existing = SYCLKernel->getAttr<WorkGroupSizeHintAttr>()) {
3933+
if (Existing->getXDimVal() != WGSH->getXDimVal() ||
3934+
Existing->getYDimVal() != WGSH->getYDimVal() ||
3935+
Existing->getZDimVal() != WGSH->getZDimVal()) {
3936+
S.Diag(SYCLKernel->getLocation(),
3937+
diag::err_conflicting_sycl_kernel_attributes);
3938+
S.Diag(Existing->getLocation(), diag::note_conflicting_attribute);
3939+
S.Diag(WGSH->getLocation(), diag::note_conflicting_attribute);
3940+
SYCLKernel->setInvalidDecl();
3941+
}
3942+
}
3943+
SYCLKernel->addAttr(A);
3944+
break;
3945+
}
39303946
case attr::Kind::SYCLIntelMaxWorkGroupSize: {
39313947
auto *SIMWGSA = cast<SYCLIntelMaxWorkGroupSizeAttr>(A);
39323948
if (auto *Existing = SYCLKernel->getAttr<ReqdWorkGroupSizeAttr>()) {

clang/test/SemaOpenCL/invalid-kernel-attrs.cl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ kernel __attribute__((vec_type_hint(int))) __attribute__((vec_type_hint(float)))
1212

1313
kernel __attribute__((work_group_size_hint(8,16,32,4))) void kernel6() {} //expected-error{{'work_group_size_hint' attribute requires exactly 3 arguments}}
1414

15+
kernel __attribute__((work_group_size_hint(1,2))) void kernel6b() {} //expected-error{{'work_group_size_hint' attribute requires exactly 3 arguments}}
16+
1517
kernel __attribute__((work_group_size_hint(1,2,3))) __attribute__((work_group_size_hint(3,2,1))) void kernel7() {} //expected-warning{{attribute 'work_group_size_hint' is already applied with different arguments}} expected-note {{previous attribute is here}}
1618

1719
__attribute__((reqd_work_group_size(8,16,32))) void kernel8(){} // expected-error {{attribute 'reqd_work_group_size' can only be applied to an OpenCL kernel}}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -fsyntax-only -sycl-std=2017 -Wno-sycl-2017-compat -verify -DEXPECT_PROP -DTRIGGER_ERROR %s
2+
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -sycl-std=2017 -Wno-sycl-2017-compat -ast-dump -DEXPECT_PROP %s | FileCheck %s
3+
4+
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -fsyntax-only -sycl-std=2020 -verify -DTRIGGER_ERROR %s
5+
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -sycl-std=2020 -ast-dump %s | FileCheck %s
6+
7+
// Test for AST of work_group_size_hint kernel attribute in SYCL 1.2.1. and SYCL 2020 modes.
8+
#include "sycl.hpp"
9+
10+
// Check the basics.
11+
#ifdef TRIGGER_ERROR
12+
[[sycl::work_group_size_hint]] void f0(); // expected-error {{'work_group_size_hint' attribute takes at least 1 argument}}
13+
[[sycl::work_group_size_hint(12, 12, 12, 12)]] void f1(); // expected-error {{'work_group_size_hint' attribute takes no more than 3 arguments}}
14+
[[sycl::work_group_size_hint("derp", 1, 2)]] void f2(); // expected-error {{integral constant expression must have integral or unscoped enumeration type, not 'const char[5]'}}
15+
[[sycl::work_group_size_hint(1, 1, 1)]] int i; // expected-error {{'work_group_size_hint' attribute only applies to functions}}
16+
#endif
17+
18+
// Produce a conflicting attribute warning when the args are different.
19+
[[sycl::work_group_size_hint(4, 1, 1)]] void f3(); // expected-note {{previous attribute is here}}
20+
[[sycl::work_group_size_hint(1, 1, 32)]] void f3() {} // expected-warning {{attribute 'work_group_size_hint' is already applied with different arguments}}
21+
22+
// 1 and 2 dim versions
23+
[[sycl::work_group_size_hint(2)]] void f4(); // ok
24+
[[sycl::work_group_size_hint(2, 1)]] void f5(); // ok
25+
26+
// FIXME: This turns out to be wrong as there aren't really default values
27+
// (that is an implementation detail we use but shouldn't expose to the user).
28+
// Instead, the dimensionality of the attribute needs to match that of the
29+
// kernel, so the one, two, and three arg forms of the attribute are actually
30+
// *different* attributes. This means that you should not be able to redeclare
31+
// the function with a different dimensionality.
32+
// As a result these two (re)declarations should result in errors.
33+
[[sycl::work_group_size_hint(2)]] void f5();
34+
[[sycl::work_group_size_hint(2, 1, 1)]] void f5();
35+
36+
// Catch the easy case where the attributes are all specified at once with
37+
// different arguments.
38+
[[sycl::work_group_size_hint(4, 1, 1), sycl::work_group_size_hint(32, 1, 1)]] void f7(); // expected-warning {{attribute 'work_group_size_hint' is already applied with different arguments}} expected-note {{previous attribute is here}}
39+
40+
// Show that the attribute works on member functions.
41+
class Functor_1 {
42+
public:
43+
[[sycl::work_group_size_hint(16, 1, 1)]] [[sycl::work_group_size_hint(16, 1, 1)]] void operator()() const;
44+
[[sycl::work_group_size_hint(16, 1, 1)]] [[sycl::work_group_size_hint(32, 1, 1)]] void operator()(int) const; // expected-warning {{attribute 'work_group_size_hint' is already applied with different arguments}} expected-note {{previous attribute is here}}
45+
};
46+
47+
// Ensure that template arguments behave appropriately based on instantiations.
48+
template <int N>
49+
[[sycl::work_group_size_hint(N, 1, 1)]] void f8(); // #f8
50+
51+
// Test that template redeclarations also get diagnosed properly.
52+
template <int X, int Y, int Z>
53+
[[sycl::work_group_size_hint(1, 1, 1)]] void f9(); // #f9prev
54+
55+
template <int X, int Y, int Z>
56+
[[sycl::work_group_size_hint(X, Y, Z)]] void f9() {} // #f9
57+
58+
// Test that a template redeclaration where the difference is known up front is
59+
// diagnosed immediately, even without instantiation.
60+
template <int X, int Y, int Z>
61+
[[sycl::work_group_size_hint(X, 1, Z)]] void f10(); // expected-note {{previous attribute is here}}
62+
template <int X, int Y, int Z>
63+
[[sycl::work_group_size_hint(X, 2, Z)]] void f10(); // expected-warning {{attribute 'work_group_size_hint' is already applied with different arguments}}
64+
65+
#ifdef TRIGGER_ERROR
66+
[[sycl::work_group_size_hint(1, 2, 0)]] void f11(); // expected-error {{'work_group_size_hint' attribute requires a positive integral compile time constant expression}}
67+
#endif
68+
69+
void instantiate() {
70+
f8<1>(); // OK
71+
#ifdef TRIGGER_ERROR
72+
// expected-error@#f8 {{'work_group_size_hint' attribute requires a positive integral compile time constant expression}}
73+
f8<-1>(); // expected-note {{in instantiation}}
74+
// expected-error@#f8 {{'work_group_size_hint' attribute requires a positive integral compile time constant expression}}
75+
f8<0>(); // expected-note {{in instantiation}}
76+
#endif
77+
78+
f9<1, 1, 1>(); // OK, args are the same on the redecl.
79+
80+
// expected-warning@#f9 {{attribute 'work_group_size_hint' is already applied with different arguments}}
81+
// expected-note@#f9prev {{previous attribute is here}}
82+
f9<1, 2, 3>(); // expected-note {{in instantiation}}
83+
}
84+
85+
// Show that the attribute works on member functions.
86+
class Functor16x2x1 {
87+
public:
88+
[[sycl::work_group_size_hint(16, 2, 1)]] void operator()() const {};
89+
};
90+
91+
// CHECK: CXXRecordDecl {{.*}} {{.*}}Functor16x2x1
92+
// CHECK: WorkGroupSizeHintAttr {{.*}}
93+
// CHECK-NEXT: ConstantExpr{{.*}}'int'
94+
// CHECK-NEXT: value: Int 16
95+
// CHECK-NEXT: IntegerLiteral{{.*}}16{{$}}
96+
// CHECK-NEXT: ConstantExpr{{.*}}'int'
97+
// CHECK-NEXT: value: Int 2
98+
// CHECK-NEXT: IntegerLiteral{{.*}}2{{$}}
99+
// CHECK-NEXT: ConstantExpr{{.*}}'int'
100+
// CHECK-NEXT: value: Int 1
101+
// CHECK-NEXT: IntegerLiteral{{.*}}1{{$}}
102+
103+
class Functor4x4x4 {
104+
public:
105+
[[sycl::work_group_size_hint(4, 4, 4)]] void operator()() const {};
106+
};
107+
108+
// Checking whether propagation of the attribute happens or not, according to the SYCL version.
109+
#if defined(EXPECT_PROP) // if attribute is propagated, then we expect errors here
110+
void f8x8x8(){};
111+
#else // otherwise no error
112+
[[sycl::work_group_size_hint(8, 8, 8)]] void f8x8x8(){};
113+
#endif
114+
class FunctorNoProp {
115+
public:
116+
void operator()() const {
117+
f8x8x8();
118+
};
119+
};
120+
121+
void invoke() {
122+
Functor16x2x1 f16x2x1;
123+
Functor4x4x4 f4x4x4;
124+
125+
sycl::queue q;
126+
127+
q.submit([&](sycl::handler &h) {
128+
h.single_task<class kernel_1>(f16x2x1);
129+
// CHECK: FunctionDecl {{.*}} {{.*}}kernel_1
130+
// CHECK: WorkGroupSizeHintAttr {{.*}}
131+
// CHECK-NEXT: ConstantExpr{{.*}}'int'
132+
// CHECK-NEXT: value: Int 16
133+
// CHECK-NEXT: IntegerLiteral{{.*}}16{{$}}
134+
// CHECK-NEXT: ConstantExpr{{.*}}'int'
135+
// CHECK-NEXT: value: Int 2
136+
// CHECK-NEXT: IntegerLiteral{{.*}}2{{$}}
137+
// CHECK-NEXT: ConstantExpr{{.*}}'int'
138+
// CHECK-NEXT: value: Int 1
139+
// CHECK-NEXT: IntegerLiteral{{.*}}1{{$}}
140+
141+
// Checking that attributes are propagated to the kernel from functions in SYCL 1.2.1 mode.
142+
#ifdef EXPECT_PROP
143+
h.single_task<class kernel_2>([=]() {
144+
f4x4x4();
145+
});
146+
#else
147+
// Otherwise using a functor that has the required attributes
148+
h.single_task<class kernel_2>(f4x4x4);
149+
#endif
150+
// CHECK: FunctionDecl {{.*}} {{.*}}kernel_2
151+
// CHECK: WorkGroupSizeHintAttr {{.*}}
152+
// CHECK-NEXT: ConstantExpr{{.*}}'int'
153+
// CHECK-NEXT: value: Int 4
154+
// CHECK-NEXT: IntegerLiteral{{.*}}4{{$}}
155+
// CHECK-NEXT: ConstantExpr{{.*}}'int'
156+
// CHECK-NEXT: value: Int 4
157+
// CHECK-NEXT: IntegerLiteral{{.*}}4{{$}}
158+
// CHECK-NEXT: ConstantExpr{{.*}}'int'
159+
// CHECK-NEXT: value: Int 4
160+
// CHECK-NEXT: IntegerLiteral{{.*}}4{{$}}
161+
162+
// Check that conflicts are reported if the attribute is propagated in SYCL 1.2.1 mode.
163+
164+
FunctorNoProp fNoProp;
165+
h.single_task<class kernel_3>(fNoProp);
166+
// CHECK: FunctionDecl {{.*}} {{.*}}kernel_3
167+
// CHECK-NOT: WorkGroupSizeHintAttr
168+
169+
});
170+
171+
// FIXME: Add tests with the C++23 lambda attribute syntax.
172+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -fsycl-is-host -fsyntax-only -verify %s
2+
3+
// Host checks for the work_group_size_hint attribute.
4+
class Functor16x2x1 {
5+
public:
6+
[[sycl::work_group_size_hint(16, 2, 1)]] void operator()() const {};
7+
};
8+
9+
// The GNU spelling is deprecated in SYCL mode, but otherwise these attributes
10+
// have the same semantics.
11+
[[sycl::work_group_size_hint(4, 1, 1)]] void f4x1x1();
12+
__attribute__((work_group_size_hint(4, 1, 1))) void f4x1x1(); // expected-warning {{attribute 'work_group_size_hint' is deprecated}} \
13+
// expected-note {{did you mean to use '[[sycl::work_group_size_hint]]' instead?}}

0 commit comments

Comments
 (0)