[clang] 666eee0 - [OpenACC] enable 'device_type' for the 'update' construct

via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 7 11:45:33 PST 2025


Author: erichkeane
Date: 2025-01-07T11:25:58-08:00
New Revision: 666eee0ef85ff8a81904b9375fc22bc48cecc6b1

URL: https://github.com/llvm/llvm-project/commit/666eee0ef85ff8a81904b9375fc22bc48cecc6b1
DIFF: https://github.com/llvm/llvm-project/commit/666eee0ef85ff8a81904b9375fc22bc48cecc6b1.diff

LOG: [OpenACC] enable 'device_type' for the 'update' construct

This has a similar restriction to 'set' in that only 'async' and 'wait'
are disallowed, so this implements that restriction and enables
'device_type'.

Added: 
    

Modified: 
    clang/lib/Sema/SemaOpenACC.cpp
    clang/test/AST/ast-print-openacc-update-construct.cpp
    clang/test/SemaOpenACC/update-construct-ast.cpp
    clang/test/SemaOpenACC/update-construct.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 00cd3a009386e5..1edff48331cd6d 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -498,12 +498,9 @@ bool checkAlreadyHasClauseOfKind(
 bool checkValidAfterDeviceType(
     SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause,
     const SemaOpenACC::OpenACCParsedClause &NewClause) {
-  // This is only a requirement on compute, combined, data and loop constructs
-  // so far, so this is fine otherwise.
-  if (!isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()) &&
-      !isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind()) &&
-      NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop &&
-      NewClause.getDirectiveKind() != OpenACCDirectiveKind::Data)
+  // This is implemented for everything but 'routine', so treat as 'fine' for
+  // that.
+  if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
     return false;
 
   // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are
@@ -578,6 +575,21 @@ bool checkValidAfterDeviceType(
     default:
       break;
     }
+  } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Set ||
+             NewClause.getDirectiveKind() == OpenACCDirectiveKind::Init ||
+             NewClause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown) {
+    // There are no restrictions on 'set', 'init', or 'shutdown'.
+    return false;
+  } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
+    // OpenACC3.3 section 2.14.4: Only the async and wait clauses may follow a
+    // device_type clause.
+    switch (NewClause.getClauseKind()) {
+    case OpenACCClauseKind::Async:
+    case OpenACCClauseKind::Wait:
+      return false;
+    default:
+      break;
+    }
   }
   S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type)
       << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind()
