Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-25 Thread Konstantin Zhuravlyov via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL282371: [AMDGPU] Expose flat work group size, register and 
wave control attributes (authored by kzhuravl).

Changed prior to commit:
  https://reviews.llvm.org/D24513?vs=71970=72436#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D24513

Files:
  cfe/trunk/include/clang/Basic/Attr.td
  cfe/trunk/include/clang/Basic/AttrDocs.td
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/lib/CodeGen/TargetInfo.cpp
  cfe/trunk/lib/Sema/SemaDeclAttr.cpp
  cfe/trunk/test/CodeGenOpenCL/amdgpu-attrs.cl
  cfe/trunk/test/CodeGenOpenCL/amdgpu-num-gpr-attr.cl
  cfe/trunk/test/SemaCUDA/amdgpu-attrs.cu
  cfe/trunk/test/SemaCUDA/amdgpu-num-gpr-attr.cu
  cfe/trunk/test/SemaOpenCL/amdgpu-attrs.cl
  cfe/trunk/test/SemaOpenCL/amdgpu-num-register-attrs.cl

Index: cfe/trunk/include/clang/Basic/Attr.td
===
--- cfe/trunk/include/clang/Basic/Attr.td
+++ cfe/trunk/include/clang/Basic/Attr.td
@@ -1050,24 +1050,37 @@
 //
 // FIXME: This provides a sub-optimal error message if you attempt to
 // use this in CUDA, since CUDA does not use the same terminology.
-def AMDGPUNumVGPR : InheritableAttr {
-  let Spellings = [GNU<"amdgpu_num_vgpr">];
-  let Args = [UnsignedArgument<"NumVGPR">];
-  let Documentation = [AMDGPUNumVGPRDocs];
-
-// FIXME: This should be for OpenCLKernelFunction, but is not to
+//
+// FIXME: SubjectList should be for OpenCLKernelFunction, but is not to
 // workaround needing to see kernel attribute before others to know if
 // this should be rejected on non-kernels.
-  let Subjects = SubjectList<[Function], ErrorDiag,
- "ExpectedKernelFunction">;
+
+def AMDGPUFlatWorkGroupSize : InheritableAttr {
+  let Spellings = [GNU<"amdgpu_flat_work_group_size">];
+  let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max">];
+  let Documentation = [AMDGPUFlatWorkGroupSizeDocs];
+  let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+}
+
+def AMDGPUWavesPerEU : InheritableAttr {
+  let Spellings = [GNU<"amdgpu_waves_per_eu">];
+  let Args = [UnsignedArgument<"Min">, UnsignedArgument<"Max", 1>];
+  let Documentation = [AMDGPUWavesPerEUDocs];
+  let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
 }
 
 def AMDGPUNumSGPR : InheritableAttr {
   let Spellings = [GNU<"amdgpu_num_sgpr">];
   let Args = [UnsignedArgument<"NumSGPR">];
-  let Documentation = [AMDGPUNumSGPRDocs];
-  let Subjects = SubjectList<[Function], ErrorDiag,
-  "ExpectedKernelFunction">;
+  let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
+  let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
+}
+
+def AMDGPUNumVGPR : InheritableAttr {
+  let Spellings = [GNU<"amdgpu_num_vgpr">];
+  let Args = [UnsignedArgument<"NumVGPR">];
+  let Documentation = [AMDGPUNumSGPRNumVGPRDocs];
+  let Subjects = SubjectList<[Function], ErrorDiag, "ExpectedKernelFunction">;
 }
 
 def NoSplitStack : InheritableAttr {
Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2382,6 +2382,9 @@
   "'%0' parameter must have pointer%select{| to unqualified pointer}1 type; "
   "type here is %2">;
 
+def err_attribute_argument_invalid : Error<
+  "%0 attribute argument is invalid: %select{max must be 0 since min is 0|"
+  "min must not be greater than max}1">;
 def err_attribute_argument_is_zero : Error<
   "%0 attribute must be greater than 0">;
 def warn_attribute_argument_n_negative : Warning<
Index: cfe/trunk/include/clang/Basic/AttrDocs.td
===
--- cfe/trunk/include/clang/Basic/AttrDocs.td
+++ cfe/trunk/include/clang/Basic/AttrDocs.td
@@ -889,12 +889,12 @@
 enumerator, a non-static data member, or a label.
 
 .. code-block: c++
-  #include 
-
-  [[maybe_unused]] void f([[maybe_unused]] bool thing1,
-  [[maybe_unused]] bool thing2) {
-[[maybe_unused]] bool b = thing1 && thing2;
-assert(b);
+  #include 
+
+  [[maybe_unused]] void f([[maybe_unused]] bool thing1,
+  [[maybe_unused]] bool thing2) {
+[[maybe_unused]] bool b = thing1 && thing2;
+assert(b);
   }
   }];
 }
