[clang] 78c7024 - [OpenACC] Implement 'present' for combined constructs.

via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 26 10:49:46 PST 2024


Author: erichkeane
Date: 2024-11-26T10:49:41-08:00
New Revision: 78c7024640a5b511685c445f554b7d985a7cf286

URL: https://github.com/llvm/llvm-project/commit/78c7024640a5b511685c445f554b7d985a7cf286
DIFF: https://github.com/llvm/llvm-project/commit/78c7024640a5b511685c445f554b7d985a7cf286.diff

LOG: [OpenACC] Implement 'present' for combined constructs.

This is another clause where the parsing does all the required
enforcement besides the construct it appertains to, so this patch
removes the restriction and adds sufficient test coverage for combined
constructs.

Added: 
    clang/test/SemaOpenACC/combined-construct-present-ast.cpp
    clang/test/SemaOpenACC/combined-construct-present-clause.c
    clang/test/SemaOpenACC/combined-construct-present-clause.cpp

Modified: 
    clang/lib/Sema/SemaOpenACC.cpp
    clang/test/AST/ast-print-openacc-combined-construct.cpp
    clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
    clang/test/SemaOpenACC/combined-construct-default-clause.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 76be9a2abf5e46..d146edeabab741 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -859,10 +859,11 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause(
 
 OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause(
     SemaOpenACC::OpenACCParsedClause &Clause) {
-  // Restrictions only properly implemented on 'compute' constructs, and
-  // 'compute' constructs are the only construct that can do anything with
-  // this yet, so skip/treat as unimplemented in this case.
-  if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()))
+  // Restrictions only properly implemented on 'compute'/'combined constructs,
+  // and 'compute'/'combined' constructs are the only construct that can do
+  // anything with this yet, so skip/treat as unimplemented in this case.
+  if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) &&
+      !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()))
     return isNotImplemented();
   // ActOnVar ensured that everything is a valid variable reference, so there
   // really isn't anything to do here. GCC does some duplicate-finding, though

diff  --git a/clang/test/AST/ast-print-openacc-combined-construct.cpp b/clang/test/AST/ast-print-openacc-combined-construct.cpp
index 6885806584f3d1..e04c39ac9bc5be 100644
--- a/clang/test/AST/ast-print-openacc-combined-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-combined-construct.cpp
@@ -122,4 +122,13 @@ void foo() {
 #pragma acc kernels loop async
   for(int i = 0;i<5;++i);
 
+// CHECK: #pragma acc parallel loop present(i, array[1], array, array[1:2])
+#pragma acc parallel loop present(i, array[1], array, array[1:2])
+  for(int i = 0;i<5;++i);
+// CHECK: #pragma acc serial loop present(i, array[1], array, array[1:2])
+#pragma acc serial loop present(i, array[1], array, array[1:2])
+  for(int i = 0;i<5;++i);
+// CHECK: #pragma acc kernels loop present(i, array[1], array, array[1:2])
+#pragma acc kernels loop present(i, array[1], array, array[1:2])
+  for(int i = 0;i<5;++i);
 }

