Skip to content

Commit

Permalink
[flang][openacc] Fix the value of lower bound, upper bound and extent
Browse files Browse the repository at this point in the history
Update the lowering to match the intent of the newly added operation
as described here D148860.

Reviewed By: razvanlupusoru

Differential Revision: https://reviews.llvm.org/D148932
  • Loading branch information
clementval committed Apr 21, 2023
1 parent d9bc7f7 commit f38d8be
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 30 deletions.
30 changes: 24 additions & 6 deletions flang/lib/Lower/OpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
const std::list<Fortran::parser::SectionSubscript> &subscripts,
std::stringstream &asFortran, const Fortran::parser::Name &name) {
int dimension = 0;
mlir::Type i64Ty = builder.getI64Type();
mlir::Type idxTy = builder.getIndexType();
mlir::Type boundTy = builder.getType<mlir::acc::DataBoundsType>();
llvm::SmallVector<mlir::Value> bounds;
for (const auto &subscript : subscripts) {
Expand All @@ -117,11 +117,23 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
asFortran << ',';
mlir::Value lbound, ubound, extent;
std::optional<std::int64_t> lval, uval;
mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
fir::ExtendedValue dataExv =
converter.getSymbolExtendedValue(*name.symbol);
mlir::Value baseLb =
fir::factory::readLowerBound(builder, loc, dataExv, dimension, one);
bool defaultLb = baseLb == one;

const auto &lower{std::get<0>(triplet->t)};
if (lower) {
lval = Fortran::semantics::GetIntValue(lower);
if (lval) {
lbound = builder.createIntegerConstant(loc, i64Ty, *lval);
if (defaultLb) {
lbound = builder.createIntegerConstant(loc, idxTy, *lval - 1);
} else {
mlir::Value lb = builder.createIntegerConstant(loc, idxTy, *lval);
lbound = builder.create<mlir::arith::SubIOp>(loc, lb, baseLb);
}
asFortran << *lval;
} else {
TODO(loc, "non constant lower bound in array section");
Expand All @@ -132,7 +144,12 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
if (upper) {
uval = Fortran::semantics::GetIntValue(upper);
if (uval) {
ubound = builder.createIntegerConstant(loc, i64Ty, *uval);
if (defaultLb) {
ubound = builder.createIntegerConstant(loc, idxTy, *uval - 1);
} else {
mlir::Value ub = builder.createIntegerConstant(loc, idxTy, *uval);
ubound = builder.create<mlir::arith::SubIOp>(loc, ub, baseLb);
}
asFortran << *uval;
} else {
TODO(loc, "non constant upper bound in array section");
Expand All @@ -152,12 +169,13 @@ genBoundsOps(fir::FirOpBuilder &builder, mlir::Location loc,
}
}
if (!ubound) {
fir::ExtendedValue x = converter.getSymbolExtendedValue(*name.symbol);
extent = fir::factory::readExtent(builder, loc, x, dimension);
mlir::Value ext =
fir::factory::readExtent(builder, loc, dataExv, dimension);
extent = builder.create<mlir::arith::SubIOp>(loc, ext, baseLb);
}
mlir::Value empty;
mlir::Value bound = builder.create<mlir::acc::DataBoundsOp>(
loc, boundTy, lbound, ubound, extent, empty, false, empty);
loc, boundTy, lbound, ubound, extent, empty, false, baseLb);
bounds.push_back(bound);
++dimension;
}
Expand Down
99 changes: 75 additions & 24 deletions flang/test/Lower/OpenACC/acc-enter-data.f90
Original file line number Diff line number Diff line change
Expand Up @@ -88,32 +88,43 @@ subroutine acc_enter_data
!CHECK: acc.enter_data wait_devnum(%[[WAIT6]] : i32) wait(%[[WAIT4]], %[[WAIT5]] : i32, i32) dataOperands(%[[CREATE_A]] : !fir.ref<!fir.array<10x10xf32>>)

!$acc enter data copyin(a(1:10,1:5))
!CHECK: %[[LB1:.*]] = arith.constant 1 : i64
!CHECK: %[[UB1:.*]] = arith.constant 10 : i64
!CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB1]] : i64) upperbound(%[[UB1]] : i64)
!CHECK: %[[LB2:.*]] = arith.constant 1 : i64
!CHECK: %[[UB2:.*]] = arith.constant 5 : i64
!CHECK: %[[BOUND2:.*]] = acc.bounds lowerbound(%[[LB2]] : i64) upperbound(%[[UB2]] : i64)
!CHECK: %[[LB1:.*]] = arith.constant 0 : index
!CHECK: %[[UB1:.*]] = arith.constant 9 : index
!CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB1]] : index) upperbound(%[[UB1]] : index) startIdx(%c1{{.*}} : 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(1:10,1:5)", structured = false}
!CHECK: acc.enter_data dataOperands(%[[COPYIN_A]] : !fir.ref<!fir.array<10x10xf32>>)

!$acc enter data copyin(a(1:,1:5))
!CHECK: %[[LB1:.*]] = arith.constant 1 : i64
!CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB1]] : i64) extent(%[[EXTENT_C10]] : index)
!CHECK: %[[LB2:.*]] = arith.constant 1 : i64
!CHECK: %[[UB2:.*]] = arith.constant 5 : i64
!CHECK: %[[BOUND2:.*]] = acc.bounds lowerbound(%[[LB2]] : i64) upperbound(%[[UB2]] : i64)
!CHECK: %[[COPYIN_A:.*]] = acc.copyin varPtr(%[[A]] : !fir.ref<!fir.array<10x10xf32>>) bounds(%[[BOUND1]], %[[BOUND2]]) -> !fir.ref<!fir.array<10x10xf32>> {name = "a(1:,1:5)", structured = false}
!CHECK: %[[LB1:.*]] = arith.constant 0 : index
!CHECK: %[[EXTENT:.*]] = arith.subi %[[EXTENT_C10:.*]], %c1{{.*}} : 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
!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(1:,1:5)", structured = false}
!CHECK: acc.enter_data dataOperands(%[[COPYIN_A]] : !fir.ref<!fir.array<10x10xf32>>)

