Skip to content

Commit 8c8fe11

Browse files
committed
[flang][hlfir] Fixed hlfir.assign codegen for polymorphic LHS.
The RHS cannot be casted to the LHS type, when LHS is polymorphic. With this change we will use the RHS type for emboxing with special hadling for i1 type. I created llvm#62419 for the AllocaOp generated during HLFIRtoFir conversion. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D149392
1 parent 6f01cb9 commit 8c8fe11

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,22 @@ class AssignOpConversion : public mlir::OpRewritePattern<hlfir::AssignOp> {
9191
if (rhsIsValue) {
9292
// createBox can only be called for fir::ExtendedValue that are
9393
// already in memory. Place the integer/real/complex/logical scalar
94-
// in memory (convert to the LHS type so that i1 are allocated in
95-
// a proper Fortran logical storage).
96-
mlir::Type lhsValueType = lhs.getFortranElementType();
97-
mlir::Value rhsVal =
98-
builder.createConvert(loc, lhsValueType, fir::getBase(rhsExv));
99-
mlir::Value temp = builder.create<fir::AllocaOp>(loc, lhsValueType);
94+
// in memory.
95+
// The RHS might be i1, which is not supported for emboxing.
96+
// If LHS is not polymorphic, we may cast the RHS to the LHS type
97+
// before emboxing. If LHS is polymorphic we have to figure out
98+
// the data type for RHS emboxing anyway.
99+
// It is probably a good idea to make sure that the data type
100+
// of the RHS is always a valid Fortran storage data type.
101+
// For the time being, just handle i1 explicitly here.
102+
mlir::Type rhsType = rhs.getFortranElementType();
103+
mlir::Value rhsVal = fir::getBase(rhsExv);
104+
if (rhsType == builder.getI1Type()) {
105+
rhsType = fir::LogicalType::get(builder.getContext(), 4);
106+
rhsVal = builder.createConvert(loc, rhsType, rhsVal);
107+
}
108+
109+
mlir::Value temp = builder.create<fir::AllocaOp>(loc, rhsType);
100110
builder.create<fir::StoreOp>(loc, rhsVal, temp);
101111
rhsExv = temp;
102112
}

flang/test/HLFIR/assign-codegen.fir

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,42 @@ func.func @test_alloc_assign_polymorphic(%lhs: !fir.ref<!fir.class<!fir.heap<!fi
206206
// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<t>>>>>) -> !fir.ref<!fir.box<none>>
207207
// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.class<!fir.array<?x!fir.type<t>>>) -> !fir.box<none>
208208
// CHECK: %[[VAL_10:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_7]], %[[VAL_8]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
209+
210+
func.func @assing_scalar_int_to_polymorphic(%arg0: !fir.ref<!fir.class<!fir.heap<none>>>) {
211+
%c123_i32 = arith.constant 123 : i32
212+
%0:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "x"} : (!fir.ref<!fir.class<!fir.heap<none>>>) -> (!fir.ref<!fir.class<!fir.heap<none>>>, !fir.ref<!fir.class<!fir.heap<none>>>)
213+
hlfir.assign %c123_i32 to %0#0 realloc : i32, !fir.ref<!fir.class<!fir.heap<none>>>
214+
return
215+
}
216+
217+
// CHECK-LABEL: func.func @assing_scalar_int_to_polymorphic(
218+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.class<!fir.heap<none>>>) {
219+
// CHECK: %[[VAL_1:.*]] = arith.constant 123 : i32
220+
// CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "x"} : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.class<!fir.heap<none>>>
221+
// CHECK: %[[VAL_3:.*]] = fir.alloca i32
222+
// CHECK: fir.store %[[VAL_1]] to %[[VAL_3]] : !fir.ref<i32>
223+
// CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]] : (!fir.ref<i32>) -> !fir.box<i32>
224+
// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.box<none>>
225+
// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]] : (!fir.box<i32>) -> !fir.box<none>
226+
// CHECK: %[[VAL_11:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_8]], %[[VAL_9]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
227+
228+
func.func @assign_i1_to_polymorphic(%arg0: !fir.ref<!fir.class<!fir.heap<none>>>) {
229+
%false = arith.constant false
230+
%0:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "x"} : (!fir.ref<!fir.class<!fir.heap<none>>>) -> (!fir.ref<!fir.class<!fir.heap<none>>>, !fir.ref<!fir.class<!fir.heap<none>>>)
231+
%1 = hlfir.no_reassoc %false : i1
232+
hlfir.assign %1 to %0#0 realloc : i1, !fir.ref<!fir.class<!fir.heap<none>>>
233+
return
234+
}
235+
236+
// CHECK-LABEL: func.func @assign_i1_to_polymorphic(
237+
// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.class<!fir.heap<none>>>) {
238+
// CHECK: %[[VAL_1:.*]] = arith.constant false
239+
// CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "x"} : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.class<!fir.heap<none>>>
240+
// CHECK: %[[VAL_3:.*]] = fir.no_reassoc %[[VAL_1]] : i1
241+
// CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i1) -> !fir.logical<4>
242+
// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.logical<4>
243+
// CHECK: fir.store %[[VAL_4]] to %[[VAL_5]] : !fir.ref<!fir.logical<4>>
244+
// CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_5]] : (!fir.ref<!fir.logical<4>>) -> !fir.box<!fir.logical<4>>
245+
// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.box<none>>
246+
// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_6]] : (!fir.box<!fir.logical<4>>) -> !fir.box<none>
247+
// CHECK: %[[VAL_13:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_10]], %[[VAL_11]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none

0 commit comments

Comments
 (0)