diff  --git a/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c b/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
index a770020764d356..69f93a6c605156 100644
--- a/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
+++ b/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c
@@ -111,8 +111,6 @@ void uses() {
   // expected-warning at +1{{OpenACC clause 'no_create' not yet implemented}}
 #pragma acc parallel loop auto no_create(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'present' not yet implemented}}
 #pragma acc parallel loop auto present(Var)
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop auto private(Var)
@@ -274,8 +272,6 @@ void uses() {
   // expected-warning at +1{{OpenACC clause 'no_create' not yet implemented}}
 #pragma acc parallel loop no_create(Var) auto
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'present' not yet implemented}}
 #pragma acc parallel loop present(Var) auto
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop private(Var) auto
@@ -438,8 +434,6 @@ void uses() {
   // expected-warning at +1{{OpenACC clause 'no_create' not yet implemented}}
 #pragma acc parallel loop independent no_create(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'present' not yet implemented}}
 #pragma acc parallel loop independent present(Var)
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop independent private(Var)
@@ -601,8 +595,6 @@ void uses() {
   // expected-warning at +1{{OpenACC clause 'no_create' not yet implemented}}
 #pragma acc parallel loop no_create(Var) independent
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'present' not yet implemented}}
 #pragma acc parallel loop present(Var) independent
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop private(Var) independent
@@ -771,8 +763,6 @@ void uses() {
   // expected-warning at +1{{OpenACC clause 'no_create' not yet implemented}}
 #pragma acc parallel loop seq no_create(Var)
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'present' not yet implemented}}
 #pragma acc parallel loop seq present(Var)
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop seq private(Var)
@@ -940,8 +930,6 @@ void uses() {
   // expected-warning at +1{{OpenACC clause 'no_create' not yet implemented}}
 #pragma acc parallel loop no_create(Var) seq
   for(unsigned i = 0; i < 5; ++i);
-  // TODOexpected-error at +1{{OpenACC 'present' clause is not valid on 'parallel loop' directive}}
-  // expected-warning at +1{{OpenACC clause 'present' not yet implemented}}
 #pragma acc parallel loop present(Var) seq
   for(unsigned i = 0; i < 5; ++i);
 #pragma acc parallel loop private(Var) seq

diff  --git a/clang/test/SemaOpenACC/combined-construct-default-clause.c b/clang/test/SemaOpenACC/combined-construct-default-clause.c
index 646942ec700133..c420c8ebeb31d6 100644
--- a/clang/test/SemaOpenACC/combined-construct-default-clause.c
+++ b/clang/test/SemaOpenACC/combined-construct-default-clause.c
@@ -11,8 +11,7 @@ void SingleOnly() {
 
   int i;
 
-  // expected-warning at +4{{OpenACC clause 'copy' not yet implemented}}
-  // expected-warning at +3{{OpenACC clause 'present' not yet implemented}}
+  // expected-warning at +3{{OpenACC clause 'copy' not yet implemented}}
   // expected-error at +2{{OpenACC 'default' clause cannot appear more than once on a 'kernels loop' directive}}
   // expected-note at +1{{previous clause is here}}
   #pragma acc kernels loop self default(present) present(i) default(none) copy(i)

diff  --git a/clang/test/SemaOpenACC/combined-construct-present-ast.cpp b/clang/test/SemaOpenACC/combined-construct-present-ast.cpp
new file mode 100644
index 00000000000000..028831c5f9899c
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-present-ast.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s
+
+// Test this with PCH.
+// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s
+// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s
+
+#ifndef PCH_HELPER
+#define PCH_HELPER
+
+int Global;
+short GlobalArray[5];
+
+void NormalUses(float *PointerParam) {
+  // CHECK: FunctionDecl{{.*}}NormalUses
+  // CHECK: ParmVarDecl
+  // CHECK-NEXT: CompoundStmt
+
+#pragma acc parallel loop present(GlobalArray, PointerParam[Global])
+  for(int i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop
+  // CHECK-NEXT: present clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
+  // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *'
+  // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <LValueToRValue>
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+}
+
+template<auto &NTTP, typename T>
+void TemplUses(T t) {
+  // CHECK-NEXT: FunctionTemplateDecl
+  // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP
+  // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T
+  // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T)'
+  // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T'
+  // CHECK-NEXT: CompoundStmt
+
+#pragma acc serial loop seq present(NTTP, t)
+  for(int i = 0; i < 5; ++i);
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop
+  // CHECK-NEXT: seq clause
+  // CHECK-NEXT: present clause
+  // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &'
+  // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+
+
+  // Check the instantiated versions of the above.
+  // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int)' implicit_instantiation
+  // CHECK-NEXT: TemplateArgument decl
+  // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int'
+  // CHECK-NEXT: TemplateArgument type 'int'
+  // CHECK-NEXT: BuiltinType{{.*}} 'int'
+  // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int'
+  // CHECK-NEXT: CompoundStmt
+
+// #pragma acc parallel seq present(NTTP, t)
+  // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop
+  // CHECK-NEXT: seq clause
+  // CHECK-NEXT: present clause
+  // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue
+  // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP
+  // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int'
+  // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int'
+  // CHECK-NEXT: ForStmt
+  // CHECK: NullStmt
+
+}
+
+void Inst() {
+  static constexpr unsigned CEVar = 1;
+  TemplUses<CEVar>(5);
+}
+#endif

diff  --git a/clang/test/SemaOpenACC/combined-construct-present-clause.c b/clang/test/SemaOpenACC/combined-construct-present-clause.c
new file mode 100644
index 00000000000000..acdaaa33929233
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-present-clause.c
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+typedef struct IsComplete {
+  struct S { int A; } CompositeMember;
+  int ScalarMember;
+  float ArrayMember[5];
+  void *PointerMember;
+} Complete;
+void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) {
+  int LocalInt;
+  short *LocalPointer;
+  float LocalArray[5];
+  Complete LocalComposite;
+  // Check Appertainment:
+#pragma acc parallel loop present(LocalInt)
+  for(int i = 5; i < 10;++i);
+#pragma acc serial loop present(LocalInt)
+  for(int i = 5; i < 10;++i);
+#pragma acc kernels loop present(LocalInt)
+  for(int i = 5; i < 10;++i);
+
+  // Valid cases:
+#pragma acc parallel loop present(LocalInt, LocalPointer, LocalArray)
+  for(int i = 5; i < 10;++i);
+#pragma acc parallel loop present(LocalArray[2:1])
+  for(int i = 5; i < 10;++i);
+
+#pragma acc parallel loop present(LocalComposite.ScalarMember, LocalComposite.ScalarMember)
+  for(int i = 5; i < 10;++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present(1 + IntParam)
+  for(int i = 5; i < 10;++i);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present(+IntParam)
+  for(int i = 5; i < 10;++i);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop present(PointerParam[2:])
+  for(int i = 5; i < 10;++i);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop present(ArrayParam[2:5])
+  for(int i = 5; i < 10;++i);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present((float*)ArrayParam[2:5])
+  for(int i = 5; i < 10;++i);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present((float)ArrayParam[2])
+  for(int i = 5; i < 10;++i);
+
+  // expected-error at +1{{OpenACC 'present' clause is not valid on 'loop' directive}}
+#pragma acc loop present(LocalInt)
+  for(int i = 5; i < 10;++i);
+}

diff  --git a/clang/test/SemaOpenACC/combined-construct-present-clause.cpp b/clang/test/SemaOpenACC/combined-construct-present-clause.cpp
new file mode 100644
index 00000000000000..814acf25c01c02
--- /dev/null
+++ b/clang/test/SemaOpenACC/combined-construct-present-clause.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+enum SomeE{};
+typedef struct IsComplete {
+  struct S { int A; } CompositeMember;
+  int ScalarMember;
+  float ArrayMember[5];
+  SomeE EnumMember;
+  char *PointerMember;
+} Complete;
+
+void uses(int IntParam, char *PointerParam, float ArrayParam[5], Complete CompositeParam, int &IntParamRef) {
+  int LocalInt;
+  char *LocalPointer;
+  float LocalArray[5];
+  // Check Appertainment:
+#pragma acc parallel loop present(LocalInt)
+  for(unsigned I = 0; I < 5; ++I);
+#pragma acc serial loop present(LocalInt)
+  for(unsigned I = 0; I < 5; ++I);
+#pragma acc kernels loop present(LocalInt)
+  for(unsigned I = 0; I < 5; ++I);
+
+  // Valid cases:
+#pragma acc parallel loop present(LocalInt, LocalPointer, LocalArray)
+  for(unsigned I = 0; I < 5; ++I);
+#pragma acc parallel loop present(LocalArray[2:1])
+  for(unsigned I = 0; I < 5; ++I);
+
+  Complete LocalComposite2;
+#pragma acc parallel loop present(LocalComposite2.ScalarMember, LocalComposite2.ScalarMember)
+  for(unsigned I = 0; I < 5; ++I);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present(1 + IntParam)
+  for(unsigned I = 0; I < 5; ++I);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present(+IntParam)
+  for(unsigned I = 0; I < 5; ++I);
+
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop present(PointerParam[2:])
+  for(unsigned I = 0; I < 5; ++I);
+
+  // expected-error at +1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+#pragma acc parallel loop present(ArrayParam[2:5])
+  for(unsigned I = 0; I < 5; ++I);
+
+  // expected-error at +2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}}
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present((float*)ArrayParam[2:5])
+  for(unsigned I = 0; I < 5; ++I);
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present((float)ArrayParam[2])
+  for(unsigned I = 0; I < 5; ++I);
+}
+
+template<typename T, unsigned Int, typename V>
+void TemplUses(T t, T (&arrayT)[Int], V TemplComp) {
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present(+t)
+  for(unsigned I = 0; I < 5; ++I);
+
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#TEMPL_USES_INST{{in instantiation of}}
+#pragma acc parallel loop present(Int)
+  for(unsigned I = 0; I < 5; ++I);
+
+  // expected-error at +1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+#pragma acc parallel loop present(t, Int)
+  for(unsigned I = 0; I < 5; ++I);
+
+#pragma acc parallel loop present(arrayT)
+  for(unsigned I = 0; I < 5; ++I);
+
+#pragma acc parallel loop present(TemplComp)
+  for(unsigned I = 0; I < 5; ++I);
+
+#pragma acc parallel loop present(TemplComp.PointerMember[5])
+  for(unsigned I = 0; I < 5; ++I);
+ int *Pointer;
+#pragma acc parallel loop present(Pointer[:Int])
+  for(unsigned I = 0; I < 5; ++I);
+#pragma acc parallel loop present(Pointer[:t])
+  for(unsigned I = 0; I < 5; ++I);
+  // expected-error at +1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}}
+#pragma acc parallel loop present(Pointer[1:])
+  for(unsigned I = 0; I < 5; ++I);
+}
+
+template<unsigned Int, auto &NTTP_REF>
+void NTTP() {
+  // NTTP's are only valid if it is a reference to something.
+  // expected-error at +2{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}}
+  // expected-note@#NTTP_INST{{in instantiation of}}
+#pragma acc parallel loop present(Int)
+  for(unsigned I = 0; I < 5; ++I);
+
+#pragma acc parallel loop present(NTTP_REF)
+  for(unsigned I = 0; I < 5; ++I);
+}
+
+void Inst() {
+  static constexpr int NTTP_REFed = 1;
+  int i;
+  int Arr[5];
+  Complete C;
+  TemplUses(i, Arr, C); // #TEMPL_USES_INST
+  NTTP<5, NTTP_REFed>(); // #NTTP_INST
+}


        


More information about the cfe-commits mailing list