Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1209,7 +1209,7 @@ def SYCLIntelKernelArgsRestrict : InheritableAttr {

def SYCLIntelNumSimdWorkItems : InheritableAttr {
let Spellings = [CXX11<"intelfpga","num_simd_work_items">];
let Args = [UnsignedArgument<"Number">];
let Args = [ExprArgument<"Value">];
let LangOpts = [SYCLIsDevice, SYCLIsHost];
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [SYCLIntelNumSimdWorkItemsAttrDocs];
Expand Down Expand Up @@ -1300,7 +1300,7 @@ def LoopUnrollHint : InheritableAttr {
def IntelReqdSubGroupSize: InheritableAttr {
let Spellings = [GNU<"intel_reqd_sub_group_size">,
CXX11<"intel", "reqd_sub_group_size">];
let Args = [ExprArgument<"SubGroupSize">];
let Args = [ExprArgument<"Value">];
let Subjects = SubjectList<[Function, CXXMethod], ErrorDiag>;
let Documentation = [IntelReqdSubGroupSizeDocs];
let LangOpts = [OpenCL, SYCLIsDevice, SYCLIsHost];
Expand Down
34 changes: 29 additions & 5 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -9986,7 +9986,9 @@ class Sema final {
Expr *E);
void AddIntelFPGABankBitsAttr(Decl *D, const AttributeCommonInfo &CI,
Expr **Exprs, unsigned Size);

template <typename AttrType>
void addIntelSYCLSingleArgFunctionAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *E);
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
void AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
bool IsPackExpansion);
Expand Down Expand Up @@ -10041,10 +10043,6 @@ class Sema final {
bool checkAllowedSYCLInitializer(VarDecl *VD,
bool CheckValueDependent = false);

// Adds an intel_reqd_sub_group_size attribute to a particular declaration.
void addIntelReqdSubGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *E);

//===--------------------------------------------------------------------===//
// C++ Coroutines TS
//
Expand Down Expand Up @@ -12836,6 +12834,32 @@ class Sema final {
}
};

template <typename AttrType>
void Sema::addIntelSYCLSingleArgFunctionAttr(Decl *D,
const AttributeCommonInfo &CI,
Expr *E) {
if (!E)
return;

if (!E->isInstantiationDependent()) {
Optional<llvm::APSInt> ArgVal = E->getIntegerConstantExpr(getASTContext());
if (!ArgVal) {
Diag(E->getExprLoc(), diag::err_attribute_argument_type)
<< CI.getAttrName() << AANT_ArgumentIntegerConstant
<< E->getSourceRange();
return;
}
int32_t ArgInt = ArgVal->getSExtValue();
if (ArgInt <= 0) {
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
<< CI.getAttrName() << /*positive*/ 0;
return;
}
}

D->addAttr(::new (Context) AttrType(Context, CI, E));
}

template <typename AttrType>
void Sema::AddOneConstantValueAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *E) {
Expand Down
10 changes: 7 additions & 3 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,7 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,
FD->getAttr<IntelReqdSubGroupSizeAttr>()) {
llvm::LLVMContext &Context = getLLVMContext();
Optional<llvm::APSInt> ArgVal =
A->getSubGroupSize()->getIntegerConstantExpr(FD->getASTContext());
A->getValue()->getIntegerConstantExpr(FD->getASTContext());
assert(ArgVal.hasValue() && "Not an integer constant expression");
llvm::Metadata *AttrMDArgs[] = {llvm::ConstantAsMetadata::get(
Builder.getInt32(ArgVal->getSExtValue()))};
Expand All @@ -629,8 +629,12 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,

if (const SYCLIntelNumSimdWorkItemsAttr *A =
FD->getAttr<SYCLIntelNumSimdWorkItemsAttr>()) {
llvm::Metadata *AttrMDArgs[] = {
llvm::ConstantAsMetadata::get(Builder.getInt32(A->getNumber()))};
llvm::LLVMContext &Context = getLLVMContext();
Optional<llvm::APSInt> ArgVal =
A->getValue()->getIntegerConstantExpr(FD->getASTContext());
assert(ArgVal.hasValue() && "Not an integer constant expression");
llvm::Metadata *AttrMDArgs[] = {llvm::ConstantAsMetadata::get(
Builder.getInt32(ArgVal->getSExtValue()))};
Fn->setMetadata("num_simd_work_items",
llvm::MDNode::get(Context, AttrMDArgs));
}
Expand Down
43 changes: 4 additions & 39 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2979,31 +2979,6 @@ static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
}

