diff options
author | Valentin Clement <clementval@gmail.com> | 2023-04-25 13:26:48 -0700 |
---|---|---|
committer | Valentin Clement <clementval@gmail.com> | 2023-04-25 13:27:11 -0700 |
commit | 6e711b951c2acfa3406cc929ebf9249fd9cc8503 (patch) | |
tree | 5a4e986d56c7c0ba705bc5234ad87b7b557b65fe | |
parent | c16a8811454f18b85597bfcb763fca27724e792c (diff) | |
download | llvm-6e711b951c2acfa3406cc929ebf9249fd9cc8503.zip llvm-6e711b951c2acfa3406cc929ebf9249fd9cc8503.tar.gz llvm-6e711b951c2acfa3406cc929ebf9249fd9cc8503.tar.bz2 |
[flang][openacc] Add initial support to lower assumed size array in data operand
Add lowering for assumed size array in data clause to the newly
added data operand operations.
Depends on D148840
Reviewed By: razvanlupusoru
Differential Revision: https://reviews.llvm.org/D148969
-rw-r--r-- | flang/lib/Lower/OpenACC.cpp | 98 | ||||
-rw-r--r-- | flang/test/Lower/OpenACC/acc-enter-data.f90 | 135 |
2 files changed, 211 insertions, 22 deletions
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 02b77c7..6d06dfc 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -102,6 +102,31 @@ genObjectList(const Fortran::parser::AccObjectList &objectList, } static llvm::SmallVector<mlir::Value> +genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc, + Fortran::lower::AbstractConverter &converter, + Fortran::lower::SymbolRef sym, mlir::Value box, int rank) { + llvm::SmallVector<mlir::Value> bounds; + mlir::Type idxTy = builder.getIndexType(); + fir::ExtendedValue dataExv = converter.getSymbolExtendedValue(sym); + mlir::Type boundTy = builder.getType<mlir::acc::DataBoundsType>(); + mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1); + assert(box.getType().isa<fir::BaseBoxType>() && "expect firbox or fir.class"); + for (int dim = 0; dim < rank; ++dim) { + mlir::Value d = builder.createIntegerConstant(loc, idxTy, dim); + mlir::Value baseLb = + fir::factory::readLowerBound(builder, loc, dataExv, dim, one); + auto dimInfo = + builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, d); + mlir::Value empty; + mlir::Value bound = builder.create<mlir::acc::DataBoundsOp>( + loc, boundTy, empty, empty, dimInfo.getExtent(), + dimInfo.getByteStride(), true, baseLb); + bounds.push_back(bound); + } + return bounds; +} + +static llvm::SmallVector<mlir::Value> genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext &stmtCtx, @@ -126,6 +151,15 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value baseLb = fir::factory::readLowerBound(builder, loc, dataExv, dimension, one); bool defaultLb = baseLb == one; + mlir::Value stride; + bool strideInBytes = false; + if (fir::getBase(dataExv).getType().isa<fir::BaseBoxType>()) { + mlir::Value d = builder.createIntegerConstant(loc, idxTy, dimension); + auto dimInfo = builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, + fir::getBase(dataExv), d); + stride = dimInfo.getByteStride(); + strideInBytes = true; + } const auto &lower{std::get<0>(triplet->t)}; if (lower) { @@ -188,9 +222,8 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, if (lbound) extent = builder.create<mlir::arith::SubIOp>(loc, extent, lbound); } - mlir::Value empty; mlir::Value bound = builder.create<mlir::acc::DataBoundsOp>( - loc, boundTy, lbound, ubound, extent, empty, false, baseLb); + loc, boundTy, lbound, ubound, extent, stride, strideInBytes, baseLb); bounds.push_back(bound); ++dimension; } @@ -209,9 +242,8 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - auto createOpAndAddOperand = [&](Fortran::lower::SymbolRef sym, - llvm::StringRef name, - mlir::Location loc) -> Op { + auto getDataOperandBaseAddr = [&](Fortran::lower::SymbolRef sym, + mlir::Location loc) -> mlir::Value { mlir::Value symAddr = converter.getSymbolAddress(sym); // TODO: Might need revisiting to handle for non-shared clauses if (!symAddr) { @@ -223,14 +255,34 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, if (!symAddr) llvm::report_fatal_error("could not retrieve symbol address"); - if (symAddr.getType().isa<fir::BaseBoxType>()) - TODO(loc, "data operand operation creation for box types"); - Op op = builder.create<Op>(loc, symAddr.getType(), symAddr); + mlir::Type symTy = symAddr.getType(); + if (auto refTy = symTy.dyn_cast<fir::ReferenceType>()) + symTy = refTy.getEleTy(); + + if (auto boxTy = + fir::unwrapRefType(symAddr.getType()).dyn_cast<fir::BaseBoxType>()) + if (boxTy.getEleTy() + .isa<fir::PointerType, fir::HeapType, fir::RecordType>()) + TODO(loc, "pointer, allocatable and derived type box"); + + return symAddr; + }; + + auto createOpAndAddOperand = [&](mlir::Value baseAddr, llvm::StringRef name, + mlir::Location loc, + llvm::SmallVector<mlir::Value> &bounds) { + if (baseAddr.getType().isa<fir::BaseBoxType>()) + baseAddr = builder.create<fir::BoxAddrOp>(loc, baseAddr); + + Op op = builder.create<Op>(loc, baseAddr.getType(), baseAddr); op.setNameAttr(builder.getStringAttr(name)); op.setStructured(structured); op.setDataClause(dataClause); + if (bounds.size() > 0) + op->insertOperands(1, bounds); op->setAttr(Op::getOperandSegmentSizeAttr(), - builder.getDenseI32ArrayAttr({1, 0, 0})); + builder.getDenseI32ArrayAttr( + {1, 0, static_cast<int32_t>(bounds.size())})); dataOperands.push_back(op.getAccPtr()); return op; }; @@ -263,12 +315,10 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, asFortran, name); } asFortran << ')'; - Op op = createOpAndAddOperand(*name.symbol, asFortran.str(), - operandLocation); - op->insertOperands(1, bounds); - op->setAttr(Op::getOperandSegmentSizeAttr(), - builder.getDenseI32ArrayAttr( - {1, 0, static_cast<int32_t>(bounds.size())})); + mlir::Value baseAddr = + getDataOperandBaseAddr(*name.symbol, operandLocation); + createOpAndAddOperand(baseAddr, asFortran.str(), + operandLocation, bounds); } else if (Fortran::parser::Unwrap< Fortran::parser::StructureComponent>( designator)) { @@ -279,8 +329,15 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, &designator.u)}) { const Fortran::parser::Name &name = Fortran::parser::GetLastName(*dataRef); - createOpAndAddOperand(*name.symbol, name.ToString(), - operandLocation); + mlir::Value baseAddr = + getDataOperandBaseAddr(*name.symbol, operandLocation); + llvm::SmallVector<mlir::Value> bounds; + if (baseAddr.getType().isa<fir::BaseBoxType>()) + bounds = genBoundsOpsFromBox(builder, operandLocation, + converter, *name.symbol, + baseAddr, (*expr).Rank()); + createOpAndAddOperand(baseAddr, name.ToString(), + operandLocation, bounds); } else { // Unsupported llvm::report_fatal_error( "Unsupported type of OpenACC operand"); @@ -291,8 +348,11 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList, [&](const Fortran::parser::Name &name) { mlir::Location operandLocation = converter.genLocation(name.source); - createOpAndAddOperand(*name.symbol, name.ToString(), - operandLocation); + mlir::Value baseAddr = + getDataOperandBaseAddr(*name.symbol, operandLocation); + llvm::SmallVector<mlir::Value> bounds; + createOpAndAddOperand(baseAddr, name.ToString(), operandLocation, + bounds); }}, accObject.u); } diff --git a/flang/test/Lower/OpenACC/acc-enter-data.f90 b/flang/test/Lower/OpenACC/acc-enter-data.f90 index e41a50c..e3b0290 100644 --- a/flang/test/Lower/OpenACC/acc-enter-data.f90 +++ b/flang/test/Lower/OpenACC/acc-enter-data.f90 @@ -41,11 +41,10 @@ subroutine acc_enter_data !CHECK: %[[CREATE_C:.*]] = acc.create varPtr(%[[C]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {dataClause = 8 : i64, name = "c", structured = false} !CHECK: acc.enter_data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>){{$}} - !$acc enter data copyin(a) create(b) attach(d) + !$acc enter data copyin(a) create(b) !CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false} !CHECK: %[[CREATE_B:.*]] = acc.create varPtr(%[[B]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "b", structured = false} -!CHECK: %[[ATTACH_D:.*]] = acc.attach varPtr(%[[D]] : !fir.ref<!fir.box<!fir.ptr<f32>>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>> {name = "d", structured = false} -!CHECK: acc.enter_data dataOperands(%[[COPYIN_A]], %[[CREATE_B]], %[[ATTACH_D]] : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.box<!fir.ptr<f32>>>){{$}} +!CHECK: acc.enter_data dataOperands(%[[COPYIN_A]], %[[CREATE_B]] : !fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>){{$}} !$acc enter data create(a) async !CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) -> !fir.ref<!fir.array<10x10xf32>> {name = "a", structured = false} @@ -219,3 +218,133 @@ subroutine acc_enter_data_non_default_lb() !CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<10xi32>>) end subroutine + +! Test lowering of assumed size arrays. +subroutine acc_enter_data_assumed(a, b, n, m) + integer :: n, m + real :: a(:) + real :: b(10:) + +!CHECK-LABEL: func.func @_QPacc_enter_data_assumed( +!CHECK-SAME: %[[A:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "b"}, %[[N:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}, %[[M:.*]]: !fir.ref<i32> {fir.bindc_name = "m"}) { + +!CHECK: %[[LB_C10:.*]] = arith.constant 10 : i64 +!CHECK: %[[LB_C10_IDX:.*]] = fir.convert %[[LB_C10]] : (i64) -> index + + !$acc enter data create(a) +!CHECK: %[[C1:.*]] = arith.constant 1 : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[BOUND:.*]] = acc.bounds extent(%[[DIMS]]#1 : index) stride(%[[DIMS]]#2 : index) startIdx(%[[C1]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[A]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "a", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + + !$acc enter data create(a(:)) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS1:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[BOUND:.*]] = acc.bounds extent(%[[DIMS1]]#1 : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[ONE]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[A]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "a(:)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + + !$acc enter data create(a(2:)) +!CHECK: %[[SIDX:.*]] = arith.constant 1 : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[LB:.*]] = arith.constant 1 : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS1:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[EXT:.*]] = arith.subi %[[DIMS1]]#1, %[[LB]] : index +!CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) extent(%[[EXT]] : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[SIDX]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[A]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "a(2:)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + + !$acc enter data create(a(:4)) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[UB:.*]] = arith.constant 3 : index +!CHECK: %[[BOUND:.*]] = acc.bounds upperbound(%[[UB]] : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[ONE]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[A]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "a(:4)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + + !$acc enter data create(a(6:10)) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[LB:.*]] = arith.constant 5 : index +!CHECK: %[[UB:.*]] = arith.constant 9 : index +!CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[ONE]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[A]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "a(6:10)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + + !$acc enter data create(a(n:)) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[LOAD_N:.*]] = fir.load %[[N]] : !fir.ref<i32> +!CHECK: %[[CONVERT_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> index +!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT_N]], %[[ONE]] : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[EXT:.*]] = arith.subi %[[DIMS]]#1, %[[LB]] : index +!CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) extent(%[[EXT]] : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[ONE]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[A]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "a(n:)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + + !$acc enter data create(a(:m)) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[LOAD_M:.*]] = fir.load %[[M]] : !fir.ref<i32> +!CHECK: %[[CONVERT_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> index +!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT_M]], %[[ONE]] : index +!CHECK: %[[BOUND:.*]] = acc.bounds upperbound(%[[UB]] : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[ONE]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[A]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "a(:m)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + + !$acc enter data create(a(n:m)) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[A]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[LOAD_N:.*]] = fir.load %[[N]] : !fir.ref<i32> +!CHECK: %[[CONVERT_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> index +!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT_N]], %[[ONE]] : index +!CHECK: %[[LOAD_M:.*]] = fir.load %[[M]] : !fir.ref<i32> +!CHECK: %[[CONVERT_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> index +!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT_M]], %[[ONE]] : index +!CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[ONE]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[A]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "a(n:m)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + + !$acc enter data create(b(:m)) +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[B]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[LOAD_M:.*]] = fir.load %[[M]] : !fir.ref<i32> +!CHECK: %[[CONVERT_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> index +!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT_M]], %[[LB_C10_IDX]] : index +!CHECK: %[[BOUND:.*]] = acc.bounds upperbound(%[[UB]] : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[LB_C10_IDX]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[B]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "b(:m)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + + !$acc enter data create(b) +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[B]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index) +!CHECK: %[[BOUND:.*]] = acc.bounds extent(%[[DIMS0]]#1 : index) stride(%[[DIMS0]]#2 : index) startIdx(%[[LB_C10_IDX]] : index) {strideInBytes = true} +!CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[B]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> +!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.ref<!fir.array<?xf32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<?xf32>> {name = "b", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<?xf32>>) + +end subroutine + |