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 @@ -104,12 +104,15 @@ static llvm::SmallVector genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc, Fortran::lower::AbstractConverter &converter, + Fortran::lower::StatementContext &stmtCtx, const std::list &subscripts, std::stringstream &asFortran, const Fortran::parser::Name &name) { int dimension = 0; mlir::Type idxTy = builder.getIndexType(); mlir::Type boundTy = builder.getType(); llvm::SmallVector bounds; + fir::ExtendedValue dataExv = converter.getSymbolExtendedValue(*name.symbol); + for (const auto &subscript : subscripts) { if (const auto *triplet{ std::get_if(&subscript.u)}) { @@ -136,7 +139,13 @@ } asFortran << *lval; } else { - TODO(loc, "non constant lower bound in array section"); + const Fortran::lower::SomeExpr *lexpr = + Fortran::semantics::GetExpr(*lower); + mlir::Value lb = + fir::getBase(converter.genExprValue(loc, *lexpr, stmtCtx)); + lb = builder.createConvert(loc, baseLb.getType(), lb); + lbound = builder.create(loc, lb, baseLb); + asFortran << lexpr->AsFortran(); } } asFortran << ':'; @@ -152,7 +161,13 @@ } asFortran << *uval; } else { - TODO(loc, "non constant upper bound in array section"); + const Fortran::lower::SomeExpr *uexpr = + Fortran::semantics::GetExpr(*upper); + mlir::Value ub = + fir::getBase(converter.genExprValue(loc, *uexpr, stmtCtx)); + ub = builder.createConvert(loc, baseLb.getType(), ub); + ubound = builder.create(loc, ub, baseLb); + asFortran << uexpr->AsFortran(); } } if (lower && upper) { @@ -169,9 +184,9 @@ } } if (!ubound) { - mlir::Value ext = - fir::factory::readExtent(builder, loc, dataExv, dimension); - extent = builder.create(loc, ext, baseLb); + extent = fir::factory::readExtent(builder, loc, dataExv, dimension); + if (lbound) + extent = builder.create(loc, extent, lbound); } mlir::Value empty; mlir::Value bound = builder.create( @@ -243,9 +258,9 @@ asFortran << name.ToString(); if (!arrayElement->subscripts.empty()) { asFortran << '('; - bounds = - genBoundsOps(builder, operandLocation, converter, - arrayElement->subscripts, asFortran, name); + bounds = genBoundsOps(builder, operandLocation, converter, + stmtCtx, arrayElement->subscripts, + asFortran, name); } asFortran << ')'; Op op = createOpAndAddOperand(*name.symbol, asFortran.str(), diff --git a/flang/test/Lower/OpenACC/acc-enter-data.f90 b/flang/test/Lower/OpenACC/acc-enter-data.f90 --- a/flang/test/Lower/OpenACC/acc-enter-data.f90 +++ b/flang/test/Lower/OpenACC/acc-enter-data.f90 @@ -99,7 +99,7 @@ !$acc enter data copyin(a(1:,1:5)) !CHECK: %[[LB1:.*]] = arith.constant 0 : index -!CHECK: %[[EXTENT:.*]] = arith.subi %[[EXTENT_C10:.*]], %c1{{.*}} : index +!CHECK: %[[EXTENT:.*]] = arith.subi %[[EXTENT_C10:.*]], %c0{{.*}} : index !CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB1]] : index) extent(%[[EXTENT]] : index) startIdx(%c1{{.*}} : index) !CHECK: %[[LB2:.*]] = arith.constant 0 : index !CHECK: %[[UB2:.*]] = arith.constant 4 : index @@ -108,32 +108,44 @@ !CHECK: acc.enter_data dataOperands(%[[COPYIN_A]] : !fir.ref>) !$acc enter data copyin(a(:10,1:5)) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index !CHECK: %[[UB1:.*]] = arith.constant 9 : index -!CHECK: %[[BOUND1:.*]] = acc.bounds upperbound(%[[UB1]] : index) -!CHECK: %[[LB2:.*]] = arith.constant 0 : index +!CHECK: %[[BOUND1:.*]] = acc.bounds upperbound(%[[UB1]] : index) startIdx(%[[ONE]] : index) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index +!CHECK: %[[LB2:.*]] = arith.constant 0 : index !CHECK: %[[UB2:.*]] = arith.constant 4 : index !CHECK: %[[BOUND2:.*]] = acc.bounds lowerbound(%[[LB2]] : index) upperbound(%[[UB2]] : index) startIdx(%c1{{.*}} : index) !CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref>) bounds(%[[BOUND1]], %[[BOUND2]]) -> !fir.ref> {name = "a(:10,1:5)", structured = false} !CHECK: acc.enter_data dataOperands(%[[COPYIN_A]] : !fir.ref>) !$acc enter data copyin(a(:,:)) -!CHECK: %[[C1:.*]] = arith.constant 1 : index -!CHECK: %[[EXT:.*]] = arith.subi %c10{{.*}}, %[[C1]] : index -!CHECK: %[[BOUND1:.*]] = acc.bounds extent(%[[EXT]] : index) startIdx(%[[C1]] : index) -!CHECK: %[[C1:.*]] = arith.constant 1 : index -!CHECK: %[[EXT:.*]] = arith.subi %c10{{.*}}, %[[C1]] : index -!CHECK: %[[BOUND2:.*]] = acc.bounds extent(%[[EXT]] : index) startIdx(%[[C1]] : index) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index +!CHECK: %[[BOUND1:.*]] = acc.bounds extent(%c10{{.*}} : index) startIdx(%[[ONE]] : index) +!CHECK: %[[ONE:.*]] = arith.constant 1 : index +!CHECK: %[[BOUND2:.*]] = acc.bounds extent(%c10{{.*}} : index) startIdx(%[[ONE]] : index) !CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref>) bounds(%[[BOUND1]], %[[BOUND2]]) -> !fir.ref> {name = "a(:,:)", structured = false} -!CHECK: acc.enter_data dataOperands(%[[COPYIN_A]] : !fir.ref>) - end subroutine acc_enter_data - -subroutine acc_enter_data_dummy(a) +subroutine acc_enter_data_dummy(a, b, n, m) + integer :: n, m real :: a(1:10) + real :: b(n:m) !CHECK-LABEL: func.func @_QPacc_enter_data_dummy -!CHECK-SAME: %[[A:.*]]: !fir.ref> {fir.bindc_name = "a"} +!CHECK-SAME: %[[A:.*]]: !fir.ref> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref> {fir.bindc_name = "b"}, %[[N:.*]]: !fir.ref {fir.bindc_name = "n"}, %[[M:.*]]: !fir.ref {fir.bindc_name = "m"} + +!CHECK: %[[LOAD_N:.*]] = fir.load %[[N]] : !fir.ref +!CHECK: %[[N_I64:.*]] = fir.convert %[[LOAD_N]] : (i32) -> i64 +!CHECK: %[[N_IDX:.*]] = fir.convert %[[N_I64]] : (i64) -> index +!CHECK: %[[LOAD_M:.*]] = fir.load %[[M]] : !fir.ref +!CHECK: %[[M_I64:.*]] = fir.convert %[[LOAD_M]] : (i32) -> i64 +!CHECK: %[[M_IDX:.*]] = fir.convert %[[M_I64]] : (i64) -> index +!CHECK: %[[M_N:.*]] = arith.subi %[[M_IDX]], %[[N_IDX]] : index +!CHECK: %[[C1:.*]] = arith.constant 1 : index +!CHECK: %[[M_N_1:.*]] = arith.addi %[[M_N]], %[[C1]] : index +!CHECK: %[[C0:.*]] = arith.constant 0 : index +!CHECK: %[[CMP:.*]] = arith.cmpi sgt, %[[M_N_1]], %[[C0]] : index +!CHECK: %[[EXT_B:.*]] = arith.select %[[CMP]], %[[M_N_1]], %[[C0]] : index !$acc enter data create(a(5:10)) !CHECK: %[[LB1:.*]] = arith.constant 4 : index @@ -142,6 +154,31 @@ !CHECK: %[[CREATE1:.*]] = acc.create varPtr(%[[A]] : !fir.ref>) bounds(%[[BOUND1]]) -> !fir.ref> {name = "a(5:10)", structured = false} !CHECK: acc.enter_data dataOperands(%[[CREATE1]] : !fir.ref>) + !$acc enter data create(b(n:m)) +!CHECK: %[[LOAD_N:.*]] = fir.load %[[N]] : !fir.ref +!CHECK: %[[CONVERT_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> index +!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT_N]], %[[N_IDX]] : index +!CHECK: %[[LOAD_M:.*]] = fir.load %[[M]] : !fir.ref +!CHECK: %[[CONVERT_M:.*]] = fir.convert %[[LOAD_M]] : (i32) -> index +!CHECK: %[[UB:.*]] = arith.subi %[[CONVERT_M]], %[[N_IDX]] : index +!CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) startIdx(%[[N_IDX]] : index) +!CHECK: %[[CREATE1:.*]] = acc.create varPtr(%[[B]] : !fir.ref>) bounds(%[[BOUND1]]) -> !fir.ref> {name = "b(n:m)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE1]] : !fir.ref>) + + !$acc enter data create(b(n:)) +!CHECK: %[[LOAD_N:.*]] = fir.load %[[N]] : !fir.ref +!CHECK: %[[CONVERT_N:.*]] = fir.convert %[[LOAD_N]] : (i32) -> index +!CHECK: %[[LB:.*]] = arith.subi %[[CONVERT_N]], %[[N_IDX]] : index +!CHECK: %[[EXT:.*]] = arith.subi %[[EXT_B]], %[[LB]] : index +!CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB]] : index) extent(%[[EXT]] : index) startIdx(%[[N_IDX]] : index) +!CHECK: %[[CREATE1:.*]] = acc.create varPtr(%[[B]] : !fir.ref>) bounds(%[[BOUND1]]) -> !fir.ref> {name = "b(n:)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE1]] : !fir.ref>) + + !$acc enter data create(b(:)) +!CHECK: %[[BOUND1:.*]] = acc.bounds extent(%[[EXT_B]] : index) startIdx(%[[N_IDX]] : index) +!CHECK: %[[CREATE1:.*]] = acc.create varPtr(%[[B]] : !fir.ref>) bounds(%[[BOUND1]]) -> !fir.ref> {name = "b(:)", structured = false} +!CHECK: acc.enter_data dataOperands(%[[CREATE1]] : !fir.ref>) + end subroutine ! Test lowering of array section for non default lower bound. @@ -162,8 +199,7 @@ !CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref>) !$acc enter data create(a(:)) -!CHECK: %[[EXT:.*]] = arith.subi %c10{{.*}}, %[[BASELB]] : index -!CHECK: %[[BOUND:.*]] = acc.bounds extent(%[[EXT]] : index) startIdx(%[[BASELB]] : index) +!CHECK: %[[BOUND:.*]] = acc.bounds extent(%c10{{.*}} : index) startIdx(%[[BASELB]] : index) !CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[A]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a(:)", structured = false} !CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref>) @@ -177,7 +213,7 @@ !$acc enter data create(a(4:)) !CHECK: %[[SECTIONLB:.*]] = arith.constant 4 : index !CHECK: %[[LB:.*]] = arith.subi %[[SECTIONLB]], %[[BASELB]] : index -!CHECK: %[[EXT:.*]] = arith.subi %c10{{.*}}, %[[BASELB]] : index +!CHECK: %[[EXT:.*]] = arith.subi %c10{{.*}}, %[[LB]] : index !CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) extent(%[[EXT]] : index) startIdx(%[[BASELB]] : index) !CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[A]] : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a(4:)", structured = false} !CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref>)