!$acc enter data copyin(a(:10,1:5))
!CHECK: %[[UB1:.*]] = arith.constant 10 : i64
!CHECK: %[[BOUND1:.*]] = acc.bounds upperbound(%[[UB1]] : i64)
!CHECK: %[[LB2:.*]] = arith.constant 1 : i64
!CHECK: %[[UB2:.*]] = arith.constant 5 : i64
!CHECK: %[[BOUND2:.*]] = acc.bounds lowerbound(%[[LB2]] : i64) upperbound(%[[UB2]] : i64)
!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>>)
!CHECK: %[[UB1:.*]] = arith.constant 9 : index
!CHECK: %[[BOUND1:.*]] = acc.bounds upperbound(%[[UB1]] : 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: %[[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

Expand All @@ -125,10 +136,50 @@ subroutine acc_enter_data_dummy(a)
!CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "a"}

!$acc enter data create(a(5:10))
!CHECK: %[[LB1:.*]] = arith.constant 5 : i64
!CHECK: %[[UB1:.*]] = arith.constant 10 : i64
!CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB1]] : i64) upperbound(%[[UB1]] : i64)
!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>>)
!CHECK: %[[LB1:.*]] = arith.constant 4 : index
!CHECK: %[[UB1:.*]] = arith.constant 9 : index
!CHECK: %[[BOUND1:.*]] = acc.bounds lowerbound(%[[LB1]] : index) upperbound(%[[UB1]] : index) startIdx(%c1{{.*}} : index)
!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>>)

end subroutine

! Test lowering of array section for non default lower bound.
subroutine acc_enter_data_non_default_lb()
integer :: a(0:9)

!CHECK-LABEL: func.func @_QPacc_enter_data_non_default_lb() {
!CHECK: %[[BASELB:.*]] = arith.constant 0 : index
!CHECK: %[[A:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "a", uniq_name = "_QFacc_enter_data_non_default_lbEa"}

!$acc enter data create(a(5:9))
!CHECK: %[[SECTIONLB:.*]] = arith.constant 5 : index
!CHECK: %[[LB:.*]] = arith.subi %[[SECTIONLB]], %[[BASELB]] : index
!CHECK: %[[SECTIONUB:.*]] = arith.constant 9 : index
!CHECK: %[[UB:.*]] = arith.subi %[[SECTIONUB]], %[[BASELB]] : index
!CHECK: %[[BOUND:.*]] = acc.bounds lowerbound(%[[LB]] : index) upperbound(%[[UB]] : index) startIdx(%[[BASELB]] : index)
!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<10xi32>> {name = "a(5:9)", structured = false}
!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: %[[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>>)

!$acc enter data create(a(:6))
!CHECK: %[[SECTIONUB:.*]] = arith.constant 6 : index
!CHECK: %[[UB:.*]] = arith.subi %[[SECTIONUB]], %[[BASELB]] : index
!CHECK: %[[BOUND:.*]] = acc.bounds upperbound(%[[UB]] : index) startIdx(%[[BASELB]] : index)
!CHECK: %[[CREATE:.*]] = acc.create varPtr(%[[A]] : !fir.ref<!fir.array<10xi32>>) bounds(%[[BOUND]]) -> !fir.ref<!fir.array<10xi32>> {name = "a(:6)", structured = false}
!CHECK: acc.enter_data dataOperands(%[[CREATE]] : !fir.ref<!fir.array<10xi32>>)

!$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: %[[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>>)

end subroutine

0 comments on commit f38d8be

Please sign in to comment.