Author: erichkeane
Date: 2025-06-06T17:06:49-07:00
New Revision: eed98e1493414ae9c30596b1eeb8f4a9b260e42a

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

LOG: [OpenACC][CIR] 'attach' clause lowering for combined/compute

Attach is identical to 'present', except it generates an acc.attach and
acc.detach.  This patch implements these, just like the preivous handful
of clauses.

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
    clang/test/CIR/CodeGenOpenACC/combined.cpp
    clang/test/CIR/CodeGenOpenACC/kernels.c
    clang/test/CIR/CodeGenOpenACC/parallel.c
    clang/test/CIR/CodeGenOpenACC/serial.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp 
b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
index 0dd40794397a8..899e91574e917 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp
@@ -887,6 +887,22 @@ class OpenACCClauseCIREmitter final
       return clauseNotImplemented(clause);
     }
   }
+
+  void VisitAttachClause(const OpenACCAttachClause &clause) {
+    if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, 
mlir::acc::SerialOp,
+                               mlir::acc::KernelsOp>) {
+      for (auto var : clause.getVarList())
+        addDataOperand<mlir::acc::AttachOp, mlir::acc::DetachOp>(
+            var, mlir::acc::DataClause::acc_attach, /*structured=*/true,
+            /*implicit=*/false);
+    } else if constexpr (isCombinedType<OpTy>) {
+      applyToComputeOp(clause);
+    } else {
+      // TODO: When we've implemented this for everything, switch this to an
+      // unreachable. data, enter data remain.
+      return clauseNotImplemented(clause);
+    }
+  }
 };
 
 template <typename OpTy>

diff  --git a/clang/test/CIR/CodeGenOpenACC/combined.cpp 
b/clang/test/CIR/CodeGenOpenACC/combined.cpp
index e2245f98866c9..1f3c9f1a8d3fa 100644
--- a/clang/test/CIR/CodeGenOpenACC/combined.cpp
+++ b/clang/test/CIR/CodeGenOpenACC/combined.cpp
@@ -1117,36 +1117,71 @@ extern "C" void acc_combined_data_clauses(int *arg1, 
int *arg2) {
 
 #pragma acc parallel loop present(arg1)
   for(unsigned I = 0; I < 5; ++I);
-  // CHECK-NEXT: %[[NOCREATE1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
-  // CHECK-NEXT: acc.parallel combined(loop) dataOperands(%[[NOCREATE1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: %[[PRESENT1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: acc.parallel combined(loop) dataOperands(%[[PRESENT1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
   // CHECK-NEXT: acc.loop combined(parallel) {
   // CHECK: acc.yield
   // CHECK-NEXT: } loc
   // CHECK-NEXT: acc.yield
   // CHECK-NEXT: } loc
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg1"}
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg1"}
 
 #pragma acc serial loop present(arg2)
   for(unsigned I = 0; I < 5; ++I);
-  // CHECK-NEXT: %[[NOCREATE2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
-  // CHECK-NEXT: acc.serial combined(loop) dataOperands(%[[NOCREATE2]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: %[[PRESENT2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.serial combined(loop) dataOperands(%[[PRESENT2]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
   // CHECK-NEXT: acc.loop combined(serial) {
   // CHECK: acc.yield
   // CHECK-NEXT: } loc
   // CHECK-NEXT: acc.yield
   // CHECK-NEXT: } loc
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE2]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg2"}
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT2]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg2"}
 
 #pragma acc kernels loop present(arg1, arg2) device_type(host) async
   for(unsigned I = 0; I < 5; ++I);
-  // CHECK-NEXT: %[[NOCREATE1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<host>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
-  // CHECK-NEXT: %[[NOCREATE2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<host>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
-  // CHECK-NEXT: acc.kernels combined(loop) dataOperands(%[[NOCREATE1]], 
%[[NOCREATE2]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<host>]) {
+  // CHECK-NEXT: %[[PRESENT1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<host>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: %[[PRESENT2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<host>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.kernels combined(loop) dataOperands(%[[PRESENT1]], 
%[[PRESENT2]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<host>]) {
+  // CHECK-NEXT: acc.loop combined(kernels) {
+  // CHECK: acc.yield
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.terminator
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<host>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg2"}
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<host>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg1"}
+
+#pragma acc parallel loop attach(arg1)
+  for(unsigned I = 0; I < 5; ++I);
+  // CHECK-NEXT: %[[ATTACH1:.*]] = acc.attach varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: acc.parallel combined(loop) dataOperands(%[[ATTACH1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: acc.loop combined(parallel) {
+  // CHECK: acc.yield
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.yield
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_attach>, name = "arg1"}
+
+#pragma acc serial loop attach(arg2)
+  for(unsigned I = 0; I < 5; ++I);
+  // CHECK-NEXT: %[[ATTACH2:.*]] = acc.attach varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.serial combined(loop) dataOperands(%[[ATTACH2]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: acc.loop combined(serial) {
+  // CHECK: acc.yield
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.yield
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH2]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_attach>, name = "arg2"}
+
+#pragma acc kernels loop attach(arg1, arg2) device_type(host) async
+  for(unsigned I = 0; I < 5; ++I);
+  // CHECK-NEXT: %[[ATTACH1:.*]] = acc.attach varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<host>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: %[[ATTACH2:.*]] = acc.attach varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<host>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.kernels combined(loop) dataOperands(%[[ATTACH1]], 
%[[ATTACH2]] : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<host>]) {
   // CHECK-NEXT: acc.loop combined(kernels) {
   // CHECK: acc.yield
   // CHECK-NEXT: } loc
   // CHECK-NEXT: acc.terminator
   // CHECK-NEXT: } loc
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<host>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg2"}
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<host>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg1"}
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<host>]) {dataClause = #acc<data_clause acc_attach>, 
name = "arg2"}
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<host>]) {dataClause = #acc<data_clause acc_attach>, 
name = "arg1"}
 }

