@@ -3155,9 +3155,7 @@ static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3155
3155
int64_t NumSimdWorkItems =
3156
3156
A->getValue ()->getIntegerConstantExpr (Ctx)->getSExtValue ();
3157
3157
3158
- if (!(XDimVal.getZExtValue () % NumSimdWorkItems == 0 ||
3159
- YDimVal.getZExtValue () % NumSimdWorkItems == 0 ||
3160
- ZDimVal.getZExtValue () % NumSimdWorkItems == 0 )) {
3158
+ if (XDimVal.getZExtValue () % NumSimdWorkItems != 0 ) {
3161
3159
S.Diag (A->getLocation (), diag::err_sycl_num_kernel_wrong_reqd_wg_size)
3162
3160
<< A << AL;
3163
3161
S.Diag (AL.getLoc (), diag::note_conflicting_attribute);
@@ -3305,14 +3303,12 @@ void Sema::AddSYCLIntelNumSimdWorkItemsAttr(Decl *D,
3305
3303
}
3306
3304
3307
3305
// If the declaration has an [[intel::reqd_work_group_size]] attribute,
3308
- // check to see if can be evenly divided by the num_simd_work_items attr.
3306
+ // check to see if the first argument can be evenly divided by the
3307
+ // num_simd_work_items attribute.
3309
3308
if (const auto *DeclAttr = D->getAttr <ReqdWorkGroupSizeAttr>()) {
3310
3309
Optional<llvm::APSInt> XDimVal = DeclAttr->getXDimVal (Context);
3311
- Optional<llvm::APSInt> YDimVal = DeclAttr->getYDimVal (Context);
3312
- Optional<llvm::APSInt> ZDimVal = DeclAttr->getZDimVal (Context);
3313
3310
3314
- if (!(*XDimVal % ArgVal == 0 || *YDimVal % ArgVal == 0 ||
3315
- *ZDimVal % ArgVal == 0 )) {
3311
+ if (*XDimVal % ArgVal != 0 ) {
3316
3312
Diag (CI.getLoc (), diag::err_sycl_num_kernel_wrong_reqd_wg_size)
3317
3313
<< CI << DeclAttr;
3318
3314
Diag (DeclAttr->getLocation (), diag::note_conflicting_attribute);
@@ -3453,87 +3449,93 @@ static void handleMaxGlobalWorkDimAttr(Sema &S, Decl *D, const ParsedAttr &A) {
3453
3449
S.addIntelSingleArgAttr <SYCLIntelMaxGlobalWorkDimAttr>(D, A, E);
3454
3450
}
3455
3451
3456
- SYCLIntelLoopFuseAttr *
3457
- Sema::mergeSYCLIntelLoopFuseAttr (Decl *D, const AttributeCommonInfo &CI,
3458
- Expr *E) {
3452
+ // Handles [[intel::loop_fuse]] and [[intel::loop_fuse_independent]].
3453
+ void Sema::AddSYCLIntelLoopFuseAttr (Decl *D, const AttributeCommonInfo &CI,
3454
+ Expr *E) {
3455
+ if (!E->isValueDependent ()) {
3456
+ // Validate that we have an integer constant expression and then store the
3457
+ // converted constant expression into the semantic attribute so that we
3458
+ // don't have to evaluate it again later.
3459
+ llvm::APSInt ArgVal;
3460
+ ExprResult Res = VerifyIntegerConstantExpression (E, &ArgVal);
3461
+ if (Res.isInvalid ())
3462
+ return ;
3463
+ E = Res.get ();
3459
3464
3460
- if (const auto ExistingAttr = D->getAttr <SYCLIntelLoopFuseAttr>()) {
3465
+ // This attribute requires a non-negative value.
3466
+ if (ArgVal < 0 ) {
3467
+ Diag (E->getExprLoc (), diag::err_attribute_requires_positive_integer)
3468
+ << CI << /* non-negative*/ 1 ;
3469
+ return ;
3470
+ }
3471
+ // Check to see if there's a duplicate attribute with different values
3472
+ // already applied to the declaration.
3473
+ if (const auto *DeclAttr = D->getAttr <SYCLIntelLoopFuseAttr>()) {
3474
+ // If the other attribute argument is instantiation dependent, we won't
3475
+ // have converted it to a constant expression yet and thus we test
3476
+ // whether this is a null pointer.
3477
+ const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue ());
3478
+ if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt ()) {
3479
+ Diag (CI.getLoc (), diag::warn_duplicate_attribute) << CI;
3480
+ Diag (DeclAttr->getLoc (), diag::note_previous_attribute);
3481
+ return ;
3482
+ }
3483
+ // [[intel::loop_fuse]] and [[intel::loop_fuse_independent]] are
3484
+ // incompatible.
3485
+ // FIXME: If additional spellings are provided for this attribute,
3486
+ // this code will do the wrong thing.
3487
+ if (DeclAttr->getAttributeSpellingListIndex () !=
3488
+ CI.getAttributeSpellingListIndex ()) {
3489
+ Diag (CI.getLoc (), diag::err_attributes_are_not_compatible)
3490
+ << CI << DeclAttr;
3491
+ Diag (DeclAttr->getLocation (), diag::note_conflicting_attribute);
3492
+ return ;
3493
+ }
3494
+ }
3495
+ }
3496
+
3497
+ D->addAttr (::new (Context) SYCLIntelLoopFuseAttr (Context, CI, E));
3498
+ }
3499
+
3500
+ SYCLIntelLoopFuseAttr *
3501
+ Sema::MergeSYCLIntelLoopFuseAttr (Decl *D, const SYCLIntelLoopFuseAttr &A) {
3502
+ // Check to see if there's a duplicate attribute with different values
3503
+ // already applied to the declaration.
3504
+ if (const auto *DeclAttr = D->getAttr <SYCLIntelLoopFuseAttr>()) {
3505
+ const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue ());
3506
+ const auto *MergeExpr = dyn_cast<ConstantExpr>(A.getValue ());
3507
+ if (DeclExpr && MergeExpr &&
3508
+ DeclExpr->getResultAsAPSInt () != MergeExpr->getResultAsAPSInt ()) {
3509
+ Diag (DeclAttr->getLoc (), diag::warn_duplicate_attribute) << &A;
3510
+ Diag (A.getLoc (), diag::note_previous_attribute);
3511
+ return nullptr ;
3512
+ }
3461
3513
// [[intel::loop_fuse]] and [[intel::loop_fuse_independent]] are
3462
3514
// incompatible.
3463
3515
// FIXME: If additional spellings are provided for this attribute,
3464
3516
// this code will do the wrong thing.
3465
- if (ExistingAttr ->getAttributeSpellingListIndex () !=
3466
- CI .getAttributeSpellingListIndex ()) {
3467
- Diag (CI .getLoc (), diag::err_attributes_are_not_compatible)
3468
- << CI << ExistingAttr ;
3469
- Diag (ExistingAttr-> getLocation (), diag::note_conflicting_attribute);
3517
+ if (DeclAttr ->getAttributeSpellingListIndex () !=
3518
+ A .getAttributeSpellingListIndex ()) {
3519
+ Diag (A .getLoc (), diag::err_attributes_are_not_compatible)
3520
+ << &A << DeclAttr ;
3521
+ Diag (DeclAttr-> getLoc (), diag::note_conflicting_attribute);
3470
3522
return nullptr ;
3471
3523
}
3472
-
3473
- if (!E->isValueDependent ()) {
3474
- Optional<llvm::APSInt> ArgVal = E->getIntegerConstantExpr (Context);
3475
- Optional<llvm::APSInt> ExistingArgVal =
3476
- ExistingAttr->getValue ()->getIntegerConstantExpr (Context);
3477
-
3478
- assert (ArgVal && ExistingArgVal &&
3479
- " Argument should be an integer constant expression" );
3480
- // Compare attribute argument value and warn if there is a mismatch.
3481
- if (ArgVal->getExtValue () != ExistingArgVal->getExtValue ())
3482
- Diag (ExistingAttr->getLoc (), diag::warn_duplicate_attribute)
3483
- << ExistingAttr;
3484
- }
3485
-
3486
- // If there is no mismatch, silently ignore duplicate attribute.
3487
- return nullptr ;
3488
- }
3489
- return ::new (Context) SYCLIntelLoopFuseAttr (Context, CI, E);
3490
- }
3491
-
3492
- static bool checkSYCLIntelLoopFuseArgument (Sema &S,
3493
- const AttributeCommonInfo &CI,
3494
- Expr *E) {
3495
- // Dependent expressions are checked when instantiated.
3496
- if (E->isValueDependent ())
3497
- return false ;
3498
-
3499
- Optional<llvm::APSInt> ArgVal = E->getIntegerConstantExpr (S.Context );
3500
- if (!ArgVal) {
3501
- S.Diag (E->getExprLoc (), diag::err_attribute_argument_type)
3502
- << CI << AANT_ArgumentIntegerConstant << E->getSourceRange ();
3503
- return true ;
3504
- }
3505
-
3506
- if (!ArgVal->isNonNegative ()) {
3507
- S.Diag (E->getExprLoc (), diag::err_attribute_requires_positive_integer)
3508
- << CI << /* non-negative*/ 1 ;
3509
- return true ;
3510
3524
}
3511
3525
3512
- return false ;
3526
+ return :: new (Context) SYCLIntelLoopFuseAttr (Context, A, A. getValue ()) ;
3513
3527
}
3514
3528
3515
- void Sema::addSYCLIntelLoopFuseAttr (Decl *D, const AttributeCommonInfo &CI,
3516
- Expr *E) {
3517
- assert (E && " argument has unexpected null value" );
3518
-
3519
- if (checkSYCLIntelLoopFuseArgument (*this , CI, E))
3520
- return ;
3521
-
3522
- SYCLIntelLoopFuseAttr *NewAttr = mergeSYCLIntelLoopFuseAttr (D, CI, E);
3523
-
3524
- if (NewAttr)
3525
- D->addAttr (NewAttr);
3526
- }
3529
+ static void handleSYCLIntelLoopFuseAttr (Sema &S, Decl *D, const ParsedAttr &A) {
3530
+ S.CheckDeprecatedSYCLAttributeSpelling (A);
3527
3531
3528
- // Handles [[intel::loop_fuse]] and [[intel::loop_fuse_independent]].
3529
- static void handleLoopFuseAttr (Sema &S, Decl *D, const ParsedAttr &Attr) {
3530
- // Default argument value is set to 1.
3531
- Expr *E = Attr.isArgExpr (0 )
3532
- ? Attr.getArgAsExpr (0 )
3532
+ // If no attribute argument is specified, set to default value '1'.
3533
+ Expr *E = A.isArgExpr (0 )
3534
+ ? A.getArgAsExpr (0 )
3533
3535
: IntegerLiteral::Create (S.Context , llvm::APInt (32 , 1 ),
3534
- S.Context .IntTy , Attr .getLoc ());
3536
+ S.Context .IntTy , A .getLoc ());
3535
3537
3536
- S.addSYCLIntelLoopFuseAttr (D, Attr , E);
3538
+ S.AddSYCLIntelLoopFuseAttr (D, A , E);
3537
3539
}
3538
3540
3539
3541
static void handleVecTypeHint (Sema &S, Decl *D, const ParsedAttr &AL) {
@@ -9136,7 +9138,7 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
9136
9138
handleUseStallEnableClustersAttr (S, D, AL);
9137
9139
break ;
9138
9140
case ParsedAttr::AT_SYCLIntelLoopFuse:
9139
- handleLoopFuseAttr (S, D, AL);
9141
+ handleSYCLIntelLoopFuseAttr (S, D, AL);
9140
9142
break ;
9141
9143
case ParsedAttr::AT_VecTypeHint:
9142
9144
handleVecTypeHint (S, D, AL);
0 commit comments