[flang-commits] [flang] [flang] get rid of descriptor in scalar type is (PR #188762)
via flang-commits
flang-commits at lists.llvm.org
Thu Mar 26 07:47:54 PDT 2026
https://github.com/jeanPerier created https://github.com/llvm/llvm-project/pull/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).
>From ca04e01c5bec22417652976be1b56a125daeb455 Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Thu, 26 Mar 2026 07:38:35 -0700
Subject: [PATCH] [flang] get rid of descriptor in scalar type is
---
.../include/flang/Optimizer/Dialect/FIRType.h | 13 +++-
flang/lib/Lower/Bridge.cpp | 77 +++++++------------
flang/lib/Optimizer/Dialect/FIRType.cpp | 49 +++++++++---
.../acc-data-operands-remapping-selector.f90 | 24 ++++++
flang/test/Lower/polymorphic.f90 | 6 +-
flang/test/Lower/select-type.f90 | 16 ++--
flang/test/Lower/volatile-allocatable.f90 | 9 ++-
7 files changed, 117 insertions(+), 77 deletions(-)
create mode 100644 flang/test/Lower/OpenACC/acc-data-operands-remapping-selector.f90
diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index a94842d82cef3..ef3328e9799bb 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 and
+ /// 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..1cd4d64d40336 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);
+ 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..496dfbd8c498c 100644
--- a/flang/test/Lower/volatile-allocatable.f90
+++ b/flang/test/Lower/volatile-allocatable.f90
@@ -127,8 +127,9 @@ 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 +179,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