// Handles intel_reqd_sub_group_size.
void Sema::addIntelReqdSubGroupSizeAttr(Decl *D,
const AttributeCommonInfo &Attr,
Expr *E) {
if (!E)
return;

if (!E->isInstantiationDependent()) {
Optional<llvm::APSInt> ArgVal = E->getIntegerConstantExpr(getASTContext());
if (!ArgVal) {
Diag(E->getExprLoc(), diag::err_attribute_argument_type)
<< Attr.getAttrName() << AANT_ArgumentIntegerConstant
<< E->getSourceRange();
return;
}
int32_t ArgInt = ArgVal->getSExtValue();
if (ArgInt <= 0) {
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
<< Attr.getAttrName() << /*positive*/ 0;
return;
}
}

D->addAttr(::new (Context) IntelReqdSubGroupSizeAttr(Context, Attr, E));
}

static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
if (S.LangOpts.SYCLIsHost)
return;
Expand All @@ -3013,7 +2988,7 @@ static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
if (D->getAttr<IntelReqdSubGroupSizeAttr>())
S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;

S.addIntelReqdSubGroupSizeAttr(D, AL, E);
S.addIntelSYCLSingleArgFunctionAttr<IntelReqdSubGroupSizeAttr>(D, AL, E);
}

// Handles num_simd_work_items.
Expand All @@ -3022,23 +2997,13 @@ static void handleNumSimdWorkItemsAttr(Sema &S, Decl *D,
if (D->isInvalidDecl())
return;

uint32_t NumSimdWorkItems = 0;
const Expr *E = Attr.getArgAsExpr(0);
if (!checkUInt32Argument(S, Attr, E, NumSimdWorkItems, 0,
/*StrictlyUnsigned=*/true))
return;

if (NumSimdWorkItems == 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero)
<< Attr << E->getSourceRange();
return;
}
Expr *E = Attr.getArgAsExpr(0);

if (D->getAttr<SYCLIntelNumSimdWorkItemsAttr>())
S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr;

D->addAttr(::new (S.Context) SYCLIntelNumSimdWorkItemsAttr(
S.Context, Attr, NumSimdWorkItems));
S.addIntelSYCLSingleArgFunctionAttr<SYCLIntelNumSimdWorkItemsAttr>(D, Attr,
E);
}

