Skip to content

Commit 3643d11

Browse files
authored
[flang][hlfir] Support box in user defined assignments (#77578)
When dealing with overlaps in user defined assignments, some entities with descriptors (fir.box) may be saved without descriptors. The current code was replacing the original box entity with the "raw" copy with a simple cast instead of creating a box for the copy. This patch ensures a fir.embox is emitted instead.
1 parent 1a57927 commit 3643d11

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIROrderedAssignments.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,14 @@ convertToMoldType(mlir::Location loc, fir::FirOpBuilder &builder,
421421
}
422422
// Variable to Variable mismatch (e.g., fir.heap<T> vs fir.ref<T>), or value
423423
// to Value mismatch (e.g. i1 vs fir.logical<4>).
424+
if (mlir::isa<fir::BaseBoxType>(mold.getType()) &&
425+
!mlir::isa<fir::BaseBoxType>(input.getType())) {
426+
// An entity may have have been saved without descriptor while the original
427+
// value had a descriptor (e.g., it was not contiguous).
428+
auto emboxed = hlfir::convertToBox(loc, builder, input, mold.getType());
429+
assert(!emboxed.second && "temp should already be in memory");
430+
input = hlfir::Entity{fir::getBase(emboxed.first)};
431+
}
424432
return hlfir::Entity{builder.createConvert(loc, mold.getType(), input)};
425433
}
426434

flang/test/HLFIR/order_assignments/user-defined-assignment.fir

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,26 @@ func.func @test_scalar_forall_overlap(%i: !fir.ref<!fir.array<10xi32>>) {
180180
// CHECK: fir.call @logical_value_to_numeric(%[[VAL_32]], %[[VAL_33]]) : (!fir.ref<i32>, !fir.logical<4>) -> ()
181181
// CHECK: }
182182
// CHECK: fir.freemem %[[VAL_15]] : !fir.heap<!fir.array<?xi1>>
183+
184+
func.func @test_saved_scalar_box(%arg0: !fir.box<!fir.type<sometype>>, %arg1: !fir.class<!fir.type<sometype>>) {
185+
hlfir.region_assign {
186+
hlfir.yield %arg0 : !fir.box<!fir.type<sometype>>
187+
} to {
188+
hlfir.yield %arg1 : !fir.class<!fir.type<sometype>>
189+
} user_defined_assign (%arg2: !fir.box<!fir.type<sometype>>) to (%arg3: !fir.class<!fir.type<sometype>>) {
190+
fir.call @user_assign_box(%arg3, %arg2) : (!fir.class<!fir.type<sometype>>, !fir.box<!fir.type<sometype>>) -> ()
191+
}
192+
return
193+
}
194+
func.func private @user_assign_box(!fir.class<!fir.type<sometype>>, !fir.box<!fir.type<sometype>>) -> ()
195+
196+
// CHECK-LABEL: func.func @test_saved_scalar_box(
197+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.type<sometype>>,
198+
// CHECK-SAME: %[[VAL_1:.*]]: !fir.class<!fir.type<sometype>>) {
199+
// CHECK: %[[VAL_2:.*]] = hlfir.as_expr %[[VAL_0]] : (!fir.box<!fir.type<sometype>>) -> !hlfir.expr<!fir.type<sometype>>
200+
// CHECK: %[[VAL_3:.*]]:3 = hlfir.associate %[[VAL_2]]
201+
// CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]]#1 : (!fir.ref<!fir.type<sometype>>) -> !fir.box<!fir.type<sometype>>
202+
// CHECK: fir.call @user_assign_box(%[[VAL_1]], %[[VAL_4]]) : (!fir.class<!fir.type<sometype>>, !fir.box<!fir.type<sometype>>) -> ()
203+
// CHECK: hlfir.end_associate %[[VAL_3]]#1, %[[VAL_3]]#2 : !fir.ref<!fir.type<sometype>>, i1
204+
// CHECK: return
205+
// CHECK: }

0 commit comments

Comments
 (0)