Skip to content

Commit 9eee41c

Browse files
committed
Fix Crash when merging attributes
Signed-off-by: Soumi Manna <[email protected]>
1 parent ecc68cc commit 9eee41c

File tree

3 files changed

+48
-42
lines changed

3 files changed

+48
-42
lines changed

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD,
744744
if (const SYCLIntelMaxWorkGroupSizeAttr *A =
745745
FD->getAttr<SYCLIntelMaxWorkGroupSizeAttr>()) {
746746

747-
// For a SYCLDevice ReqdWorkGroupSizeAttr arguments are reversed.
747+
// Attributes arguments (first and third) are reversed on SYCLDevice.
748748
if (getLangOpts().SYCLIsDevice) {
749749
llvm::Metadata *AttrMDArgs[] = {
750750
llvm::ConstantAsMetadata::get(Builder.getInt(*A->getZDimVal())),

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3450,6 +3450,33 @@ static void handleWorkGroupSizeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
34503450
AL.getArgAsExpr(2));
34513451
}
34523452

3453+
// Handles max_work_group_size attribute.
3454+
// Returns a OneArgResult value; EqualToOne means all argument values are
3455+
// equal to one, NotEqualToOne means at least one argument value is not
3456+
// equal to one, and Unknown means that at least one of the argument values
3457+
// could not be determined.
3458+
enum class AttrArgResult { Unknown, EqualToOne, NotEqualToOne };
3459+
static AttrArgResult AreAllAttrArgsOne(const Expr *E, const Expr *E1,
3460+
const Expr *E2, const Expr *E3) {
3461+
// If any of the operand is still value dependent, we can't test anything.
3462+
const auto *CE = dyn_cast<ConstantExpr>(E);
3463+
const auto *CE1 = dyn_cast<ConstantExpr>(E1);
3464+
const auto *CE2 = dyn_cast<ConstantExpr>(E2);
3465+
const auto *CE3 = dyn_cast<ConstantExpr>(E3);
3466+
3467+
if (!CE || !CE1 || !CE2 || !CE3)
3468+
return AttrArgResult::Unknown;
3469+
3470+
// Otherwise, test that the values.
3471+
if (CE->getResultAsAPSInt() == 0 &&
3472+
(CE1->getResultAsAPSInt() != 1 ||
3473+
CE2->getResultAsAPSInt() != 1 ||
3474+
CE3->getResultAsAPSInt() != 1)) {
3475+
return AttrArgResult::NotEqualToOne;
3476+
}
3477+
return AttrArgResult::EqualToOne;
3478+
}
3479+
34533480
void Sema::AddSYCLIntelMaxWorkGroupSizeAttr(Decl *D,
34543481
const AttributeCommonInfo &CI,
34553482
Expr *XDim, Expr *YDim,
@@ -3491,26 +3518,16 @@ void Sema::AddSYCLIntelMaxWorkGroupSizeAttr(Decl *D,
34913518
return;
34923519

34933520
// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr, check to see if
3494-
// the attributes hold equal values (1, 1, 1) in case the value of
3521+
// the attribute holds equal values to (1, 1, 1) in case the value of
34953522
// SYCLIntelMaxGlobalWorkDimAttr equals to 0.
34963523
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
3497-
if (const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue())) {
3498-
// Test the attribute value.
3499-
const auto *DeclXDimExpr = dyn_cast<ConstantExpr>(XDim);
3500-
const auto *DeclYDimExpr = dyn_cast<ConstantExpr>(YDim);
3501-
const auto *DeclZDimExpr = dyn_cast<ConstantExpr>(ZDim);
3502-
// If the value is dependent, we can not test anything.
3503-
if (!DeclXDimExpr || !DeclYDimExpr || !DeclZDimExpr)
3504-
return;
3524+
AttrArgResult Results[] = {
3525+
AreAllAttrArgsOne(DeclAttr->getValue(), XDim, YDim, ZDim)};
35053526

3506-
if (DeclExpr->getResultAsAPSInt() == 0 &&
3507-
(DeclXDimExpr->getResultAsAPSInt() != 1 ||
3508-
DeclYDimExpr->getResultAsAPSInt() != 1 ||
3509-
DeclZDimExpr->getResultAsAPSInt() != 1)) {
3510-
Diag(CI.getLoc(), diag::err_sycl_x_y_z_arguments_must_be_one)
3511-
<< CI << DeclAttr;
3512-
return;
3513-
}
3527+
if (llvm::is_contained(Results, AttrArgResult::NotEqualToOne)) {
3528+
Diag(CI.getLoc(), diag::err_sycl_x_y_z_arguments_must_be_one)
3529+
<< CI << DeclAttr;
3530+
return;
35143531
}
35153532
}
35163533

@@ -3563,35 +3580,26 @@ SYCLIntelMaxWorkGroupSizeAttr *Sema::MergeSYCLIntelMaxWorkGroupSizeAttr(
35633580
return nullptr;
35643581
}
35653582

3566-
// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr, check to see if
3567-
// the attributes hold equal values (1, 1, 1) in case the value of
3568-
// SYCLIntelMaxGlobalWorkDimAttr equals to 0.
3583+
// If the declaration has a SYCLIntelMaxWorkGroupSizeAttr,
3584+
// check to see if the attribute holds equal values to
3585+
// (1, 1, 1) in case the value of SYCLIntelMaxGlobalWorkDimAttr
3586+
// equals to 0.
35693587
if (const auto *DeclAttr = D->getAttr<SYCLIntelMaxGlobalWorkDimAttr>()) {
3570-
if (const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue())) {
3571-
// Test the attribute value.
3572-
const auto *DeclXDimExpr = dyn_cast<ConstantExpr>(A.getXDim());
3573-
const auto *DeclYDimExpr = dyn_cast<ConstantExpr>(A.getYDim());
3574-
const auto *DeclZDimExpr = dyn_cast<ConstantExpr>(A.getZDim());
3575-
// If the value is dependent, we can not test anything.
3576-
if (!DeclXDimExpr || !DeclYDimExpr || !DeclZDimExpr)
3577-
return nullptr;
3588+
AttrArgResult Results[] = {
3589+
AreAllAttrArgsOne(DeclAttr->getValue(), A.getXDim(), A.getYDim(),
3590+
A.getZDim())};
35783591

3579-
if (DeclExpr->getResultAsAPSInt() == 0 &&
3580-
(DeclXDimExpr->getResultAsAPSInt() != 1 ||
3581-
DeclYDimExpr->getResultAsAPSInt() != 1 ||
3582-
DeclZDimExpr->getResultAsAPSInt() != 1)) {
3583-
Diag(A.getLoc(), diag::err_sycl_x_y_z_arguments_must_be_one)
3584-
<< &A << DeclAttr;
3585-
return nullptr;
3586-
}
3592+
if (llvm::is_contained(Results, AttrArgResult::NotEqualToOne)) {
3593+
Diag(A.getLoc(), diag::err_sycl_x_y_z_arguments_must_be_one)
3594+
<< &A << DeclAttr;
3595+
return nullptr;
35873596
}
35883597
}
35893598

35903599
return ::new (Context) SYCLIntelMaxWorkGroupSizeAttr(
35913600
Context, A, A.getXDim(), A.getYDim(), A.getZDim());
35923601
}
35933602

3594-
// Handles max_work_group_size.
35953603
static void handleSYCLIntelMaxWorkGroupSize(Sema &S, Decl *D,
35963604
const ParsedAttr &AL) {
35973605
S.AddSYCLIntelMaxWorkGroupSizeAttr(D, AL, AL.getArgAsExpr(0),

clang/test/SemaSYCL/sycl-device-intel-max-global-work-dim-template.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,8 @@ template <int size>
7373
// In case the value of 'max_global_work_dim' attribute equals to 0 we shall
7474
// ensure that if max_work_group_size and reqd_work_group_size attributes exist,
7575
// they hold equal values (1, 1, 1).
76-
77-
// TODO: Test case compiles now without any diagnostic but it shouldn't.
7876
template <int N>
79-
[[intel::max_work_group_size(N, N, N)]] void func5(); // OK now. Error is expected here.
77+
[[intel::max_work_group_size(N, N, N)]] void func5(); // expected-error {{all 'max_work_group_size' attribute arguments must be '1' when the 'max_global_work_dim' attribute argument is '0'}}
8078
template <int N>
8179
[[intel::max_global_work_dim(0)]] void func5();
8280

@@ -129,7 +127,7 @@ int check() {
129127
func3<3>(); // OK
130128
func3<-1>(); // expected-note {{in instantiation of function template specialization 'func3<-1>' requested here}}
131129
func4<2>(); // expected-note {{in instantiation of function template specialization 'func4<2>' requested here}}
132-
func5<6>(); // OK now. Expecte note here.
130+
func5<6>(); // expected-note {{in instantiation of function template specialization 'func5<6>' requested here}}
133131
func6<2>(); // expected-note {{in instantiation of function template specialization 'func6<2>' requested here}}
134132
func7<2>(); // expected-note {{in instantiation of function template specialization 'func7<2>' requested here}}
135133
func8<2>(); // expected-note {{in instantiation of function template specialization 'func8<2>' requested here}}

0 commit comments

Comments
 (0)