llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang <details> <summary>Changes</summary> Since SM_90 CUDA supports specifying additional argument to the launch_bounds attribute: maxBlocksPerCluster, to express the maximum number of CTAs that can be part of the cluster. See: https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#cluster-dimension-directives-maxclusterrank and https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#launch-bounds for details. -- Patch is 24.44 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66496.diff 13 Files Affected: - (modified) clang/include/clang/Basic/Attr.td (+2-1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+4) - (modified) clang/include/clang/Sema/Sema.h (+3-2) - (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+10-2) - (modified) clang/lib/Parse/ParseOpenMP.cpp (+2-1) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+39-7) - (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+9-1) - (modified) clang/test/CodeGenCUDA/launch-bounds.cu (+69) - (modified) clang/test/SemaCUDA/launch_bounds.cu (+3-1) - (added) clang/test/SemaCUDA/launch_bounds_sm_90.cu (+45) - (modified) llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp (+36-43) - (modified) llvm/lib/Target/NVPTX/NVPTXUtilities.cpp (+4) - (modified) llvm/lib/Target/NVPTX/NVPTXUtilities.h (+1) <pre> diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index c95db7e8049d47a..3c51261bd3eb081 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1267,7 +1267,8 @@ def CUDAInvalidTarget : InheritableAttr { def CUDALaunchBounds : InheritableAttr { let Spellings = [GNU&lt;&quot;launch_bounds&quot;&gt;, Declspec&lt;&quot;__launch_bounds__&quot;&gt;]; - let Args = [ExprArgument&lt;&quot;MaxThreads&quot;&gt;, ExprArgument&lt;&quot;MinBlocks&quot;, 1&gt;]; + let Args = [ExprArgument&lt;&quot;MaxThreads&quot;&gt;, ExprArgument&lt;&quot;MinBlocks&quot;, 1&gt;, + ExprArgument&lt;&quot;MaxBlocks&quot;, 1&gt;]; let LangOpts = [CUDA]; let Subjects = SubjectList&lt;[ObjCMethod, FunctionLike]&gt;; // An AST node is created for this attribute, but is not used by other parts diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0ac4df8edb242f6..088e3a45c7babba 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11836,6 +11836,10 @@ def err_sycl_special_type_num_init_method : Error&lt; &quot;types with &#x27;sycl_special_class&#x27; attribute must have one and only one &#x27;__init&#x27; &quot; &quot;method defined&quot;&gt;; +def warn_cuda_maxclusterrank_sm_90 : Warning&lt; + &quot;maxclusterrank requires sm_90 or higher, CUDA arch provided: %0, ignoring &quot; + &quot;%1 attribute&quot;&gt;, InGroup&lt;IgnoredAttributes&gt;; + def err_bit_int_bad_size : Error&lt;&quot;%select{signed|unsigned}0 _BitInt must &quot; &quot;have a bit size of at least %select{2|1}0&quot;&gt;; def err_bit_int_max_size : Error&lt;&quot;%select{signed|unsigned}0 _BitInt of bit &quot; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 47379e00a7445e3..dca7b66da3796d9 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11051,12 +11051,13 @@ class Sema final { /// Create an CUDALaunchBoundsAttr attribute. CUDALaunchBoundsAttr *CreateLaunchBoundsAttr(const AttributeCommonInfo &amp;CI, Expr *MaxThreads, - Expr *MinBlocks); + Expr *MinBlocks, + Expr *MaxBlocks); /// AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular /// declaration. void AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &amp;CI, - Expr *MaxThreads, Expr *MinBlocks); + Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks); /// AddModeAttr - Adds a mode attribute to a particular declaration. void AddModeAttr(Decl *D, const AttributeCommonInfo &amp;CI, IdentifierInfo *Name, diff --git a/clang/lib/CodeGen/Targets/NVPTX.cpp b/clang/lib/CodeGen/Targets/NVPTX.cpp index 0d4bbd795648008..64d019a10514d60 100644 --- a/clang/lib/CodeGen/Targets/NVPTX.cpp +++ b/clang/lib/CodeGen/Targets/NVPTX.cpp @@ -296,8 +296,8 @@ void CodeGenModule::handleCUDALaunchBoundsAttr( NVPTXTargetCodeGenInfo::addNVVMMetadata(F, &quot;maxntidx&quot;, MaxThreads.getExtValue()); - // min blocks is an optional argument for CUDALaunchBoundsAttr. If it was - // not specified in __launch_bounds__ or if the user specified a 0 value, + // min and max blocks is an optional argument for CUDALaunchBoundsAttr. If it + // was not specified in __launch_bounds__ or if the user specified a 0 value, // we don&#x27;t have to add a PTX directive. if (Attr-&gt;getMinBlocks()) { llvm::APSInt MinBlocks(32); @@ -307,6 +307,14 @@ void CodeGenModule::handleCUDALaunchBoundsAttr( NVPTXTargetCodeGenInfo::addNVVMMetadata(F, &quot;minctasm&quot;, MinBlocks.getExtValue()); } + if (Attr-&gt;getMaxBlocks()) { + llvm::APSInt MaxBlocks(32); + MaxBlocks = Attr-&gt;getMaxBlocks()-&gt;EvaluateKnownConstInt(getContext()); + if (MaxBlocks &gt; 0) + // Create !{&lt;func-ref&gt;, metadata !&quot;maxclusterrank&quot;, i32 &lt;val&gt;} node + NVPTXTargetCodeGenInfo::addNVVMMetadata(F, &quot;maxclusterrank&quot;, + MaxBlocks.getExtValue()); + } } std::unique_ptr&lt;TargetCodeGenInfo&gt; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 605b97617432ed3..8a8a126bf7244d4 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -3739,7 +3739,8 @@ OMPClause *Parser::ParseOpenMPOMPXAttributesClause(bool ParseOnly) { continue; if (auto *A = Actions.CreateLaunchBoundsAttr( PA, PA.getArgAsExpr(0), - PA.getNumArgs() &gt; 1 ? PA.getArgAsExpr(1) : nullptr)) + PA.getNumArgs() &gt; 1 ? PA.getArgAsExpr(1) : nullptr, + PA.getNumArgs() &gt; 2 ? PA.getArgAsExpr(2) : nullptr)) Attrs.push_back(A); continue; default: diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index cc98713241395ec..e62a0d4fc29f9cd 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5607,6 +5607,21 @@ bool Sema::CheckRegparmAttr(const ParsedAttr &amp;AL, unsigned &amp;numParams) { return false; } +// Helper to get CudaArch. +static CudaArch getCudaArch(const TargetInfo &amp;TI) { + if (!TI.hasFeature(&quot;ptx&quot;)) { + return CudaArch::UNKNOWN; + } + for (const auto &amp;Feature : TI.getTargetOpts().FeatureMap) { + if (Feature.getValue()) { + CudaArch Arch = StringToCudaArch(Feature.getKey()); + if (Arch != CudaArch::UNKNOWN) + return Arch; + } + } + return CudaArch::UNKNOWN; +} + // Checks whether an argument of launch_bounds attribute is // acceptable, performs implicit conversion to Rvalue, and returns // non-nullptr Expr result on success. Otherwise, it returns nullptr @@ -5650,8 +5665,8 @@ static Expr *makeLaunchBoundsArgExpr(Sema &amp;S, Expr *E, CUDALaunchBoundsAttr * Sema::CreateLaunchBoundsAttr(const AttributeCommonInfo &amp;CI, Expr *MaxThreads, - Expr *MinBlocks) { - CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks); + Expr *MinBlocks, Expr *MaxBlocks) { + CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks); MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0); if (MaxThreads == nullptr) return nullptr; @@ -5662,22 +5677,39 @@ Sema::CreateLaunchBoundsAttr(const AttributeCommonInfo &amp;CI, Expr *MaxThreads, return nullptr; } + if (MaxBlocks) { + // Feature &#x27;.maxclusterrank&#x27; requires .target sm_90 or higher. + auto SM = getCudaArch(Context.getTargetInfo()); + if (SM == CudaArch::UNKNOWN || SM &lt; CudaArch::SM_90) { + Diag(MaxBlocks-&gt;getBeginLoc(), diag::warn_cuda_maxclusterrank_sm_90) + &lt;&lt; CudaArchToString(SM) &lt;&lt; CI &lt;&lt; MaxBlocks-&gt;getSourceRange(); + // Ignore it by setting MaxBlocks to null; + MaxBlocks = nullptr; + } else { + MaxBlocks = makeLaunchBoundsArgExpr(*this, MaxBlocks, TmpAttr, 2); + if (MaxBlocks == nullptr) + return nullptr; + } + } + return ::new (Context) - CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks); + CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks); } void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &amp;CI, - Expr *MaxThreads, Expr *MinBlocks) { - if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks)) + Expr *MaxThreads, Expr *MinBlocks, + Expr *MaxBlocks) { + if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks, MaxBlocks)) D-&gt;addAttr(Attr); } static void handleLaunchBoundsAttr(Sema &amp;S, Decl *D, const ParsedAttr &amp;AL) { - if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 2)) + if (!AL.checkAtLeastNumArgs(S, 1) || !AL.checkAtMostNumArgs(S, 3)) return; S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0), - AL.getNumArgs() &gt; 1 ? AL.getArgAsExpr(1) : nullptr); + AL.getNumArgs() &gt; 1 ? AL.getArgAsExpr(1) : nullptr, + AL.getNumArgs() &gt; 2 ? AL.getArgAsExpr(2) : nullptr); } static void handleArgumentWithTypeTagAttr(Sema &amp;S, Decl *D, diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 37a7d6204413a38..3f7268f5450a6fa 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -302,7 +302,15 @@ static void instantiateDependentCUDALaunchBoundsAttr( MinBlocks = Result.getAs&lt;Expr&gt;(); } - S.AddLaunchBoundsAttr(New, Attr, MaxThreads, MinBlocks); + Expr *MaxBlocks = nullptr; + if (Attr.getMaxBlocks()) { + Result = S.SubstExpr(Attr.getMaxBlocks(), TemplateArgs); + if (Result.isInvalid()) + return; + MaxBlocks = Result.getAs&lt;Expr&gt;(); + } + + S.AddLaunchBoundsAttr(New, Attr, MaxThreads, MinBlocks, MaxBlocks); } static void diff --git a/clang/test/CodeGenCUDA/launch-bounds.cu b/clang/test/CodeGenCUDA/launch-bounds.cu index 58bcc410201f35f..31ca9216b413e92 100644 --- a/clang/test/CodeGenCUDA/launch-bounds.cu +++ b/clang/test/CodeGenCUDA/launch-bounds.cu @@ -1,9 +1,13 @@ // RUN: %clang_cc1 %s -triple nvptx-unknown-unknown -fcuda-is-device -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple nvptx-unknown-unknown -target-cpu sm_90 -DUSE_MAX_BLOCKS -fcuda-is-device -emit-llvm -o - | FileCheck -check-prefix=CHECK_MAX_BLOCKS %s #include &quot;Inputs/cuda.h&quot; #define MAX_THREADS_PER_BLOCK 256 #define MIN_BLOCKS_PER_MP 2 +#ifdef USE_MAX_BLOCKS +#define MAX_BLOCKS_PER_MP 4 +#endif // Test both max threads per block and Min cta per sm. extern &quot;C&quot; { @@ -17,6 +21,21 @@ Kernel1() // CHECK: !{{[0-9]+}} = !{ptr @Kernel1, !&quot;maxntidx&quot;, i32 256} // CHECK: !{{[0-9]+}} = !{ptr @Kernel1, !&quot;minctasm&quot;, i32 2} +#ifdef USE_MAX_BLOCKS +// Test max threads per block and min/max cta per sm. +extern &quot;C&quot; { +__global__ void +__launch_bounds__( MAX_THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP, MAX_BLOCKS_PER_MP ) +Kernel1_sm_90() +{ +} +} + +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @Kernel1_sm_90, !&quot;maxntidx&quot;, i32 256} +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @Kernel1_sm_90, !&quot;minctasm&quot;, i32 2} +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @Kernel1_sm_90, !&quot;maxclusterrank&quot;, i32 4} +#endif // USE_MAX_BLOCKS + // Test only max threads per block. Min cta per sm defaults to 0, and // CodeGen doesn&#x27;t output a zero value for minctasm. extern &quot;C&quot; { @@ -50,6 +69,20 @@ template __global__ void Kernel4&lt;MAX_THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP&gt;(); // CHECK: !{{[0-9]+}} = !{ptr @{{.*}}Kernel4{{.*}}, !&quot;maxntidx&quot;, i32 256} // CHECK: !{{[0-9]+}} = !{ptr @{{.*}}Kernel4{{.*}}, !&quot;minctasm&quot;, i32 2} +#ifdef USE_MAX_BLOCKS +template &lt;int max_threads_per_block, int min_blocks_per_mp, int max_blocks_per_mp&gt; +__global__ void +__launch_bounds__(max_threads_per_block, min_blocks_per_mp, max_blocks_per_mp) +Kernel4_sm_90() +{ +} +template __global__ void Kernel4_sm_90&lt;MAX_THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP, MAX_BLOCKS_PER_MP&gt;(); + +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel4_sm_90{{.*}}, !&quot;maxntidx&quot;, i32 256} +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel4_sm_90{{.*}}, !&quot;minctasm&quot;, i32 2} +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel4_sm_90{{.*}}, !&quot;maxclusterrank&quot;, i32 4} +#endif //USE_MAX_BLOCKS + const int constint = 100; template &lt;int max_threads_per_block, int min_blocks_per_mp&gt; __global__ void @@ -63,6 +96,23 @@ template __global__ void Kernel5&lt;MAX_THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP&gt;(); // CHECK: !{{[0-9]+}} = !{ptr @{{.*}}Kernel5{{.*}}, !&quot;maxntidx&quot;, i32 356} // CHECK: !{{[0-9]+}} = !{ptr @{{.*}}Kernel5{{.*}}, !&quot;minctasm&quot;, i32 258} +#ifdef USE_MAX_BLOCKS + +template &lt;int max_threads_per_block, int min_blocks_per_mp, int max_blocks_per_mp&gt; +__global__ void +__launch_bounds__(max_threads_per_block + constint, + min_blocks_per_mp + max_threads_per_block, + max_blocks_per_mp + max_threads_per_block) +Kernel5_sm_90() +{ +} +template __global__ void Kernel5_sm_90&lt;MAX_THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP, MAX_BLOCKS_PER_MP&gt;(); + +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel5_sm_90{{.*}}, !&quot;maxntidx&quot;, i32 356} +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel5_sm_90{{.*}}, !&quot;minctasm&quot;, i32 258} +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel5_sm_90{{.*}}, !&quot;maxclusterrank&quot;, i32 260} +#endif //USE_MAX_BLOCKS + // Make sure we don&#x27;t emit negative launch bounds values. __global__ void __launch_bounds__( -MAX_THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP ) @@ -80,7 +130,26 @@ Kernel7() // CHECK: !{{[0-9]+}} = !{ptr @{{.*}}Kernel7{{.*}}, !&quot;maxntidx&quot;, // CHECK-NOT: !{{[0-9]+}} = !{ptr @{{.*}}Kernel7{{.*}}, !&quot;minctasm&quot;, +#ifdef USE_MAX_BLOCKS +__global__ void +__launch_bounds__( MAX_THREADS_PER_BLOCK, -MIN_BLOCKS_PER_MP, -MAX_BLOCKS_PER_MP ) +Kernel7_sm_90() +{ +} +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel7_sm_90{{.*}}, !&quot;maxntidx&quot;, +// CHECK_MAX_BLOCKS-NOT: !{{[0-9]+}} = !{ptr @{{.*}}Kernel7_sm_90{{.*}}, !&quot;minctasm&quot;, +// CHECK_MAX_BLOCKS-NOT: !{{[0-9]+}} = !{ptr @{{.*}}Kernel7_sm_90{{.*}}, !&quot;maxclusterrank&quot;, +#endif // USE_MAX_BLOCKS + const char constchar = 12; __global__ void __launch_bounds__(constint, constchar) Kernel8() {} // CHECK: !{{[0-9]+}} = !{ptr @{{.*}}Kernel8{{.*}}, !&quot;maxntidx&quot;, i32 100 // CHECK: !{{[0-9]+}} = !{ptr @{{.*}}Kernel8{{.*}}, !&quot;minctasm&quot;, i32 12 + +#ifdef USE_MAX_BLOCKS +const char constchar_2 = 14; +__global__ void __launch_bounds__(constint, constchar, constchar_2) Kernel8_sm_90() {} +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel8_sm_90{{.*}}, !&quot;maxntidx&quot;, i32 100 +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel8_sm_90{{.*}}, !&quot;minctasm&quot;, i32 12 +// CHECK_MAX_BLOCKS: !{{[0-9]+}} = !{ptr @{{.*}}Kernel8_sm_90{{.*}}, !&quot;maxclusterrank&quot;, i32 14 +#endif // USE_MAX_BLOCKS diff --git a/clang/test/SemaCUDA/launch_bounds.cu b/clang/test/SemaCUDA/launch_bounds.cu index 0ca0c0145d8bbb6..b1f29480da30c65 100644 --- a/clang/test/SemaCUDA/launch_bounds.cu +++ b/clang/test/SemaCUDA/launch_bounds.cu @@ -12,7 +12,7 @@ __launch_bounds__(0x10000000000000000) void TestWayTooBigArg(void); // expected- __launch_bounds__(-128, 7) void TestNegArg1(void); // expected-warning {{&#x27;launch_bounds&#x27; attribute parameter 0 is negative and will be ignored}} __launch_bounds__(128, -7) void TestNegArg2(void); // expected-warning {{&#x27;launch_bounds&#x27; attribute parameter 1 is negative and will be ignored}} -__launch_bounds__(1, 2, 3) void Test3Args(void); // expected-error {{&#x27;launch_bounds&#x27; attribute takes no more than 2 arguments}} +__launch_bounds__(1, 2, 3, 4) void Test4Args(void); // expected-error {{&#x27;launch_bounds&#x27; attribute takes no more than 3 arguments}} __launch_bounds__() void TestNoArgs(void); // expected-error {{&#x27;launch_bounds&#x27; attribute takes at least 1 argument}} int TestNoFunction __launch_bounds__(128, 7); // expected-warning {{&#x27;launch_bounds&#x27; attribute only applies to Objective-C methods, functions, and function pointers}} @@ -47,3 +47,5 @@ __launch_bounds__(Args) void TestTemplateVariadicArgs(void) {} // expected-error template &lt;int... Args&gt; __launch_bounds__(1, Args) void TestTemplateVariadicArgs2(void) {} // expected-error {{expression contains unexpanded parameter pack &#x27;Args&#x27;}} + +__launch_bounds__(1, 2, 3) void Test3Args(void); // expected-warning {{maxclusterrank requires sm_90 or higher, CUDA arch provided: unknown, ignoring &#x27;launch_bounds&#x27; attribute}} diff --git a/clang/test/SemaCUDA/launch_bounds_sm_90.cu b/clang/test/SemaCUDA/launch_bounds_sm_90.cu new file mode 100644 index 000000000000000..6b2369983b74fbb --- /dev/null +++ b/clang/test/SemaCUDA/launch_bounds_sm_90.cu @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -triple nvptx-unknown-unknown -target-cpu sm_90 -verify %s + +#include &quot;Inputs/cuda.h&quot; + +__launch_bounds__(128, 7) void Test2Args(void); +__launch_bounds__(128) void Test1Arg(void); + +__launch_bounds__(0xffffffff) void TestMaxArg(void); +__launch_bounds__(0x100000000) void TestTooBigArg(void); // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}} +__launch_bounds__(0x10000000000000000) void TestWayTooBigArg(void); // expected-error {{integer literal is too large to be represented in any integer type}} +__launch_bounds__(1, 1, 0x10000000000000000) void TestWayTooBigArg(void); // expected-error {{integer literal is too large to be represented in any integer type}} + +__launch_bounds__(-128, 7) void TestNegArg1(void); // expected-warning {{&#x27;launch_bounds&#x27; attribute parameter 0 is negative and will be ignored}} +__launch_bounds__(128, -7) void TestNegArg2(void); // expected-warning {{&#x27;launch_bounds&#x27; attribute parameter 1 is negative and will be ignored}} +__launch_bounds__(128, 1, -7) void TestNegArg2(void); // expected-warning {{&#x27;launch_bounds&#x27; attribute parameter 2 is negative and will be ignored}} + + +__launch_bounds__(1, 2, 3, 4) void Test4Args(void); // expected-error {{&#x27;launch_bounds&#x27; attribute takes no more than 3 arguments}} +__launch_bounds__() void TestNoArgs(void); // expected-error {{&#x27;launch_bounds&#x27; attribute takes at least 1 argument}} + +int TestNoFunction __launch_bounds__(128, 7, 13); // expected-warning {{&#x27;launch_bounds&#x27; attribute only applies to Objective-C methods, functions, and function pointers}} + +__launch_bounds__(true) void TestBool(void); +__launch_bounds__(128, 1, 128.0) void TestFP(void); // expected-error {{&#x27;launch_bounds&#x27; attribute requires parameter 2 to be an integer constant}} +__launch_bounds__(128, 1, (void*)0) void TestNullptr(void); // expected-error {{&#x27;launch_bounds&#x27; ... <truncated> </pre> </details> https://github.com/llvm/llvm-project/pull/66496 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits