[flang] Load fir.ref<fir.class<T>> instead of creating a wrong box
authorValentin Clement <clementval@gmail.com>
Tue, 14 Mar 2023 20:44:41 +0000 (21:44 +0100)
committerValentin Clement <clementval@gmail.com>
Tue, 14 Mar 2023 20:45:20 +0000 (21:45 +0100)
When a subroutine has an entry statement, the non-used argument
will be a fir.alloca and result in a fir.ref<fir.class<T>> for
polymorphic entities. In createBox, just load the box instead of
creating a wrong box.

Reviewed By: PeteSteinfeld

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

flang/lib/Optimizer/Builder/FIRBuilder.cpp
flang/test/Lower/polymorphic.f90

index 64c3c26231eb24256ef95682761e7ed9797469bd..39253e727265e9a0279600ea31161cf20b748440 100644 (file)
@@ -516,6 +516,9 @@ mlir::Value fir::FirOpBuilder::createBox(mlir::Location loc,
         << itemAddr.getType();
     llvm_unreachable("not a memory reference type");
   }
+  if (itemAddr.getType().isa<fir::ReferenceType>() &&
+      elementType.isa<fir::BaseBoxType>())
+    return create<fir::LoadOp>(loc, fir::getBase(exv));
   mlir::Type boxTy = fir::BoxType::get(elementType);
   mlir::Value tdesc;
   if (isPolymorphic) {
index 6bb9f735f5d9a50fbecdfade66ec4f8c5747b368..dd023b9694ff16c912369d8d642da91536367c1d 100644 (file)
@@ -1086,6 +1086,32 @@ module polymorphic_test
 ! CHECK: %[[CONV:.*]] = fir.convert %[[RES]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
 ! CHECK: fir.call @_QMpolymorphic_testPtakes_p1_opt(%[[CONV]]) {{.*}} : (!fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> ()
 
+  subroutine class_with_entry(a)
+    class(p1) :: a,b
+    select type (a)
+    type is(p2)
+      print*, a%c
+    class default
+      print*, a%a
+    end select
+    return
+  entry d(b)
+    select type(b)
+    type is(p2)
+      print*,b%c
+    class default
+      print*,b%a
+    end select
+  end subroutine
+
+! CHECK-LABEL: func.func @_QMpolymorphic_testPclass_with_entry(
+! CHECK-SAME: %[[A:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}) {
+! CHECK: %[[B:.*]] = fir.alloca !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {bindc_name = "b", uniq_name = "_QMpolymorphic_testFclass_with_entryEb"}
+
+! CHECK-LABEL: func.func @_QMpolymorphic_testPd(
+! CHECK-SAME: %[[B:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "b"}) {
+! CHECK: %[[A:.*]] = fir.alloca !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {bindc_name = "a", uniq_name = "_QMpolymorphic_testFclass_with_entryEa"}
+
 end module
 
 program test