@@ -3209,65 +3209,148 @@ static void handleWorkGroupSizeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
3209
3209
WGSize[1 ], WGSize[2 ]));
3210
3210
}
3211
3211
3212
- // Handles intel_reqd_sub_group_size.
3213
- static void handleSubGroupSize (Sema &S, Decl *D, const ParsedAttr &AL ) {
3214
- if (S. LangOpts .SYCLIsHost )
3212
+ void Sema::AddIntelReqdSubGroupSize (Decl *D, const AttributeCommonInfo &CI,
3213
+ Expr *E ) {
3214
+ if (LangOpts.SYCLIsHost )
3215
3215
return ;
3216
3216
3217
- Expr *E = AL.getArgAsExpr (0 );
3217
+ if (!E->isValueDependent ()) {
3218
+ // Validate that we have an integer constant expression and then store the
3219
+ // converted constant expression into the semantic attribute so that we
3220
+ // don't have to evaluate it again later.
3221
+ llvm::APSInt ArgVal;
3222
+ ExprResult Res = VerifyIntegerConstantExpression (E, &ArgVal);
3223
+ if (Res.isInvalid ())
3224
+ return ;
3225
+ E = Res.get ();
3218
3226
3219
- if (D->getAttr <IntelReqdSubGroupSizeAttr>())
3220
- S.Diag (AL.getLoc (), diag::warn_duplicate_attribute) << AL;
3227
+ // This attribute requires a strictly positive value.
3228
+ if (ArgVal <= 0 ) {
3229
+ Diag (E->getExprLoc (), diag::err_attribute_requires_positive_integer)
3230
+ << CI << /* positive*/ 0 ;
3231
+ return ;
3232
+ }
3233
+
3234
+ // Check to see if there's a duplicate attribute with different values
3235
+ // already applied to the declaration.
3236
+ if (const auto *DeclAttr = D->getAttr <IntelReqdSubGroupSizeAttr>()) {
3237
+ // If the other attribute argument is instantiation dependent, we won't
3238
+ // have converted it to a constant expression yet and thus we test
3239
+ // whether this is a null pointer.
3240
+ const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue ());
3241
+ if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt ()) {
3242
+ Diag (CI.getLoc (), diag::warn_duplicate_attribute) << CI;
3243
+ Diag (DeclAttr->getLoc (), diag::note_previous_attribute);
3244
+ return ;
3245
+ }
3246
+ }
3247
+ }
3221
3248
3222
- S. addIntelSingleArgAttr <IntelReqdSubGroupSizeAttr>(D, AL , E);
3249
+ D-> addAttr (:: new (Context) IntelReqdSubGroupSizeAttr (Context, CI , E) );
3223
3250
}
3224
3251
3225
- // Handles num_simd_work_items.
3226
- static void handleNumSimdWorkItemsAttr (Sema &S, Decl *D, const ParsedAttr &AL) {
3227
- if (D->isInvalidDecl ())
3228
- return ;
3252
+ IntelReqdSubGroupSizeAttr *
3253
+ Sema::MergeIntelReqdSubGroupSizeAttr (Decl *D,
3254
+ const IntelReqdSubGroupSizeAttr &A) {
3255
+ // Check to see if there's a duplicate attribute with different values
3256
+ // already applied to the declaration.
3257
+ if (const auto *DeclAttr = D->getAttr <IntelReqdSubGroupSizeAttr>()) {
3258
+ const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue ());
3259
+ const auto *MergeExpr = dyn_cast<ConstantExpr>(A.getValue ());
3260
+ if (DeclExpr && MergeExpr &&
3261
+ DeclExpr->getResultAsAPSInt () != MergeExpr->getResultAsAPSInt ()) {
3262
+ Diag (DeclAttr->getLoc (), diag::warn_duplicate_attribute) << &A;
3263
+ Diag (A.getLoc (), diag::note_previous_attribute);
3264
+ return nullptr ;
3265
+ }
3266
+ }
3267
+ return ::new (Context) IntelReqdSubGroupSizeAttr (Context, A, A.getValue ());
3268
+ }
3229
3269
3270
+ static void handleIntelReqdSubGroupSize (Sema &S, Decl *D,
3271
+ const ParsedAttr &AL) {
3230
3272
Expr *E = AL.getArgAsExpr (0 );
3273
+ S.AddIntelReqdSubGroupSize (D, AL, E);
3274
+ }
3231
3275
3232
- if (D->getAttr <SYCLIntelNumSimdWorkItemsAttr>())
3233
- S.Diag (AL.getLoc (), diag::warn_duplicate_attribute) << AL;
3234
-
3235
- S.CheckDeprecatedSYCLAttributeSpelling (AL);
3236
-
3276
+ void Sema::AddSYCLIntelNumSimdWorkItemsAttr (Decl *D,
3277
+ const AttributeCommonInfo &CI,
3278
+ Expr *E) {
3237
3279
if (!E->isValueDependent ()) {
3280
+ // Validate that we have an integer constant expression and then store the
3281
+ // converted constant expression into the semantic attribute so that we
3282
+ // don't have to evaluate it again later.
3238
3283
llvm::APSInt ArgVal;
3239
- ExprResult ICE = S.VerifyIntegerConstantExpression (E, &ArgVal);
3240
-
3241
- if (ICE.isInvalid ())
3284
+ ExprResult Res = VerifyIntegerConstantExpression (E, &ArgVal);
3285
+ if (Res.isInvalid ())
3242
3286
return ;
3287
+ E = Res.get ();
3243
3288
3244
- E = ICE.get ();
3245
- int64_t NumSimdWorkItems = ArgVal.getSExtValue ();
3246
-
3247
- if (NumSimdWorkItems == 0 ) {
3248
- S.Diag (E->getExprLoc (), diag::err_attribute_argument_is_zero)
3249
- << AL << E->getSourceRange ();
3289
+ // This attribute requires a strictly positive value.
3290
+ if (ArgVal <= 0 ) {
3291
+ Diag (E->getExprLoc (), diag::err_attribute_requires_positive_integer)
3292
+ << CI << /* positive*/ 0 ;
3250
3293
return ;
3251
3294
}
3252
3295
3253
- if (const auto *A = D->getAttr <ReqdWorkGroupSizeAttr>()) {
3254
- ASTContext &Ctx = S.getASTContext ();
3255
- Optional<llvm::APSInt> XDimVal = A->getXDimVal (Ctx);
3256
- Optional<llvm::APSInt> YDimVal = A->getYDimVal (Ctx);
3257
- Optional<llvm::APSInt> ZDimVal = A->getZDimVal (Ctx);
3258
-
3259
- if (!(XDimVal->getZExtValue () % NumSimdWorkItems == 0 ||
3260
- YDimVal->getZExtValue () % NumSimdWorkItems == 0 ||
3261
- ZDimVal->getZExtValue () % NumSimdWorkItems == 0 )) {
3262
- S.Diag (AL.getLoc (), diag::err_sycl_num_kernel_wrong_reqd_wg_size)
3263
- << AL << A;
3264
- S.Diag (A->getLocation (), diag::note_conflicting_attribute);
3296
+ // Check to see if there's a duplicate attribute with different values
3297
+ // already applied to the declaration.
3298
+ if (const auto *DeclAttr = D->getAttr <SYCLIntelNumSimdWorkItemsAttr>()) {
3299
+ // If the other attribute argument is instantiation dependent, we won't
3300
+ // have converted it to a constant expression yet and thus we test
3301
+ // whether this is a null pointer.
3302
+ const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue ());
3303
+ if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt ()) {
3304
+ Diag (CI.getLoc (), diag::warn_duplicate_attribute) << CI;
3305
+ Diag (DeclAttr->getLoc (), diag::note_previous_attribute);
3306
+ return ;
3307
+ }
3308
+ }
3309
+
3310
+ // If the declaration has an [[intel::reqd_work_group_size]] attribute,
3311
+ // check to see if can be evenly divided by the num_simd_work_items attr.
3312
+ if (const auto *DeclAttr = D->getAttr <ReqdWorkGroupSizeAttr>()) {
3313
+ Optional<llvm::APSInt> XDimVal = DeclAttr->getXDimVal (Context);
3314
+ Optional<llvm::APSInt> YDimVal = DeclAttr->getYDimVal (Context);
3315
+ Optional<llvm::APSInt> ZDimVal = DeclAttr->getZDimVal (Context);
3316
+
3317
+ if (!(*XDimVal % ArgVal == 0 || *YDimVal % ArgVal == 0 ||
3318
+ *ZDimVal % ArgVal == 0 )) {
3319
+ Diag (CI.getLoc (), diag::err_sycl_num_kernel_wrong_reqd_wg_size)
3320
+ << CI << DeclAttr;
3321
+ Diag (DeclAttr->getLocation (), diag::note_conflicting_attribute);
3265
3322
return ;
3266
3323
}
3267
3324
}
3268
3325
}
3269
3326
3270
- S.addIntelSingleArgAttr <SYCLIntelNumSimdWorkItemsAttr>(D, AL, E);
3327
+ D->addAttr (::new (Context) SYCLIntelNumSimdWorkItemsAttr (Context, CI, E));
3328
+ }
3329
+
3330
+ SYCLIntelNumSimdWorkItemsAttr *Sema::MergeSYCLIntelNumSimdWorkItemsAttr (
3331
+ Decl *D, const SYCLIntelNumSimdWorkItemsAttr &A) {
3332
+ // Check to see if there's a duplicate attribute with different values
3333
+ // already applied to the declaration.
3334
+ if (const auto *DeclAttr = D->getAttr <SYCLIntelNumSimdWorkItemsAttr>()) {
3335
+ const auto *DeclExpr = dyn_cast<ConstantExpr>(DeclAttr->getValue ());
3336
+ const auto *MergeExpr = dyn_cast<ConstantExpr>(A.getValue ());
3337
+ if (DeclExpr && MergeExpr &&
3338
+ DeclExpr->getResultAsAPSInt () != MergeExpr->getResultAsAPSInt ()) {
3339
+ Diag (DeclAttr->getLoc (), diag::warn_duplicate_attribute) << &A;
3340
+ Diag (A.getLoc (), diag::note_previous_attribute);
3341
+ return nullptr ;
3342
+ }
3343
+ }
3344
+ return ::new (Context)
3345
+ SYCLIntelNumSimdWorkItemsAttr (Context, A, A.getValue ());
3346
+ }
3347
+
3348
+ static void handleSYCLIntelNumSimdWorkItemsAttr (Sema &S, Decl *D,
3349
+ const ParsedAttr &A) {
3350
+ S.CheckDeprecatedSYCLAttributeSpelling (A);
3351
+
3352
+ Expr *E = A.getArgAsExpr (0 );
3353
+ S.AddSYCLIntelNumSimdWorkItemsAttr (D, A, E);
3271
3354
}
3272
3355
3273
3356
// Handles use_stall_enable_clusters
@@ -8848,10 +8931,10 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
8848
8931
handleWorkGroupSize<SYCLIntelMaxWorkGroupSizeAttr>(S, D, AL);
8849
8932
break ;
8850
8933
case ParsedAttr::AT_IntelReqdSubGroupSize:
8851
- handleSubGroupSize (S, D, AL);
8934
+ handleIntelReqdSubGroupSize (S, D, AL);
8852
8935
break ;
8853
8936
case ParsedAttr::AT_SYCLIntelNumSimdWorkItems:
8854
- handleNumSimdWorkItemsAttr (S, D, AL);
8937
+ handleSYCLIntelNumSimdWorkItemsAttr (S, D, AL);
8855
8938
break ;
8856
8939
case ParsedAttr::AT_SYCLIntelSchedulerTargetFmaxMhz:
8857
8940
handleSchedulerTargetFmaxMhzAttr (S, D, AL);
0 commit comments