[flang-commits] [flang] bb89975 - [flang][hlfir] Use the assignment runtime for unlimited polymorphic.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Mon Aug 14 10:16:21 PDT 2023


Author: Slava Zakharin
Date: 2023-08-14T10:16:14-07:00
New Revision: bb8997515bc571076b6f67111ab3f03a7a5580d3

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

LOG: [flang][hlfir] Use the assignment runtime for unlimited polymorphic.

Handle special case of element-per-element assignments generated
for creating a temp for unlimited polymorphic hlfir.expr.
We currently end up generating an invalid fir.store. We should use
the assignment runtime instead.

Reviewed By: tblah

Differential Revision: https://reviews.llvm.org/D157752

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 dfaaea6c2fc9be..491bdd19896cb2 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -138,7 +138,18 @@ class AssignOpConversion : public mlir::OpRewritePattern<hlfir::AssignOp> {
       } else {
         fir::runtime::genAssign(builder, loc, to, from);
       }
-    } else if (lhs.isArray()) {
+    } else if (lhs.isArray() ||
+               // Special case for element-by-element (or scalar) assignments
+               // generated for creating polymorphic expressions.
+               // The LHS of these assignments is a box describing just
+               // a single element, not the whole allocatable temp.
+               // They do not have 'realloc' attribute, because reallocation
+               // must not happen. The only expected effect of such an
+               // assignment is the copy of the contents, because the dynamic
+               // types of the LHS and the RHS must match already. We use the
+               // runtime in this case so that the polymorphic (including
+               // unlimited) content is copied properly.
+               (lhs.isPolymorphic() && assignOp.isTemporaryLHS())) {
       // Use the runtime for simplicity. An optimization pass will be added to
       // inline array assignment when profitable.
       mlir::Value from = emboxRHS(rhsExv);

diff  --git a/flang/test/HLFIR/assign-codegen.fir b/flang/test/HLFIR/assign-codegen.fir
index 29d002b09c2f64..326e7dee444881 100644
--- a/flang/test/HLFIR/assign-codegen.fir
+++ b/flang/test/HLFIR/assign-codegen.fir
@@ -370,3 +370,59 @@ func.func @_QFPtest_scalar_temp_lhs_no_finalization(%arg0: !fir.ref<!fir.type<_Q
 }
 // CHECK-LABEL:   func.func @_QFPtest_scalar_temp_lhs_no_finalization(
 // CHECK-NOT: fir.call @_FortranADestroy
+
+func.func @test_upoly_expr_assignment(%arg0: !fir.class<!fir.array<?xnone>> {fir.bindc_name = "y"}) {
+  %0 = fir.alloca !fir.class<!fir.heap<!fir.array<?xnone>>>
+  %c0 = arith.constant 0 : index
+  %2:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEy"} : (!fir.class<!fir.array<?xnone>>) -> (!fir.class<!fir.array<?xnone>>, !fir.class<!fir.array<?xnone>>)
+  %3:3 = fir.box_dims %2#0, %c0 : (!fir.class<!fir.array<?xnone>>, index) -> (index, index, index)
+  %8:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = ".tmp.array"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>) -> (!fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>)
+  %22 = fir.load %8#0 : !fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>
+  %c1_2 = arith.constant 1 : index
+  fir.do_loop %arg2 = %c1_2 to %3#1 step %c1_2 unordered {
+    %27 = hlfir.designate %2#0 (%arg2)  : (!fir.class<!fir.array<?xnone>>, index) -> !fir.class<none>
+    %c0_3 = arith.constant 0 : index
+    %28:3 = fir.box_dims %22, %c0_3 : (!fir.class<!fir.heap<!fir.array<?xnone>>>, index) -> (index, index, index)
+    %c1_4 = arith.constant 1 : index
+    %29 = arith.subi %28#0, %c1_4 : index
+    %30 = arith.addi %arg2, %29 : index
+    %31 = hlfir.designate %22 (%30)  : (!fir.class<!fir.heap<!fir.array<?xnone>>>, index) -> !fir.class<none>
+    hlfir.assign %27 to %31 temporary_lhs : !fir.class<none>, !fir.class<none>
+  }
+  return
+}
+// CHECK-LABEL:   func.func @test_upoly_expr_assignment(
+// CHECK-SAME:        %[[VAL_0:.*]]: !fir.class<!fir.array<?xnone>> {fir.bindc_name = "y"}) {
+// CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.class<none>
+// CHECK:           %[[VAL_2:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?xnone>>>
+// CHECK:           %[[VAL_3:.*]] = arith.constant 0 : index
+// CHECK:           %[[VAL_4:.*]] = fir.declare %[[VAL_0]] {uniq_name = "_QFtestEy"} : (!fir.class<!fir.array<?xnone>>) -> !fir.class<!fir.array<?xnone>>
+// CHECK:           %[[VAL_5:.*]] = fir.rebox %[[VAL_4]] : (!fir.class<!fir.array<?xnone>>) -> !fir.class<!fir.array<?xnone>>
+// CHECK:           %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_5]], %[[VAL_3]] : (!fir.class<!fir.array<?xnone>>, index) -> (index, index, index)
+// CHECK:           %[[VAL_7:.*]] = fir.declare %[[VAL_2]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = ".tmp.array"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>) -> !fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>
+// CHECK:           %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>
+// CHECK:           %[[VAL_9:.*]] = arith.constant 1 : index
+// CHECK:           fir.do_loop %[[VAL_10:.*]] = %[[VAL_9]] to %[[VAL_6]]#1 step %[[VAL_9]] unordered {
+// CHECK:             %[[VAL_11:.*]] = fir.array_coor %[[VAL_4]] %[[VAL_10]] : (!fir.class<!fir.array<?xnone>>, index) -> !fir.ref<none>
+// CHECK:             %[[VAL_12:.*]] = fir.embox %[[VAL_11]] source_box %[[VAL_4]] : (!fir.ref<none>, !fir.class<!fir.array<?xnone>>) -> !fir.class<none>
+// CHECK:             %[[VAL_13:.*]] = arith.constant 0 : index
+// CHECK:             %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_8]], %[[VAL_13]] : (!fir.class<!fir.heap<!fir.array<?xnone>>>, index) -> (index, index, index)
+// CHECK:             %[[VAL_15:.*]] = arith.constant 1 : index
+// CHECK:             %[[VAL_16:.*]] = arith.subi %[[VAL_14]]#0, %[[VAL_15]] : index
+// CHECK:             %[[VAL_17:.*]] = arith.addi %[[VAL_10]], %[[VAL_16]] : index
+// CHECK:             %[[VAL_18:.*]] = arith.constant 0 : index
+// CHECK:             %[[VAL_19:.*]]:3 = fir.box_dims %[[VAL_8]], %[[VAL_18]] : (!fir.class<!fir.heap<!fir.array<?xnone>>>, index) -> (index, index, index)
+// CHECK:             %[[VAL_20:.*]] = fir.shift %[[VAL_19]]#0 : (index) -> !fir.shift<1>
+// CHECK:             %[[VAL_21:.*]] = fir.array_coor %[[VAL_8]](%[[VAL_20]]) %[[VAL_17]] : (!fir.class<!fir.heap<!fir.array<?xnone>>>, !fir.shift<1>, index) -> !fir.ref<none>
+// CHECK:             %[[VAL_22:.*]] = fir.embox %[[VAL_21]] source_box %[[VAL_8]] : (!fir.ref<none>, !fir.class<!fir.heap<!fir.array<?xnone>>>) -> !fir.class<none>
+// CHECK:             fir.store %[[VAL_22]] to %[[VAL_1]] : !fir.ref<!fir.class<none>>
+// CHECK:             %[[VAL_23:.*]] = fir.address_of(@_QQcl.{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
+// CHECK:             %[[VAL_24:.*]] = arith.constant {{.*}} : index
+// CHECK:             %[[VAL_25:.*]] = arith.constant {{.*}} : i32
+// CHECK:             %[[VAL_26:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.class<none>>) -> !fir.ref<!fir.box<none>>
+// CHECK:             %[[VAL_27:.*]] = fir.convert %[[VAL_12]] : (!fir.class<none>) -> !fir.box<none>
+// CHECK:             %[[VAL_28:.*]] = fir.convert %[[VAL_23]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK:             %[[VAL_29:.*]] = fir.call @_FortranAAssignTemporary(%[[VAL_26]], %[[VAL_27]], %[[VAL_28]], %[[VAL_25]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
+// CHECK:           }
+// CHECK:           return
+// CHECK:         }


        


More information about the flang-commits mailing list