[flang-commits] [PATCH] D143372: [flang][hlfir] deref pointers before lowering assignment to hlfir.assign

Jean Perier via Phabricator via flang-commits flang-commits at lists.llvm.org
Mon Feb 6 00:32:16 PST 2023


jeanPerier created this revision.
jeanPerier added a reviewer: clementval.
jeanPerier added a project: Flang.
Herald added subscribers: sunshaoce, mehdi_amini, jdoerfert.
Herald added a project: All.
jeanPerier requested review of this revision.

There is little point not to dereference pointers LHS and RHS before
before emitting an hlfir.assign when lowering an assignment.
This pushes complexity and descriptor read side effects that are better
expressed in a load before the assignment.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D143372

Files:
  flang/lib/Lower/Bridge.cpp
  flang/lib/Optimizer/Builder/HLFIRTools.cpp
  flang/test/Lower/HLFIR/allocatable-and-pointer-subparts.f90
  flang/test/Lower/HLFIR/assignment-intrinsics.f90


Index: flang/test/Lower/HLFIR/assignment-intrinsics.f90
===================================================================
--- flang/test/Lower/HLFIR/assignment-intrinsics.f90
+++ flang/test/Lower/HLFIR/assignment-intrinsics.f90
@@ -135,6 +135,17 @@
 ! CHECK:  %[[VAL_11:.*]]:2 = hlfir.declare {{.*}}  {uniq_name = "_QFarray_characterEy"} : (!fir.ref<!fir.array<10x!fir.char<1,?>>>, !fir.shape<1>, index) -> (!fir.box<!fir.array<10x!fir.char<1,?>>>, !fir.ref<!fir.array<10x!fir.char<1,?>>>)
 ! CHECK:  hlfir.assign %[[VAL_11]]#0 to %[[VAL_6]]#0 : !fir.box<!fir.array<10x!fir.char<1,?>>>, !fir.box<!fir.array<10x!fir.char<1,?>>>
 
+subroutine array_pointer(x, y)
+  real, pointer :: x(:), y(:)
+  x = y
+end subroutine
+! CHECK-LABEL: func.func @_QParray_pointer(
+! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %{{.*}}Ex
+! CHECK:  %[[VAL_2:.*]]:2 = hlfir.declare %{{.*}}Ey
+! CHECK:  %[[VAL_3:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK:  %[[VAL_4:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK:  hlfir.assign %[[VAL_3]] to %[[VAL_4]] : !fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.box<!fir.ptr<!fir.array<?xf32>>>
+
 ! -----------------------------------------------------------------------------
 !     Test assignments with array LHS and scalar RHS
 ! -----------------------------------------------------------------------------
Index: flang/test/Lower/HLFIR/allocatable-and-pointer-subparts.f90
===================================================================
--- flang/test/Lower/HLFIR/allocatable-and-pointer-subparts.f90
+++ flang/test/Lower/HLFIR/allocatable-and-pointer-subparts.f90
@@ -26,7 +26,8 @@
 ! CHECK:  %[[VAL_1:.*]]:2 = hlfir.declare %{{.*}} {{.*}}Ex
 ! CHECK:  %[[VAL_2:.*]] = hlfir.designate %[[VAL_1]]#0{"p"}   {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt2{p:!fir.box<!fir.ptr<!fir.type<_QMmTt1{x:f32}>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt1{x:f32}>>>>
 ! CHECK:  %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt1{x:f32}>>>>
-! CHECK:  %[[VAL_4:.*]] = hlfir.designate %[[VAL_3]]{"x"}   : (!fir.box<!fir.ptr<!fir.type<_QMmTt1{x:f32}>>>) -> !fir.ref<f32>
+! CHECK:  %[[VAL_4:.*]] = fir.box_addr %[[VAL_3:.*]] : (!fir.box<!fir.ptr<!fir.type<_QMmTt1{x:f32}>>>) -> !fir.ptr<!fir.type<_QMmTt1{x:f32}>>
+! CHECK:  hlfir.designate %[[VAL_4]]{"x"}   : (!fir.ptr<!fir.type<_QMmTt1{x:f32}>>) -> !fir.ref<f32>
 
 subroutine test_symbol_followed_by_ref(x)
   character(:), allocatable :: x(:)
Index: flang/lib/Optimizer/Builder/HLFIRTools.cpp
===================================================================
--- flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -570,9 +570,9 @@
   if (entity.isMutableBox()) {
     hlfir::Entity boxLoad{builder.create<fir::LoadOp>(loc, entity)};
     if (entity.isScalar()) {
-      mlir::Type elementType = boxLoad.getFortranElementType();
-      if (fir::isa_trivial(elementType))
+      if (!entity.isPolymorphic() && !entity.hasLengthParameters())
         return hlfir::Entity{builder.create<fir::BoxAddrOp>(loc, boxLoad)};
+      mlir::Type elementType = boxLoad.getFortranElementType();
       if (auto charType = elementType.dyn_cast<fir::CharacterType>()) {
         mlir::Value base = builder.create<fir::BoxAddrOp>(loc, boxLoad);
         if (charType.hasConstantLen())
@@ -585,7 +585,10 @@
                 .getResult()};
       }
     }
-    // Keep the entity boxed for now.
+    // Otherwise, the entity is either an array, a polymorphic entity, or a
+    // derived type with length parameters. All these entities require a fir.box
+    // or fir.class to hold bounds, dynamic type or length parameter
+    // information. Keep them boxed.
     return boxLoad;
   }
   return entity;
Index: flang/lib/Lower/Bridge.cpp
===================================================================
--- flang/lib/Lower/Bridge.cpp
+++ flang/lib/Lower/Bridge.cpp
@@ -2731,12 +2731,15 @@
                 Fortran::lower::StatementContext stmtCtx;
                 if (Fortran::lower::isWholeAllocatable(assign.lhs))
                   TODO(loc, "HLFIR assignment to whole allocatable");
-                hlfir::EntityWithAttributes rhs =
-                    Fortran::lower::convertExprToHLFIR(loc, *this, assign.rhs,
-                                                       localSymbols, stmtCtx);
-                hlfir::EntityWithAttributes lhs =
-                    Fortran::lower::convertExprToHLFIR(loc, *this, assign.lhs,
-                                                       localSymbols, stmtCtx);
+                hlfir::Entity rhs = Fortran::lower::convertExprToHLFIR(
+                    loc, *this, assign.rhs, localSymbols, stmtCtx);
+                // Dereference pointers and allocatables RHS: the target is
+                // being assigned from.
+                rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs);
+                hlfir::Entity lhs = Fortran::lower::convertExprToHLFIR(
+                    loc, *this, assign.lhs, localSymbols, stmtCtx);
+                // Dereference pointers LHS: the target is being assigned to.
+                lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs);
                 builder.create<hlfir::AssignOp>(loc, rhs, lhs);
               },
               // [2] User defined assignment. If the context is a scalar


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143372.495013.patch
Type: text/x-patch
Size: 5454 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20230206/737e8ba8/attachment-0001.bin>


More information about the flang-commits mailing list