Skip to content

Commit d96007d

Browse files
committed
[SYCL] Add template parameter support for intel_reqd_sub_group_size attribute
Signed-off-by: Soumi Manna <[email protected]>
1 parent 0473316 commit d96007d

File tree

9 files changed

+101
-22
lines changed

9 files changed

+101
-22
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1262,7 +1262,7 @@ def LoopUnrollHint : InheritableAttr {
12621262

12631263
def IntelReqdSubGroupSize: InheritableAttr {
12641264
let Spellings = [GNU<"intel_reqd_sub_group_size">, CXX11<"cl", "intel_reqd_sub_group_size">];
1265-
let Args = [UnsignedArgument<"SubGroupSize">];
1265+
let Args = [ExprArgument<"SubGroupSize">];
12661266
let Subjects = SubjectList<[Function, CXXMethod], ErrorDiag>;
12671267
let Documentation = [IntelReqdSubGroupSizeDocs];
12681268
let LangOpts = [OpenCL, SYCLIsDevice, SYCLIsHost];

clang/include/clang/Sema/Sema.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9917,6 +9917,11 @@ class Sema final {
99179917

99189918
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type);
99199919

9920+
// addIntelReqdSubGroupSizeAttr - Adds an intel_reqd_sub_group_size attribute
9921+
// to a particular declaration.
9922+
void addIntelReqdSubGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI,
9923+
Expr *E);
9924+
99209925
//===--------------------------------------------------------------------===//
99219926
// C++ Coroutines TS
99229927
//

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,14 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,
574574

575575
if (const IntelReqdSubGroupSizeAttr *A =
576576
FD->getAttr<IntelReqdSubGroupSizeAttr>()) {
577+
llvm::APSInt ArgVal(32);
578+
llvm::LLVMContext &Context = getLLVMContext();
579+
bool IsValid = A->getSubGroupSize()->isIntegerConstantExpr(
580+
ArgVal, FD->getASTContext());
581+
assert(IsValid && "Not an integer constant expression");
582+
(void)IsValid;
577583
llvm::Metadata *AttrMDArgs[] = {
578-
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getSubGroupSize()))};
584+
llvm::ConstantAsMetadata::get(Builder.getInt32(ArgVal.getSExtValue()))};
579585
Fn->setMetadata("intel_reqd_sub_group_size",
580586
llvm::MDNode::get(Context, AttrMDArgs));
581587
}

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2980,27 +2980,41 @@ static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
29802980
}
29812981

29822982
// Handles intel_reqd_sub_group_size.
2983+
void Sema::addIntelReqdSubGroupSizeAttr(Decl *D,
2984+
const AttributeCommonInfo &Attr,
2985+
Expr *E) {
2986+
if (!E)
2987+
return;
2988+
2989+
if (!E->isInstantiationDependent()) {
2990+
llvm::APSInt ArgVal(32);
2991+
if (!E->isIntegerConstantExpr(ArgVal, getASTContext())) {
2992+
Diag(E->getExprLoc(), diag::err_attribute_argument_type)
2993+
<< Attr.getAttrName() << AANT_ArgumentIntegerConstant
2994+
<< E->getSourceRange();
2995+
return;
2996+
}
2997+
int32_t ArgInt = ArgVal.getSExtValue();
2998+
if (ArgInt <= 0) {
2999+
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
3000+
<< Attr.getAttrName() << /*positive*/ 0;
3001+
return;
3002+
}
3003+
}
3004+
3005+
D->addAttr(::new (Context) IntelReqdSubGroupSizeAttr(Context, Attr, E));
3006+
}
3007+
29833008
static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
29843009
if (S.LangOpts.SYCLIsHost)
29853010
return;
29863011

2987-
uint32_t SGSize;
2988-
const Expr *E = AL.getArgAsExpr(0);
2989-
if (!checkUInt32Argument(S, AL, E, SGSize))
2990-
return;
2991-
if (SGSize == 0) {
2992-
S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
2993-
<< AL << E->getSourceRange();
2994-
return;
2995-
}
3012+
Expr *E = AL.getArgAsExpr(0);
29963013

