diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 3da76457434a3..bb89ad0b9f300 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3233,10 +3233,12 @@ void Sema::AddIntelReqdSubGroupSize(Decl *D, const AttributeCommonInfo &CI, // If the other attribute argument is instantiation dependent, we won't // have converted it to a constant expression yet and thus we test // whether this is a null pointer. - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt()) { - Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; - Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (ArgVal != DeclExpr->getResultAsAPSInt()) { + Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; + Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + } + // Drop the duplicate attribute. return; } } @@ -3251,13 +3253,16 @@ Sema::MergeIntelReqdSubGroupSizeAttr(Decl *D, // Check to see if there's a duplicate attribute with different values // already applied to the declaration. if (const auto *DeclAttr = D->getAttr()) { - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - const auto *MergeExpr = dyn_cast(A.getValue()); - if (DeclExpr && MergeExpr && - DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { - Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; - Diag(A.getLoc(), diag::note_previous_attribute); - return nullptr; + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (const auto *MergeExpr = dyn_cast(A.getValue())) { + if (DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { + Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; + Diag(A.getLoc(), diag::note_previous_attribute); + return nullptr; + } + // Do not add a duplicate attribute. + return nullptr; + } } } return ::new (Context) IntelReqdSubGroupSizeAttr(Context, A, A.getValue()); @@ -3295,10 +3300,12 @@ void Sema::AddSYCLIntelNumSimdWorkItemsAttr(Decl *D, // If the other attribute argument is instantiation dependent, we won't // have converted it to a constant expression yet and thus we test // whether this is a null pointer. - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt()) { - Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; - Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (ArgVal != DeclExpr->getResultAsAPSInt()) { + Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; + Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + } + // Drop the duplicate attribute. return; } } @@ -3326,13 +3333,15 @@ SYCLIntelNumSimdWorkItemsAttr *Sema::MergeSYCLIntelNumSimdWorkItemsAttr( // Check to see if there's a duplicate attribute with different values // already applied to the declaration. if (const auto *DeclAttr = D->getAttr()) { - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - const auto *MergeExpr = dyn_cast(A.getValue()); - if (DeclExpr && MergeExpr && - DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { - Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; - Diag(A.getLoc(), diag::note_previous_attribute); - return nullptr; + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (const auto *MergeExpr = dyn_cast(A.getValue())) { + if (DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { + Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; + Diag(A.getLoc(), diag::note_previous_attribute); + } + // Do not add a duplicate attribute. + return nullptr; + } } } return ::new (Context) @@ -3389,10 +3398,12 @@ void Sema::AddSYCLIntelSchedulerTargetFmaxMhzAttr(Decl *D, // If the other attribute argument is instantiation dependent, we won't // have converted it to a constant expression yet and thus we test // whether this is a null pointer. - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt()) { - Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; - Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (ArgVal != DeclExpr->getResultAsAPSInt()) { + Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; + Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + } + // Drop the duplicate attribute. return; } } @@ -3409,13 +3420,16 @@ Sema::MergeSYCLIntelSchedulerTargetFmaxMhzAttr( // already applied to the declaration. if (const auto *DeclAttr = D->getAttr()) { - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - const auto *MergeExpr = dyn_cast(A.getValue()); - if (DeclExpr && MergeExpr && - DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { - Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; - Diag(A.getLoc(), diag::note_previous_attribute); - return nullptr; + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (const auto *MergeExpr = dyn_cast(A.getValue())) { + if (DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { + Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; + Diag(A.getLoc(), diag::note_previous_attribute); + return nullptr; + } + // Do not add a duplicate attribute. + return nullptr; + } } } return ::new (Context) @@ -3472,15 +3486,6 @@ void Sema::AddSYCLIntelLoopFuseAttr(Decl *D, const AttributeCommonInfo &CI, // Check to see if there's a duplicate attribute with different values // already applied to the declaration. if (const auto *DeclAttr = D->getAttr()) { - // If the other attribute argument is instantiation dependent, we won't - // have converted it to a constant expression yet and thus we test - // whether this is a null pointer. - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt()) { - Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; - Diag(DeclAttr->getLoc(), diag::note_previous_attribute); - return; - } // [[intel::loop_fuse]] and [[intel::loop_fuse_independent]] are // incompatible. // FIXME: If additional spellings are provided for this attribute, @@ -3492,6 +3497,17 @@ void Sema::AddSYCLIntelLoopFuseAttr(Decl *D, const AttributeCommonInfo &CI, Diag(DeclAttr->getLocation(), diag::note_conflicting_attribute); return; } + // If the other attribute argument is instantiation dependent, we won't + // have converted it to a constant expression yet and thus we test + // whether this is a null pointer. + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (ArgVal != DeclExpr->getResultAsAPSInt()) { + Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; + Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + } + // Drop the duplicate attribute. + return; + } } } @@ -3503,14 +3519,6 @@ Sema::MergeSYCLIntelLoopFuseAttr(Decl *D, const SYCLIntelLoopFuseAttr &A) { // Check to see if there's a duplicate attribute with different values // already applied to the declaration. if (const auto *DeclAttr = D->getAttr()) { - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - const auto *MergeExpr = dyn_cast(A.getValue()); - if (DeclExpr && MergeExpr && - DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { - Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; - Diag(A.getLoc(), diag::note_previous_attribute); - return nullptr; - } // [[intel::loop_fuse]] and [[intel::loop_fuse_independent]] are // incompatible. // FIXME: If additional spellings are provided for this attribute, @@ -3522,6 +3530,16 @@ Sema::MergeSYCLIntelLoopFuseAttr(Decl *D, const SYCLIntelLoopFuseAttr &A) { Diag(DeclAttr->getLoc(), diag::note_conflicting_attribute); return nullptr; } + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (const auto *MergeExpr = dyn_cast(A.getValue())) { + if (DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { + Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; + Diag(A.getLoc(), diag::note_previous_attribute); + } + // Do not add a duplicate attribute. + return nullptr; + } + } } return ::new (Context) SYCLIntelLoopFuseAttr(Context, A, A.getValue()); @@ -5764,10 +5782,12 @@ void Sema::AddSYCLIntelNoGlobalWorkOffsetAttr(Decl *D, // If the other attribute argument is instantiation dependent, we won't // have converted it to a constant expression yet and thus we test // whether this is a null pointer. - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt()) { - Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; - Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (ArgVal != DeclExpr->getResultAsAPSInt()) { + Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; + Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + } + // Drop the duplicate attribute. return; } } @@ -5781,13 +5801,15 @@ SYCLIntelNoGlobalWorkOffsetAttr *Sema::MergeSYCLIntelNoGlobalWorkOffsetAttr( // Check to see if there's a duplicate attribute with different values // already applied to the declaration. if (const auto *DeclAttr = D->getAttr()) { - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - const auto *MergeExpr = dyn_cast(A.getValue()); - if (DeclExpr && MergeExpr && - DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { - Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; - Diag(A.getLoc(), diag::note_previous_attribute); - return nullptr; + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (const auto *MergeExpr = dyn_cast(A.getValue())) { + if (DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { + Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; + Diag(A.getLoc(), diag::note_previous_attribute); + } + // Do not add a duplicate attribute. + return nullptr; + } } } return ::new (Context) @@ -5967,10 +5989,12 @@ void Sema::AddIntelFPGAMaxReplicatesAttr(Decl *D, const AttributeCommonInfo &CI, // If the other attribute argument is instantiation dependent, we won't // have converted it to a constant expression yet and thus we test // whether this is a null pointer. - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt()) { - Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; - Diag(DeclAttr->getLocation(), diag::note_previous_attribute); + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (ArgVal != DeclExpr->getResultAsAPSInt()) { + Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; + Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + } + // Drop the duplicate attribute. return; } } @@ -5996,13 +6020,15 @@ Sema::MergeIntelFPGAMaxReplicatesAttr(Decl *D, // Check to see if there's a duplicate attribute with different values // already applied to the declaration. if (const auto *DeclAttr = D->getAttr()) { - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - const auto *MergeExpr = dyn_cast(A.getValue()); - if (DeclExpr && MergeExpr && - DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { - Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; - Diag(A.getLoc(), diag::note_previous_attribute); - return nullptr; + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (const auto *MergeExpr = dyn_cast(A.getValue())) { + if (DeclExpr->getResultAsAPSInt() != MergeExpr->getResultAsAPSInt()) { + Diag(DeclAttr->getLoc(), diag::warn_duplicate_attribute) << &A; + Diag(A.getLoc(), diag::note_previous_attribute); + } + // Do not add a duplicate attribute. + return nullptr; + } } } // [[intel::fpga_register]] and [[intel::max_replicates()]] @@ -6166,24 +6192,28 @@ void Sema::AddIntelFPGAPrivateCopiesAttr(Decl *D, const AttributeCommonInfo &CI, // If the other attribute argument is instantiation dependent, we won't // have converted it to a constant expression yet and thus we test // whether this is a null pointer. - const auto *DeclExpr = dyn_cast(DeclAttr->getValue()); - if (DeclExpr && ArgVal != DeclExpr->getResultAsAPSInt()) { - Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; - Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + if (const auto *DeclExpr = dyn_cast(DeclAttr->getValue())) { + if (ArgVal != DeclExpr->getResultAsAPSInt()) { + Diag(CI.getLoc(), diag::warn_duplicate_attribute) << CI; + Diag(DeclAttr->getLoc(), diag::note_previous_attribute); + } + // Drop the duplicate attribute. return; } } - // [[intel::fpga_register]] and [[intel::private_copies()]] - // attributes are incompatible. - if (checkAttrMutualExclusion(*this, D, CI)) - return; - // If the declaration does not have [[intel::memory]] - // attribute, this creates default implicit memory. - if (!D->hasAttr()) - D->addAttr(IntelFPGAMemoryAttr::CreateImplicit( - Context, IntelFPGAMemoryAttr::Default)); } + // [[intel::fpga_register]] and [[intel::private_copies()]] + // attributes are incompatible. + if (checkAttrMutualExclusion(*this, D, CI)) + return; + + // If the declaration does not have [[intel::memory]] + // attribute, this creates default implicit memory. + if (!D->hasAttr()) + D->addAttr(IntelFPGAMemoryAttr::CreateImplicit( + Context, IntelFPGAMemoryAttr::Default)); + D->addAttr(::new (Context) IntelFPGAPrivateCopiesAttr(Context, CI, E)); } diff --git a/clang/test/SemaSYCL/intel-fpga-local.cpp b/clang/test/SemaSYCL/intel-fpga-local.cpp index a68ffcc20eb64..bb3e93537ec6a 100644 --- a/clang/test/SemaSYCL/intel-fpga-local.cpp +++ b/clang/test/SemaSYCL/intel-fpga-local.cpp @@ -155,24 +155,16 @@ void check_ast() //CHECK-NEXT: ConstantExpr //CHECK-NEXT: value:{{.*}}12 //CHECK-NEXT: IntegerLiteral{{.*}}12{{$}} - //CHECK: IntelFPGAMaxReplicatesAttr - //CHECK-NEXT: ConstantExpr - //CHECK-NEXT: value:{{.*}}12 - //CHECK-NEXT: IntegerLiteral{{.*}}12{{$}} [[intel::max_replicates(12)]] [[intel::max_replicates(12)]] int var_max_replicates; // OK - // Checking of duplicate argument values. + // Check duplicate argument values. //CHECK: VarDecl{{.*}}var_private_copies //CHECK: IntelFPGAMemoryAttr{{.*}}Implicit //CHECK: IntelFPGAPrivateCopiesAttr //CHECK-NEXT: ConstantExpr //CHECK-NEXT: value:{{.*}}12 //CHECK-NEXT: IntegerLiteral{{.*}}12{{$}} - //CHECK: IntelFPGAPrivateCopiesAttr - //CHECK-NEXT: ConstantExpr - //CHECK-NEXT: value:{{.*}}12 - //CHECK-NEXT: IntegerLiteral{{.*}}12{{$}} [[intel::private_copies(12)]] [[intel::private_copies(12)]] int var_private_copies; // OK diff --git a/clang/test/SemaSYCL/intel-fpga-no-global-work-offset.cpp b/clang/test/SemaSYCL/intel-fpga-no-global-work-offset.cpp index f6198408a85ed..b3c2d4b8e40c2 100644 --- a/clang/test/SemaSYCL/intel-fpga-no-global-work-offset.cpp +++ b/clang/test/SemaSYCL/intel-fpga-no-global-work-offset.cpp @@ -41,16 +41,25 @@ int main() { h.single_task( []() [[intel::no_global_work_offset(-1)]]{}); - // expected-error@+2{{integral constant expression must have integral or unscoped enumeration type, not 'const char [4]'}} + // Ignore duplicate attribute. h.single_task( + // CHECK: SYCLIntelNoGlobalWorkOffsetAttr {{.*}} + // CHECK-NEXT: ConstantExpr {{.*}} 'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + []() [[intel::no_global_work_offset, + intel::no_global_work_offset]]{}); // OK + + // expected-error@+2{{integral constant expression must have integral or unscoped enumeration type, not 'const char [4]'}} + h.single_task( []() [[intel::no_global_work_offset("foo")]]{}); - h.single_task([]() { + h.single_task([]() { // expected-error@+1{{'no_global_work_offset' attribute only applies to functions}} [[intel::no_global_work_offset(1)]] int a; }); - h.single_task( + h.single_task( []() [[intel::no_global_work_offset(0), // expected-note {{previous attribute is here}} intel::no_global_work_offset(1)]]{}); // expected-warning{{attribute 'no_global_work_offset' is already applied with different arguments}} }); diff --git a/clang/test/SemaSYCL/loop_fusion.cpp b/clang/test/SemaSYCL/loop_fusion.cpp index 6305af9b989c4..e2e990846b2af 100644 --- a/clang/test/SemaSYCL/loop_fusion.cpp +++ b/clang/test/SemaSYCL/loop_fusion.cpp @@ -11,8 +11,7 @@ [[intel::loop_fuse(0, 1)]] void func3() {} // expected-error{{'loop_fuse' attribute takes no more than 1 argument}} [[intel::loop_fuse_independent(2, 3)]] void func4() {} // expected-error{{'loop_fuse_independent' attribute takes no more than 1 argument}} -// Tests for Intel FPGA loop attributes duplication -// No diagnostic is thrown since arguments match. Duplicate attribute is silently ignored. +// No diagnostic is emitted because the arguments match. Duplicate attribute is silently ignored. [[intel::loop_fuse]] [[intel::loop_fuse]] void func5() {} [[intel::loop_fuse_independent(10)]] [[intel::loop_fuse_independent(10)]] void func6() {} diff --git a/clang/test/SemaSYCL/loop_fusion_ast.cpp b/clang/test/SemaSYCL/loop_fusion_ast.cpp index 5523d6a770de1..72407b70b65eb 100644 --- a/clang/test/SemaSYCL/loop_fusion_ast.cpp +++ b/clang/test/SemaSYCL/loop_fusion_ast.cpp @@ -111,6 +111,26 @@ void foo() { // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1 h.single_task( []() [[intel::loop_fuse_independent]]{}); + + // Ignore duplicate attribute. + h.single_task( + // CHECK: FunctionDecl {{.*}}kernel_name_4 + // CHECK: SYCLIntelLoopFuseAttr {{.*}} loop_fuse + // CHECK-NEXT: ConstantExpr {{.*}} 'int' + // CHECK-NEXT: value: Int 3 + // CHECK-NEXT: IntegerLiteral{{.*}}3{{$}} + []() [[intel::loop_fuse(3), + intel::loop_fuse(3)]]{}); + + // Ignore duplicate attribute. + h.single_task( + // CHECK: FunctionDecl {{.*}}kernel_name_5 + // CHECK: SYCLIntelLoopFuseAttr {{.*}} loop_fuse_independent + // CHECK-NEXT: ConstantExpr {{.*}} 'int' + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + []() [[intel::loop_fuse_independent, + intel::loop_fuse_independent]]{}); }); func5<1>(); diff --git a/clang/test/SemaSYCL/num_simd_work_items_device.cpp b/clang/test/SemaSYCL/num_simd_work_items_device.cpp index 67be03c530de7..c0a378a34c04c 100644 --- a/clang/test/SemaSYCL/num_simd_work_items_device.cpp +++ b/clang/test/SemaSYCL/num_simd_work_items_device.cpp @@ -26,9 +26,11 @@ void foo() { }); } +// No diagnostic is emitted because the arguments match. [[intel::num_simd_work_items(12)]] void bar(); [[intel::num_simd_work_items(12)]] void bar() {} // OK +// Diagnostic is emitted because the arguments mismatch. [[intel::num_simd_work_items(12)]] void baz(); // expected-note {{previous attribute is here}} [[intel::num_simd_work_items(100)]] void baz(); // expected-warning {{attribute 'num_simd_work_items' is already applied with different parameters}} diff --git a/clang/test/SemaSYCL/reqd-sub-group-size-device.cpp b/clang/test/SemaSYCL/reqd-sub-group-size-device.cpp index a845061febdd9..73bee4228a5f9 100644 --- a/clang/test/SemaSYCL/reqd-sub-group-size-device.cpp +++ b/clang/test/SemaSYCL/reqd-sub-group-size-device.cpp @@ -10,9 +10,11 @@ queue q; // expected-note@-1 {{conflicting attribute is here}} [[intel::reqd_sub_group_size(32)]] void baz() {} // expected-note {{conflicting attribute is here}} +// No diagnostic is emitted because the arguments match. [[intel::reqd_sub_group_size(12)]] void bar(); [[intel::reqd_sub_group_size(12)]] void bar() {} // OK +// Diagnostic is emitted because the arguments mismatch. [[intel::reqd_sub_group_size(12)]] void quux(); // expected-note {{previous attribute is here}} [[intel::reqd_sub_group_size(100)]] void quux(); // expected-warning {{attribute 'reqd_sub_group_size' is already applied with different arguments}} diff --git a/clang/test/SemaSYCL/scheduler_target_fmax_mhz.cpp b/clang/test/SemaSYCL/scheduler_target_fmax_mhz.cpp index fc1444ee39437..984ceacd8b67e 100644 --- a/clang/test/SemaSYCL/scheduler_target_fmax_mhz.cpp +++ b/clang/test/SemaSYCL/scheduler_target_fmax_mhz.cpp @@ -6,9 +6,11 @@ [[intelfpga::scheduler_target_fmax_mhz(2)]] void func() {} +// No diagnostic is emitted because the arguments match. [[intel::scheduler_target_fmax_mhz(12)]] void bar(); [[intel::scheduler_target_fmax_mhz(12)]] void bar() {} // OK +// Diagnostic is emitted because the arguments mismatch. [[intel::scheduler_target_fmax_mhz(12)]] void baz(); // expected-note {{previous attribute is here}} [[intel::scheduler_target_fmax_mhz(100)]] void baz(); // expected-warning {{attribute 'scheduler_target_fmax_mhz' is already applied with different arguments}} diff --git a/clang/test/SemaSYCL/sycl-device-intel-fpga-no-global-work-offset.cpp b/clang/test/SemaSYCL/sycl-device-intel-fpga-no-global-work-offset.cpp index 799f274ac0cc5..ade25659d3cae 100644 --- a/clang/test/SemaSYCL/sycl-device-intel-fpga-no-global-work-offset.cpp +++ b/clang/test/SemaSYCL/sycl-device-intel-fpga-no-global-work-offset.cpp @@ -36,15 +36,18 @@ int main() { KernelFunctor<1>(); } +// No diagnostic is thrown since arguments match. Silently ignore duplicate attribute. [[intel::no_global_work_offset]] void func3 (); [[intel::no_global_work_offset(1)]] void func3() {} // OK [[intel::no_global_work_offset(0)]] void func4(); // expected-note {{previous attribute is here}} [[intel::no_global_work_offset]] void func4(); // expected-warning{{attribute 'no_global_work_offset' is already applied with different arguments}} +// No diagnostic is emitted because the arguments match. [[intel::no_global_work_offset(1)]] void func5(); [[intel::no_global_work_offset(1)]] void func5() {} // OK +// Diagnostic is emitted because the arguments mismatch. [[intel::no_global_work_offset(0)]] void func6(); // expected-note {{previous attribute is here}} [[intel::no_global_work_offset(1)]] void func6(); // expected-warning{{attribute 'no_global_work_offset' is already applied with different arguments}} @@ -73,6 +76,10 @@ int check() { return 0; } +// No diagnostic is emitted because the arguments match. Duplicate attribute is silently ignored. +[[intel::no_global_work_offset(1)]] +[[intel::no_global_work_offset(1)]] void func8() {} + // CHECK: FunctionDecl {{.*}} {{.*}} func6 'void ()' // CHECK: TemplateArgument integral 1 // CHECK: SYCLIntelNoGlobalWorkOffsetAttr {{.*}} @@ -81,3 +88,9 @@ int check() { // CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} // CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} + +// CHECK: FunctionDecl {{.*}} {{.*}} func8 'void ()' +// CHECK: SYCLIntelNoGlobalWorkOffsetAttr {{.*}} +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 1 +// CHECK-NEXT: IntegerLiteral{{.*}}1{{$}} diff --git a/clang/test/SemaSYCL/sycl-device-num_simd_work_items-template.cpp b/clang/test/SemaSYCL/sycl-device-num_simd_work_items-template.cpp index 3ed44721314e4..b9445054752f8 100644 --- a/clang/test/SemaSYCL/sycl-device-num_simd_work_items-template.cpp +++ b/clang/test/SemaSYCL/sycl-device-num_simd_work_items-template.cpp @@ -67,16 +67,19 @@ template [[intel::num_simd_work_items(N)]] void func4() {} // expected-warning {{attribute 'num_simd_work_items' is already applied with different arguments}} int check() { - // no error expected + // no error expected. func3<8>(); //expected-note@+1{{in instantiation of function template specialization 'func3<-1>' requested here}} func3<-1>(); - - func4<6>(); //expected-note {{in instantiation of function template specialization 'func4<6>' requested here}} - + //expected-note@+1 {{in instantiation of function template specialization 'func4<6>' requested here}} + func4<6>(); return 0; } +// No diagnostic is emitted because the arguments match. Duplicate attribute is silently ignored. +[[intel::num_simd_work_items(2)]] +[[intel::num_simd_work_items(2)]] void func5() {} + // CHECK: FunctionTemplateDecl {{.*}} {{.*}} func3 // CHECK: NonTypeTemplateParmDecl {{.*}} {{.*}} referenced 'int' depth 0 index 0 N // CHECK: FunctionDecl {{.*}} {{.*}} func3 'void ()' @@ -84,3 +87,9 @@ int check() { // CHECK: SubstNonTypeTemplateParmExpr {{.*}} // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} // CHECK-NEXT: IntegerLiteral{{.*}}8{{$}} + +// CHECK: FunctionDecl {{.*}} {{.*}} func5 'void ()' +// CHECK: SYCLIntelNumSimdWorkItemsAttr {{.*}} +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 2 +// CHECK-NEXT: IntegerLiteral{{.*}}2{{$}} diff --git a/clang/test/SemaSYCL/sycl-device-reqd-sub-group-size-template.cpp b/clang/test/SemaSYCL/sycl-device-reqd-sub-group-size-template.cpp index 29812d30608ce..90908b01ce2ad 100644 --- a/clang/test/SemaSYCL/sycl-device-reqd-sub-group-size-template.cpp +++ b/clang/test/SemaSYCL/sycl-device-reqd-sub-group-size-template.cpp @@ -71,12 +71,14 @@ int check() { func3<12>(); //expected-note@+1{{in instantiation of function template specialization 'func3<-1>' requested here}} func3<-1>(); - func4<6>(); //expected-note {{in instantiation of function template specialization 'func4<6>' requested here}} - return 0; } +// No diagnostic is emitted because the arguments match. Duplicate attribute is silently ignored. +[[intel::reqd_sub_group_size(8)]] +[[intel::reqd_sub_group_size(8)]] void func5() {} + // CHECK: FunctionTemplateDecl {{.*}} {{.*}} func3 // CHECK: NonTypeTemplateParmDecl {{.*}} {{.*}} referenced 'int' depth 0 index 0 N // CHECK: FunctionDecl {{.*}} {{.*}} func3 'void ()' @@ -84,3 +86,9 @@ int check() { // CHECK: SubstNonTypeTemplateParmExpr {{.*}} // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} // CHECK-NEXT: IntegerLiteral{{.*}}12{{$}} + +// CHECK: FunctionDecl {{.*}} {{.*}} func5 'void ()' +// CHECK: IntelReqdSubGroupSizeAttr {{.*}} +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 8 +// CHECK-NEXT: IntegerLiteral{{.*}}8{{$}} diff --git a/clang/test/SemaSYCL/sycl-device-scheduler_target_fmax_mhz-template.cpp b/clang/test/SemaSYCL/sycl-device-scheduler_target_fmax_mhz-template.cpp index ae3f1a5ff1302..407488f9bb0ae 100644 --- a/clang/test/SemaSYCL/sycl-device-scheduler_target_fmax_mhz-template.cpp +++ b/clang/test/SemaSYCL/sycl-device-scheduler_target_fmax_mhz-template.cpp @@ -75,6 +75,10 @@ int check() { return 0; } +// No diagnostic is emitted because the arguments match. Duplicate attribute is silently ignored. +[[intel::scheduler_target_fmax_mhz(8)]] +[[intel::scheduler_target_fmax_mhz(8)]] void func5() {} + // CHECK: FunctionDecl {{.*}} {{.*}} func3 'void ()' // CHECK: TemplateArgument integral 3 // CHECK: SYCLIntelSchedulerTargetFmaxMhzAttr {{.*}} @@ -83,3 +87,9 @@ int check() { // CHECK-NEXT: SubstNonTypeTemplateParmExpr {{.*}} // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}} // CHECK-NEXT: IntegerLiteral{{.*}}3{{$}} + +// CHECK: FunctionDecl {{.*}} {{.*}} func5 'void ()' +// CHECK: SYCLIntelSchedulerTargetFmaxMhzAttr {{.*}} +// CHECK-NEXT: ConstantExpr {{.*}} 'int' +// CHECK-NEXT: value: Int 8 +// CHECK-NEXT: IntegerLiteral{{.*}}8{{$}}