From 8c8fe11916b03887f89f04b216e0044f2a9cb505 Mon Sep 17 00:00:00 2001 From: Slava Zakharin Date: Fri, 28 Apr 2023 09:07:23 -0700 Subject: [PATCH] [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 https://github.com/llvm/llvm-project/issues/62419 for the AllocaOp generated during HLFIRtoFir conversion. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D149392 --- .../Optimizer/HLFIR/Transforms/ConvertToFIR.cpp | 22 ++++++++---- flang/test/HLFIR/assign-codegen.fir | 39 ++++++++++++++++++++++ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp index de4ec72..7bff805 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp @@ -91,12 +91,22 @@ public: 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 6da5acc..401d55b 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 -- 2.7.4