2997-
IntelReqdSubGroupSizeAttr *Existing =
2998-
D->getAttr<IntelReqdSubGroupSizeAttr>();
2999-
if (Existing && Existing->getSubGroupSize() != SGSize)
3014+
if (D->getAttr<IntelReqdSubGroupSizeAttr>())
30003015
S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
30013016

3002-
D->addAttr(::new (S.Context)
3003-
IntelReqdSubGroupSizeAttr(S.Context, AL, SGSize));
3017+
S.addIntelReqdSubGroupSizeAttr(D, AL, E);
30043018
}
30053019

30063020
// Handles num_simd_work_items.

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,17 @@ static void instantiateSYCLIntelPipeIOAttr(
579579
S.addSYCLIntelPipeIOAttr(New, *Attr, Result.getAs<Expr>());
580580
}
581581

582+
static void instantiateIntelReqdSubGroupSizeAttr(
583+
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
584+
const IntelReqdSubGroupSizeAttr *Attr, Decl *New) {
585+
// The SubGroupSize expression is a constant expression.
586+
EnterExpressionEvaluationContext Unevaluated(
587+
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
588+
ExprResult Result = S.SubstExpr(Attr->getSubGroupSize(), TemplateArgs);
589+
if (!Result.isInvalid())
590+
S.addIntelReqdSubGroupSizeAttr(New, *Attr, Result.getAs<Expr>());
591+
}
592+
582593
void Sema::InstantiateAttrsForDecl(
583594
const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
584595
Decl *New, LateInstantiatedAttrVec *LateAttrs,
@@ -721,7 +732,12 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
721732
instantiateSYCLIntelPipeIOAttr(*this, TemplateArgs, SYCLIntelPipeIO, New);
722733
continue;
723734
}
724-
735+
if (const auto *IntelReqdSubGroupSize =
736+
dyn_cast<IntelReqdSubGroupSizeAttr>(TmplAttr)) {
737+
instantiateIntelReqdSubGroupSizeAttr(*this, TemplateArgs,
738+
IntelReqdSubGroupSize, New);
739+
continue;
740+
}
725741
// Existing DLL attribute on the instantiation takes precedence.
726742
if (TmplAttr->getKind() == attr::DLLExport ||
727743
TmplAttr->getKind() == attr::DLLImport) {

clang/test/CodeGenSYCL/reqd-sub-group-size.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ class Functor {
1414
}
1515
};
1616

17+
template <int SIZE>
18+
class Functor5 {
19+
public:
20+
[[cl::intel_reqd_sub_group_size(SIZE)]] void operator()() {}
21+
};
22+
1723
template <typename name, typename Func>
1824
__attribute__((sycl_kernel)) void kernel(Func kernelFunc) {
1925
kernelFunc();
@@ -28,12 +34,16 @@ void bar() {
2834

2935
kernel<class kernel_name3>(
3036
[]() [[cl::intel_reqd_sub_group_size(4)]] {});
37+
38+
Functor5<2> f5;
39+
kernel<class kernel_name4>(f5);
3140
}
3241

3342
// CHECK: define spir_kernel void @{{.*}}kernel_name1() {{.*}} !intel_reqd_sub_group_size ![[SGSIZE16:[0-9]+]]
3443
// CHECK: define spir_kernel void @{{.*}}kernel_name2() {{.*}} !intel_reqd_sub_group_size ![[SGSIZE8:[0-9]+]]
3544
// CHECK: define spir_kernel void @{{.*}}kernel_name3() {{.*}} !intel_reqd_sub_group_size ![[SGSIZE4:[0-9]+]]
45+
// CHECK: define spir_kernel void @{{.*}}kernel_name4() {{.*}} !intel_reqd_sub_group_size ![[SGSIZE2:[0-9]+]]
3646
// CHECK: ![[SGSIZE16]] = !{i32 16}
3747
// CHECK: ![[SGSIZE8]] = !{i32 8}
3848
// CHECK: ![[SGSIZE4]] = !{i32 4}
39-
49+
// CHECK: ![[SGSIZE2]] = !{i32 2}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ kernel __attribute__((reqd_work_group_size(1,0,2))) void kernel12(){} // expecte
3535
kernel __attribute__((reqd_work_group_size(0,1,2))) void kernel13(){} // expected-error {{'reqd_work_group_size' attribute must be greater than 0}}
3636

3737
__attribute__((intel_reqd_sub_group_size(8))) void kernel14(){} // expected-error {{attribute 'intel_reqd_sub_group_size' can only be applied to an OpenCL kernel}}
38-
kernel __attribute__((intel_reqd_sub_group_size(0))) void kernel15(){} // expected-error {{'intel_reqd_sub_group_size' attribute must be greater than 0}}
38+
kernel __attribute__((intel_reqd_sub_group_size(0))) void kernel15(){} // expected-error {{'intel_reqd_sub_group_size' attribute requires a positive integral compile time constant expression}}
3939
kernel __attribute__((intel_reqd_sub_group_size(8))) __attribute__((intel_reqd_sub_group_size(16))) void kernel16() {} //expected-warning{{attribute 'intel_reqd_sub_group_size' is already applied with different parameters}}
4040

4141
__kernel __attribute__((work_group_size_hint(8,-16,32))) void neg1() {} //expected-error{{'work_group_size_hint' attribute requires a non-negative integral compile time constant expression}}

clang/test/SemaSYCL/reqd-sub-group-size-device.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,11 @@ void bar() {
4949
}
5050

5151
// CHECK: FunctionDecl {{.*}} {{.*}}kernel_name1
52-
// CHECK: IntelReqdSubGroupSizeAttr {{.*}} 16
52+
// CHECK: IntelReqdSubGroupSizeAttr {{.*}}
53+
// CHECK-NEXT: IntegerLiteral{{.*}}16{{$}}
5354
// CHECK: FunctionDecl {{.*}} {{.*}}kernel_name2
54-
// CHECK: IntelReqdSubGroupSizeAttr {{.*}} 4
55+
// CHECK: IntelReqdSubGroupSizeAttr {{.*}}
56+
// CHECK-NEXT: IntegerLiteral{{.*}}4{{$}}
5557
// CHECK: FunctionDecl {{.*}} {{.*}}kernel_name5
56-
// CHECK: IntelReqdSubGroupSizeAttr {{.*}} 2
58+
// CHECK: IntelReqdSubGroupSizeAttr {{.*}}
59+
// CHECK-NEXT: IntegerLiteral{{.*}}2{{$}}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsyntax-only -verify -pedantic %s
2+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsyntax-only -ast-dump -verify -pedantic %s | FileCheck %s
3+
4+
// Test that checkes template parameter support for 'intel_reqd_sub_group_size' attribute on sycl device.
5+
6+
template <int SIZE>
7+
class KernelFunctor {
8+
public:
9+
//expected-error@+1{{'intel_reqd_sub_group_size' attribute requires a positive integral compile time constant expression}}
10+
[[cl::intel_reqd_sub_group_size(SIZE)]] void operator()() {}
11+
};
12+
13+
int main() {
14+
//expected-note@+1{{in instantiation of template class 'KernelFunctor<-1>' requested here}}
15+
KernelFunctor<-1>();
16+
// no error expected
17+
KernelFunctor<10>();
18+
}
19+
20+
// CHECK: ClassTemplateDecl {{.*}} {{.*}} KernelFunctor
21+
// CHECK: ClassTemplateSpecializationDecl {{.*}} {{.*}} class KernelFunctor definition
22+
// CHECK: CXXRecordDecl {{.*}} {{.*}} implicit class KernelFunctor
23+
// CHECK: IntelReqdSubGroupSizeAttr {{.*}}
24+
// CHECK: SubstNonTypeTemplateParmExpr {{.*}}
25+
// CHECK-NEXT: IntegerLiteral{{.*}}10{{$}}

0 commit comments

Comments
 (0)