[flang-commits] [flang] 9f548c1 - [flang][openacc] Support array section with non constant bounds
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Mon Apr 24 10:12:47 PDT 2023
Author: Valentin Clement
Date: 2023-04-24T10:12:40-07:00
New Revision: 9f548c18249f27a6208d80b1063d3a5039b2b1cd
URL: https://github.com/llvm/llvm-project/commit/9f548c18249f27a6208d80b1063d3a5039b2b1cd
DIFF: https://github.com/llvm/llvm-project/commit/9f548c18249f27a6208d80b1063d3a5039b2b1cd.diff
LOG: [flang][openacc] Support array section with non constant bounds
Add lowering for non constant lower and upper bounds
in array section.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D148840
Added:
Modified:
flang/lib/Lower/OpenACC.cpp
flang/test/Lower/OpenACC/acc-enter-data.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index e8a492c6a2076..02b77c747a563 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -104,12 +104,15 @@ genObjectList(const Fortran::parser::AccObjectList &objectList,
static llvm::SmallVector<mlir::Value>
genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
Fortran::lower::AbstractConverter &converter,
+ Fortran::lower::StatementContext &stmtCtx,
const std::list<Fortran::parser::SectionSubscript> &subscripts,
std::stringstream &asFortran, const Fortran::parser::Name &name) {
int dimension = 0;
mlir::Type idxTy = builder.getIndexType();
mlir::Type boundTy = builder.getType<mlir::acc::DataBoundsType>();
llvm::SmallVector<mlir::Value> bounds;
+ fir::ExtendedValue dataExv = converter.getSymbolExtendedValue(*name.symbol);
+
for (const auto &subscript : subscripts) {
if (const auto *triplet{
std::get_if<Fortran::parser::SubscriptTriplet>(&subscript.u)}) {
@@ -136,7 +139,13 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
}
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<mlir::arith::SubIOp>(loc, lb, baseLb);
+ asFortran << lexpr->AsFortran();
}
}
asFortran << ':';
@@ -152,7 +161,13 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
}
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<mlir::arith::SubIOp>(loc, ub, baseLb);
+ asFortran << uexpr->AsFortran();
}
}
if (lower && upper) {
@@ -169,9 +184,9 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
}
}
if (!ubound) {
- mlir::Value ext =
- fir::factory::readExtent(builder, loc, dataExv, dimension);
- extent = builder.create<mlir::arith::SubIOp>(loc, ext, baseLb);
+ extent = fir::factory::readExtent(builder, loc, dataExv, dimension);
+ if (lbound)
+ extent = builder.create<mlir::arith::SubIOp>(loc, extent, lbound);
}
mlir::Value empty;
mlir::Value bound = builder.create<mlir::acc::DataBoundsOp>(
@@ -243,9 +258,9 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
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
index a618d5eff1a3b..e41a50cdd5301 100644
--- a/flang/test/Lower/OpenACC/acc-enter-data.f90
+++ b/flang/test/Lower/OpenACC/acc-enter-data.f90
@@ -99,7 +99,7 @@ subroutine acc_enter_data
!$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 @@ subroutine acc_enter_data
!CHECK: acc.enter_data dataOperands(%[[COPYIN_A]] : !fir.ref<!fir.array<10x10xf32>>)
!$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<!fir.array<10x10xf32>>) bounds(%[[BOUND1]], %[[BOUND2]]) -> !fir.ref<!fir.array<10x10xf32>> {name = "a(:10,1:5)", structured = false}
!CHECK: acc.enter_data dataOperands(%[[COPYIN_A]] : !fir.ref<!fir.array<10x10xf32>>)
!$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<!fir.array<10x10xf32>>) bounds(%[[BOUND1]], %[[BOUND2]]) -> !fir.ref<!fir.array<10x10xf32>> {name = "a(:,:)", structured = false}
-!CHECK: acc.enter_data dataOperands(%[[COPYIN_A]] : !fir.ref<!fir.array<10x10xf32>>)
-
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.array<10xf32>> {fir.bindc_name = "a"}
+!CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.array<?xf32>> {fir.bindc_name = "b"}, %[[N:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}, %[[M:.*]]: !fir.ref<i32> {fir.bindc_name = "m"}
+
+!CHECK: %[[LOAD_N:.*]] = fir.load %[[N]] : !fir.ref<i32>
+!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<i32>
+!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 @@ subroutine acc_enter_data_dummy(a)
!CHECK: %[[CREATE1:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10xf32>>) bounds(%[[BOUND1]]) -> !fir.ref<!fir.array<10xf32>> {name = "a(5:10)", structured = false}
!CHECK: acc.enter_data dataOperands(%[[CREATE1]] : !fir.ref<!fir.array<10xf32>>)
+ !$acc enter data create(b(n:m))
+!CHECK: %[[LOAD_N:.*]] = fir.load %[[N]] : !fir.ref<i32>
+!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<i32>
+!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<!fir.array<?xf32>>) bounds(%[[BOUND1]]) -> !fir.ref<!fir.array<?xf32>> {name = "b(n:m)", structured = false}
+!CHECK: acc.enter_data dataOperands(%[[CREATE1]] : !fir.ref<!fir.array<?xf32>>)
+
+ !$acc enter data create(b(n:))
+!CHECK: %[[LOAD_N:.*]] = fir.load %[[N]] : !fir.ref<i32>
+!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<!fir.array<?xf32>>) bounds(%[[BOUND1]]) -> !fir.ref<!fir.array<?xf32>> {name = "b(n:)", structured = false}
+!CHECK: acc.enter_data dataOperands(%[[CREATE1]] : !fir.ref<!fir.array<?xf32>>)
+
+ !$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<!fir.array<?xf32>>) bounds(%[[BOUND1]]) -> !fir.ref<!fir.array<?xf32>> {name = "b(:)", structured = false}
+!CHECK: acc.enter_data dataOperands(%[[CREATE1]] : !fir.ref<!fir.array<?xf32>>)
+
end subroutine
! Test lowering of array section for non default lower bound.
@@ -162,8 +199,7 @@ subroutine acc_enter_data_non_default_lb()
!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<10xi32>>)
!$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<!fir.array<10xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<10xi32>> {name = "a(:)", structured = false}
!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<10xi32>>)
@@ -177,7 +213,7 @@ subroutine acc_enter_data_non_default_lb()
!$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<!fir.array<10xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<10xi32>> {name = "a(4:)", structured = false}
!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<10xi32>>)
More information about the flang-commits
mailing list