[flang] Do not try to rebox for assumed type
authorValentin Clement <clementval@gmail.com>
Thu, 16 Mar 2023 16:16:18 +0000 (17:16 +0100)
committerValentin Clement <clementval@gmail.com>
Thu, 16 Mar 2023 16:16:45 +0000 (17:16 +0100)
Just use conversion from assuemd type to assumed type
because a rebox needs more information that are not available
with assumed type.

Also use `isAssumedType` instead of `isBoxNone` since assumed
type can have sequence information.

Depends on D146207

Reviewed By: PeteSteinfeld

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

flang/include/flang/Optimizer/Dialect/FIRType.h
flang/lib/Lower/ConvertExpr.cpp
flang/lib/Optimizer/Builder/FIRBuilder.cpp
flang/lib/Optimizer/Dialect/FIRType.cpp
flang/test/Lower/assumed-type.f90

index 83486ff..942c789 100644 (file)
@@ -318,6 +318,9 @@ bool isPolymorphicType(mlir::Type ty);
 /// value.
 bool isUnlimitedPolymorphicType(mlir::Type ty);
 
+/// Return true iff `ty` is the type of an assumed type.
+bool isAssumedType(mlir::Type ty);
+
 /// Return true iff `boxTy` wraps a record type or an unlimited polymorphic
 /// entity. Polymorphic entities with intrinsic type spec do not have addendum
 inline bool boxHasAddendum(fir::BaseBoxType boxTy) {
index 0dcbb30..03b803e 100644 (file)
@@ -2715,12 +2715,12 @@ public:
             box = Fortran::evaluate::IsVariable(*expr)
                       ? builder.createBox(loc, genBoxArg(*expr),
                                           fir::isPolymorphicType(argTy),
-                                          fir::isBoxNone(argTy))
+                                          fir::isAssumedType(argTy))
                       : builder.createBox(getLoc(), genTempExtAddr(*expr),
                                           fir::isPolymorphicType(argTy),
-                                          fir::isBoxNone(argTy));
+                                          fir::isAssumedType(argTy));
             if (box.getType().isa<fir::BoxType>() &&
-                fir::isPolymorphicType(argTy) && !fir::isBoxNone(argTy)) {
+                fir::isPolymorphicType(argTy) && !fir::isAssumedType(argTy)) {
               mlir::Type actualTy = argTy;
               if (Fortran::lower::isParentComponent(*expr))
                 actualTy = fir::BoxType::get(converter.genType(*expr));
index 23cc3de..244f972 100644 (file)
@@ -360,10 +360,11 @@ fir::FirOpBuilder::convertWithSemantics(mlir::Location loc, mlir::Type toTy,
     return create<fir::EmboxProcOp>(loc, toTy, proc);
   }
 
-  if ((fir::isPolymorphicType(fromTy) &&
-       (fir::isAllocatableType(fromTy) || fir::isPointerType(fromTy)) &&
-       fir::isPolymorphicType(toTy)) ||
-      (fir::isPolymorphicType(fromTy) && toTy.isa<fir::BoxType>()))
+  if (((fir::isPolymorphicType(fromTy) &&
+        (fir::isAllocatableType(fromTy) || fir::isPointerType(fromTy)) &&
+        fir::isPolymorphicType(toTy)) ||
+       (fir::isPolymorphicType(fromTy) && toTy.isa<fir::BoxType>())) &&
+      !(fir::isUnlimitedPolymorphicType(fromTy) && fir::isAssumedType(toTy)))
     return create<fir::ReboxOp>(loc, toTy, val, mlir::Value{},
                                 /*slice=*/mlir::Value{});
 
index c25c683..c15244d 100644 (file)
@@ -300,7 +300,7 @@ bool isScalarBoxedRecordType(mlir::Type ty) {
   return false;
 }
 
-static bool isAssumedType(mlir::Type ty) {
+bool isAssumedType(mlir::Type ty) {
   if (auto boxTy = ty.dyn_cast<fir::BoxType>()) {
     if (boxTy.getEleTy().isa<mlir::NoneType>())
       return true;
index 25d4326..8425b7d 100644 (file)
@@ -8,6 +8,12 @@ module assumed_type_test
     end subroutine
   end interface
 
+  interface
+    subroutine assumed_r(a)
+      type(*), intent(in), target :: a(*)
+    end subroutine
+  end interface
+
 contains
 
   subroutine call_assmued()
@@ -20,4 +26,17 @@ contains
 ! CHECK: %[[BOX_NONE:.*]] = fir.embox %[[I]] : (!fir.ref<i32>) -> !fir.box<none>
 ! CHECK: fir.call @_QPassumed(%[[BOX_NONE]]) fastmath<contract> : (!fir.box<none>) -> ()
 
+  subroutine call_assumed_r()
+    integer, target :: i(10)
+    call assumed_r(i)
+  end subroutine
+
+! CHECK-LABEL: func.func @_QMassumed_type_testPcall_assumed_r() {
+! CHECK: %[[C10:.*]] = arith.constant 10 : index
+! CHECK: %[[I:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "i", fir.target, uniq_name = "_QMassumed_type_testFcall_assumed_rEi"}
+! CHECK: %[[SHAPE:.*]] = fir.shape %[[C10]] : (index) -> !fir.shape<1>
+! CHECK: %[[BOX_NONE:.*]] = fir.embox %[[I]](%[[SHAPE]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xnone>>
+! CHECK: %[[CONV:.*]] = fir.convert %[[BOX_NONE]] : (!fir.box<!fir.array<10xnone>>) -> !fir.box<!fir.array<?xnone>>
+! CHECK: fir.call @_QPassumed_r(%[[CONV]]) {{.*}} : (!fir.box<!fir.array<?xnone>>) -> ()
+
 end module