@@ -1178,11 +1190,8 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause(
 
 OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause(
     SemaOpenACC::OpenACCParsedClause &Clause) {
-  // Restrictions only properly implemented on 'compute', 'combined', 'data' and
-  // 'loop' constructs, and 'compute'/'combined'/'data'/'loop' constructs are
-  // the only construct that can do anything with this yet, so skip/treat as
-  // unimplemented in this case.
-  if (!isDirectiveKindImplemented(Clause.getDirectiveKind()))
+  // Restrictions implemented properly on everything except 'routine'.
+  if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Routine)
     return isNotImplemented();
 
   // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the

diff  --git a/clang/test/AST/ast-print-openacc-update-construct.cpp b/clang/test/AST/ast-print-openacc-update-construct.cpp
index 627c15be4b863e..ce83bcad003a2a 100644
--- a/clang/test/AST/ast-print-openacc-update-construct.cpp
+++ b/clang/test/AST/ast-print-openacc-update-construct.cpp
@@ -29,4 +29,10 @@ void uses(bool cond) {
 
 // CHECK: #pragma acc update wait(devnum: I : queues: *iPtr, I) if(I == array[I]) async(I)
 #pragma acc update wait(devnum:I:queues:*iPtr, I) if(I == array[I]) async(I)
+
+// CHECK: #pragma acc update device_type(I) dtype(H)
+#pragma acc update device_type(I) dtype(H)
+
+// CHECK: #pragma acc update device_type(J) dtype(K)
+#pragma acc update device_type(J) dtype(K)
 }

diff  --git a/clang/test/SemaOpenACC/update-construct-ast.cpp b/clang/test/SemaOpenACC/update-construct-ast.cpp
index f55409d99a13cf..114de654670d30 100644
--- a/clang/test/SemaOpenACC/update-construct-ast.cpp
+++ b/clang/test/SemaOpenACC/update-construct-ast.cpp
@@ -27,11 +27,13 @@ void NormalFunc() {
   // CHECK-NEXT: ImplicitCastExpr
   // CHECK-NEXT: DeclRefExpr{{.*}}'some_long' 'long ()'
 
-#pragma acc update wait async
+#pragma acc update wait async device_type(A) dtype(B)
   // CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
   // CHECK-NEXT: wait clause
   // CHECK-NEXT: <<<NULL>>>
   // CHECK-NEXT: async clause
+  // CHECK-NEXT: device_type(A)
+  // CHECK-NEXT: dtype(B)
 #pragma acc update wait(some_int(), some_long()) async(some_int())
   // CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
   // CHECK-NEXT: wait clause
@@ -87,11 +89,13 @@ void TemplFunc(T t) {
   // CHECK-NEXT: NestedNameSpecifier TypeSpec 'T'
   // CHECK-NEXT: DeclRefExpr{{.*}}'t' 'T'
 
-#pragma acc update wait async
+#pragma acc update wait async device_type(T) dtype(U)
   // CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
   // CHECK-NEXT: wait clause
   // CHECK-NEXT: <<<NULL>>>
   // CHECK-NEXT: async clause
+  // CHECK-NEXT: device_type(T)
+  // CHECK-NEXT: dtype(U)
 #pragma acc update wait(T::value, t) async(T::value)
   // CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
   // CHECK-NEXT: wait clause
@@ -144,6 +148,8 @@ void TemplFunc(T t) {
   // CHECK-NEXT: wait clause
   // CHECK-NEXT: <<<NULL>>>
   // CHECK-NEXT: async clause
+  // CHECK-NEXT: device_type(T)
+  // CHECK-NEXT: dtype(U)
 
   // CHECK-NEXT: OpenACCUpdateConstruct{{.*}}update
   // CHECK-NEXT: wait clause

diff  --git a/clang/test/SemaOpenACC/update-construct.cpp b/clang/test/SemaOpenACC/update-construct.cpp
index 6aa7613d2b81d9..04c0aaaab99ae1 100644
--- a/clang/test/SemaOpenACC/update-construct.cpp
+++ b/clang/test/SemaOpenACC/update-construct.cpp
@@ -8,8 +8,7 @@ void uses() {
 #pragma acc update async self(Var)
   // expected-warning at +1{{OpenACC clause 'self' not yet implemented}}
 #pragma acc update wait self(Var)
-  // expected-warning at +2{{OpenACC clause 'self' not yet implemented}}
-  // expected-warning at +1{{OpenACC clause 'device_type' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause 'self' not yet implemented}}
 #pragma acc update self(Var) device_type(I)
   // expected-warning at +1{{OpenACC clause 'self' not yet implemented}}
 #pragma acc update if(true) self(Var)
@@ -22,46 +21,41 @@ void uses() {
   // expected-warning at +1{{OpenACC clause 'device' not yet implemented}}
 #pragma acc update device(Var)
 
-  // TODO: OpenACC: These all should diagnose as they aren't allowed after
-  // device_type.
-    // expected-warning at +3{{OpenACC clause 'self' not yet implemented}}
-    // expected-warning at +2{{OpenACC clause 'device_type' not yet implemented}}
-    // expected-warning at +1{{OpenACC clause 'device_type' not yet implemented}}
-#pragma acc update self(Var) device_type(I) device_type(I)
-    // expected-warning at +2{{OpenACC clause 'self' not yet implemented}}
-    // expected-warning at +1{{OpenACC clause 'device_type' not yet implemented}}
+  // expected-warning at +3{{OpenACC clause 'self' not yet implemented}}
+  // expected-error at +2{{OpenACC clause 'if' may not follow a 'device_type' clause in a 'update' construct}}
+  // expected-note at +1{{previous clause is here}}
 #pragma acc update self(Var) device_type(I) if(true)
-    // expected-warning at +2{{OpenACC clause 'self' not yet implemented}}
-    // expected-warning at +1{{OpenACC clause 'device_type' not yet implemented}}
+  // expected-warning at +3{{OpenACC clause 'self' not yet implemented}}
+  // expected-error at +2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'update' construct}}
+  // expected-note at +1{{previous clause is here}}
 #pragma acc update self(Var) device_type(I) if_present
-    // expected-warning at +2{{OpenACC clause 'device_type' not yet implemented}}
-    // expected-warning at +1{{OpenACC clause 'self' not yet implemented}}
+  // expected-error at +2{{OpenACC clause 'self' may not follow a 'device_type' clause in a 'update' construct}}
+  // expected-note at +1{{previous clause is here}}
 #pragma acc update device_type(I) self(Var)
-    // expected-warning at +2{{OpenACC clause 'device_type' not yet implemented}}
-    // expected-warning at +1{{OpenACC clause 'host' not yet implemented}}
+  // expected-error at +2{{OpenACC clause 'host' may not follow a 'device_type' clause in a 'update' construct}}
+  // expected-note at +1{{previous clause is here}}
 #pragma acc update device_type(I) host(Var)
-    // expected-warning at +2{{OpenACC clause 'device_type' not yet implemented}}
-    // expected-warning at +1{{OpenACC clause 'device' not yet implemented}}
+  // expected-error at +2{{OpenACC clause 'device' may not follow a 'device_type' clause in a 'update' construct}}
+  // expected-note at +1{{previous clause is here}}
 #pragma acc update device_type(I) device(Var)
   // These 2 are OK.
-    // expected-warning at +2{{OpenACC clause 'self' not yet implemented}}
-    // expected-warning at +1{{OpenACC clause 'device_type' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause 'self' not yet implemented}}
 #pragma acc update self(Var) device_type(I) async
-    // expected-warning at +2{{OpenACC clause 'self' not yet implemented}}
-    // expected-warning at +1{{OpenACC clause 'device_type' not yet implemented}}
+  // expected-warning at +1{{OpenACC clause 'self' not yet implemented}}
 #pragma acc update self(Var) device_type(I) wait
+  // Unless otherwise specified, we assume 'device_type' can happen after itself.
+  // expected-warning at +1{{OpenACC clause 'self' not yet implemented}}
+#pragma acc update self(Var) device_type(I) device_type(I)
 
   // TODO: OpenACC: These should diagnose because there isn't at least 1 of
   // 'self', 'host', or 'device'.
 #pragma acc update async
 #pragma acc update wait
-    // expected-warning at +1{{OpenACC clause 'device_type' not yet implemented}}
 #pragma acc update device_type(I)
 #pragma acc update if(true)
 #pragma acc update if_present
 
-  // expected-error at +2{{value of type 'struct NotConvertible' is not contextually convertible to 'bool'}}
-  // expected-warning at +1{{OpenACC clause 'device_type' not yet implemented}}
+  // expected-error at +1{{value of type 'struct NotConvertible' is not contextually convertible to 'bool'}}
 #pragma acc update if (NC) device_type(I)
 
   // expected-error at +2{{OpenACC 'if' clause cannot appear more than once on a 'update' directive}}


        


More information about the cfe-commits mailing list