Skip to content

Commit ad1cf4c

Browse files
committed
[flang][OpenMP] Handle usage of array elements in loop-control expressions
Extends the fix-up logic for `trip_count` calculation in `target` regions. Previously, if an array element was used to compute any of the loop bounds, the trip-count calculation ops would extract arra elements from the mapped declaration of the array inside the target region. This commit hanles that situation.
1 parent ed2a10b commit ad1cf4c

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ class HostClausesInsertionGuard {
134134
assert(targetParentRegion != nullptr &&
135135
"Expected omp.target op to be nested in a parent region.");
136136

137+
llvm::DenseSet<mlir::Operation *> visitedOps;
138+
137139
// Walk the parent region in pre-order to make sure we visit `targetOp`
138140
// before its nested ops.
139141
targetParentRegion->walk<mlir::WalkOrder::PreOrder>(
@@ -149,6 +151,10 @@ class HostClausesInsertionGuard {
149151
if (operandDefiningOp == nullptr)
150152
continue;
151153

154+
if (visitedOps.contains(operandDefiningOp))
155+
continue;
156+
157+
visitedOps.insert(operandDefiningOp);
152158
auto parentTargetOp =
153159
operandDefiningOp->getParentOfType<mlir::omp::TargetOp>();
154160

@@ -179,7 +185,9 @@ class HostClausesInsertionGuard {
179185

180186
mlir::IRMapping mapper;
181187
builder.setInsertionPoint(escapingOperand->getOwner());
188+
182189
mlir::Operation *lastSliceOp = nullptr;
190+
llvm::SetVector<mlir::Operation *> opsToClone;
183191

184192
for (auto *op : backwardSlice) {
185193
// DeclareOps need special handling by searching for the corresponding ops
@@ -188,12 +196,17 @@ class HostClausesInsertionGuard {
188196
//
189197
// TODO this might need a more elaborate handling in the future but for
190198
// now this seems sufficient for our purposes.
191-
if (llvm::isa<hlfir::DeclareOp>(op))
199+
if (llvm::isa<hlfir::DeclareOp>(op)) {
200+
opsToClone.clear();
192201
break;
202+
}
193203

194-
lastSliceOp = builder.clone(*op, mapper);
204+
opsToClone.insert(op);
195205
}
196206

207+
for (mlir::Operation *op : opsToClone)
208+
lastSliceOp = builder.clone(*op, mapper);
209+
197210
builder.restoreInsertionPoint(ip);
198211
return lastSliceOp;
199212
}

flang/test/Lower/OpenMP/target-do-loop-control-exprs.f90

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,34 @@ subroutine foo_with_dummy_arg(nodes)
6262
! CHECK: omp.target
6363

6464
! CHECK: }
65+
66+
67+
subroutine bounds_expr_in_loop_control(array)
68+
real, intent(out) :: array(:,:)
69+
integer :: bounds(2), i, j
70+
bounds = shape(array)
71+
72+
!$omp target teams distribute parallel do simd collapse(2)
73+
do j = 1,bounds(2)
74+
do i = 1,bounds(1)
75+
array(i,j) = 0.
76+
enddo
77+
enddo
78+
end subroutine bounds_expr_in_loop_control
79+
80+
81+
! CHECK: func.func @_QPbounds_expr_in_loop_control(%[[FUNC_ARG:.*]]: {{.*}}) {
82+
83+
! CHECK: %[[BOUNDS_DECL:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = "{{.*}}Ebounds"} : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> ({{.*}})
84+
85+
! Verify that the host declaration of `bounds` (i.e. not the target/mapped one)
86+
! is used for the trip count calculation. Trip count is calculation ops are emitted
87+
! directly before the `omp.target` op and after all `omp.map.info` op; hence the
88+
! `CHECK-NOT: ...` line.
89+
90+
! CHECK: hlfir.designate %[[BOUNDS_DECL:.*]]#0 (%c2{{.*}})
91+
! CHECK: hlfir.designate %[[BOUNDS_DECL:.*]]#0 (%c1{{.*}})
92+
! CHECK-NOT: omp.map.info
93+
! CHECK: omp.target
94+
95+
! CHECK: }

0 commit comments

Comments
 (0)