diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -1368,7 +1368,6 @@ addOperand(operands, operandSegments, async); addOperand(operands, operandSegments, waitDevnum); addOperands(operands, operandSegments, waitOperands); - operandSegments.append({0, 0, 0}); addOperands(operands, operandSegments, dataClauseOperands); mlir::acc::ExitDataOp exitDataOp = createSimpleOp( diff --git a/flang/lib/Optimizer/Transforms/OpenACC/OpenACCDataOperandConversion.cpp b/flang/lib/Optimizer/Transforms/OpenACC/OpenACCDataOperandConversion.cpp --- a/flang/lib/Optimizer/Transforms/OpenACC/OpenACCDataOperandConversion.cpp +++ b/flang/lib/Optimizer/Transforms/OpenACC/OpenACCDataOperandConversion.cpp @@ -116,7 +116,6 @@ fir::LLVMTypeConverter converter( op.getOperation()->getParentOfType(), true); patterns.add>(converter); - patterns.add>(converter); patterns.add>(converter); ConversionTarget target(*context); @@ -147,13 +146,6 @@ allDataOperandsAreConverted(op.getAttachOperands()); }); - target.addDynamicallyLegalOp( - [allDataOperandsAreConverted](acc::ExitDataOp op) { - return allDataOperandsAreConverted(op.getCopyoutOperands()) && - allDataOperandsAreConverted(op.getDeleteOperands()) && - allDataOperandsAreConverted(op.getDetachOperands()); - }); - target.addDynamicallyLegalOp( [allDataOperandsAreConverted](acc::ParallelOp op) { return allDataOperandsAreConverted(op.getReductionOperands()) && diff --git a/flang/test/Transforms/OpenACC/convert-data-operands-to-llvmir.fir b/flang/test/Transforms/OpenACC/convert-data-operands-to-llvmir.fir --- a/flang/test/Transforms/OpenACC/convert-data-operands-to-llvmir.fir +++ b/flang/test/Transforms/OpenACC/convert-data-operands-to-llvmir.fir @@ -30,28 +30,6 @@ fir.has_value %0 : !fir.array<10xf32> } -func.func @_QQsub_enter_exit() attributes {fir.bindc_name = "a"} { - %0 = fir.address_of(@_QFEa) : !fir.ref> - acc.exit_data copyout(%0 : !fir.ref>) - return -} - -// CHECK-LABEL: func.func @_QQsub_enter_exit() attributes {fir.bindc_name = "a"} { -// CHECK: %[[ADDR:.*]] = fir.address_of(@_QFEa) : !fir.ref> -// CHECK: %[[CAST1:.*]] = builtin.unrealized_conversion_cast %[[ADDR]] : !fir.ref> to !llvm.ptr> -// CHECK: acc.exit_data copyout(%[[CAST1]] : !llvm.ptr>) - -// LLVMIR-LABEL: llvm.func @_QQsub_enter_exit() attributes {fir.bindc_name = "a"} { -// LLVMIR: %[[ADDR:.*]] = llvm.mlir.addressof @_QFEa : !llvm.ptr> -// LLVMIR: acc.exit_data copyout(%[[ADDR]] : !llvm.ptr>) - -// ----- - -fir.global internal @_QFEa : !fir.array<10xf32> { - %0 = fir.undefined !fir.array<10xf32> - fir.has_value %0 : !fir.array<10xf32> -} - func.func @_QQsub_parallel() attributes {fir.bindc_name = "test"} { %0 = fir.address_of(@_QFEa) : !fir.ref> %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"} diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -813,9 +813,6 @@ Optional:$waitDevnum, Variadic:$waitOperands, UnitAttr:$wait, - Variadic:$copyoutOperands, - Variadic:$deleteOperands, - Variadic:$detachOperands, Variadic:$dataClauseOperands, UnitAttr:$finalize); @@ -833,9 +830,6 @@ | `async` `(` $asyncOperand `:` type($asyncOperand) `)` | `wait_devnum` `(` $waitDevnum `:` type($waitDevnum) `)` | `wait` `(` $waitOperands `:` type($waitOperands) `)` - | `copyout` `(` $copyoutOperands `:` type($copyoutOperands) `)` - | `delete` `(` $deleteOperands `:` type($deleteOperands) `)` - | `detach` `(` $detachOperands `:` type($detachOperands) `)` | `dataOperands` `(` $dataClauseOperands `:` type($dataClauseOperands) `)` ) attr-dict-with-keyword diff --git a/mlir/lib/Conversion/OpenACCToLLVM/OpenACCToLLVM.cpp b/mlir/lib/Conversion/OpenACCToLLVM/OpenACCToLLVM.cpp --- a/mlir/lib/Conversion/OpenACCToLLVM/OpenACCToLLVM.cpp +++ b/mlir/lib/Conversion/OpenACCToLLVM/OpenACCToLLVM.cpp @@ -156,7 +156,6 @@ void mlir::populateOpenACCToLLVMConversionPatterns( LLVMTypeConverter &converter, RewritePatternSet &patterns) { patterns.add>(converter); - patterns.add>(converter); patterns.add>(converter); } @@ -208,13 +207,6 @@ allDataOperandsAreConverted(op.getAttachOperands()); }); - target.addDynamicallyLegalOp( - [allDataOperandsAreConverted](acc::ExitDataOp op) { - return allDataOperandsAreConverted(op.getCopyoutOperands()) && - allDataOperandsAreConverted(op.getDeleteOperands()) && - allDataOperandsAreConverted(op.getDetachOperands()); - }); - target.addDynamicallyLegalOp( [allDataOperandsAreConverted](acc::ParallelOp op) { return allDataOperandsAreConverted(op.getReductionOperands()) && diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -541,11 +541,9 @@ // 2.6.6. Data Exit Directive restriction // At least one copyout, delete, or detach clause must appear on an exit data // directive. - if (getCopyoutOperands().empty() && getDeleteOperands().empty() && - getDetachOperands().empty() && getDataClauseOperands().empty()) - return emitError( - "at least one operand in copyout, delete or detach must appear on the " - "exit data operation"); + if (getDataClauseOperands().empty()) + return emitError("at least one operand must be present in dataOperands on " + "the exit data operation"); // The async attribute represent the async clause without value. Therefore the // attribute and operand cannot appear at the same time. @@ -564,8 +562,7 @@ } unsigned ExitDataOp::getNumDataOperands() { - return getCopyoutOperands().size() + getDeleteOperands().size() + - getDetachOperands().size() + getDataClauseOperands().size(); + return getDataClauseOperands().size(); } Value ExitDataOp::getDataOperand(unsigned i) { diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp --- a/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.cpp @@ -202,17 +202,31 @@ unsigned index = 0; + llvm::SmallVector deleteOperands, copyoutOperands; + for (mlir::Value dataOp : op.getDataClauseOperands()) { + if (auto devicePtrOp = mlir::dyn_cast_or_null( + dataOp.getDefiningOp())) { + for (auto &u : devicePtrOp.getAccPtr().getUses()) { + if (mlir::dyn_cast_or_null(u.getOwner())) + deleteOperands.push_back(devicePtrOp.getVarPtr()); + else if (mlir::dyn_cast_or_null(u.getOwner())) + copyoutOperands.push_back(devicePtrOp.getVarPtr()); + } + } + } + + auto nbTotalOperands = deleteOperands.size() + copyoutOperands.size(); + // Delete operands are handled as `delete` call. - if (failed(processOperands(builder, moduleTranslation, op, - op.getDeleteOperands(), op.getNumDataOperands(), - kDeleteFlag, flags, names, index, mapperAllocas))) + if (failed(processOperands(builder, moduleTranslation, op, deleteOperands, + nbTotalOperands, kDeleteFlag, flags, names, index, + mapperAllocas))) return failure(); // Copyout operands are handled as `from` call. - if (failed(processOperands(builder, moduleTranslation, op, - op.getCopyoutOperands(), op.getNumDataOperands(), - kHostCopyoutFlag, flags, names, index, - mapperAllocas))) + if (failed(processOperands(builder, moduleTranslation, op, copyoutOperands, + nbTotalOperands, kHostCopyoutFlag, flags, names, + index, mapperAllocas))) return failure(); return success(); @@ -509,7 +523,8 @@ "unexpected OpenACC terminator with operands"); return success(); }) - .Case([](auto op) { + .Case([](auto op) { // NOP return success(); }) diff --git a/mlir/test/Conversion/OpenACCToLLVM/convert-data-operands-to-llvmir.mlir b/mlir/test/Conversion/OpenACCToLLVM/convert-data-operands-to-llvmir.mlir --- a/mlir/test/Conversion/OpenACCToLLVM/convert-data-operands-to-llvmir.mlir +++ b/mlir/test/Conversion/OpenACCToLLVM/convert-data-operands-to-llvmir.mlir @@ -1,42 +1,5 @@ // RUN: mlir-opt -convert-openacc-to-llvm='use-opaque-pointers=1' -split-input-file %s | FileCheck %s -func.func @testexitdataop(%a: memref<10xf32>, %b: memref<10xf32>) -> () { - acc.exit_data copyout(%b : memref<10xf32>) delete(%a : memref<10xf32>) - return -} - -// CHECK: acc.exit_data copyout(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)>) delete(%{{.*}} : !llvm.struct<"openacc_data.1", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)>) - -// ----- - -func.func @testexitdataop(%a: !llvm.ptr, %b: memref<10xf32>) -> () { - acc.exit_data copyout(%b : memref<10xf32>) delete(%a : !llvm.ptr) - return -} - -// CHECK: acc.exit_data copyout(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)>) delete(%{{.*}} : !llvm.ptr) - -// ----- - -func.func @testexitdataop(%a: memref<10xi64>, %b: memref<10xf32>) -> () { - acc.exit_data copyout(%b : memref<10xf32>) delete(%a : memref<10xi64>) attributes {async} - return -} - -// CHECK: acc.exit_data copyout(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)>) delete(%{{.*}} : !llvm.struct<"openacc_data.1", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)>) attributes {async} - -// ----- - -func.func @testexitdataop(%a: memref<10xf32>, %b: memref<10xf32>) -> () { - %ifCond = arith.constant true - acc.exit_data if(%ifCond) copyout(%b : memref<10xf32>) delete(%a : memref<10xf32>) - return -} - -// CHECK: acc.exit_data if(%{{.*}}) copyout(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)>) delete(%{{.*}} : !llvm.struct<"openacc_data.1", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)>) - -// ----- - func.func @testdataregion(%a: memref<10xf32>, %b: memref<10xf32>) -> () { acc.data copy(%b : memref<10xf32>) copyout(%a : memref<10xf32>) { acc.parallel { diff --git a/mlir/test/Conversion/OpenACCToSCF/convert-openacc-to-scf.mlir b/mlir/test/Conversion/OpenACCToSCF/convert-openacc-to-scf.mlir --- a/mlir/test/Conversion/OpenACCToSCF/convert-openacc-to-scf.mlir +++ b/mlir/test/Conversion/OpenACCToSCF/convert-openacc-to-scf.mlir @@ -13,14 +13,16 @@ // ----- -func.func @testexitdataop(%a: memref<10xf32>, %ifCond: i1) -> () { - acc.exit_data if(%ifCond) delete(%a: memref<10xf32>) +func.func @testexitdataop(%a: memref, %ifCond: i1) -> () { + %0 = acc.getdeviceptr varPtr(%a : memref) -> memref + acc.exit_data if(%ifCond) dataOperands(%0 : memref) + acc.delete accPtr(%0 : memref) return } -// CHECK: func @testexitdataop(%{{.*}}: memref<10xf32>, [[IFCOND:%.*]]: i1) +// CHECK: func @testexitdataop(%{{.*}}: memref, [[IFCOND:%.*]]: i1) // CHECK: scf.if [[IFCOND]] { -// CHECK-NEXT: acc.exit_data delete(%{{.*}} : memref<10xf32>) +// CHECK-NEXT: acc.exit_data dataOperands(%{{.*}} : memref) // CHECK-NEXT: } // ----- @@ -88,21 +90,25 @@ // ----- -func.func @exit_data_true(%d1 : memref<10xf32>) { +func.func @exit_data_true(%d1 : memref) { %true = arith.constant true - acc.exit_data if(%true) delete(%d1 : memref<10xf32>) attributes {async} + %0 = acc.getdeviceptr varPtr(%d1 : memref) -> memref + acc.exit_data if(%true) dataOperands(%0 : memref) attributes {async} + acc.delete accPtr(%0 : memref) return } // CHECK-LABEL: func.func @exit_data_true // CHECK-NOT:if -// CHECK:acc.exit_data delete +// CHECK:acc.exit_data dataOperands // ----- -func.func @exit_data_false(%d1 : memref<10xf32>) { +func.func @exit_data_false(%d1 : memref) { %false = arith.constant false - acc.exit_data if(%false) delete(%d1 : memref<10xf32>) attributes {async} + %0 = acc.getdeviceptr varPtr(%d1 : memref) -> memref + acc.exit_data if(%false) dataOperands(%0 : memref) attributes {async} + acc.delete accPtr(%0 : memref) return } diff --git a/mlir/test/Dialect/OpenACC/canonicalize.mlir b/mlir/test/Dialect/OpenACC/canonicalize.mlir --- a/mlir/test/Dialect/OpenACC/canonicalize.mlir +++ b/mlir/test/Dialect/OpenACC/canonicalize.mlir @@ -23,19 +23,23 @@ // ----- -func.func @testexitdataop(%a: memref<10xf32>) -> () { +func.func @testexitdataop(%a: memref) -> () { %ifCond = arith.constant true - acc.exit_data if(%ifCond) delete(%a: memref<10xf32>) + %0 = acc.getdeviceptr varPtr(%a : memref) -> memref + acc.exit_data if(%ifCond) dataOperands(%0 : memref) + acc.delete accPtr(%0 : memref) return } -// CHECK: acc.exit_data delete(%{{.*}} : memref<10xf32>) +// CHECK: acc.exit_data dataOperands(%{{.*}} : memref) // ----- -func.func @testexitdataop(%a: memref<10xf32>) -> () { +func.func @testexitdataop(%a: memref) -> () { %ifCond = arith.constant false - acc.exit_data if(%ifCond) delete(%a: memref<10xf32>) + %0 = acc.getdeviceptr varPtr(%a : memref) -> memref + acc.exit_data if(%ifCond) dataOperands(%0 : memref) + acc.delete accPtr(%0 : memref) return } @@ -80,13 +84,15 @@ // ----- -func.func @testexitdataop(%a: memref<10xf32>, %ifCond: i1) -> () { - acc.exit_data if(%ifCond) delete(%a: memref<10xf32>) +func.func @testexitdataop(%a: memref, %ifCond: i1) -> () { + %0 = acc.getdeviceptr varPtr(%a : memref) -> memref + acc.exit_data if(%ifCond) dataOperands(%0 : memref) + acc.delete accPtr(%0 : memref) return } -// CHECK: func @testexitdataop(%{{.*}}: memref<10xf32>, [[IFCOND:%.*]]: i1) -// CHECK: acc.exit_data if(%{{.*}}) delete(%{{.*}} : memref<10xf32>) +// CHECK: func @testexitdataop(%{{.*}}: memref, [[IFCOND:%.*]]: i1) +// CHECK: acc.exit_data if(%{{.*}}) dataOperands(%{{.*}} : memref) // ----- diff --git a/mlir/test/Dialect/OpenACC/invalid.mlir b/mlir/test/Dialect/OpenACC/invalid.mlir --- a/mlir/test/Dialect/OpenACC/invalid.mlir +++ b/mlir/test/Dialect/OpenACC/invalid.mlir @@ -167,22 +167,26 @@ // ----- -// expected-error@+1 {{at least one operand in copyout, delete or detach must appear on the exit data operation}} +// expected-error@+1 {{at least one operand must be present in dataOperands on the exit data operation}} acc.exit_data attributes {async} // ----- %cst = arith.constant 1 : index -%value = memref.alloc() : memref<10xf32> +%value = memref.alloc() : memref +%0 = acc.getdeviceptr varPtr(%value : memref) -> memref // expected-error@+1 {{async attribute cannot appear with asyncOperand}} -acc.exit_data async(%cst: index) delete(%value : memref<10xf32>) attributes {async} +acc.exit_data async(%cst: index) dataOperands(%0 : memref) attributes {async} +acc.delete accPtr(%0 : memref) // ----- %cst = arith.constant 1 : index -%value = memref.alloc() : memref<10xf32> +%value = memref.alloc() : memref +%0 = acc.getdeviceptr varPtr(%value : memref) -> memref // expected-error@+1 {{wait_devnum cannot appear without waitOperands}} -acc.exit_data wait_devnum(%cst: index) delete(%value : memref<10xf32>) +acc.exit_data wait_devnum(%cst: index) dataOperands(%0 : memref) +acc.delete accPtr(%0 : memref) // ----- diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir --- a/mlir/test/Dialect/OpenACC/ops.mlir +++ b/mlir/test/Dialect/OpenACC/ops.mlir @@ -907,41 +907,101 @@ // ----- -func.func @testexitdataop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32>) -> () { +func.func @testexitdataop(%a: !llvm.ptr) -> () { %ifCond = arith.constant true %i64Value = arith.constant 1 : i64 %i32Value = arith.constant 1 : i32 %idxValue = arith.constant 1 : index - acc.exit_data copyout(%a : memref<10xf32>) - acc.exit_data delete(%a : memref<10xf32>) - acc.exit_data delete(%a : memref<10xf32>) attributes {async,finalize} - acc.exit_data detach(%a : memref<10xf32>) - acc.exit_data copyout(%a : memref<10xf32>) attributes {async} - acc.exit_data delete(%a : memref<10xf32>) attributes {wait} - acc.exit_data async(%i64Value : i64) copyout(%a : memref<10xf32>) - acc.exit_data copyout(%a : memref<10xf32>) async(%i64Value : i64) - acc.exit_data if(%ifCond) copyout(%a : memref<10xf32>) - acc.exit_data wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) copyout(%a : memref<10xf32>) + %0 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data dataOperands(%0 : !llvm.ptr) + acc.copyout accPtr(%0 : !llvm.ptr) to varPtr(%a : !llvm.ptr) + + %1 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data dataOperands(%1 : !llvm.ptr) + acc.delete accPtr(%1 : !llvm.ptr) + + %2 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data dataOperands(%2 : !llvm.ptr) attributes {async,finalize} + acc.delete accPtr(%2 : !llvm.ptr) + + %3 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data dataOperands(%3 : !llvm.ptr) + acc.detach accPtr(%3 : !llvm.ptr) + + %4 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data dataOperands(%4 : !llvm.ptr) attributes {async} + acc.copyout accPtr(%4 : !llvm.ptr) to varPtr(%a : !llvm.ptr) + + %5 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data dataOperands(%5 : !llvm.ptr) attributes {wait} + acc.delete accPtr(%5 : !llvm.ptr) + + %6 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data async(%i64Value : i64) dataOperands(%6 : !llvm.ptr) + acc.copyout accPtr(%6 : !llvm.ptr) to varPtr(%a : !llvm.ptr) + + %7 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data dataOperands(%7 : !llvm.ptr) async(%i64Value : i64) + acc.copyout accPtr(%7 : !llvm.ptr) to varPtr(%a : !llvm.ptr) + + %8 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data if(%ifCond) dataOperands(%8 : !llvm.ptr) + acc.copyout accPtr(%8 : !llvm.ptr) to varPtr(%a : !llvm.ptr) + + %9 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr + acc.exit_data wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) dataOperands(%9 : !llvm.ptr) + acc.copyout accPtr(%9 : !llvm.ptr) to varPtr(%a : !llvm.ptr) return } -// CHECK: func @testexitdataop([[ARGA:%.*]]: memref<10xf32>, [[ARGB:%.*]]: memref<10xf32>, [[ARGC:%.*]]: memref<10x10xf32>) { -// CHECK: [[IFCOND1:%.*]] = arith.constant true -// CHECK: [[I64VALUE:%.*]] = arith.constant 1 : i64 -// CHECK: [[I32VALUE:%.*]] = arith.constant 1 : i32 -// CHECK: [[IDXVALUE:%.*]] = arith.constant 1 : index -// CHECK: acc.exit_data copyout([[ARGA]] : memref<10xf32>) -// CHECK: acc.exit_data delete([[ARGA]] : memref<10xf32>) -// CHECK: acc.exit_data delete([[ARGA]] : memref<10xf32>) attributes {async, finalize} -// CHECK: acc.exit_data detach([[ARGA]] : memref<10xf32>) -// CHECK: acc.exit_data copyout([[ARGA]] : memref<10xf32>) attributes {async} -// CHECK: acc.exit_data delete([[ARGA]] : memref<10xf32>) attributes {wait} -// CHECK: acc.exit_data async([[I64VALUE]] : i64) copyout([[ARGA]] : memref<10xf32>) -// CHECK: acc.exit_data async([[I64VALUE]] : i64) copyout([[ARGA]] : memref<10xf32>) -// CHECK: acc.exit_data if([[IFCOND]]) copyout([[ARGA]] : memref<10xf32>) -// CHECK: acc.exit_data wait_devnum([[I64VALUE]] : i64) wait([[I32VALUE]], [[IDXVALUE]] : i32, index) copyout([[ARGA]] : memref<10xf32>) +// CHECK: func @testexitdataop(%[[ARGA:.*]]: !llvm.ptr) { +// CHECK: %[[IFCOND:.*]] = arith.constant true +// CHECK: %[[I64VALUE:.*]] = arith.constant 1 : i64 +// CHECK: %[[I32VALUE:.*]] = arith.constant 1 : i32 +// CHECK: %[[IDXVALUE:.*]] = arith.constant 1 : index + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data dataOperands(%[[DEVPTR]] : !llvm.ptr) +// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data dataOperands(%[[DEVPTR]] : !llvm.ptr) +// CHECK: acc.delete accPtr(%[[DEVPTR]] : !llvm.ptr) + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data dataOperands(%[[DEVPTR]] : !llvm.ptr) attributes {async, finalize} +// CHECK: acc.delete accPtr(%[[DEVPTR]] : !llvm.ptr) + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data dataOperands(%[[DEVPTR]] : !llvm.ptr) +// CHECK: acc.detach accPtr(%[[DEVPTR]] : !llvm.ptr) + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data dataOperands(%[[DEVPTR]] : !llvm.ptr) attributes {async} +// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data dataOperands(%[[DEVPTR]] : !llvm.ptr) attributes {wait} +// CHECK: acc.delete accPtr(%[[DEVPTR]] : !llvm.ptr) + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data async(%[[I64VALUE]] : i64) dataOperands(%[[DEVPTR]] : !llvm.ptr) +// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data async(%[[I64VALUE]] : i64) dataOperands(%[[DEVPTR]] : !llvm.ptr) +// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data if(%[[IFCOND]]) dataOperands(%[[DEVPTR]] : !llvm.ptr) +// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) + +// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[ARGA]] : !llvm.ptr) -> !llvm.ptr +// CHECK: acc.exit_data wait_devnum(%[[I64VALUE]] : i64) wait(%[[I32VALUE]], %[[IDXVALUE]] : i32, index) dataOperands(%[[DEVPTR]] : !llvm.ptr) +// CHECK: acc.copyout accPtr(%[[DEVPTR]] : !llvm.ptr) to varPtr(%[[ARGA]] : !llvm.ptr) + // ----- diff --git a/mlir/test/Target/LLVMIR/openacc-llvm.mlir b/mlir/test/Target/LLVMIR/openacc-llvm.mlir --- a/mlir/test/Target/LLVMIR/openacc-llvm.mlir +++ b/mlir/test/Target/LLVMIR/openacc-llvm.mlir @@ -47,56 +47,48 @@ // ----- -llvm.func @testexitdataop(%arg0: !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, %arg1: !llvm.ptr) { - %0 = llvm.mlir.constant(10 : index) : i64 - %1 = llvm.mlir.null : !llvm.ptr - %2 = llvm.getelementptr %1[%0] : (!llvm.ptr, i64) -> !llvm.ptr - %3 = llvm.ptrtoint %2 : !llvm.ptr to i64 - %4 = llvm.extractvalue %arg0[1] : !llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)> - %5 = llvm.mlir.undef : !llvm.struct<"openacc_data", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)> - %6 = llvm.insertvalue %arg0, %5[0] : !llvm.struct<"openacc_data", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)> - %7 = llvm.insertvalue %4, %6[1] : !llvm.struct<"openacc_data", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)> - %8 = llvm.insertvalue %3, %7[2] : !llvm.struct<"openacc_data", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)> - acc.exit_data copyout(%arg1 : !llvm.ptr) delete(%8 : !llvm.struct<"openacc_data", (struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>, ptr, i64)>) +llvm.func @testexitdataop(%arg0: !llvm.ptr, %arg1: !llvm.ptr) { + %arg0_devptr = acc.getdeviceptr varPtr(%arg0 : !llvm.ptr) -> !llvm.ptr + %1 = acc.getdeviceptr varPtr(%arg1 : !llvm.ptr) -> !llvm.ptr + acc.exit_data dataOperands(%arg0_devptr, %1 : !llvm.ptr, !llvm.ptr) + acc.delete accPtr(%arg0_devptr : !llvm.ptr) + acc.copyout accPtr(%1 : !llvm.ptr) to varPtr(%arg1 : !llvm.ptr) llvm.return } // CHECK: %struct.ident_t = type { i32, i32, i32, i32, ptr } -// CHECK: [[LOCSTR:@.*]] = private unnamed_addr constant [{{[0-9]*}} x i8] c";{{.*}};testexitdataop;{{[0-9]*}};{{[0-9]*}};;\00", align 1 -// CHECK: [[LOCGLOBAL:@.*]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{[0-9]*}}, ptr [[LOCSTR]] }, align 8 -// CHECK: [[MAPNAME1:@.*]] = private unnamed_addr constant [{{[0-9]*}} x i8] c";{{.*}};unknown;{{[0-9]*}};{{[0-9]*}};;\00", align 1 -// CHECK: [[MAPNAME2:@.*]] = private unnamed_addr constant [{{[0-9]*}} x i8] c";{{.*}};unknown;{{[0-9]*}};{{[0-9]*}};;\00", align 1 -// CHECK: [[MAPTYPES:@.*]] = private unnamed_addr constant [{{[0-9]*}} x i64] [i64 8, i64 2] -// CHECK: [[MAPNAMES:@.*]] = private constant [{{[0-9]*}} x ptr] [ptr [[MAPNAME1]], ptr [[MAPNAME2]]] +// CHECK: @[[LOCSTR:.*]] = private unnamed_addr constant [{{[0-9]*}} x i8] c";{{.*}};testexitdataop;{{[0-9]*}};{{[0-9]*}};;\00" +// CHECK: @[[LOCGLOBAL:.*]] = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 {{[0-9]*}}, ptr @[[LOCSTR]] } +// CHECK: @[[MAPNAME1:.*]] = private unnamed_addr constant [{{[0-9]*}} x i8] c";{{.*}};unknown;{{[0-9]*}};{{[0-9]*}};;\00" +// CHECK: @[[MAPNAME2:.*]] = private unnamed_addr constant [{{[0-9]*}} x i8] c";{{.*}};unknown;{{[0-9]*}};{{[0-9]*}};;\00" +// CHECK: @[[MAPTYPES:.*]] = private unnamed_addr constant [{{[0-9]*}} x i64] [i64 8, i64 2] +// CHECK: @[[MAPNAMES:.*]] = private constant [{{[0-9]*}} x ptr] [ptr @[[MAPNAME1]], ptr @[[MAPNAME2]]] -// CHECK: define void @testexitdataop({ ptr, ptr, i64, [1 x i64], [1 x i64] } %{{.*}}, ptr [[SIMPLEPTR:%.*]]) -// CHECK: [[ARGBASE_ALLOCA:%.*]] = alloca [{{[0-9]*}} x ptr], align 8 -// CHECK: [[ARG_ALLOCA:%.*]] = alloca [{{[0-9]*}} x ptr], align 8 -// CHECK: [[SIZE_ALLOCA:%.*]] = alloca [{{[0-9]*}} x i64], align 8 +// CHECK: define void @testexitdataop(ptr %[[PTR0:.*]], ptr %[[PTR1:.*]]) +// CHECK: %[[OFFLOAD_BASEPTRS:.*]] = alloca [{{[0-9]*}} x ptr] +// CHECK: %[[OFFLOAD_PTRS:.*]] = alloca [{{[0-9]*}} x ptr] +// CHECK: %[[OFFLOAS_SIZES:.*]] = alloca [{{[0-9]*}} x i64] -// CHECK: [[ARGBASE:%.*]] = extractvalue %openacc_data %{{.*}}, 0 -// CHECK: [[ARG:%.*]] = extractvalue %openacc_data %{{.*}}, 1 -// CHECK: [[ARGSIZE:%.*]] = extractvalue %openacc_data %{{.*}}, 2 -// CHECK: [[ARGBASEGEP:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ARGBASE_ALLOCA]], i32 0, i32 0 -// CHECK: store { ptr, ptr, i64, [1 x i64], [1 x i64] } [[ARGBASE]], ptr [[ARGBASEGEP]], align 8 -// CHECK: [[ARGGEP:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ARG_ALLOCA]], i32 0, i32 0 -// CHECK: store ptr [[ARG]], ptr [[ARGGEP]], align 8 -// CHECK: [[SIZEGEP:%.*]] = getelementptr inbounds [2 x i64], ptr [[SIZE_ALLOCA]], i32 0, i32 0 -// CHECK: store i64 [[ARGSIZE]], ptr [[SIZEGEP]], align 4 +// CHECK: %[[OFFLOAD_BASEPTRS_GEP:.*]] = getelementptr inbounds [2 x ptr], ptr %[[OFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK: store ptr %[[PTR0]], ptr %[[OFFLOAD_BASEPTRS_GEP]] +// CHECK: %[[OFFLOAD_PTRS_GEP:.*]] = getelementptr inbounds [2 x ptr], ptr %[[OFFLOAD_PTRS]], i32 0, i32 0 +// CHECK: store ptr %[[PTR0]], ptr %[[OFFLOAD_PTRS_GEP]] +// CHECK: %[[OFFLOAS_SIZES_GEP:.*]] = getelementptr inbounds [2 x i64], ptr %[[OFFLOAS_SIZES]], i32 0, i32 0 +// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[OFFLOAS_SIZES_GEP]] -// CHECK: [[ARGBASEGEP:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ARGBASE_ALLOCA]], i32 0, i32 1 -// CHECK: store ptr [[SIMPLEPTR]], ptr [[ARGBASEGEP]], align 8 -// CHECK: [[ARGGEP:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ARG_ALLOCA]], i32 0, i32 1 -// CHECK: store ptr [[SIMPLEPTR]], ptr [[ARGGEP]], align 8 -// CHECK: [[SIZEGEP:%.*]] = getelementptr inbounds [2 x i64], ptr [[SIZE_ALLOCA]], i32 0, i32 1 -// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr [[SIZEGEP]], align 4 +// CHECK: %[[OFFLOAD_BASEPTRS_GEP:.*]] = getelementptr inbounds [2 x ptr], ptr %[[OFFLOAD_BASEPTRS]], i32 0, i32 1 +// CHECK: store ptr %[[PTR1]], ptr %[[OFFLOAD_BASEPTRS_GEP]] +// CHECK: %[[OFFLOAD_PTRS_GEP:.*]] = getelementptr inbounds [2 x ptr], ptr %[[OFFLOAD_PTRS]], i32 0, i32 1 +// CHECK: store ptr %[[PTR1]], ptr %[[OFFLOAD_PTRS_GEP]] +// CHECK: %[[OFFLOAS_SIZES_GEP:.*]] = getelementptr inbounds [2 x i64], ptr %[[OFFLOAS_SIZES]], i32 0, i32 1 +// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[OFFLOAS_SIZES_GEP]] -// CHECK: [[ARGBASE_ALLOCA_GEP:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ARGBASE_ALLOCA]], i32 0, i32 0 -// CHECK: [[ARG_ALLOCA_GEP:%.*]] = getelementptr inbounds [2 x ptr], ptr [[ARG_ALLOCA]], i32 0, i32 0 -// CHECK: [[SIZE_ALLOCA_GEP:%.*]] = getelementptr inbounds [2 x i64], ptr [[SIZE_ALLOCA]], i32 0, i32 0 +// CHECK: %[[OFFLOAD_BASEPTRS_GEP:.*]] = getelementptr inbounds [2 x ptr], ptr %[[OFFLOAD_BASEPTRS]], i32 0, i32 0 +// CHECK: %[[OFFLOAD_PTRS_GEP:.*]] = getelementptr inbounds [2 x ptr], ptr %[[OFFLOAD_PTRS]], i32 0, i32 0 +// CHECK: %[[OFFLOAS_SIZES_GEP:.*]] = getelementptr inbounds [2 x i64], ptr %[[OFFLOAS_SIZES]], i32 0, i32 0 -// CHECK: call void @__tgt_target_data_end_mapper(ptr [[LOCGLOBAL]], i64 -1, i32 2, ptr [[ARGBASE_ALLOCA_GEP]], ptr [[ARG_ALLOCA_GEP]], ptr [[SIZE_ALLOCA_GEP]], ptr [[MAPTYPES]], ptr [[MAPNAMES]], ptr null) +// CHECK: call void @__tgt_target_data_end_mapper(ptr @[[LOCGLOBAL]], i64 -1, i32 2, ptr %[[OFFLOAD_BASEPTRS_GEP]], ptr %[[OFFLOAD_PTRS_GEP]], ptr %[[OFFLOAS_SIZES_GEP]], ptr @[[MAPTYPES]], ptr @[[MAPNAMES]], ptr null) // CHECK: declare void @__tgt_target_data_end_mapper(ptr, i64, i32, ptr, ptr, ptr, ptr, ptr, ptr) #0