@@ -911,15 +911,15 @@
 `void`.
 
 .. code-block: c++
-  struct [[nodiscard]] error_info { /*...*/ };
-  error_info enable_missile_safety_mode();
-  
-  void launch_missiles();
-  void test_missiles() {
-enable_missile_safety_mode(); // diagnoses
-launch_missiles();
-  }
-  error_info ();
+  struct [[nodiscard]] error_info { /*...*/ };
+  error_info enable_missile_safety_mode();
+  
+  void launch_missiles();
+  void test_missiles() {
+enable_missile_safety_mode(); // diagnoses
+launch_missiles();
+  }
+  

Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-22 Thread Tom Stellard via cfe-commits
tstellarAMD accepted this revision.
tstellarAMD added a comment.

LGTM.


https://reviews.llvm.org/D24513



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-21 Thread Konstantin Zhuravlyov via cfe-commits
kzhuravl added a comment.

Thanks for the review Aaron!

Tom, would you be able to do a final glance over?


https://reviews.llvm.org/D24513



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-21 Thread Aaron Ballman via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM, thank you!


https://reviews.llvm.org/D24513



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-20 Thread Konstantin Zhuravlyov via cfe-commits
kzhuravl added inline comments.


Comment at: lib/Sema/SemaDeclAttr.cpp:4967
@@ +4966,3 @@
+
+  D->addAttr(::new (S.Context)
+ AMDGPUFlatWorkGroupSizeAttr(Attr.getLoc(), S.Context, Min, Max,

aaron.ballman wrote:
> Is it okay to supply `0, 0` as the min, max arguments?
Yes, I mentioned `0, 0` case in the docs.


Comment at: lib/Sema/SemaDeclAttr.cpp:4997
@@ +4996,3 @@
+
+  D->addAttr(::new (S.Context)
+ AMDGPUWavesPerEUAttr(Attr.getLoc(), S.Context, Min, Max,

aaron.ballman wrote:
> Is it okay to supply `0, 0` as the min, max arguments?
Yes, I mentioned `0, 0` case in the docs.


Comment at: lib/Sema/SemaDeclAttr.cpp:6039-6043
@@ -5976,3 +6038,7 @@
   D->setInvalidDecl();
-} else if (Attr *A = D->getAttr()) {
+} else if (Attr *A = D->getAttr()) {
+  Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
+<< A << ExpectedKernelFunction;
+  D->setInvalidDecl();
+} else if (Attr *A = D->getAttr()) {
   Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)

aaron.ballman wrote:
> Yes, totally fine to be a follow-up patch. I was hoping it would look 
> something like (we can bikeshed the name):
> ```
> def SomeAttr {
>   /* Blah */
> }
> 
> def SomeOtherAttr {
>   let RequiredCompanionAttributes = [SomeAttr];
> }
> ```
This seems like a good start. Thanks :)


https://reviews.llvm.org/D24513



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-20 Thread Konstantin Zhuravlyov via cfe-commits
kzhuravl updated this revision to Diff 71970.
kzhuravl added a comment.
Herald added a subscriber: kzhuravl.

Mention `0, 0` case in the docs.


https://reviews.llvm.org/D24513

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/TargetInfo.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGenOpenCL/amdgpu-attrs.cl
  test/CodeGenOpenCL/amdgpu-num-gpr-attr.cl
  test/SemaCUDA/amdgpu-attrs.cu
  test/SemaCUDA/amdgpu-num-gpr-attr.cu
  test/SemaOpenCL/amdgpu-attrs.cl
  test/SemaOpenCL/amdgpu-num-register-attrs.cl

Index: test/SemaOpenCL/amdgpu-num-register-attrs.cl
===
--- test/SemaOpenCL/amdgpu-num-register-attrs.cl
+++ test/SemaOpenCL/amdgpu-num-register-attrs.cl
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -triple r600-- -verify -fsyntax-only %s
-
-typedef __attribute__((amdgpu_num_vgpr(128))) struct FooStruct { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-  int x;
-  float y;
-} FooStruct;
-
-
-__attribute__((amdgpu_num_vgpr("ABC"))) kernel void foo2() {} // expected-error {{'amdgpu_num_vgpr' attribute requires an integer constant}}
-__attribute__((amdgpu_num_sgpr("ABC"))) kernel void foo3() {} // expected-error {{'amdgpu_num_sgpr' attribute requires an integer constant}}
-
-
-__attribute__((amdgpu_num_vgpr(40))) void foo4() {} // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-__attribute__((amdgpu_num_sgpr(64))) void foo5() {} // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
-
-__attribute__((amdgpu_num_vgpr(40))) kernel void foo7() {}
-__attribute__((amdgpu_num_sgpr(64))) kernel void foo8() {}
-__attribute__((amdgpu_num_vgpr(40), amdgpu_num_sgpr(64))) kernel void foo9() {}
-
-// Check 0 VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0))) kernel void foo10() {}
-
-// Check 0 SGPR is accepted.
-__attribute__((amdgpu_num_sgpr(0))) kernel void foo11() {}
-
-// Check both 0 SGPR and VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0), amdgpu_num_sgpr(0))) kernel void foo12() {}
-
-// Too large VGPR value.
-__attribute__((amdgpu_num_vgpr(4294967296))) kernel void foo13() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296))) kernel void foo14() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296), amdgpu_num_vgpr(4294967296))) kernel void foo15() {} // expected-error 2 {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-
-// Make sure it is accepted with kernel keyword before the attribute.
-kernel __attribute__((amdgpu_num_vgpr(40))) void foo16() {}
-
-kernel __attribute__((amdgpu_num_sgpr(40))) void foo17() {}
Index: test/SemaOpenCL/amdgpu-attrs.cl
===
--- test/SemaOpenCL/amdgpu-attrs.cl
+++ test/SemaOpenCL/amdgpu-attrs.cl
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -triple amdgcn-- -verify -fsyntax-only %s
+
+typedef __attribute__((amdgpu_flat_work_group_size(32, 64))) struct struct_flat_work_group_size_32_64 { // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_flat_work_group_size_32_64;
+typedef __attribute__((amdgpu_waves_per_eu(2))) struct struct_waves_per_eu_2 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2;
+typedef __attribute__((amdgpu_waves_per_eu(2, 4))) struct struct_waves_per_eu_2_4 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2_4;
+typedef __attribute__((amdgpu_num_sgpr(32))) struct struct_num_sgpr_32 { // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_sgpr_32;
+typedef __attribute__((amdgpu_num_vgpr(64))) struct struct_num_vgpr_64 { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_vgpr_64;
+
+__attribute__((amdgpu_flat_work_group_size(32, 64))) void func_flat_work_group_size_32_64() {} // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+__attribute__((amdgpu_waves_per_eu(2))) void func_waves_per_eu_2() {} // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+__attribute__((amdgpu_waves_per_eu(2, 4))) void func_waves_per_eu_2_4() {} // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+__attribute__((amdgpu_num_sgpr(32))) void func_num_sgpr_32() {} // expected-error 

Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-15 Thread Aaron Ballman via cfe-commits
aaron.ballman added inline comments.


Comment at: lib/Sema/SemaDeclAttr.cpp:4967
@@ +4966,3 @@
+
+  D->addAttr(::new (S.Context)
+ AMDGPUFlatWorkGroupSizeAttr(Attr.getLoc(), S.Context, Min, Max,

Is it okay to supply `0, 0` as the min, max arguments?


Comment at: lib/Sema/SemaDeclAttr.cpp:4997
@@ +4996,3 @@
+
+  D->addAttr(::new (S.Context)
+ AMDGPUWavesPerEUAttr(Attr.getLoc(), S.Context, Min, Max,

Is it okay to supply `0, 0` as the min, max arguments?


Comment at: lib/Sema/SemaDeclAttr.cpp:6039-6043
@@ -5976,3 +6038,7 @@
   D->setInvalidDecl();
-} else if (Attr *A = D->getAttr()) {
+} else if (Attr *A = D->getAttr()) {
+  Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
+<< A << ExpectedKernelFunction;
+  D->setInvalidDecl();
+} else if (Attr *A = D->getAttr()) {
   Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)

Yes, totally fine to be a follow-up patch. I was hoping it would look something 
like (we can bikeshed the name):
```
def SomeAttr {
  /* Blah */
}

def SomeOtherAttr {
  let RequiredCompanionAttributes = [SomeAttr];
}
```


https://reviews.llvm.org/D24513



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-14 Thread Konstantin Zhuravlyov via cfe-commits
kzhuravl added inline comments.


Comment at: include/clang/Basic/Attr.td:1067
@@ +1066,3 @@
+  let Spellings = [GNU<"amdgpu_waves_per_eu">];
+  let Args = [UnsignedArgument<"Min">, VariadicUnsignedArgument<"Max">];
+  let Documentation = [AMDGPUWavesPerEUDocs];

aaron.ballman wrote:
> Looking at the documentation, are you sure this should be a 
> `VariadicUnsignedArgument`? It seems like this should be an 
> `UnsignedArgument` with the optional bit set. Or can you pass multiple Max 
> values?
You are right. Switched to UnsignedArgument since only one Max is allowed. 
Thanks.


Comment at: lib/Sema/SemaDeclAttr.cpp:6048
@@ -5976,2 +6047,3 @@
   D->setInvalidDecl();
-} else if (Attr *A = D->getAttr()) {
+} else if (Attr *A = D->getAttr()) {
+  Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)

aaron.ballman wrote:
> This list is getting to the point where we really need to start handling this 
> in Attr.td soon. Are you planning to work on more AMDGPU attributes in the 
> near future?
I agree, and yes, few more attributes will need to be added in the near future. 
Would it be ok if I change it to start handling in Attr.td after this change, 
but before other attributes are added?


https://reviews.llvm.org/D24513



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-14 Thread Konstantin Zhuravlyov via cfe-commits
kzhuravl updated this revision to Diff 71449.
kzhuravl marked 15 inline comments as done.
kzhuravl added a comment.

Address review feedback


https://reviews.llvm.org/D24513

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/TargetInfo.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGenOpenCL/amdgpu-attrs.cl
  test/CodeGenOpenCL/amdgpu-num-gpr-attr.cl
  test/SemaCUDA/amdgpu-attrs.cu
  test/SemaCUDA/amdgpu-num-gpr-attr.cu
  test/SemaOpenCL/amdgpu-attrs.cl
  test/SemaOpenCL/amdgpu-num-register-attrs.cl

Index: test/SemaOpenCL/amdgpu-num-register-attrs.cl
===
--- test/SemaOpenCL/amdgpu-num-register-attrs.cl
+++ test/SemaOpenCL/amdgpu-num-register-attrs.cl
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -triple r600-- -verify -fsyntax-only %s
-
-typedef __attribute__((amdgpu_num_vgpr(128))) struct FooStruct { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-  int x;
-  float y;
-} FooStruct;
-
-
-__attribute__((amdgpu_num_vgpr("ABC"))) kernel void foo2() {} // expected-error {{'amdgpu_num_vgpr' attribute requires an integer constant}}
-__attribute__((amdgpu_num_sgpr("ABC"))) kernel void foo3() {} // expected-error {{'amdgpu_num_sgpr' attribute requires an integer constant}}
-
-
-__attribute__((amdgpu_num_vgpr(40))) void foo4() {} // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-__attribute__((amdgpu_num_sgpr(64))) void foo5() {} // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
-
-__attribute__((amdgpu_num_vgpr(40))) kernel void foo7() {}
-__attribute__((amdgpu_num_sgpr(64))) kernel void foo8() {}
-__attribute__((amdgpu_num_vgpr(40), amdgpu_num_sgpr(64))) kernel void foo9() {}
-
-// Check 0 VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0))) kernel void foo10() {}
-
-// Check 0 SGPR is accepted.
-__attribute__((amdgpu_num_sgpr(0))) kernel void foo11() {}
-
-// Check both 0 SGPR and VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0), amdgpu_num_sgpr(0))) kernel void foo12() {}
-
-// Too large VGPR value.
-__attribute__((amdgpu_num_vgpr(4294967296))) kernel void foo13() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296))) kernel void foo14() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296), amdgpu_num_vgpr(4294967296))) kernel void foo15() {} // expected-error 2 {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-
-// Make sure it is accepted with kernel keyword before the attribute.
-kernel __attribute__((amdgpu_num_vgpr(40))) void foo16() {}
-
-kernel __attribute__((amdgpu_num_sgpr(40))) void foo17() {}
Index: test/SemaOpenCL/amdgpu-attrs.cl
===
--- test/SemaOpenCL/amdgpu-attrs.cl
+++ test/SemaOpenCL/amdgpu-attrs.cl
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -triple amdgcn-- -verify -fsyntax-only %s
+
+typedef __attribute__((amdgpu_flat_work_group_size(32, 64))) struct struct_flat_work_group_size_32_64 { // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_flat_work_group_size_32_64;
+typedef __attribute__((amdgpu_waves_per_eu(2))) struct struct_waves_per_eu_2 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2;
+typedef __attribute__((amdgpu_waves_per_eu(2, 4))) struct struct_waves_per_eu_2_4 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2_4;
+typedef __attribute__((amdgpu_num_sgpr(32))) struct struct_num_sgpr_32 { // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_sgpr_32;
+typedef __attribute__((amdgpu_num_vgpr(64))) struct struct_num_vgpr_64 { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_vgpr_64;
+
+__attribute__((amdgpu_flat_work_group_size(32, 64))) void func_flat_work_group_size_32_64() {} // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+__attribute__((amdgpu_waves_per_eu(2))) void func_waves_per_eu_2() {} // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+__attribute__((amdgpu_waves_per_eu(2, 4))) void func_waves_per_eu_2_4() {} // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+__attribute__((amdgpu_num_sgpr(32))) void func_num_sgpr_32() {} // expected-error 

Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-14 Thread Aaron Ballman via cfe-commits
aaron.ballman requested changes to this revision.
This revision now requires changes to proceed.


Comment at: include/clang/Basic/Attr.td:1054-1056
@@ -1058,3 +1053,5 @@
+//
 // FIXME: This should be for OpenCLKernelFunction, but is not to
 // workaround needing to see kernel attribute before others to know if
 // this should be rejected on non-kernels.
+

This FIXME is now detached from what "this" is referring to. Can you clarify by 
mentioning that the Subjects list is what should be modified?


Comment at: include/clang/Basic/Attr.td:1067
@@ +1066,3 @@
+  let Spellings = [GNU<"amdgpu_waves_per_eu">];
+  let Args = [UnsignedArgument<"Min">, VariadicUnsignedArgument<"Max">];
+  let Documentation = [AMDGPUWavesPerEUDocs];

Looking at the documentation, are you sure this should be a 
`VariadicUnsignedArgument`? It seems like this should be an `UnsignedArgument` 
with the optional bit set. Or can you pass multiple Max values?


Comment at: include/clang/Basic/AttrDocs.td:1138
@@ +1137,3 @@
+ wavefronts are able to fit within the resources of an EU. Requesting
+more wavefronts can  hide memory latency but limits available registers which
+can result in spilling. Requesting fewer wavefronts can help reduce cache

There's an extra space between "can" and "hide".


Comment at: include/clang/Basic/AttrDocs.td:1144
@@ +1143,3 @@
+to ensure it is capable of meeting the requested values. However, when the
+kernel is executed there may be other reasons that prevent meeting the request,
+for example, there may be wavefronts from other kernels executing on the EU.

Comma after "executed".


Comment at: include/clang/Basic/AttrDocs.td:1147
@@ +1146,3 @@
+
+The error will be given if:
+  - Specified values violate subtarget specifications;

An error instead of The error.


Comment at: include/clang/Basic/DiagnosticSemaKinds.td:2385
@@ -2384,1 +2384,3 @@
+def err_attribute_argument_invalid : Error<
+  "%0 attribute parameter is invalid: %1">;
 def err_attribute_argument_is_zero : Error<

I think this should say the attribute argument is invalid, rather than the 
attribute parameter.


Comment at: lib/CodeGen/TargetInfo.cpp:6958
@@ +6957,3 @@
+
+  if (const auto Attr = FD->getAttr()) {
+unsigned Min = Attr->getMin();

Should be `const auto *Attr`.


Comment at: lib/CodeGen/TargetInfo.cpp:6967-6969
@@ +6966,5 @@
+  F->addFnAttr("amdgpu-flat-work-group-size", AttrVal);
+} else {
+  assert(Max == 0 && "Max must be zero");
+}
+  }

Elide braces?


Comment at: lib/CodeGen/TargetInfo.cpp:6972
@@ +6971,3 @@
+
+  if (const auto Attr = FD->getAttr()) {
+unsigned Min = Attr->getMin();

`const auto *` here as well.


Comment at: lib/CodeGen/TargetInfo.cpp:6983-6985
@@ -6961,1 +6982,5 @@
+  F->addFnAttr("amdgpu-waves-per-eu", AttrVal);
+} else {
+  assert(Max == 0 && "Max must be zero");
+}
   }

Elide braces?


Comment at: lib/CodeGen/TargetInfo.cpp:6995
@@ +6994,3 @@
+
+  if (const auto Attr = FD->getAttr()) {
+uint32_t NumVGPR = Attr->getNumVGPR();

`const auto *` here as well.


Comment at: lib/Sema/SemaDeclAttr.cpp:4947
@@ +4946,3 @@
+  uint32_t Min = 0;
+  Expr *MinExpr = static_cast(Attr.getArgAsExpr(0));
+  if (!checkUInt32Argument(S, Attr, MinExpr, Min))

I don't think this case is required (here, or elsewhere). `getArgAsExpr()` 
already returns an `Expr *`.


Comment at: lib/Sema/SemaDeclAttr.cpp:4959-4960
@@ +4958,4 @@
+  << Attr.getName()
+  << "maximum flat work-group size must be zero since minimum flat "
+ "work-group size is zero";
+return;

Please include this text in the diagnostic rather than hard-coding it here. You 
can use `%select` to differentiate between different text snippets in the 
diagnostic, and the diagnostic doesn't need to continue to try to be generic. 
Same comment applies elsewhere.


Comment at: lib/Sema/SemaDeclAttr.cpp:4988
@@ +4987,3 @@
+  return;
+  }
+

This will change if you use the optional bit rather than a variadic argument, 
but this silently eats attributes that have more than two arguments, which is 
not a good user experience.


Comment at: lib/Sema/SemaDeclAttr.cpp:6048
@@ -5976,2 +6047,3 @@
   D->setInvalidDecl();
-} else if (Attr *A = D->getAttr()) {
+} else if (Attr *A = D->getAttr()) {
+  Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)