diff  --git a/clang/test/CIR/CodeGenOpenACC/kernels.c 
b/clang/test/CIR/CodeGenOpenACC/kernels.c
index b8a43ccadb40a..d0c6f1134c8d2 100644
--- a/clang/test/CIR/CodeGenOpenACC/kernels.c
+++ b/clang/test/CIR/CodeGenOpenACC/kernels.c
@@ -472,19 +472,37 @@ void acc_kernels_data_clauses(int *arg1, int *arg2) {
 
 #pragma acc kernels present(arg1)
   ;
-  // CHECK-NEXT: %[[NOCREATE1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
-  // CHECK-NEXT: acc.kernels dataOperands(%[[NOCREATE1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: %[[PRESENT1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: acc.kernels dataOperands(%[[PRESENT1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
   // CHECK-NEXT: acc.terminator
   // CHECK-NEXT: } loc
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg1"}
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg1"}
 
 #pragma acc kernels present(arg1, arg2) device_type(nvidia) async
   ;
-  // CHECK-NEXT: %[[NOCREATE1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
-  // CHECK-NEXT: %[[NOCREATE2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
-  // CHECK-NEXT: acc.kernels dataOperands(%[[NOCREATE1]], %[[NOCREATE2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {
+  // CHECK-NEXT: %[[PRESENT1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: %[[PRESENT2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.kernels dataOperands(%[[PRESENT1]], %[[PRESENT2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {
+  // CHECK-NEXT: acc.terminator
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg2"}
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg1"}
+
+#pragma acc kernels attach(arg1)
+  ;
+  // CHECK-NEXT: %[[ATTACH1:.*]] = acc.attach varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: acc.kernels dataOperands(%[[ATTACH1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: acc.terminator
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_attach>, name = "arg1"}
+
+#pragma acc kernels attach(arg1, arg2) device_type(nvidia) async
+  ;
+  // CHECK-NEXT: %[[ATTACH1:.*]] = acc.attach varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: %[[ATTACH2:.*]] = acc.attach varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.kernels dataOperands(%[[ATTACH1]], %[[ATTACH2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {
   // CHECK-NEXT: acc.terminator
   // CHECK-NEXT: } loc
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg2"}
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg1"}
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_attach>, 
name = "arg2"}
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_attach>, 
name = "arg1"}
 }

