Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2999,6 +2999,12 @@ def AtomicCaptureOp : OpenACC_Op<"atomic.capture",
acc.atomic.write ...
acc.terminator
}

acc.atomic.capture {
acc.atomic.update ...
acc.atomic.write ...
acc.terminator
}
```

}];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ def AtomicCaptureOpInterface : OpInterface<"AtomicCaptureOpInterface"> {
implement one of the atomic interfaces. It can be found in one of these
forms:
`{ atomic.update, atomic.read }`
`{ atomic.update, atomic.write }`
`{ atomic.read, atomic.update }`
`{ atomic.read, atomic.write }`
}];
Expand Down Expand Up @@ -291,12 +292,15 @@ def AtomicCaptureOpInterface : OpInterface<"AtomicCaptureOpInterface"> {
auto secondWriteStmt = dyn_cast<AtomicWriteOpInterface>(secondOp);

if (!((firstUpdateStmt && secondReadStmt) ||
(firstUpdateStmt && secondWriteStmt) ||
(firstReadStmt && secondUpdateStmt) ||
(firstReadStmt && secondWriteStmt)))
return ops.front().emitError()
<< "invalid sequence of operations in the capture region";
if (firstUpdateStmt && secondReadStmt &&
firstUpdateStmt.getX() != secondReadStmt.getX())
if ((firstUpdateStmt && secondReadStmt &&
firstUpdateStmt.getX() != secondReadStmt.getX()) ||
(firstUpdateStmt && secondWriteStmt &&
firstUpdateStmt.getX() != secondWriteStmt.getX()))
return firstUpdateStmt.emitError()
<< "updated variable in atomic.update must be captured in "
"second operation";
Expand Down
18 changes: 17 additions & 1 deletion mlir/test/Dialect/OpenACC/invalid.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,6 @@ func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {

func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
acc.atomic.capture {
// expected-error @below {{invalid sequence of operations in the capture region}}
acc.atomic.update %x : memref<i32> {
^bb0(%xval: i32):
%newval = llvm.add %xval, %expr : i32
Expand All @@ -704,6 +703,23 @@ func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {

// -----

func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
acc.atomic.capture {
// expected-error @below {{updated variable in atomic.update must be captured in second operation}}
acc.atomic.update %x : memref<i32> {
^bb0(%xval: i32):
%newval = llvm.add %xval, %expr : i32
acc.yield %newval : i32
}
acc.atomic.write %v = %expr : memref<i32>, i32

acc.terminator
}
return
}

// -----

func.func @acc_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
acc.atomic.capture {
// expected-error @below {{invalid sequence of operations in the capture region}}
Expand Down
33 changes: 32 additions & 1 deletion mlir/test/Dialect/OpenMP/invalid.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,22 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {

func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
omp.atomic.capture {
// expected-error @below {{invalid sequence of operations in the capture region}}
// expected-error @below {{updated variable in atomic.update must be captured in second operation}}
omp.atomic.update %x : memref<i32> {
^bb0(%xval: i32):
%newval = llvm.add %xval, %expr : i32
omp.yield (%newval : i32)
}
omp.atomic.write %v = %expr : memref<i32>, i32
omp.terminator
}
return
}

// -----

func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
omp.atomic.capture {
omp.atomic.update %x : memref<i32> {
^bb0(%xval: i32):
%newval = llvm.add %xval, %expr : i32
Expand All @@ -1289,6 +1304,22 @@ func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {

// -----

func.func @omp_atomic_capture(%x: memref<i32>, %v: memref<i32>, %expr: i32) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this test used?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is supposed to be a 'valid' config test, so I don't have diagnostics. That said, I seem to have double-added this 'is valid' test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add the "valid" tests to ops.mlir (mlir/test/Dialect/OpenACC/ops.mlir and mlir/test/Dialect/OpenMP/ops.mlir)?

The invalid tests look great to me.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! Yes, I did that. Thanks for the help on where to put those!

omp.atomic.capture {
omp.atomic.update %x : memref<i32> {
^bb0(%xval: i32):
%newval = llvm.add %xval, %expr : i32
omp.yield (%newval : i32)
}
omp.atomic.write %x = %expr : memref<i32>, i32

omp.terminator
}
return
}

// -----

func.func @omp_atomic_capture(%x: memref<i32>, %y: memref<i32>, %v: memref<i32>, %expr: i32) {
omp.atomic.capture {
// expected-error @below {{updated variable in atomic.update must be captured in second operation}}
Expand Down
Loading