// Handles max_global_work_dim.
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2740,15 +2740,15 @@ void Sema::MarkDevice(void) {
KernelBody ? KernelBody->getAttr<SYCLSimdAttr>() : nullptr;
if (auto *Existing =
SYCLKernel->getAttr<IntelReqdSubGroupSizeAttr>()) {
if (getIntExprValue(Existing->getSubGroupSize(), getASTContext()) !=
getIntExprValue(Attr->getSubGroupSize(), getASTContext())) {
if (getIntExprValue(Existing->getValue(), getASTContext()) !=
getIntExprValue(Attr->getValue(), getASTContext())) {
Diag(SYCLKernel->getLocation(),
diag::err_conflicting_sycl_kernel_attributes);
Diag(Existing->getLocation(), diag::note_conflicting_attribute);
Diag(Attr->getLocation(), diag::note_conflicting_attribute);
SYCLKernel->setInvalidDecl();
}
} else if (KBSimdAttr && (getIntExprValue(Attr->getSubGroupSize(),
} else if (KBSimdAttr && (getIntExprValue(Attr->getValue(),
getASTContext()) != 1)) {
reportConflictingAttrs(*this, KernelBody, KBSimdAttr, Attr);
} else {
Expand Down
21 changes: 14 additions & 7 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,15 +541,16 @@ static void instantiateSYCLIntelPipeIOAttr(
S.addSYCLIntelPipeIOAttr(New, *Attr, Result.getAs<Expr>());
}

static void instantiateIntelReqdSubGroupSizeAttr(
template <typename AttrName>
static void instantiateIntelSYCLFunctionAttr(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const IntelReqdSubGroupSizeAttr *Attr, Decl *New) {
// The SubGroupSize expression is a constant expression.
const AttrName *Attr, Decl *New) {
EnterExpressionEvaluationContext Unevaluated(
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
ExprResult Result = S.SubstExpr(Attr->getSubGroupSize(), TemplateArgs);
ExprResult Result = S.SubstExpr(Attr->getValue(), TemplateArgs);
if (!Result.isInvalid())
S.addIntelReqdSubGroupSizeAttr(New, *Attr, Result.getAs<Expr>());
S.addIntelSYCLSingleArgFunctionAttr<AttrName>(New, *Attr,
Result.getAs<Expr>());
}

void Sema::InstantiateAttrsForDecl(
Expand Down Expand Up @@ -697,8 +698,14 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
}
if (const auto *IntelReqdSubGroupSize =
dyn_cast<IntelReqdSubGroupSizeAttr>(TmplAttr)) {
instantiateIntelReqdSubGroupSizeAttr(*this, TemplateArgs,
IntelReqdSubGroupSize, New);
instantiateIntelSYCLFunctionAttr<IntelReqdSubGroupSizeAttr>(
*this, TemplateArgs, IntelReqdSubGroupSize, New);
continue;
}
if (const auto *SYCLIntelNumSimdWorkItems =
dyn_cast<SYCLIntelNumSimdWorkItemsAttr>(TmplAttr)) {
instantiateIntelSYCLFunctionAttr<SYCLIntelNumSimdWorkItemsAttr>(
*this, TemplateArgs, SYCLIntelNumSimdWorkItems, New);
continue;
}
// Existing DLL attribute on the instantiation takes precedence.
Expand Down
11 changes: 10 additions & 1 deletion clang/test/CodeGenSYCL/num-simd-work-items.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ class Foo {
[[intelfpga::num_simd_work_items(1)]] void operator()() const {}
};

template <int SIZE>
class Functor {
public:
[[intelfpga::num_simd_work_items(SIZE)]] void operator()() const {}
};

template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) {
kernelFunc();
Expand All @@ -17,10 +23,13 @@ void bar() {
kernel<class kernel_name2>(
[]() [[intelfpga::num_simd_work_items(42)]] {});

Functor<2> f;
kernel<class kernel_name3>(f);
}

// CHECK: define spir_kernel void @{{.*}}kernel_name1() {{.*}} !num_simd_work_items ![[NUM1:[0-9]+]]
// CHECK: define spir_kernel void @{{.*}}kernel_name2() {{.*}} !num_simd_work_items ![[NUM42:[0-9]+]]
// CHECK: define spir_kernel void @{{.*}}kernel_name3() {{.*}} !num_simd_work_items ![[NUM2:[0-9]+]]
// CHECK: ![[NUM1]] = !{i32 1}
// CHECK: ![[NUM42]] = !{i32 42}

// CHECK: ![[NUM2]] = !{i32 2}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// RUN: %clang_cc1 %s -fsycl -fsycl-is-device -triple spir64 -fsyntax-only -Wno-sycl-2017-compat -DTRIGGER_ERROR -verify
// RUN: %clang_cc1 %s -fsycl -fsycl-is-device -triple spir64 -fsyntax-only -Wno-sycl-2017-compat -ast-dump | FileCheck %s
// RUN: %clang_cc1 -fsycl -fsycl-is-host -fsyntax-only -Wno-sycl-2017-compat -verify %s

#ifndef __SYCL_DEVICE_ONLY__
struct FuncObj {
Expand All @@ -20,7 +19,6 @@ void foo() {
}

#else // __SYCL_DEVICE_ONLY__

[[intelfpga::num_simd_work_items(2)]] void func_do_not_ignore() {}

struct FuncObj {
Expand All @@ -34,28 +32,31 @@ __attribute__((sycl_kernel)) void kernel(const Func &kernelFunc) {

int main() {
// CHECK-LABEL: FunctionDecl {{.*}}test_kernel1
// CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} 42
// CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}}
// CHECK-NEXT: IntegerLiteral{{.*}}42{{$}}
kernel<class test_kernel1>(
FuncObj());

// CHECK-LABEL: FunctionDecl {{.*}}test_kernel2
// CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} 8
// CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}}
// CHECK-NEXT: IntegerLiteral{{.*}}8{{$}}
kernel<class test_kernel2>(
[]() [[intelfpga::num_simd_work_items(8)]] {});

// CHECK-LABEL: FunctionDecl {{.*}}test_kernel3
// CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} 2
// CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}}
// CHECK-NEXT: IntegerLiteral{{.*}}2{{$}}
kernel<class test_kernel3>(
[]() { func_do_not_ignore(); });

#ifdef TRIGGER_ERROR
[[intelfpga::num_simd_work_items(0)]] int Var = 0; // expected-error{{'num_simd_work_items' attribute only applies to functions}}

kernel<class test_kernel4>(
[]() [[intelfpga::num_simd_work_items(0)]] {}); // expected-error{{'num_simd_work_items' attribute must be greater than 0}}
[]() [[intelfpga::num_simd_work_items(0)]]{}); // expected-error{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}}

kernel<class test_kernel5>(
[]() [[intelfpga::num_simd_work_items(-42)]] {}); // expected-error{{'num_simd_work_items' attribute requires a non-negative integral compile time constant expression}}
[]() [[intelfpga::num_simd_work_items(-42)]]{}); // expected-error{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}}

kernel<class test_kernel6>(
[]() [[intelfpga::num_simd_work_items(1), intelfpga::num_simd_work_items(2)]] {}); // expected-warning{{attribute 'num_simd_work_items' is already applied with different parameters}}
Expand Down
8 changes: 8 additions & 0 deletions clang/test/SemaSYCL/num_simd_work_items_host.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: %clang_cc1 -fsycl -fsycl-is-host -fsyntax-only -Wno-sycl-2017-compat -verify %s
// expected-no-diagnostics

[[intelfpga::num_simd_work_items(2)]] void func_do_not_ignore() {}

struct FuncObj {
[[intelfpga::num_simd_work_items(42)]] void operator()() const {}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsyntax-only -ast-dump -verify -pedantic %s | FileCheck %s

// Test that checkes template parameter support for 'num_simd_work_items' attribute on sycl device.

template <int SIZE>
class KernelFunctor {
public:
// expected-error@+1{{'num_simd_work_items' attribute requires a positive integral compile time constant expression}}
[[intelfpga::num_simd_work_items(SIZE)]] void operator()() {}
};

int main() {
//expected-note@+1{{in instantiation of template class 'KernelFunctor<-1>' requested here}}
KernelFunctor<-1>();
// no error expected
KernelFunctor<10>();
}

// CHECK: ClassTemplateDecl {{.*}} {{.*}} KernelFunctor
// CHECK: ClassTemplateSpecializationDecl {{.*}} {{.*}} class KernelFunctor definition
// CHECK: CXXRecordDecl {{.*}} {{.*}} implicit class KernelFunctor
// CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}}
// CHECK: SubstNonTypeTemplateParmExpr {{.*}}
// CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}
// CHECK-NEXT: IntegerLiteral{{.*}}10{{$}}