diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp index de4ec72776436..7bff805571151 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp @@ -91,12 +91,22 @@ class AssignOpConversion : public mlir::OpRewritePattern { if (rhsIsValue) { // createBox can only be called for fir::ExtendedValue that are // already in memory. Place the integer/real/complex/logical scalar - // in memory (convert to the LHS type so that i1 are allocated in - // a proper Fortran logical storage). - mlir::Type lhsValueType = lhs.getFortranElementType(); - mlir::Value rhsVal = - builder.createConvert(loc, lhsValueType, fir::getBase(rhsExv)); - mlir::Value temp = builder.create(loc, lhsValueType); + // in memory. + // The RHS might be i1, which is not supported for emboxing. + // If LHS is not polymorphic, we may cast the RHS to the LHS type + // before emboxing. If LHS is polymorphic we have to figure out + // the data type for RHS emboxing anyway. + // It is probably a good idea to make sure that the data type + // of the RHS is always a valid Fortran storage data type. + // For the time being, just handle i1 explicitly here. + mlir::Type rhsType = rhs.getFortranElementType(); + mlir::Value rhsVal = fir::getBase(rhsExv); + if (rhsType == builder.getI1Type()) { + rhsType = fir::LogicalType::get(builder.getContext(), 4); + rhsVal = builder.createConvert(loc, rhsType, rhsVal); + } + + mlir::Value temp = builder.create(loc, rhsType); builder.create(loc, rhsVal, temp); rhsExv = temp; } diff --git a/flang/test/HLFIR/assign-codegen.fir b/flang/test/HLFIR/assign-codegen.fir index 6da5acc7dec2d..401d55bb53940 100644 --- a/flang/test/HLFIR/assign-codegen.fir +++ b/flang/test/HLFIR/assign-codegen.fir @@ -206,3 +206,42 @@ func.func @test_alloc_assign_polymorphic(%lhs: !fir.ref>>>>) -> !fir.ref> // CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.class>>) -> !fir.box // CHECK: %[[VAL_10:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_7]], %[[VAL_8]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.ref, i32) -> none + +func.func @assing_scalar_int_to_polymorphic(%arg0: !fir.ref>>) { + %c123_i32 = arith.constant 123 : i32 + %0:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs, uniq_name = "x"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) + hlfir.assign %c123_i32 to %0#0 realloc : i32, !fir.ref>> + return +} + +// CHECK-LABEL: func.func @assing_scalar_int_to_polymorphic( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>) { +// CHECK: %[[VAL_1:.*]] = arith.constant 123 : i32 +// CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "x"} : (!fir.ref>>) -> !fir.ref>> +// CHECK: %[[VAL_3:.*]] = fir.alloca i32 +// CHECK: fir.store %[[VAL_1]] to %[[VAL_3]] : !fir.ref +// CHECK: %[[VAL_4:.*]] = fir.embox %[[VAL_3]] : (!fir.ref) -> !fir.box +// CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_2]] : (!fir.ref>>) -> !fir.ref> +// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_4]] : (!fir.box) -> !fir.box +// CHECK: %[[VAL_11:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_8]], %[[VAL_9]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.ref, i32) -> none + +func.func @assign_i1_to_polymorphic(%arg0: !fir.ref>>) { + %false = arith.constant false + %0:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs, uniq_name = "x"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) + %1 = hlfir.no_reassoc %false : i1 + hlfir.assign %1 to %0#0 realloc : i1, !fir.ref>> + return +} + +// CHECK-LABEL: func.func @assign_i1_to_polymorphic( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>) { +// CHECK: %[[VAL_1:.*]] = arith.constant false +// CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "x"} : (!fir.ref>>) -> !fir.ref>> +// CHECK: %[[VAL_3:.*]] = fir.no_reassoc %[[VAL_1]] : i1 +// CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i1) -> !fir.logical<4> +// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.logical<4> +// CHECK: fir.store %[[VAL_4]] to %[[VAL_5]] : !fir.ref> +// CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_5]] : (!fir.ref>) -> !fir.box> +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_2]] : (!fir.ref>>) -> !fir.ref> +// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_6]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_13:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_10]], %[[VAL_11]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.ref, i32) -> none