This list is getting to the point where we really need to start handling this 
in Attr.td soon. Are you planning to work on more AMDGPU attributes in the near 

Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-14 Thread Konstantin Zhuravlyov via cfe-commits
kzhuravl updated this revision to Diff 71382.
kzhuravl added a comment.

Fix minor typos


https://reviews.llvm.org/D24513

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/TargetInfo.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGenOpenCL/amdgpu-attrs.cl
  test/CodeGenOpenCL/amdgpu-num-gpr-attr.cl
  test/SemaCUDA/amdgpu-attrs.cu
  test/SemaCUDA/amdgpu-num-gpr-attr.cu
  test/SemaOpenCL/amdgpu-attrs.cl
  test/SemaOpenCL/amdgpu-num-register-attrs.cl

Index: test/SemaOpenCL/amdgpu-num-register-attrs.cl
===
--- test/SemaOpenCL/amdgpu-num-register-attrs.cl
+++ test/SemaOpenCL/amdgpu-num-register-attrs.cl
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -triple r600-- -verify -fsyntax-only %s
-
-typedef __attribute__((amdgpu_num_vgpr(128))) struct FooStruct { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-  int x;
-  float y;
-} FooStruct;
-
-
-__attribute__((amdgpu_num_vgpr("ABC"))) kernel void foo2() {} // expected-error {{'amdgpu_num_vgpr' attribute requires an integer constant}}
-__attribute__((amdgpu_num_sgpr("ABC"))) kernel void foo3() {} // expected-error {{'amdgpu_num_sgpr' attribute requires an integer constant}}
-
-
-__attribute__((amdgpu_num_vgpr(40))) void foo4() {} // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-__attribute__((amdgpu_num_sgpr(64))) void foo5() {} // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
-
-__attribute__((amdgpu_num_vgpr(40))) kernel void foo7() {}
-__attribute__((amdgpu_num_sgpr(64))) kernel void foo8() {}
-__attribute__((amdgpu_num_vgpr(40), amdgpu_num_sgpr(64))) kernel void foo9() {}
-
-// Check 0 VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0))) kernel void foo10() {}
-
-// Check 0 SGPR is accepted.
-__attribute__((amdgpu_num_sgpr(0))) kernel void foo11() {}
-
-// Check both 0 SGPR and VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0), amdgpu_num_sgpr(0))) kernel void foo12() {}
-
-// Too large VGPR value.
-__attribute__((amdgpu_num_vgpr(4294967296))) kernel void foo13() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296))) kernel void foo14() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296), amdgpu_num_vgpr(4294967296))) kernel void foo15() {} // expected-error 2 {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-
-// Make sure it is accepted with kernel keyword before the attribute.
-kernel __attribute__((amdgpu_num_vgpr(40))) void foo16() {}
-
-kernel __attribute__((amdgpu_num_sgpr(40))) void foo17() {}
Index: test/SemaOpenCL/amdgpu-attrs.cl
===
--- test/SemaOpenCL/amdgpu-attrs.cl
+++ test/SemaOpenCL/amdgpu-attrs.cl
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple amdgcn-- -verify -fsyntax-only %s
+
+typedef __attribute__((amdgpu_flat_work_group_size(32, 64))) struct struct_flat_work_group_size_32_64 { // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_flat_work_group_size_32_64;
+typedef __attribute__((amdgpu_waves_per_eu(2))) struct struct_waves_per_eu_2 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2;
+typedef __attribute__((amdgpu_waves_per_eu(2, 4))) struct struct_waves_per_eu_2_4 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2_4;
+typedef __attribute__((amdgpu_num_sgpr(32))) struct struct_num_sgpr_32 { // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_sgpr_32;
+typedef __attribute__((amdgpu_num_vgpr(64))) struct struct_num_vgpr_64 { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_vgpr_64;
+
+__attribute__((amdgpu_flat_work_group_size(32, 64))) void func_flat_work_group_size_32_64() {} // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+__attribute__((amdgpu_waves_per_eu(2))) void func_waves_per_eu_2() {} // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+__attribute__((amdgpu_waves_per_eu(2, 4))) void func_waves_per_eu_2_4() {} // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+__attribute__((amdgpu_num_sgpr(32))) void func_num_sgpr_32() {} // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel 

Re: [PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-14 Thread Konstantin Zhuravlyov via cfe-commits
kzhuravl updated the summary for this revision.
kzhuravl updated this revision to Diff 71311.
kzhuravl added a comment.

Update docs in AttrDocs.td


https://reviews.llvm.org/D24513

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/TargetInfo.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGenOpenCL/amdgpu-attrs.cl
  test/CodeGenOpenCL/amdgpu-num-gpr-attr.cl
  test/SemaCUDA/amdgpu-attrs.cu
  test/SemaCUDA/amdgpu-num-gpr-attr.cu
  test/SemaOpenCL/amdgpu-attrs.cl
  test/SemaOpenCL/amdgpu-num-register-attrs.cl

Index: test/SemaOpenCL/amdgpu-num-register-attrs.cl
===
--- test/SemaOpenCL/amdgpu-num-register-attrs.cl
+++ test/SemaOpenCL/amdgpu-num-register-attrs.cl
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -triple r600-- -verify -fsyntax-only %s
-
-typedef __attribute__((amdgpu_num_vgpr(128))) struct FooStruct { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-  int x;
-  float y;
-} FooStruct;
-
-
-__attribute__((amdgpu_num_vgpr("ABC"))) kernel void foo2() {} // expected-error {{'amdgpu_num_vgpr' attribute requires an integer constant}}
-__attribute__((amdgpu_num_sgpr("ABC"))) kernel void foo3() {} // expected-error {{'amdgpu_num_sgpr' attribute requires an integer constant}}
-
-
-__attribute__((amdgpu_num_vgpr(40))) void foo4() {} // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-__attribute__((amdgpu_num_sgpr(64))) void foo5() {} // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
-
-__attribute__((amdgpu_num_vgpr(40))) kernel void foo7() {}
-__attribute__((amdgpu_num_sgpr(64))) kernel void foo8() {}
-__attribute__((amdgpu_num_vgpr(40), amdgpu_num_sgpr(64))) kernel void foo9() {}
-
-// Check 0 VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0))) kernel void foo10() {}
-
-// Check 0 SGPR is accepted.
-__attribute__((amdgpu_num_sgpr(0))) kernel void foo11() {}
-
-// Check both 0 SGPR and VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0), amdgpu_num_sgpr(0))) kernel void foo12() {}
-
-// Too large VGPR value.
-__attribute__((amdgpu_num_vgpr(4294967296))) kernel void foo13() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296))) kernel void foo14() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296), amdgpu_num_vgpr(4294967296))) kernel void foo15() {} // expected-error 2 {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-
-// Make sure it is accepted with kernel keyword before the attribute.
-kernel __attribute__((amdgpu_num_vgpr(40))) void foo16() {}
-
-kernel __attribute__((amdgpu_num_sgpr(40))) void foo17() {}
Index: test/SemaOpenCL/amdgpu-attrs.cl
===
--- test/SemaOpenCL/amdgpu-attrs.cl
+++ test/SemaOpenCL/amdgpu-attrs.cl
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple amdgcn-- -verify -fsyntax-only %s
+
+typedef __attribute__((amdgpu_flat_work_group_size(32, 64))) struct struct_flat_work_group_size_32_64 { // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_flat_work_group_size_32_64;
+typedef __attribute__((amdgpu_waves_per_eu(2))) struct struct_waves_per_eu_2 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2;
+typedef __attribute__((amdgpu_waves_per_eu(2, 4))) struct struct_waves_per_eu_2_4 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2_4;
+typedef __attribute__((amdgpu_num_sgpr(32))) struct struct_num_sgpr_32 { // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_sgpr_32;
+typedef __attribute__((amdgpu_num_vgpr(64))) struct struct_num_vgpr_64 { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_vgpr_64;
+
+__attribute__((amdgpu_flat_work_group_size(32, 64))) void func_flat_work_group_size_32_64() {} // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+__attribute__((amdgpu_waves_per_eu(2))) void func_waves_per_eu_2() {} // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+__attribute__((amdgpu_waves_per_eu(2, 4))) void func_waves_per_eu_2_4() {} // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+__attribute__((amdgpu_num_sgpr(32))) void func_num_sgpr_32() {} // expected-error 

[PATCH] D24513: [AMDGPU] Expose flat work group size, register and wave control attributes

2016-09-13 Thread Konstantin Zhuravlyov via cfe-commits
kzhuravl created this revision.
kzhuravl added reviewers: arsenm, aaron.ballman.
kzhuravl added subscribers: yaxunl, kanarayan, cfe-commits.
Herald added a reviewer: tstellarAMD.
Herald added subscribers: nhaehnle, wdng.

__attribute__((amdgpu_flat_work_group_size(, ))) - request minimum 
and maximum flat work group size
__attribute__((amdgpu_waves_per_eu([, ]))) - request minimum and/or 
maximum waves per execution unit

TODO: need to update docs in AttrDocs.td

https://reviews.llvm.org/D24513

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/CodeGen/TargetInfo.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGenOpenCL/amdgpu-attrs.cl
  test/CodeGenOpenCL/amdgpu-num-gpr-attr.cl
  test/SemaCUDA/amdgpu-attrs.cu
  test/SemaCUDA/amdgpu-num-gpr-attr.cu
  test/SemaOpenCL/amdgpu-attrs.cl
  test/SemaOpenCL/amdgpu-num-register-attrs.cl

Index: test/SemaOpenCL/amdgpu-num-register-attrs.cl
===
--- test/SemaOpenCL/amdgpu-num-register-attrs.cl
+++ test/SemaOpenCL/amdgpu-num-register-attrs.cl
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -triple r600-- -verify -fsyntax-only %s
-
-typedef __attribute__((amdgpu_num_vgpr(128))) struct FooStruct { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-  int x;
-  float y;
-} FooStruct;
-
-
-__attribute__((amdgpu_num_vgpr("ABC"))) kernel void foo2() {} // expected-error {{'amdgpu_num_vgpr' attribute requires an integer constant}}
-__attribute__((amdgpu_num_sgpr("ABC"))) kernel void foo3() {} // expected-error {{'amdgpu_num_sgpr' attribute requires an integer constant}}
-
-
-__attribute__((amdgpu_num_vgpr(40))) void foo4() {} // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
-__attribute__((amdgpu_num_sgpr(64))) void foo5() {} // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
-
-__attribute__((amdgpu_num_vgpr(40))) kernel void foo7() {}
-__attribute__((amdgpu_num_sgpr(64))) kernel void foo8() {}
-__attribute__((amdgpu_num_vgpr(40), amdgpu_num_sgpr(64))) kernel void foo9() {}
-
-// Check 0 VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0))) kernel void foo10() {}
-
-// Check 0 SGPR is accepted.
-__attribute__((amdgpu_num_sgpr(0))) kernel void foo11() {}
-
-// Check both 0 SGPR and VGPR is accepted.
-__attribute__((amdgpu_num_vgpr(0), amdgpu_num_sgpr(0))) kernel void foo12() {}
-
-// Too large VGPR value.
-__attribute__((amdgpu_num_vgpr(4294967296))) kernel void foo13() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296))) kernel void foo14() {} // expected-error {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-__attribute__((amdgpu_num_sgpr(4294967296), amdgpu_num_vgpr(4294967296))) kernel void foo15() {} // expected-error 2 {{integer constant expression evaluates to value 4294967296 that cannot be represented in a 32-bit unsigned integer type}}
-
-
-// Make sure it is accepted with kernel keyword before the attribute.
-kernel __attribute__((amdgpu_num_vgpr(40))) void foo16() {}
-
-kernel __attribute__((amdgpu_num_sgpr(40))) void foo17() {}
Index: test/SemaOpenCL/amdgpu-attrs.cl
===
--- test/SemaOpenCL/amdgpu-attrs.cl
+++ test/SemaOpenCL/amdgpu-attrs.cl
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple amdgcn-- -verify -fsyntax-only %s
+
+typedef __attribute__((amdgpu_flat_work_group_size(32, 64))) struct struct_flat_work_group_size_32_64 { // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_flat_work_group_size_32_64;
+typedef __attribute__((amdgpu_waves_per_eu(2))) struct struct_waves_per_eu_2 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2;
+typedef __attribute__((amdgpu_waves_per_eu(2, 4))) struct struct_waves_per_eu_2_4 { // expected-error {{'amdgpu_waves_per_eu' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_waves_per_eu_2_4;
+typedef __attribute__((amdgpu_num_sgpr(32))) struct struct_num_sgpr_32 { // expected-error {{'amdgpu_num_sgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_sgpr_32;
+typedef __attribute__((amdgpu_num_vgpr(64))) struct struct_num_vgpr_64 { // expected-error {{'amdgpu_num_vgpr' attribute only applies to kernel functions}}
+  int x;
+  float y;
+} struct_num_vgpr_64;
+
+__attribute__((amdgpu_flat_work_group_size(32, 64))) void func_flat_work_group_size_32_64() {} // expected-error {{'amdgpu_flat_work_group_size' attribute only applies to kernel functions}}
+__attribute__((amdgpu_waves_per_eu(2))) void func_waves_per_eu_2() {} //