Skip to content

Commit 86e6a8c

Browse files
committed
[flang][hlfir] Handle scalar to array in hlfir.assign codegen.
The scalar must be placed in memory before creating descriptors and calling the runtime assignment API. Differential Revision: https://reviews.llvm.org/D142698
1 parent 1efde67 commit 86e6a8c

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,26 @@ class AssignOpConversion : public mlir::OpRewritePattern<hlfir::AssignOp> {
9292
"variable to fir::ExtendedValue must not require cleanup");
9393

9494
if (lhs.isArray()) {
95+
const bool rhsIsValue = fir::isa_trivial(fir::getBase(rhsExv).getType());
96+
if (rhsIsValue) {
97+
// createBox can only be called for fir::ExtendedValue that are
98+
// already in memory. Place the integer/real/complex/logical scalar
99+
// in memory (convert to the LHS type so that i1 are allocated in
100+
// a proper Fortran logical storage).
101+
mlir::Type lhsValueType = lhs.getFortranElementType();
102+
mlir::Value rhsVal =
103+
builder.createConvert(loc, lhsValueType, fir::getBase(rhsExv));
104+
mlir::Value temp = builder.create<fir::AllocaOp>(loc, lhsValueType);
105+
builder.create<fir::StoreOp>(loc, rhsVal, temp);
106+
rhsExv = temp;
107+
}
108+
95109
// Use the runtime for simplicity. An optimization pass will be added to
96110
// inline array assignment when profitable.
97111
auto to = fir::getBase(builder.createBox(loc, lhsExv));
98112
auto from = fir::getBase(builder.createBox(loc, rhsExv));
99113
bool cleanUpTemp = false;
100-
if (mayAlias(rhs, lhs))
114+
if (!rhsIsValue && mayAlias(rhs, lhs))
101115
std::tie(from, cleanUpTemp) = genTempFromSourceBox(loc, builder, from);
102116

103117
auto toMutableBox = builder.createTemporary(loc, to.getType());

flang/test/HLFIR/assign-codegen.fir

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,32 @@ func.func @array(%arg0: !fir.box<!fir.array<?xi32>>, %arg1: !fir.ref<!fir.array<
155155
// CHECK: %[[VAL_29:.*]] = fir.call @_FortranAAssign(%[[VAL_26]], %[[VAL_27]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
156156
// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_22]] : (!fir.box<!fir.heap<!fir.array<100xi32>>>) -> !fir.heap<!fir.array<100xi32>>
157157
// CHECK: fir.freemem %[[VAL_30]] : !fir.heap<!fir.array<100xi32>>
158+
159+
160+
func.func @test_scalar_to_array(%lhs: !fir.box<!fir.array<?xi32>>, %rhs: i32) {
161+
hlfir.assign %rhs to %lhs : i32, !fir.box<!fir.array<?xi32>>
162+
return
163+
}
164+
// CHECK-LABEL: func.func @test_scalar_to_array(
165+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xi32>>,
166+
// CHECK-SAME: %[[VAL_1:.*]]: i32) {
167+
// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.array<?xi32>>
168+
// CHECK: %[[VAL_5:.*]] = fir.alloca i32
169+
// CHECK: fir.store %[[VAL_1]] to %[[VAL_5]] : !fir.ref<i32>
170+
// CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_5]] : (!fir.ref<i32>) -> !fir.box<i32>
171+
// CHECK: fir.store %[[VAL_0]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
172+
// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.array<?xi32>>>) -> !fir.ref<!fir.box<none>>
173+
// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_6]] : (!fir.box<i32>) -> !fir.box<none>
174+
// CHECK: %[[VAL_13:.*]] = fir.call @_FortranAAssign(%[[VAL_10]], %[[VAL_11]]
175+
176+
177+
func.func @test_i1_scalar_to_array(%lhs: !fir.box<!fir.array<?x!fir.logical<4>>>, %rhs: i1) {
178+
hlfir.assign %rhs to %lhs : i1, !fir.box<!fir.array<?x!fir.logical<4>>>
179+
return
180+
}
181+
// CHECK-LABEL: func.func @test_i1_scalar_to_array(
182+
// CHECK: %[[VAL_5:.*]] = fir.convert %{{.*}} : (i1) -> !fir.logical<4>
183+
// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.logical<4>
184+
// CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_6]] : (!fir.ref<!fir.logical<4>>) -> !fir.box<!fir.logical<4>>
185+
// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.logical<4>>) -> !fir.box<none>
186+
// CHECK: %[[VAL_14:.*]] = fir.call @_FortranAAssign(%{{.*}}, %[[VAL_12]]

0 commit comments

Comments
 (0)