diff --git a/flang/lib/Lower/DirectivesCommon.h b/flang/lib/Lower/DirectivesCommon.h index f4903f607a2da..d918f1e55c27b 100644 --- a/flang/lib/Lower/DirectivesCommon.h +++ b/flang/lib/Lower/DirectivesCommon.h @@ -597,6 +597,7 @@ genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1); assert(box.getType().isa() && "expect fir.box or fir.class"); + mlir::Value byteStride; for (unsigned dim = 0; dim < dataExv.rank(); ++dim) { mlir::Value d = builder.createIntegerConstant(loc, idxTy, dim); mlir::Value baseLb = @@ -606,9 +607,13 @@ genBoundsOpsFromBox(fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value lb = builder.createIntegerConstant(loc, idxTy, 0); mlir::Value ub = builder.create(loc, dimInfo.getExtent(), one); - mlir::Value bound = - builder.create(loc, boundTy, lb, ub, mlir::Value(), - dimInfo.getByteStride(), true, baseLb); + if (dim == 0) // First stride is the element size. + byteStride = dimInfo.getByteStride(); + mlir::Value bound = builder.create( + loc, boundTy, lb, ub, mlir::Value(), byteStride, true, baseLb); + // Compute the stride for the next dimension. + byteStride = builder.create(loc, byteStride, + dimInfo.getExtent()); bounds.push_back(bound); } return bounds; diff --git a/flang/test/Lower/OpenACC/acc-bounds.f90 b/flang/test/Lower/OpenACC/acc-bounds.f90 index 519f9fa2bffd2..cc91f4be1e317 100644 --- a/flang/test/Lower/OpenACC/acc-bounds.f90 +++ b/flang/test/Lower/OpenACC/acc-bounds.f90 @@ -102,4 +102,26 @@ subroutine acc_undefined_extent(a) ! HLFIR: %[[PRESENT:.*]] = acc.present varPtr(%[[DECL_ARG0]]#1 : !fir.ref>) bounds(%[[BOUND]]) -> !fir.ref> {name = "a"} ! CHECK: acc.kernels dataOperands(%[[PRESENT]] : !fir.ref>) + subroutine acc_multi_strides(a) + real, dimension(:,:,:) :: a + + !$acc kernels present(a) + !$acc end kernels + end subroutine + +! CHECK-LABEL: func.func @_QMopenacc_boundsPacc_multi_strides( +! CHECK-SAME: %[[ARG0:.*]]: !fir.box> {fir.bindc_name = "a"}) +! HLFIR: %[[DECL_ARG0:.*]]:2 = hlfir.declare %[[ARG0]] {uniq_name = "_QMopenacc_boundsFacc_multi_stridesEa"} : (!fir.box>) -> (!fir.box>, !fir.box>) +! HLFIR: %[[BOX_DIMS0:.*]]:3 = fir.box_dims %[[DECL_ARG0]]#1, %c0{{.*}} : (!fir.box>, index) -> (index, index, index) +! HLFIR: %[[BOUNDS0:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) stride(%[[BOX_DIMS0]]#2 : index) startIdx(%{{.*}} : index) {strideInBytes = true} +! HLFIR: %[[STRIDE1:.*]] = arith.muli %[[BOX_DIMS0]]#2, %[[BOX_DIMS0]]#1 : index +! HLFIR: %[[BOX_DIMS1:.*]]:3 = fir.box_dims %[[DECL_ARG0]]#1, %c1{{.*}} : (!fir.box>, index) -> (index, index, index) +! HLFIR: %[[BOUNDS1:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) stride(%[[STRIDE1]] : index) startIdx(%{{.*}} : index) {strideInBytes = true} +! HLFIR: %[[STRIDE2:.*]] = arith.muli %[[STRIDE1]], %[[BOX_DIMS1]]#1 : index +! HLFIR: %[[BOX_DIMS2:.*]]:3 = fir.box_dims %[[DECL_ARG0]]#1, %c2{{.*}} : (!fir.box>, index) -> (index, index, index) +! HLFIR: %[[BOUNDS2:.*]] = acc.bounds lowerbound(%{{.*}} : index) upperbound(%{{.*}} : index) stride(%[[STRIDE2]] : index) startIdx(%{{.*}} : index) {strideInBytes = true} +! HLFIR: %[[BOX_ADDR:.*]] = fir.box_addr %[[DECL_ARG0]]#1 : (!fir.box>) -> !fir.ref> +! HLFIR: %[[PRESENT:.*]] = acc.present varPtr(%[[BOX_ADDR]] : !fir.ref>) bounds(%29, %33, %37) -> !fir.ref> {name = "a"} +! HLFIR: acc.kernels dataOperands(%[[PRESENT]] : !fir.ref>) { + end module