[flang-commits] [flang] 8c8fe11 - [flang][hlfir] Fixed hlfir.assign codegen for polymorphic LHS.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Fri Apr 28 09:10:50 PDT 2023


Author: Slava Zakharin
Date: 2023-04-28T09:10:41-07:00
New Revision: 8c8fe11916b03887f89f04b216e0044f2a9cb505

URL: https://github.com/llvm/llvm-project/commit/8c8fe11916b03887f89f04b216e0044f2a9cb505
DIFF: https://github.com/llvm/llvm-project/commit/8c8fe11916b03887f89f04b216e0044f2a9cb505.diff

LOG: [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

Added: 
    

Modified: 
    flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
    flang/test/HLFIR/assign-codegen.fir

Removed: 
    


################################################################################
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<hlfir::AssignOp> {
       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<fir::AllocaOp>(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<fir::AllocaOp>(loc, rhsType);
         builder.create<fir::StoreOp>(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.class<!fir.heap<!fi
 // CHECK:  %[[VAL_7:.*]] = fir.convert %[[VAL_0]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<t>>>>>) -> !fir.ref<!fir.box<none>>
 // CHECK:  %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.class<!fir.array<?x!fir.type<t>>>) -> !fir.box<none>
 // CHECK:  %[[VAL_10:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_7]], %[[VAL_8]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
+
+func.func @assing_scalar_int_to_polymorphic(%arg0: !fir.ref<!fir.class<!fir.heap<none>>>) {
+  %c123_i32 = arith.constant 123 : i32
+  %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>>>)
+  hlfir.assign %c123_i32 to %0#0 realloc : i32, !fir.ref<!fir.class<!fir.heap<none>>>
+  return
+}
+
+// CHECK-LABEL:   func.func @assing_scalar_int_to_polymorphic(
+// CHECK-SAME:        %[[VAL_0:.*]]: !fir.ref<!fir.class<!fir.heap<none>>>) {
+// CHECK:           %[[VAL_1:.*]] = arith.constant 123 : i32
+// 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>>>
+// CHECK:           %[[VAL_3:.*]] = fir.alloca i32
+// CHECK:           fir.store %[[VAL_1]] to %[[VAL_3]] : !fir.ref<i32>
+// CHECK:           %[[VAL_4:.*]] = fir.embox %[[VAL_3]] : (!fir.ref<i32>) -> !fir.box<i32>
+// CHECK:           %[[VAL_8:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.box<none>>
+// CHECK:           %[[VAL_9:.*]] = fir.convert %[[VAL_4]] : (!fir.box<i32>) -> !fir.box<none>
+// CHECK:           %[[VAL_11:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_8]], %[[VAL_9]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
+
+func.func @assign_i1_to_polymorphic(%arg0: !fir.ref<!fir.class<!fir.heap<none>>>) {
+  %false = arith.constant false
+  %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>>>)
+  %1 = hlfir.no_reassoc %false : i1
+  hlfir.assign %1 to %0#0 realloc : i1, !fir.ref<!fir.class<!fir.heap<none>>>
+  return
+}
+
+// CHECK-LABEL:   func.func @assign_i1_to_polymorphic(
+// CHECK-SAME:                                        %[[VAL_0:.*]]: !fir.ref<!fir.class<!fir.heap<none>>>) {
+// CHECK:           %[[VAL_1:.*]] = arith.constant false
+// 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>>>
+// 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<!fir.logical<4>>
+// CHECK:           %[[VAL_6:.*]] = fir.embox %[[VAL_5]] : (!fir.ref<!fir.logical<4>>) -> !fir.box<!fir.logical<4>>
+// CHECK:           %[[VAL_10:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.box<none>>
+// CHECK:           %[[VAL_11:.*]] = fir.convert %[[VAL_6]] : (!fir.box<!fir.logical<4>>) -> !fir.box<none>
+// CHECK:           %[[VAL_13:.*]] = fir.call @_FortranAAssignPolymorphic(%[[VAL_10]], %[[VAL_11]], %{{.*}}, %{{.*}}) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none


        


More information about the flang-commits mailing list