[flang-commits] [flang] 6566040 - [flang] get rid of descriptor in scalar type is (#188762)

via flang-commits flang-commits at lists.llvm.org
Mon Mar 30 00:43:46 PDT 2026


Author: jeanPerier
Date: 2026-03-30T09:43:41+02:00
New Revision: 656604093d62952dc80275a62763e1860ab56734

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

LOG: [flang] get rid of descriptor in scalar type is (#188762)

Select type lowering was keeping scalar selector as descriptors inside
TYPE IS for derived type, leading to a declare using a fir.box.
This is not the canonical representation for such variables that can be
tracked with a simple pointer. This code that is remapping variables
that appear in data operation in lowering was not expecting a
fir.declare to be emitted with fir.box for such entity (an assert was
hit in the added OpenACC test).

Align the lowering of derived type scalar selector with the handling of
intrinsic selector. While doing this, simplify the logic by using and
adding fir::BaseBoxAddr helpers to ensure that attributes such as
VOLATILE are correctly propagated (they matter more than keeping the
fir.ptr/fir.heap type that is not relevant for the selector that does
not have the POINTER/ALLOCATABLE attributes).

Added: 
    flang/test/Lower/OpenACC/acc-data-operands-remapping-selector.f90

Modified: 
    flang/include/flang/Optimizer/Dialect/FIRType.h
    flang/lib/Lower/Bridge.cpp
    flang/lib/Optimizer/Dialect/FIRType.cpp
    flang/test/Lower/polymorphic.f90
    flang/test/Lower/select-type.f90
    flang/test/Lower/volatile-allocatable.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index a94842d82cef3..05f6a0746876f 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -48,7 +48,9 @@ class BaseBoxType : public mlir::Type {
   mlir::Type getEleTy() const;
 
   /// Get the raw address type of the memory described by the box.
-  mlir::Type getBaseAddressType() const;
+  /// When \p dropHeapOrPtr is true, the returned type is always a
+  /// fir::ReferenceType.
+  mlir::Type getBaseAddressType(bool dropHeapOrPtr = false) const;
 
   /// Unwrap element type from fir.heap, fir.ptr and fir.array.
   mlir::Type unwrapInnerType() const;
@@ -68,11 +70,20 @@ class BaseBoxType : public mlir::Type {
   /// Is this a box describing volatile memory?
   bool isVolatile() const;
 
+  /// Is this a box describing an array or assumed-rank?
+  bool isArray() const;
+
   /// Return the same type, except for the shape, that is taken the shape
   /// of shapeMold.
   BaseBoxType getBoxTypeWithNewShape(mlir::Type shapeMold) const;
   BaseBoxType getBoxTypeWithNewShape(int rank) const;
 
+  /// Return a box type with the same attributes and shape, except that the
+  /// element type that is changed to the provided one. The returned box will be
+  /// a fir.class if \p polymorphic is true and a fir.box otherwise.
+  BaseBoxType getBoxTypeWithNewElementType(mlir::Type elementType,
+                                           bool polymorphic) const;
+
   /// Return the same type, except for the attribute (fir.heap/fir.ptr).
   BaseBoxType getBoxTypeWithNewAttr(Attribute attr) const;
 

diff  --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 7459f814a0d4d..647bc741e7edc 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -4503,10 +4503,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
     bool hasLocalScope = false;
     llvm::SmallVector<const Fortran::semantics::Scope *> typeCaseScopes;
 
-    const auto selectorIsVolatile = [&selector]() {
-      return fir::isa_volatile_type(fir::getBase(selector).getType());
-    };
-
     const auto &typeCaseList =
         std::get<std::list<Fortran::parser::SelectTypeConstruct::TypeCase>>(
             selectTypeConstruct.t);
@@ -4634,10 +4630,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
         };
 
         mlir::Type baseTy = fir::getBase(selector).getType();
-        bool isPointer = fir::isPointerType(baseTy);
-        bool isAllocatable = fir::isAllocatableType(baseTy);
-        bool isArray =
-            mlir::isa<fir::SequenceType>(fir::dyn_cast_ptrOrBoxEleTy(baseTy));
+        auto selectorBoxType = llvm::cast<fir::BaseBoxType>(baseTy);
+        const bool isArray = selectorBoxType.isArray();
         const fir::BoxValue *selectorBox = selector.getBoxOf<fir::BoxValue>();
         if (std::holds_alternative<Fortran::parser::Default>(guard.u)) {
           // CLASS DEFAULT
@@ -4647,72 +4641,55 @@ class FirConverter : public Fortran::lower::AbstractConverter {
           // TYPE IS
           fir::ExactTypeAttr attr =
               mlir::dyn_cast<fir::ExactTypeAttr>(typeGuardAttr);
-          mlir::Value exactValue;
-          mlir::Type addrTy = attr.getType();
-          if (isArray) {
-            auto seqTy = mlir::dyn_cast<fir::SequenceType>(
-                fir::dyn_cast_ptrOrBoxEleTy(baseTy));
-            addrTy = fir::SequenceType::get(seqTy.getShape(), attr.getType());
-          }
-          if (isPointer)
-            addrTy = fir::PointerType::get(addrTy);
-          if (isAllocatable)
-            addrTy = fir::HeapType::get(addrTy);
+          fir::BaseBoxType newBoxType =
+              selectorBoxType.getBoxTypeWithNewElementType(
+                  attr.getType(), /*polymorphic=*/false);
+          mlir::Type addrTy =
+              newBoxType.getBaseAddressType(/*dropHeapOrPtr=*/true);
+
+          mlir::Value rawPointer = fir::BoxAddrOp::create(
+              *builder, loc, addrTy, fir::getBase(selector));
           if (std::holds_alternative<Fortran::parser::IntrinsicTypeSpec>(
                   typeSpec->u)) {
-            mlir::Type refTy =
-                fir::ReferenceType::get(addrTy, selectorIsVolatile());
-            if (isPointer || isAllocatable)
-              refTy = addrTy;
-            exactValue = fir::BoxAddrOp::create(*builder, loc, refTy,
-                                                fir::getBase(selector));
             const Fortran::semantics::IntrinsicTypeSpec *intrinsic =
                 typeSpec->declTypeSpec->AsIntrinsic();
             if (isArray) {
-              mlir::Value exact = fir::ConvertOp::create(
-                  *builder, loc,
-                  fir::BoxType::get(addrTy, selectorIsVolatile()),
-                  fir::getBase(selector));
-              addAssocEntitySymbol(selectorBox->clone(exact));
+              mlir::Value boxCast = fir::ConvertOp::create(
+                  *builder, loc, newBoxType, fir::getBase(selector));
+              addAssocEntitySymbol(selectorBox->clone(boxCast));
             } else if (intrinsic->category() ==
                        Fortran::common::TypeCategory::Character) {
               auto charTy = mlir::dyn_cast<fir::CharacterType>(attr.getType());
               mlir::Value charLen =
                   fir::factory::CharacterExprHelper(*builder, loc)
                       .readLengthFromBox(fir::getBase(selector), charTy);
-              addAssocEntitySymbol(fir::CharBoxValue(exactValue, charLen));
+              addAssocEntitySymbol(fir::CharBoxValue(rawPointer, charLen));
             } else {
-              addAssocEntitySymbol(exactValue);
+              addAssocEntitySymbol(rawPointer);
             }
           } else if (std::holds_alternative<Fortran::parser::DerivedTypeSpec>(
                          typeSpec->u)) {
-            exactValue = fir::ConvertOp::create(
-                *builder, loc, fir::BoxType::get(addrTy, selectorIsVolatile()),
-                fir::getBase(selector));
-            addAssocEntitySymbol(selectorBox->clone(exactValue));
+            if (isArray) {
+              mlir::Value boxCast = fir::ConvertOp::create(
+                  *builder, loc, newBoxType, fir::getBase(selector));
+              addAssocEntitySymbol(selectorBox->clone(boxCast));
+            } else {
+              addAssocEntitySymbol(rawPointer);
+            }
           }
         } else if (std::holds_alternative<Fortran::parser::DerivedTypeSpec>(
                        guard.u)) {
           // CLASS IS
           fir::SubclassAttr attr =
               mlir::dyn_cast<fir::SubclassAttr>(typeGuardAttr);
-          mlir::Type addrTy = attr.getType();
-          if (isArray) {
-            auto seqTy = mlir::dyn_cast<fir::SequenceType>(
-                fir::dyn_cast_ptrOrBoxEleTy(baseTy));
-            addrTy = fir::SequenceType::get(seqTy.getShape(), attr.getType());
-          }
-          if (isPointer)
-            addrTy = fir::PointerType::get(addrTy);
-          if (isAllocatable)
-            addrTy = fir::HeapType::get(addrTy);
-          mlir::Type classTy =
-              fir::ClassType::get(addrTy, selectorIsVolatile());
-          if (classTy == baseTy) {
+          fir::BaseBoxType newClassType =
+              selectorBoxType.getBoxTypeWithNewElementType(
+                  attr.getType(), /*polymorphic=*/true);
+          if (newClassType == baseTy) {
             addAssocEntitySymbol(selector);
           } else {
             mlir::Value derived = fir::ConvertOp::create(
-                *builder, loc, classTy, fir::getBase(selector));
+                *builder, loc, newClassType, fir::getBase(selector));
             addAssocEntitySymbol(selectorBox->clone(derived));
           }
         }

diff  --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index ccdc8e45feede..9c058289075fa 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -684,30 +684,39 @@ std::string getTypeAsString(mlir::Type ty, const fir::KindMapping &kindMap,
   return buf;
 }
 
-mlir::Type changeElementType(mlir::Type type, mlir::Type newElementType,
-                             bool turnBoxIntoClass) {
+static mlir::Type changeElementTypeImpl(mlir::Type type,
+                                        mlir::Type newElementType,
+                                        bool turnBoxIntoClass,
+                                        bool turnClassIntoBox) {
   return llvm::TypeSwitch<mlir::Type, mlir::Type>(type)
       .Case([&](fir::SequenceType seqTy) -> mlir::Type {
         return fir::SequenceType::get(seqTy.getShape(), newElementType);
       })
-      .Case<fir::ReferenceType, fir::ClassType>([&](auto t) -> mlir::Type {
+      .Case<fir::ReferenceType>([&](auto t) -> mlir::Type {
         using FIRT = decltype(t);
-        auto newEleTy =
-            changeElementType(t.getEleTy(), newElementType, turnBoxIntoClass);
+        auto newEleTy = changeElementTypeImpl(
+            t.getEleTy(), newElementType, turnBoxIntoClass, turnClassIntoBox);
         return FIRT::get(newEleTy, t.isVolatile());
       })
       .Case<fir::PointerType, fir::HeapType>([&](auto t) -> mlir::Type {
         using FIRT = decltype(t);
-        return FIRT::get(
-            changeElementType(t.getEleTy(), newElementType, turnBoxIntoClass));
+        return FIRT::get(changeElementTypeImpl(
+            t.getEleTy(), newElementType, turnBoxIntoClass, turnClassIntoBox));
       })
       .Case([&](fir::BoxType t) -> mlir::Type {
         mlir::Type newInnerType =
-            changeElementType(t.getEleTy(), newElementType, false);
+            changeElementTypeImpl(t.getEleTy(), newElementType, false, false);
         if (turnBoxIntoClass)
           return fir::ClassType::get(newInnerType, t.isVolatile());
         return fir::BoxType::get(newInnerType, t.isVolatile());
       })
+      .Case([&](fir::ClassType t) -> mlir::Type {
+        mlir::Type newInnerType =
+            changeElementTypeImpl(t.getEleTy(), newElementType, false, false);
+        if (turnClassIntoBox)
+          return fir::BoxType::get(newInnerType, t.isVolatile());
+        return fir::ClassType::get(newInnerType, t.isVolatile());
+      })
       .Default([&](mlir::Type t) -> mlir::Type {
         assert((fir::isa_trivial(t) || llvm::isa<fir::RecordType>(t) ||
                 llvm::isa<mlir::NoneType>(t)) &&
@@ -716,6 +725,12 @@ mlir::Type changeElementType(mlir::Type type, mlir::Type newElementType,
       });
 }
 
+mlir::Type changeElementType(mlir::Type type, mlir::Type newElementType,
+                             bool turnBoxIntoClass) {
+  return changeElementTypeImpl(type, newElementType, turnBoxIntoClass,
+                               /*turnClassIntoBox=*/false);
+}
+
 } // namespace fir
 
 namespace {
@@ -1432,11 +1447,11 @@ mlir::Type BaseBoxType::getEleTy() const {
           [](auto type) { return type.getEleTy(); });
 }
 
-mlir::Type BaseBoxType::getBaseAddressType() const {
+mlir::Type BaseBoxType::getBaseAddressType(bool dropHeapOrPtr) const {
   mlir::Type eleTy = getEleTy();
-  if (fir::isa_ref_type(eleTy))
+  if (!dropHeapOrPtr && fir::isa_ref_type(eleTy))
     return eleTy;
-  return fir::ReferenceType::get(eleTy, isVolatile());
+  return fir::ReferenceType::get(getElementOrSequenceType(), isVolatile());
 }
 
 mlir::Type BaseBoxType::unwrapInnerType() const {
@@ -1500,6 +1515,14 @@ fir::BaseBoxType fir::BaseBoxType::getBoxTypeWithNewShape(int rank) const {
   return mlir::cast<fir::BaseBoxType>(changeTypeShape(*this, newShape));
 }
 
+fir::BaseBoxType
+fir::BaseBoxType::getBoxTypeWithNewElementType(mlir::Type elementType,
+                                               bool polymorphic) const {
+  return llvm::cast<fir::BaseBoxType>(changeElementTypeImpl(
+      *this, elementType, /*turnBoxIntoClass=*/polymorphic,
+      /*turnClassIntoBox=*/!polymorphic));
+}
+
 fir::BaseBoxType fir::BaseBoxType::getBoxTypeWithNewAttr(
     fir::BaseBoxType::Attribute attr) const {
   mlir::Type baseType = fir::unwrapRefType(getEleTy());
@@ -1539,6 +1562,10 @@ bool fir::BaseBoxType::isPointerOrAllocatable() const {
 
 bool BaseBoxType::isVolatile() const { return fir::isa_volatile_type(*this); }
 
+bool BaseBoxType::isArray() const {
+  return llvm::isa<fir::SequenceType>(getElementOrSequenceType());
+}
+
 //===----------------------------------------------------------------------===//
 // FIROpsDialect
 //===----------------------------------------------------------------------===//

diff  --git a/flang/test/Lower/OpenACC/acc-data-operands-remapping-selector.f90 b/flang/test/Lower/OpenACC/acc-data-operands-remapping-selector.f90
new file mode 100644
index 0000000000000..5d7f5ee9a5ae6
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-data-operands-remapping-selector.f90
@@ -0,0 +1,24 @@
+! Test remapping of select type selector.
+! RUN: %flang_fc1 -fopenacc -emit-hlfir %s -o - | FileCheck %s
+
+module copyin_selector
+  type t
+    integer :: i
+  end type
+contains
+subroutine foo(x)
+  class(*) :: x
+  select type(x)
+    type is (t)
+      !$acc parallel copyin(x)
+        call bar(x)
+      !$acc end parallel
+  end select
+end subroutine
+end module
+! CHECK-LABEL:  func.func @_QMcopyin_selectorPfoo(
+! CHECK:    fir.select_type
+! CHECK:    %[[COPYIN:.*]] = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.type<_QMcopyin_selectorTt{i:i32}>>) -> !fir.ref<!fir.type<_QMcopyin_selectorTt{i:i32}>> {name = "x"}
+! CHECK:    acc.parallel dataOperands(%[[COPYIN]] : !fir.ref<!fir.type<_QMcopyin_selectorTt{i:i32}>>) {
+! CHECK:      %[[DECL:.*]]:2 = hlfir.declare %[[COPYIN]] {uniq_name = "_QMcopyin_selectorFfooEx"} : (!fir.ref<!fir.type<_QMcopyin_selectorTt{i:i32}>>) -> (!fir.ref<!fir.type<_QMcopyin_selectorTt{i:i32}>>, !fir.ref<!fir.type<_QMcopyin_selectorTt{i:i32}>>)
+! CHECK:      fir.call @_QPbar(%[[DECL]]#0)

diff  --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90
index d8e800771c433..6e84bec14420b 100644
--- a/flang/test/Lower/polymorphic.f90
+++ b/flang/test/Lower/polymorphic.f90
@@ -1014,10 +1014,10 @@ subroutine test_parent_comp_in_select_type(s)
 ! CHECK:  %[[LOAD_S:.*]] = fir.load %[[S]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
 ! CHECK:  fir.select_type %[[LOAD_S]] : !fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>, ^bb1, unit, ^bb2]
 ! CHECK: ^bb1:
-! CHECK:  %[[CONV_S:.*]] = fir.convert %[[LOAD_S]] : (!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>>
-! CHECK:  %[[REBOX_P1:.*]] = fir.rebox %[[CONV_S]] : (!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
+! CHECK:  %[[CONV_S:.*]] = fir.box_addr %[[LOAD_S]] : (!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>
+! CHECK:  %[[EMBOX_P1:.*]] = fir.embox %[[CONV_S]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
 ! CHECK:  %[[LOAD_P:.*]] = fir.load %[[P]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
-! CHECK:  %[[LHS_CONV:.*]] = fir.convert %[[REBOX_P1]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ref<!fir.box<none>>
+! CHECK:  %[[LHS_CONV:.*]] = fir.convert %[[EMBOX_P1]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ref<!fir.box<none>>
 ! CHECK:  %[[RHS_CONV:.*]] = fir.convert %[[LOAD_P]] : (!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.box<none>
 ! CHECK:  fir.call @_FortranAAssign(%[[LHS_CONV]], %[[RHS_CONV]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
 

diff  --git a/flang/test/Lower/select-type.f90 b/flang/test/Lower/select-type.f90
index 246b653390b59..871b084950688 100644
--- a/flang/test/Lower/select-type.f90
+++ b/flang/test/Lower/select-type.f90
@@ -660,15 +660,15 @@ subroutine select_type10(a)
 ! CHECK:  %[[SELECTOR:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
 ! CHECK:  fir.select_type %[[SELECTOR]] : !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb{{.*}}, #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>, ^bb{{.*}}, #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb{{.*}}, unit, ^bb{{.*}}]
 ! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK:  %[[EXACT_BOX:.*]] = fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
 ! CHECK:  %[[C1:.*]] = arith.constant 1 : i32
-! CHECK:  %[[COORD_A:.*]] = fir.coordinate_of %[[EXACT_BOX]], a : (!fir.box<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<i32>
+! CHECK:  %[[COORD_A:.*]] = fir.coordinate_of %[[EXACT_BOX]], a : (!fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.ref<i32>
 ! CHECK:  fir.store %[[C1]] to %[[COORD_A]] : !fir.ref<i32>
 ! CHECK:  cf.br ^bb{{.*}}
 ! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.ptr<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>
+! CHECK:  %[[EXACT_BOX:.*]] = fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>
 ! CHECK:  %[[C3:.*]] = arith.constant 3 : i32
-! CHECK:  %[[COORD_C:.*]] = fir.coordinate_of %[[EXACT_BOX]], c : (!fir.box<!fir.ptr<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>) -> !fir.ref<i32>
+! CHECK:  %[[COORD_C:.*]] = fir.coordinate_of %[[EXACT_BOX]], c : (!fir.ref<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>) -> !fir.ref<i32>
 ! CHECK:  fir.store %[[C3]] to %[[COORD_C]] : !fir.ref<i32>
 ! CHECK:  cf.br ^bb{{.*}}
 ! CHECK: ^bb{{.*}}
@@ -693,15 +693,15 @@ subroutine select_type11(a)
 ! CHECK: %[[SELECTOR:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
 ! CHECK: fir.select_type %[[SELECTOR]] : !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb1, #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>, ^bb2, unit, ^bb3]
 ! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK:  %[[EXACT_BOX:.*]] = fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
 ! CHECK:  %[[C1:.*]] = arith.constant 1 : i32
-! CHECK:  %[[COORD_A:.*]] = fir.coordinate_of %[[EXACT_BOX]], a : (!fir.box<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<i32>
+! CHECK:  %[[COORD_A:.*]] = fir.coordinate_of %[[EXACT_BOX]], a : (!fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.ref<i32>
 ! CHECK:  fir.store %[[C1]] to %[[COORD_A]] : !fir.ref<i32>
 ! CHECK:  cf.br ^bb{{.*}}
 ! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.heap<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>
+! CHECK:  %[[EXACT_BOX:.*]] = fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>
 ! CHECK:  %[[C3:.*]] = arith.constant 3 : i32
-! CHECK:  %[[COORD_C:.*]] = fir.coordinate_of %[[EXACT_BOX]], c : (!fir.box<!fir.heap<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>) -> !fir.ref<i32>
+! CHECK:  %[[COORD_C:.*]] = fir.coordinate_of %[[EXACT_BOX]], c : (!fir.ref<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>) -> !fir.ref<i32>
 ! CHECK:  fir.store %[[C3]] to %[[COORD_C]] : !fir.ref<i32>
 ! CHECK:  cf.br ^bb{{.*}}
 

diff  --git a/flang/test/Lower/volatile-allocatable.f90 b/flang/test/Lower/volatile-allocatable.f90
index 4c0bea60ecaa1..752b3ac07cb47 100644
--- a/flang/test/Lower/volatile-allocatable.f90
+++ b/flang/test/Lower/volatile-allocatable.f90
@@ -127,8 +127,8 @@ subroutine test_unlimited_polymorphic()
 ! CHECK:           %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.ref<i64>, i1, !fir.box<none>, !fir.ref<i8>, i32, {{.*}}) -> i32
 ! CHECK:           fir.call @_FortranAAllocatableInitDerivedForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i32, i32) -> ()
 ! CHECK:           %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.ref<i64>, i1, !fir.box<none>, !fir.ref<i8>, i32, {{.*}}) -> i32
-! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFtest_scalar_volatileEv1"} : (!fir.box<!fir.heap<!fir.type<{{.*}}>>, volatile>) -> (!fir.box<!fir.type<{{.*}}>, volatile>, !fir.box<!fir.type<{{.*}}>, volatile>)
-! CHECK:           %{{.+}} = hlfir.designate %{{.+}}#0{"j"}   : (!fir.box<!fir.type<{{.*}}>, volatile>) -> !fir.ref<i32, volatile>
+! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFtest_scalar_volatileEv1"} : (!fir.ref<!fir.type<{{.*}}, volatile>) -> (!fir.ref<!fir.type<{{.*}}>, volatile>, !fir.ref<!fir.type<{{.*}}>, volatile>)
+! CHECK:           %{{.+}} = hlfir.designate %{{.+}}#0{"j"}   : (!fir.ref<!fir.type<{{.*}}>, volatile>) -> !fir.ref<i32, volatile>
 ! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQro._QMderived_typesText_type.0"} : (!fir.ref<!fir.type<{{.*}}>>) -> (!fir.ref<!fir.type<{{.*}}>>, !fir.ref<!fir.type<{{.*}}>>)
 ! CHECK:           %{{.+}} = fir.call @_FortranAAllocatableAllocateSource(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
 ! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX766F6C6174696C6520636861726163746572"} : (!fir.ref<!fir.char<1,18>>, index) -> (!fir.ref<!fir.char<1,18>>, !fir.ref<!fir.char<1,18>>)
@@ -178,10 +178,10 @@ subroutine test_unlimited_polymorphic()
 ! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs<allocatable, volatile>, uniq_name = "_QFtest_unlimited_polymorphicEupa"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>, volatile>, volatile>) -> (!fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>, volatile>, volatile>, !fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>, volatile>, volatile>)
 ! CHECK:           fir.call @_FortranAAllocatableInitIntrinsicForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, i32, i32, i32, i32) -> ()
 ! CHECK:           %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.ref<i64>, i1, !fir.box<none>, !fir.ref<i8>, i32, {{.*}}) -> i32
-! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFtest_unlimited_polymorphicEup"} : (!fir.heap<i32>) -> (!fir.heap<i32>, !fir.heap<i32>)
+! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFtest_unlimited_polymorphicEup"} : (!fir.ref<i32, volatile>) -> (!fir.ref<i32, volatile>, !fir.ref<i32, volatile>)
 ! CHECK:           fir.call @_FortranAAllocatableInitCharacterForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, i64, i32, i32, i32) -> ()
 ! CHECK:           %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.ref<i64>, i1, !fir.box<none>, !fir.ref<i8>, i32, {{.*}}) -> i32
-! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFtest_unlimited_polymorphicEup"} : (!fir.heap<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.heap<!fir.char<1,?>>)
+! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFtest_unlimited_polymorphicEup"} : (!fir.ref<!fir.char<1,?>, volatile>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>, volatile>)
 ! CHECK:           %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX636C617373282A29"} : (!fir.ref<!fir.char<1,8>>, index) -> (!fir.ref<!fir.char<1,8>>, !fir.ref<!fir.char<1,8>>)
 ! CHECK:           fir.call @_FortranAAllocatableInitIntrinsicForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, i32, i32, i32, i32) -> ()
 ! CHECK:           fir.call @_FortranAAllocatableSetBounds(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()


        


More information about the flang-commits mailing list