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 @@ -462,20 +462,20 @@ } } -template -static void genDataExitOperantions(fir::FirOpBuilder &builder, - llvm::SmallVector operands, - bool structured, bool implicit) { +template +static void genDataExitOperations(fir::FirOpBuilder &builder, + llvm::SmallVector operands, + bool structured, bool implicit) { for (mlir::Value operand : operands) { - auto getDevicePtrOp = mlir::dyn_cast_or_null(operand.getDefiningOp()); - assert(getDevicePtrOp && "acc.getdeivceptr op expected"); + auto entryOp = mlir::dyn_cast_or_null(operand.getDefiningOp()); + assert(entryOp && "data entry op expected"); mlir::Value varPtr; - if constexpr (std::is_same_v) - varPtr = getDevicePtrOp.getVarPtr(); - builder.create(getDevicePtrOp.getLoc(), - getDevicePtrOp.getAccPtr(), varPtr, getDevicePtrOp.getBounds(), - getDevicePtrOp.getDataClause(), structured, implicit, - builder.getStringAttr(*getDevicePtrOp.getName())); + if constexpr (std::is_same_v) + varPtr = entryOp.getVarPtr(); + builder.create(entryOp.getLoc(), entryOp.getAccPtr(), varPtr, + entryOp.getBounds(), entryOp.getDataClause(), + structured, implicit, + builder.getStringAttr(*entryOp.getName())); } } @@ -979,18 +979,38 @@ return computeOp; } +template +static void genDataOperandOperationsWithModifier( + const Clause *x, Fortran::lower::AbstractConverter &converter, + Fortran::semantics::SemanticsContext &semanticsContext, + Fortran::lower::StatementContext &stmtCtx, + Fortran::parser::AccDataModifier::Modifier mod, + llvm::SmallVectorImpl &dataClauseOperands, + const mlir::acc::DataClause clause, + const mlir::acc::DataClause clauseWithModifier) { + const Fortran::parser::AccObjectListWithModifier &listWithModifier = x->v; + const auto &accObjectList = + std::get(listWithModifier.t); + const auto &modifier = + std::get>( + listWithModifier.t); + mlir::acc::DataClause dataClause = + (modifier && (*modifier).v == mod) ? clauseWithModifier : clause; + genDataOperandOperations(accObjectList, converter, semanticsContext, + stmtCtx, dataClauseOperands, dataClause, + /*structured=*/true); +} + static void genACCDataOp(Fortran::lower::AbstractConverter &converter, mlir::Location currentLocation, Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::StatementContext &stmtCtx, const Fortran::parser::AccClauseList &accClauseList) { mlir::Value ifCond; - llvm::SmallVector copyOperands, copyinOperands, - copyinReadonlyOperands, copyoutOperands, copyoutZeroOperands, - createOperands, createZeroOperands, noCreateOperands, presentOperands, - deviceptrOperands, attachOperands, dataClauseOperands; + llvm::SmallVector attachEntryOperands, dataClauseOperands, + copyEntryOperands, copyoutEntryOperands; - fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); // Lower clauses values mapped to operands. // Keep track of each group of operands separatly as clauses can appear @@ -1002,68 +1022,91 @@ genIfClause(converter, clauseLocation, ifClause, ifCond, stmtCtx); } else if (const auto *copyClause = std::get_if(&clause.u)) { - genObjectList(copyClause->v, converter, semanticsContext, stmtCtx, - copyOperands); + genDataOperandOperations( + copyClause->v, converter, semanticsContext, stmtCtx, + copyEntryOperands, mlir::acc::DataClause::acc_copy, + /*structured=*/true); } else if (const auto *copyinClause = std::get_if(&clause.u)) { - genObjectListWithModifier( + genDataOperandOperationsWithModifier( copyinClause, converter, semanticsContext, stmtCtx, Fortran::parser::AccDataModifier::Modifier::ReadOnly, - copyinReadonlyOperands, copyinOperands); + dataClauseOperands, mlir::acc::DataClause::acc_copyin, + mlir::acc::DataClause::acc_copyin_readonly); } else if (const auto *copyoutClause = std::get_if( &clause.u)) { - genObjectListWithModifier( + genDataOperandOperationsWithModifier( copyoutClause, converter, semanticsContext, stmtCtx, - Fortran::parser::AccDataModifier::Modifier::Zero, copyoutZeroOperands, - copyoutOperands); + Fortran::parser::AccDataModifier::Modifier::ReadOnly, + copyoutEntryOperands, mlir::acc::DataClause::acc_copyout, + mlir::acc::DataClause::acc_copyout_zero); } else if (const auto *createClause = std::get_if(&clause.u)) { - genObjectListWithModifier( + genDataOperandOperationsWithModifier( createClause, converter, semanticsContext, stmtCtx, - Fortran::parser::AccDataModifier::Modifier::Zero, createZeroOperands, - createOperands); + Fortran::parser::AccDataModifier::Modifier::Zero, dataClauseOperands, + mlir::acc::DataClause::acc_create, + mlir::acc::DataClause::acc_create_zero); } else if (const auto *noCreateClause = std::get_if( &clause.u)) { - genObjectList(noCreateClause->v, converter, semanticsContext, stmtCtx, - noCreateOperands); + genDataOperandOperations( + noCreateClause->v, converter, semanticsContext, stmtCtx, + dataClauseOperands, mlir::acc::DataClause::acc_no_create, + /*structured=*/true); } else if (const auto *presentClause = std::get_if( &clause.u)) { - genObjectList(presentClause->v, converter, semanticsContext, stmtCtx, - presentOperands); + genDataOperandOperations( + presentClause->v, converter, semanticsContext, stmtCtx, + dataClauseOperands, mlir::acc::DataClause::acc_present, + /*structured=*/true); } else if (const auto *deviceptrClause = std::get_if( &clause.u)) { - genObjectList(deviceptrClause->v, converter, semanticsContext, stmtCtx, - deviceptrOperands); + genDataOperandOperations( + deviceptrClause->v, converter, semanticsContext, stmtCtx, + dataClauseOperands, mlir::acc::DataClause::acc_deviceptr, + /*structured=*/true); } else if (const auto *attachClause = std::get_if(&clause.u)) { - genObjectList(attachClause->v, converter, semanticsContext, stmtCtx, - attachOperands); + genDataOperandOperations( + attachClause->v, converter, semanticsContext, stmtCtx, + attachEntryOperands, mlir::acc::DataClause::acc_attach, + /*structured=*/true); } } + dataClauseOperands.append(attachEntryOperands); + dataClauseOperands.append(copyEntryOperands); + dataClauseOperands.append(copyoutEntryOperands); + // Prepare the operand segment size attribute and the operands value range. llvm::SmallVector operands; llvm::SmallVector operandSegments; addOperand(operands, operandSegments, ifCond); - addOperands(operands, operandSegments, copyOperands); - addOperands(operands, operandSegments, copyinOperands); - addOperands(operands, operandSegments, copyinReadonlyOperands); - addOperands(operands, operandSegments, copyoutOperands); - addOperands(operands, operandSegments, copyoutZeroOperands); - addOperands(operands, operandSegments, createOperands); - addOperands(operands, operandSegments, createZeroOperands); - addOperands(operands, operandSegments, noCreateOperands); - addOperands(operands, operandSegments, presentOperands); - addOperands(operands, operandSegments, deviceptrOperands); - addOperands(operands, operandSegments, attachOperands); + operandSegments.append({0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}); addOperands(operands, operandSegments, dataClauseOperands); - createRegionOp( - firOpBuilder, currentLocation, operands, operandSegments); + auto dataOp = createRegionOp( + builder, currentLocation, operands, operandSegments); + + auto insPt = builder.saveInsertionPoint(); + builder.setInsertionPointAfter(dataOp); + + // Create the exit operations after the region. + genDataExitOperations( + builder, copyEntryOperands, /*structured=*/true, /*implicit=*/false); + genDataExitOperations( + builder, copyoutEntryOperands, /*structured=*/true, /*implicit=*/false); + genDataExitOperations( + builder, attachEntryOperands, /*structured=*/true, /*implicit=*/false); + + builder.restoreInsertionPoint(insPt); } static void @@ -1304,10 +1347,12 @@ if (addFinalizeAttr) exitDataOp.setFinalizeAttr(builder.getUnitAttr()); - - genDataExitOperantions(builder, copyoutOperands, /*structured=*/false, /*implicit=*/false); - genDataExitOperantions(builder, deleteOperands, /*structured=*/false, /*implicit=*/false); - genDataExitOperantions(builder, detachOperands, /*structured=*/false, /*implicit=*/false); + genDataExitOperations( + builder, copyoutOperands, /*structured=*/false, /*implicit=*/false); + genDataExitOperations( + builder, deleteOperands, /*structured=*/false, /*implicit=*/false); + genDataExitOperations( + builder, detachOperands, /*structured=*/false, /*implicit=*/false); } template diff --git a/flang/test/Lower/OpenACC/acc-data-operands.f90 b/flang/test/Lower/OpenACC/acc-data-operands.f90 --- a/flang/test/Lower/OpenACC/acc-data-operands.f90 +++ b/flang/test/Lower/OpenACC/acc-data-operands.f90 @@ -1,6 +1,6 @@ ! This test checks lowering of complex OpenACC data operands. -! RUN: bbc --use-desc-for-alloc=false -fopenacc -emit-fir %s -o - | FileCheck %s +! RUN: bbc -fopenacc -emit-fir %s -o - | FileCheck %s module acc_data_operand @@ -16,39 +16,25 @@ !$acc data copyin(a(1:50)) copyout(a(51:100)) !$acc end data - - !CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_section - - !CHECK: %[[ARR:.*]] = fir.alloca !fir.array<100xf32> - - !CHECK: %[[C1:.*]] = arith.constant 1 : i64 - !CHECK: %[[LB1:.*]] = fir.convert %[[C1]] : (i64) -> index - !CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64 - !CHECK: %[[STEP1:.*]] = fir.convert %[[C1_I64]] : (i64) -> index - !CHECK: %[[C50_I64:.*]] = arith.constant 50 : i64 - !CHECK: %[[UB1:.*]] = fir.convert %[[C50_I64]] : (i64) -> index - !CHECK: %[[SHAPE1:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> - !CHECK: %[[SLICE1:.*]] = fir.slice %[[LB1]], %[[UB1]], %[[STEP1]] : (index, index, index) -> !fir.slice<1> - !CHECK: %[[ARR_SECTION1:.*]] = fir.embox %[[ARR]](%[[SHAPE1]]) [%[[SLICE1]]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>) -> !fir.box> - !CHECK: %[[MEM1:.*]] = fir.alloca !fir.box> - !CHECK: fir.store %[[ARR_SECTION1]] to %[[MEM1]] : !fir.ref>> - - !CHECK: %[[C51_I64:.*]] = arith.constant 51 : i64 - !CHECK: %[[LB2:.*]] = fir.convert %[[C51_I64]] : (i64) -> index - !CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64 - !CHECK: %[[STEP2:.*]] = fir.convert %[[C1_I64]] : (i64) -> index - !CHECK: %[[C100_I64:.*]] = arith.constant 100 : i64 - !CHECK: %[[UB2:.*]] = fir.convert %[[C100_I64]] : (i64) -> index - !CHECK: %[[SHAPE2:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> - !CHECK: %[[SLICE2:.*]] = fir.slice %[[LB2]], %[[UB2]], %[[STEP2]] : (index, index, index) -> !fir.slice<1> - !CHECK: %[[ARR_SECTION2:.*]] = fir.embox %[[ARR]](%[[SHAPE2]]) [%[[SLICE2]]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>) -> !fir.box> - !CHECK: %[[MEM2:.*]] = fir.alloca !fir.box> - !CHECK: fir.store %[[ARR_SECTION2]] to %[[MEM2]] : !fir.ref>> - - !CHECK: acc.data copyin(%[[MEM1]] : !fir.ref>>) copyout(%[[MEM2]] : !fir.ref>>) - end subroutine +! CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_section +! CHECK: %[[ARR:.*]] = fir.alloca !fir.array<100xf32> +! CHECK: %[[ONE:.*]] = arith.constant 1 : index +! CHECK: %[[LB:.*]] = arith.constant 0 : index +! CHECK: %[[UB:.*]] = arith.constant 49 : index +! CHECK: %[[BOUND_1_50:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[ONE]] : index) startIdx(%[[ONE]] : index) +! CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[ARR]] : !fir.ref>) bounds(%[[BOUND_1_50]]) -> !fir.ref> {name = "a(1:50)"} +! CHECK: %[[ONE:.*]] = arith.constant 1 : index +! CHECK: %[[LB:.*]] = arith.constant 50 : index +! CHECK: %[[UB:.*]] = arith.constant 99 : index +! CHECK: %[[BOUND_51_100:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[ONE]] : index) startIdx(%[[ONE]] : index) +! CHECK: %[[COPYOUT_CREATE:.*]] = acc.create varPtr(%[[ARR]] : !fir.ref>) bounds(%[[BOUND_51_100]]) -> !fir.ref> {dataClause = 4 : i64, name = "a(51:100)"} +! CHECK: acc.data dataOperands(%[[COPYIN]], %[[COPYOUT_CREATE]] : !fir.ref>, !fir.ref>) { +! CHECK: acc.terminator +! CHECK: } +! CHECK: acc.copyout accPtr(%[[COPYOUT_CREATE]] : !fir.ref>) bounds(%[[BOUND_51_100]]) to varPtr(%[[ARR]] : !fir.ref>) {name = "a(51:100)"} + ! Testing array sections of a derived-type component subroutine acc_operand_array_section_component() @@ -56,40 +42,46 @@ !$acc data copy(w%data(1:20)) !$acc end data - - !CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_section_component - !CHECK: %[[W:.*]] = fir.alloca !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> - !CHECK: %[[FIELD_INDEX:.*]] = fir.field_index data, !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> - !CHECK: %[[DATA_COORD:.*]] = fir.coordinate_of %[[W]], %[[FIELD_INDEX]] : (!fir.ref}>>, !fir.field) -> !fir.ref> - !CHECK: %[[C1_I64_1:.*]] = arith.constant 1 : i64 - !CHECK: %[[LB:.*]] = fir.convert %[[C1_I64_1]] : (i64) -> index - !CHECK: %[[C1_I64_2:.*]] = arith.constant 1 : i64 - !CHECK: %[[STEP:.*]] = fir.convert %[[C1_I64_2]] : (i64) -> index - !CHECK: %[[C20_I64:.*]] = arith.constant 20 : i64 - !CHECK: %[[UB:.*]] = fir.convert %[[C20_I64]] : (i64) -> index - !CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1> - !CHECK: %[[SLICE:.*]] = fir.slice %[[LB]], %[[UB]], %[[STEP]] : (index, index, index) -> !fir.slice<1> - !CHECK: %[[ARR_SECTION:.*]] = fir.embox %[[DATA_COORD]](%[[SHAPE]]) [%[[SLICE]]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>) -> !fir.box> - !CHECK: %[[MEM:.*]] = fir.alloca !fir.box> - !CHECK: fir.store %[[ARR_SECTION]] to %[[MEM]] : !fir.ref>> - !CHECK: acc.data copy(%[[MEM]] : !fir.ref>>) - end subroutine +! CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_section_component() { +! CHECK: %[[W:.*]] = fir.alloca !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> {bindc_name = "w", uniq_name = "_QMacc_data_operandFacc_operand_array_section_componentEw"} +! CHECK: %[[FIELD_DATA:.*]] = fir.field_index data, !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> +! CHECK: %[[COORD_DATA:.*]] = fir.coordinate_of %[[W]], %[[FIELD_DATA]] : (!fir.ref}>>, !fir.field) -> !fir.ref> +! CHECK: %[[ONE:.*]] = arith.constant 1 : index +! CHECK: %[[LB:.*]] = arith.constant 0 : index +! CHECK: %[[UB:.*]] = arith.constant 19 : index +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[ONE]] : index) startIdx(%[[ONE]] : index) +! CHECK: %[[COPY_COPYIN:.*]] = acc.copyin varPtr(%[[COORD_DATA]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = 3 : i64, name = "w%data(1:20)"} +! CHECK: acc.data dataOperands(%[[COPY_COPYIN]] : !fir.ref>) { +! CHECK: acc.terminator +! CHECK: } +! CHECK: acc.copyout accPtr(%[[COPY_COPYIN]] : !fir.ref>) bounds(%[[BOUND]]) to varPtr(%[[COORD_DATA]] : !fir.ref>) {dataClause = 3 : i64, name = "w%data(1:20)"} + ! Testing derived-type component without section subroutine acc_operand_derived_type_component() type(wrapper) :: w !$acc data copy(w%data) !$acc end data +end subroutine - !CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_derived_type_component - !CHECK: %[[W:.*]] = fir.alloca !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> - !CHECK: %[[FIELD_INDEX:.*]] = fir.field_index data, !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> - !CHECK: %[[DATA_COORD:.*]] = fir.coordinate_of %[[W]], %[[FIELD_INDEX]] : (!fir.ref}>>, !fir.field) -> !fir.ref> - !CHECK: acc.data copy(%[[DATA_COORD]] : !fir.ref>) { +! CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_derived_type_component() { +! CHECK: %[[W:.*]] = fir.alloca !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> {bindc_name = "w", uniq_name = "_QMacc_data_operandFacc_operand_derived_type_componentEw"} +! CHECK: %[[FIELD_DATA:.*]] = fir.field_index data, !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> +! CHECK: %[[COORD_DATA:.*]] = fir.coordinate_of %[[W]], %[[FIELD_DATA]] : (!fir.ref}>>, !fir.field) -> !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = 3 : i64, name = "w%data"} +! CHECK: acc.data dataOperands(%[[COPY_COPYIN]] : !fir.ref>) { +! CHECK: acc.terminator +! CHECK: } +! CHECK: acc.copyout accPtr(%[[COPY_COPYIN]] : !fir.ref>) bounds(%[[BOUND]]) to varPtr(%[[COORD_DATA]] : !fir.ref>) {dataClause = 3 : i64, name = "w%data"} -end subroutine ! Testing array of derived-type component without section subroutine acc_operand_array_derived_type_component() @@ -97,19 +89,28 @@ !$acc data copy(w(1)%data) !$acc end data - - !CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_derived_type_component - !CHECK: %[[W:.*]] = fir.alloca !fir.array<10x!fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>> - !CHECK: %[[C1_I64_1:.*]] = arith.constant 1 : i64 - !CHECK: %[[C1_I64_2:.*]] = arith.constant 1 : i64 - !CHECK: %[[IDX:.*]] = arith.subi %[[C1_I64_1]], %[[C1_I64_2]] : i64 - !CHECK: %[[COORD1:.*]] = fir.coordinate_of %[[W]], %[[IDX]] : (!fir.ref}>>>, i64) -> !fir.ref}>> - !CHECK: %[[COORD2:.*]] = fir.field_index data, !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> - !CHECK: %[[COORD_OF:.*]] = fir.coordinate_of %[[COORD1]], %[[COORD2]] : (!fir.ref}>>, !fir.field) -> !fir.ref> - !CHECK: acc.data copy(%[[COORD_OF]] : !fir.ref>) - end subroutine +! CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_derived_type_component() { +! CHECK: %[[W:.*]] = fir.alloca !fir.array<10x!fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}>> {bindc_name = "w", uniq_name = "_QMacc_data_operandFacc_operand_array_derived_type_componentEw"} +! CHECK: %[[C1:.*]] = arith.constant 1 : i64 +! CHECK: %[[SUB:.*]] = arith.constant 1 : i64 +! CHECK: %[[IDX:.*]] = arith.subi %[[C1]], %[[SUB]] : i64 +! CHECK: %[[W_1:.*]] = fir.coordinate_of %[[W]], %[[IDX]] : (!fir.ref}>>>, i64) -> !fir.ref}>> +! CHECK: %[[FIELD_DATA:.*]] = fir.field_index data, !fir.type<_QMacc_data_operandTwrapper{data:!fir.array<100xf32>}> +! CHECK: %[[COORD_W1_DATA:.*]] = fir.coordinate_of %[[W_1]], %[[FIELD_DATA]] : (!fir.ref}>>, !fir.field) -> !fir.ref> +! CHECK: %[[EXT:.*]] = arith.constant 100 : index +! CHECK: %[[ONE:.*]] = arith.constant 1 : index +! CHECK: %[[LB:.*]] = arith.constant 0 : index +! CHECK: %[[LBEXT:.*]] = arith.addi %[[EXT]], %[[ONE]] : index +! CHECK: %[[UB:.*]] = arith.subi %[[LBEXT]], %[[ONE]] : index +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[ONE]] : index) startIdx(%[[ONE]] : index) +! CHECK: %[[COPY_COPYIN:.*]] = acc.copyin varPtr(%[[COORD_W1_DATA]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {dataClause = 3 : i64, name = "w(1_8)%data"} +! CHECK: acc.data dataOperands(%[[COPY_COPYIN]] : !fir.ref>) { +! CHECK: acc.terminator +! CHECK: } +! CHECK: acc.copyout accPtr(%[[COPY_COPYIN]] : !fir.ref>) bounds(%[[BOUND]]) to varPtr(%[[COORD_W1_DATA]] : !fir.ref>) {dataClause = 3 : i64, name = "w(1_8)%data"} + ! Testing array sections on allocatable array subroutine acc_operand_array_section_allocatable() real, allocatable :: a(:) @@ -119,39 +120,42 @@ !$acc data copyin(a(1:50)) copyout(a(51:100)) !$acc end data - !CHECK: %[[ARR_HEAP:.*]] = fir.alloca !fir.heap> {uniq_name = "_QMacc_data_operandFacc_operand_array_section_allocatableEa.addr"} - - !CHECK: %[[LOAD_ARR0:.*]] = fir.load %[[ARR_HEAP]] : !fir.ref>> - !CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64 - !CHECK: %[[LB0:.*]] = fir.convert %[[C1_I64]] : (i64) -> index - !CHECK: %[[C1_STEP:.*]] = arith.constant 1 : i64 - !CHECK: %[[STEP0:.*]] = fir.convert %[[C1_STEP]] : (i64) -> index - !CHECK: %[[C50_I64:.*]] = arith.constant 50 : i64 - !CHECK: %[[UB0:.*]] = fir.convert %[[C50_I64]] : (i64) -> index - !CHECK: %[[SHAPE_SHIFT0:.*]] = fir.shape_shift %{{.*}}, %{{.*}} : (index, index) -> !fir.shapeshift<1> - !CHECK: %[[SLICE0:.*]] = fir.slice %[[LB0]], %[[UB0]], %[[STEP0]] : (index, index, index) -> !fir.slice<1> - !CHECK: %[[ARR_SECTION0:.*]] = fir.embox %[[LOAD_ARR0]](%[[SHAPE_SHIFT0]]) [%[[SLICE0]]] : (!fir.heap>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box> - !CHECK: %[[MEM0:.*]] = fir.alloca !fir.box> - !CHECK: fir.store %[[ARR_SECTION0]] to %[[MEM0]] : !fir.ref>> - - !CHECK: %[[LOAD_ARR1:.*]] = fir.load %[[ARR_HEAP]] : !fir.ref>> - !CHECK: %[[C51_I64:.*]] = arith.constant 51 : i64 - !CHECK: %[[LB1:.*]] = fir.convert %[[C51_I64]] : (i64) -> index - !CHECK: %[[C1_STEP:.*]] = arith.constant 1 : i64 - !CHECK: %[[STEP1:.*]] = fir.convert %[[C1_STEP]] : (i64) -> index - !CHECK: %[[C100_I64:.*]] = arith.constant 100 : i64 - !CHECK: %[[UB1:.*]] = fir.convert %[[C100_I64]] : (i64) -> index - !CHECK: %[[SHAPE_SHIFT1:.*]] = fir.shape_shift %{{.*}}, %{{.*}} : (index, index) -> !fir.shapeshift<1> - !CHECK: %[[SLICE1:.*]] = fir.slice %[[LB1]], %[[UB1]], %[[STEP1]] : (index, index, index) -> !fir.slice<1> - !CHECK: %[[ARR_SECTION1:.*]] = fir.embox %[[LOAD_ARR1]](%[[SHAPE_SHIFT1]]) [%[[SLICE1]]] : (!fir.heap>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box> - !CHECK: %[[MEM1:.*]] = fir.alloca !fir.box> - !CHECK: fir.store %[[ARR_SECTION1]] to %[[MEM1]] : !fir.ref>> - - !CHECK: acc.data copyin(%[[MEM0]] : !fir.ref>>) copyout(%[[MEM1]] : !fir.ref>>) - deallocate(a) end subroutine +! CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_section_allocatable() { +! CHECK: %[[A:.*]] = fir.alloca !fir.box>> {bindc_name = "a", uniq_name = "_QMacc_data_operandFacc_operand_array_section_allocatableEa"} +! CHECK: %[[LOAD_BOX_A_0:.*]] = fir.load %[[A]] : !fir.ref>>> +! CHECK: %[[LOAD_BOX_A_1:.*]] = fir.load %[[A]] : !fir.ref>>> +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[DIMS0_0:.*]]:3 = fir.box_dims %[[LOAD_BOX_A_1]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[DIMS0_1:.*]]:3 = fir.box_dims %[[LOAD_BOX_A_0]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[C1:.*]] = arith.constant 1 : index +! CHECK: %[[LB:.*]] = arith.subi %[[C1]], %[[DIMS0_0]]#0 : index +! CHECK: %[[C50:.*]] = arith.constant 50 : index +! CHECK: %[[UB:.*]] = arith.subi %[[C50]], %[[DIMS0_0]]#0 : index +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[DIMS0_1]]#2 : index) startIdx(%[[DIMS0_0]]#0 : index) {strideInBytes = true} +! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD_BOX_A_0]] : (!fir.box>>) -> !fir.heap> +! CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[BOX_ADDR]] : !fir.heap>) bounds(%[[BOUND]]) -> !fir.heap> {name = "a(1:50)"} +! CHECK: %[[LOAD_BOX_A_0:.*]] = fir.load %[[A]] : !fir.ref>>> +! CHECK: %[[LOAD_BOX_A_1:.*]] = fir.load %[[A]] : !fir.ref>>> +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[DIMS0_0:.*]]:3 = fir.box_dims %[[LOAD_BOX_A_1]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[DIMS0_1:.*]]:3 = fir.box_dims %[[LOAD_BOX_A_0]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[C51:.*]] = arith.constant 51 : index +! CHECK: %[[LB:.*]] = arith.subi %[[C51]], %[[DIMS0_0]]#0 : index +! CHECK: %[[C100:.*]] = arith.constant 100 : index +! CHECK: %[[UB:.*]] = arith.subi %[[C100]], %[[DIMS0_0]]#0 : index +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[DIMS0_1]]#2 : index) startIdx(%[[DIMS0_0]]#0 : index) {strideInBytes = true} +! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD_BOX_A_0]] : (!fir.box>>) -> !fir.heap> +! CHECK: %[[COPYOUT_CREATE:.*]] = acc.create varPtr(%[[BOX_ADDR]] : !fir.heap>) bounds(%[[BOUND]]) -> !fir.heap> {dataClause = 4 : i64, name = "a(51:100)"} +! CHECK: acc.data dataOperands(%[[COPYIN]], %[[COPYOUT_CREATE]] : !fir.heap>, !fir.heap>) { +! CHECK: acc.terminator +! CHECK: } +! CHECK: acc.copyout accPtr(%[[COPYOUT_CREATE]] : !fir.heap>) bounds(%[[BOUND]]) to varPtr(%[[BOX_ADDR]] : !fir.heap>) {name = "a(51:100)"} + ! Testing array sections on pointer array subroutine acc_operand_array_section_pointer() @@ -162,30 +166,26 @@ !$acc data copyin(p(1:50)) !$acc end data +end subroutine - !CHECK: %[[C100:.*]] = arith.constant 100 : index - !CHECK: %[[ARR:.*]] = fir.alloca !fir.array<100xf32> {bindc_name = "a", fir.target, uniq_name = "_QMacc_data_operandFacc_operand_array_section_pointerEa"} - !CHECK: %[[PTR:.*]] = fir.alloca !fir.box>> {bindc_name = "p", uniq_name = "_QMacc_data_operandFacc_operand_array_section_pointerEp"} - !CHECK: %[[SHAPE0:.*]] = fir.shape %[[C100]] : (index) -> !fir.shape<1> - !CHECK: %[[EMBOX0:.*]] = fir.embox %[[ARR]](%[[SHAPE0]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box>> - !CHECK: fir.store %[[EMBOX0]] to %[[PTR]] : !fir.ref>>> - !CHECK: %[[PTR_LOAD:.*]] = fir.load %[[PTR]] : !fir.ref>>> - !CHECK: %[[C0:.*]] = arith.constant 0 : index - !CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[PTR_LOAD]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) - !CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64 - !CHECK: %[[LB0:.*]] = fir.convert %[[C1_I64]] : (i64) -> index - !CHECK: %[[C1_STEP:.*]] = arith.constant 1 : i64 - !CHECK: %[[STEP0:.*]] = fir.convert %[[C1_STEP]] : (i64) -> index - !CHECK: %[[C50_I64:.*]] = arith.constant 50 : i64 - !CHECK: %[[UB0:.*]] = fir.convert %[[C50_I64]] : (i64) -> index - !CHECK: %[[SHIFT0:.*]] = fir.shift %[[BOX_DIMS]]#0 : (index) -> !fir.shift<1> - !CHECK: %[[SLICE0:.*]] = fir.slice %[[LB0]], %[[UB0]], %[[STEP0]] : (index, index, index) -> !fir.slice<1> - !CHECK: %[[REBOX0:.*]] = fir.rebox %7(%[[SHIFT0]]) [%[[SLICE0]]] : (!fir.box>>, !fir.shift<1>, !fir.slice<1>) -> !fir.box> - !CHECK: %[[MEM0:.*]] = fir.alloca !fir.box> - !CHECK: fir.store %[[REBOX0]] to %[[MEM0]] : !fir.ref>> - - !CHECK: acc.data copyin(%[[MEM0]] : !fir.ref>>) { +! CHECK-LABEL: func.func @_QMacc_data_operandPacc_operand_array_section_pointer() { +! CHECK: %[[P:.*]] = fir.alloca !fir.box>> {bindc_name = "p", uniq_name = "_QMacc_data_operandFacc_operand_array_section_pointerEp"} +! CHECK: %[[LOAD_BOX_P_0:.*]] = fir.load %[[P]] : !fir.ref>>> +! CHECK: %[[LOAD_BOX_P_1:.*]] = fir.load %[[P]] : !fir.ref>>> +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[DIMS0_0:.*]]:3 = fir.box_dims %[[LOAD_BOX_P_1]], %[[C0:.*]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[DIMS0_1:.*]]:3 = fir.box_dims %[[LOAD_BOX_P_0]], %[[C0]] : (!fir.box>>, index) -> (index, index, index) +! CHECK: %[[C1:.*]] = arith.constant 1 : index +! CHECK: %[[LB:.*]] = arith.subi %[[C1]], %[[DIMS0_0]]#0 : index +! CHECK: %[[C50:.*]] = arith.constant 50 : index +! CHECK: %[[UB:.*]] = arith.subi %[[C50]], %[[DIMS0_0]]#0 : index +! CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) stride(%[[DIMS0_1]]#2 : index) startIdx(%[[DIMS0_0]]#0 : index) {strideInBytes = true} +! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[LOAD_BOX_P_0]] : (!fir.box>>) -> !fir.ptr> +! CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[BOX_ADDR]] : !fir.ptr>) bounds(%[[BOUND]]) -> !fir.ptr> {name = "p(1:50)"} +! CHECK: acc.data dataOperands(%[[COPYIN]] : !fir.ptr>) { +! CHECK: acc.terminator +! CHECK: } -end subroutine end module diff --git a/flang/test/Lower/OpenACC/acc-data.f90 b/flang/test/Lower/OpenACC/acc-data.f90 --- a/flang/test/Lower/OpenACC/acc-data.f90 +++ b/flang/test/Lower/OpenACC/acc-data.f90 @@ -7,91 +7,131 @@ real, pointer :: d, e logical :: ifCondition = .TRUE. -!CHECK: [[A:%.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ea"} -!CHECK: [[B:%.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Eb"} -!CHECK: [[C:%.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ec"} -!CHECK: [[D:%.*]] = fir.alloca !fir.box> {bindc_name = "d", uniq_name = "{{.*}}Ed"} -!CHECK: [[E:%.*]] = fir.alloca !fir.box> {bindc_name = "e", uniq_name = "{{.*}}Ee"} +! CHECK: %[[A:.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ea"} +! CHECK: %[[B:.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Eb"} +! CHECK: %[[C:.*]] = fir.alloca !fir.array<10x10xf32> {{{.*}}uniq_name = "{{.*}}Ec"} +! CHECK: %[[D:.*]] = fir.alloca !fir.box> {bindc_name = "d", uniq_name = "{{.*}}Ed"} +! CHECK: %[[E:.*]] = fir.alloca !fir.box> {bindc_name = "e", uniq_name = "{{.*}}Ee"} !$acc data if(.TRUE.) copy(a) !$acc end data -!CHECK: [[IF1:%.*]] = arith.constant true -!CHECK: acc.data if([[IF1]]) copy([[A]] : !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[IF1:.*]] = arith.constant true +! CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 3 : i64, name = "a"} +! CHECK: acc.data if(%[[IF1]]) dataOperands(%[[COPYIN]] : !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} +! CHECK: acc.copyout accPtr(%[[COPYIN]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[A]] : !fir.ref>) {dataClause = 3 : i64, name = "a"} !$acc data copy(a) if(ifCondition) !$acc end data -!CHECK: [[IFCOND:%.*]] = fir.load %{{.*}} : !fir.ref> -!CHECK: [[IF2:%.*]] = fir.convert [[IFCOND]] : (!fir.logical<4>) -> i1 -!CHECK: acc.data if([[IF2]]) copy([[A]] : !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[COPYIN:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 3 : i64, name = "a"} +! CHECK: %[[IFCOND:.*]] = fir.load %{{.*}} : !fir.ref> +! CHECK: %[[IF2:.*]] = fir.convert %[[IFCOND]] : (!fir.logical<4>) -> i1 +! CHECK: acc.data if(%[[IF2]]) dataOperands(%[[COPYIN]] : !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} +! CHECK: acc.copyout accPtr(%[[COPYIN]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[A]] : !fir.ref>) {dataClause = 3 : i64, name = "a"} !$acc data copy(a, b, c) !$acc end data -!CHECK: acc.data copy([[A]], [[B]], [[C]] : !fir.ref>, !fir.ref>, !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 3 : i64, name = "a"} +! CHECK: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 3 : i64, name = "b"} +! CHECK: %[[COPYIN_C:.*]] = acc.copyin varPtr(%[[C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 3 : i64, name = "c"} +! CHECK: acc.data dataOperands(%[[COPYIN_A]], %[[COPYIN_B]], %[[COPYIN_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} +! CHECK: acc.copyout accPtr(%[[COPYIN_A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[A]] : !fir.ref>) {dataClause = 3 : i64, name = "a"} +! CHECK: acc.copyout accPtr(%[[COPYIN_B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[B]] : !fir.ref>) {dataClause = 3 : i64, name = "b"} +! CHECK: acc.copyout accPtr(%[[COPYIN_C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[C]] : !fir.ref>) {dataClause = 3 : i64, name = "c"} !$acc data copy(a) copy(b) copy(c) !$acc end data -!CHECK: acc.data copy([[A]], [[B]], [[C]] : !fir.ref>, !fir.ref>, !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 3 : i64, name = "a"} +! CHECK: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 3 : i64, name = "b"} +! CHECK: %[[COPYIN_C:.*]] = acc.copyin varPtr(%[[C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 3 : i64, name = "c"} +! CHECK: acc.data dataOperands(%[[COPYIN_A]], %[[COPYIN_B]], %[[COPYIN_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} +! CHECK: acc.copyout accPtr(%[[COPYIN_A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[A]] : !fir.ref>) {dataClause = 3 : i64, name = "a"} +! CHECK: acc.copyout accPtr(%[[COPYIN_B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[B]] : !fir.ref>) {dataClause = 3 : i64, name = "b"} +! CHECK: acc.copyout accPtr(%[[COPYIN_C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[C]] : !fir.ref>) {dataClause = 3 : i64, name = "c"} !$acc data copyin(a) copyin(readonly: b, c) !$acc end data -!CHECK: acc.data copyin([[A]] : !fir.ref>) copyin_readonly([[B]], [[C]] : !fir.ref>, !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "a"} +! CHECK: %[[COPYIN_B:.*]] = acc.copyin varPtr(%[[B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 2 : i64, name = "b"} +! CHECK: %[[COPYIN_C:.*]] = acc.copyin varPtr(%[[C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 2 : i64, name = "c"} +! CHECK: acc.data dataOperands(%[[COPYIN_A]], %[[COPYIN_B]], %[[COPYIN_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} !$acc data copyout(a) copyout(zero: b) copyout(c) !$acc end data -!CHECK: acc.data copyout([[A]], [[C]] : !fir.ref>, !fir.ref>) copyout_zero([[B]] : !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 4 : i64, name = "a"} +! CHECK: %[[CREATE_B:.*]] = acc.create varPtr(%[[B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 4 : i64, name = "b"} +! CHECK: %[[CREATE_C:.*]] = acc.create varPtr(%[[C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 4 : i64, name = "c"} +! CHECK: acc.data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} +! CHECK: acc.copyout accPtr(%[[CREATE_A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[A]] : !fir.ref>) {name = "a"} +! CHECK: acc.copyout accPtr(%[[CREATE_B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[B]] : !fir.ref>) {name = "b"} +! CHECK: acc.copyout accPtr(%[[CREATE_C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) to varPtr(%[[C]] : !fir.ref>) {name = "c"} !$acc data create(a, b) create(zero: c) !$acc end data -!CHECK: acc.data create([[A]], [[B]] : !fir.ref>, !fir.ref>) create_zero([[C]] : !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[CREATE_A:.*]] = acc.create varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "a"} +! CHECK: %[[CREATE_B:.*]] = acc.create varPtr(%[[B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "b"} +! CHECK: %[[CREATE_C:.*]] = acc.create varPtr(%[[C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 8 : i64, name = "c"} +! CHECK: acc.data dataOperands(%[[CREATE_A]], %[[CREATE_B]], %[[CREATE_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} !$acc data no_create(a, b) create(zero: c) !$acc end data -!CHECK: acc.data create_zero([[C]] : !fir.ref>) no_create([[A]], [[B]] : !fir.ref>, !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[NO_CREATE_A:.*]] = acc.nocreate varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "a"} +! CHECK: %[[NO_CREATE_B:.*]] = acc.nocreate varPtr(%[[B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "b"} +! CHECK: %[[CREATE_C:.*]] = acc.create varPtr(%[[C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {dataClause = 8 : i64, name = "c"} +! CHECK: acc.data dataOperands(%[[NO_CREATE_A]], %[[NO_CREATE_B]], %[[CREATE_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} !$acc data present(a, b, c) !$acc end data -!CHECK: acc.data present([[A]], [[B]], [[C]] : !fir.ref>, !fir.ref>, !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[PRESENT_A:.*]] = acc.present varPtr(%[[A]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "a"} +! CHECK: %[[PRESENT_B:.*]] = acc.present varPtr(%[[B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "b"} +! CHECK: %[[PRESENT_C:.*]] = acc.present varPtr(%[[C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "c"} +! CHECK: acc.data dataOperands(%[[PRESENT_A]], %[[PRESENT_B]], %[[PRESENT_C]] : !fir.ref>, !fir.ref>, !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} !$acc data deviceptr(b, c) !$acc end data -!CHECK: acc.data deviceptr([[B]], [[C]] : !fir.ref>, !fir.ref>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[DEVICEPTR_B:.*]] = acc.deviceptr varPtr(%[[B]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "b"} +! CHECK: %[[DEVICEPTR_C:.*]] = acc.deviceptr varPtr(%[[C]] : !fir.ref>) bounds(%{{.*}}, %{{.*}}) -> !fir.ref> {name = "c"} +! CHECK: acc.data dataOperands(%[[DEVICEPTR_B]], %[[DEVICEPTR_C]] : !fir.ref>, !fir.ref>) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} !$acc data attach(d, e) !$acc end data -!CHECK: acc.data attach([[D]], [[E]] : !fir.ref>>, !fir.ref>>) { -!CHECK: acc.terminator -!CHECK-NEXT: }{{$}} +! CHECK: %[[ATTACH_D:.*]] = acc.attach varPtr(%{{.*}} : !fir.ptr) -> !fir.ptr {name = "d"} +! CHECK: %[[ATTACH_E:.*]] = acc.attach varPtr(%{{.*}} : !fir.ptr) -> !fir.ptr {name = "e"} +! CHECK: acc.data dataOperands(%[[ATTACH_D]], %[[ATTACH_E]] : !fir.ptr, !fir.ptr) { +! CHECK: acc.terminator +! CHECK-NEXT: }{{$}} +! CHECK: acc.detach accPtr(%[[ATTACH_D]] : !fir.ptr) {dataClause = 10 : i64, name = "d"} +! CHECK: acc.detach accPtr(%[[ATTACH_E]] : !fir.ptr) {dataClause = 10 : i64, name = "e"} end subroutine acc_data