diff  --git a/clang/test/CIR/CodeGenOpenACC/parallel.c 
b/clang/test/CIR/CodeGenOpenACC/parallel.c
index 55c623ec3df80..0127613233eca 100644
--- a/clang/test/CIR/CodeGenOpenACC/parallel.c
+++ b/clang/test/CIR/CodeGenOpenACC/parallel.c
@@ -499,20 +499,38 @@ void acc_parallel_data_clauses(int *arg1, int *arg2) {
 
 #pragma acc parallel present(arg1)
   ;
-  // CHECK-NEXT: %[[NOCREATE1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
-  // CHECK-NEXT: acc.parallel dataOperands(%[[NOCREATE1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: %[[PRESENT1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: acc.parallel dataOperands(%[[PRESENT1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
   // CHECK-NEXT: acc.yield
   // CHECK-NEXT: } loc
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg1"}
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg1"}
 
 #pragma acc parallel present(arg1, arg2) device_type(radeon) async
   ;
-  // CHECK-NEXT: %[[NOCREATE1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<radeon>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
-  // CHECK-NEXT: %[[NOCREATE2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<radeon>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
-  // CHECK-NEXT: acc.parallel dataOperands(%[[NOCREATE1]], %[[NOCREATE2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<radeon>]) {
+  // CHECK-NEXT: %[[PRESENT1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<radeon>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: %[[PRESENT2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<radeon>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.parallel dataOperands(%[[PRESENT1]], %[[PRESENT2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<radeon>]) {
+  // CHECK-NEXT: acc.yield
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<radeon>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg2"}
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<radeon>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg1"}
+
+#pragma acc parallel attach(arg1)
+  ;
+  // CHECK-NEXT: %[[ATTACH1:.*]] = acc.attach varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: acc.parallel dataOperands(%[[ATTACH1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: acc.yield
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_attach>, name = "arg1"}
+
+#pragma acc parallel attach(arg1, arg2) device_type(radeon) async
+  ;
+  // CHECK-NEXT: %[[ATTACH1:.*]] = acc.attach varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<radeon>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: %[[ATTACH2:.*]] = acc.attach varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<radeon>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.parallel dataOperands(%[[ATTACH1]], %[[ATTACH2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<radeon>]) {
   // CHECK-NEXT: acc.yield
   // CHECK-NEXT: } loc
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<radeon>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg2"}
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<radeon>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg1"}
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<radeon>]) {dataClause = #acc<data_clause acc_attach>, 
name = "arg2"}
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<radeon>]) {dataClause = #acc<data_clause acc_attach>, 
name = "arg1"}
 }
 

diff  --git a/clang/test/CIR/CodeGenOpenACC/serial.c 
b/clang/test/CIR/CodeGenOpenACC/serial.c
index 43dd7c8a4aa13..1c9695b34833f 100644
--- a/clang/test/CIR/CodeGenOpenACC/serial.c
+++ b/clang/test/CIR/CodeGenOpenACC/serial.c
@@ -322,18 +322,35 @@ void acc_serial_data_clauses(int *arg1, int *arg2) {
 
 #pragma acc serial present(arg1)
   ;
-  // CHECK-NEXT: %[[NOCREATE1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
-  // CHECK-NEXT: acc.serial dataOperands(%[[NOCREATE1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: %[[PRESENT1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: acc.serial dataOperands(%[[PRESENT1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
   // CHECK-NEXT: acc.yield
   // CHECK-NEXT: } loc
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg1"}
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_present>, name = "arg1"}
 #pragma acc serial present(arg1, arg2) device_type(nvidia) async
   ;
-  // CHECK-NEXT: %[[NOCREATE1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
-  // CHECK-NEXT: %[[NOCREATE2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
-  // CHECK-NEXT: acc.serial dataOperands(%[[NOCREATE1]], %[[NOCREATE2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {
+  // CHECK-NEXT: %[[PRESENT1:.*]] = acc.present varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: %[[PRESENT2:.*]] = acc.present varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.serial dataOperands(%[[PRESENT1]], %[[PRESENT2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {
+  // CHECK-NEXT: acc.yield
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg2"}
+  // CHECK-NEXT: acc.delete accPtr(%[[PRESENT1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg1"}
+
+#pragma acc serial attach(arg1)
+  ;
+  // CHECK-NEXT: %[[ATTACH1:.*]] = acc.attach varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) -> !cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: acc.serial dataOperands(%[[ATTACH1]] : 
!cir.ptr<!cir.ptr<!s32i>>) {
+  // CHECK-NEXT: acc.yield
+  // CHECK-NEXT: } loc
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH1]] : !cir.ptr<!cir.ptr<!s32i>>) 
{dataClause = #acc<data_clause acc_attach>, name = "arg1"}
+#pragma acc serial attach(arg1, arg2) device_type(nvidia) async
+  ;
+  // CHECK-NEXT: %[[ATTACH1:.*]] = acc.attach varPtr(%[[ARG1]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg1"}
+  // CHECK-NEXT: %[[ATTACH2:.*]] = acc.attach varPtr(%[[ARG2]] : 
!cir.ptr<!cir.ptr<!s32i>>) async([#acc.device_type<nvidia>]) -> 
!cir.ptr<!cir.ptr<!s32i>> {name = "arg2"}
+  // CHECK-NEXT: acc.serial dataOperands(%[[ATTACH1]], %[[ATTACH2]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {
   // CHECK-NEXT: acc.yield
   // CHECK-NEXT: } loc
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg2"}
-  // CHECK-NEXT: acc.delete accPtr(%[[NOCREATE1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_present>, 
name = "arg1"}
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH2]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_attach>, 
name = "arg2"}
+  // CHECK-NEXT: acc.detach accPtr(%[[ATTACH1]] : !cir.ptr<!cir.ptr<!s32i>>) 
async([#acc.device_type<nvidia>]) {dataClause = #acc<data_clause acc_attach>, 
name = "arg1"}
 }


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

Reply via email to