Skip to content

Commit 839435c

Browse files
authored
[flang] Fix fir::isPolymorphic for TYPE(*) assumed-size arrays (#77339)
fir::isPolymorphic was returning false for TYPE(*) assumed-size arrays causing bad fir.rebox to be created when passing a polymorphic actual argument to such TYPE(*) dummy. Fix fir::isAssumedSize to return true for fir.ref<fir.array<none>> and fir.ref<none>. @cabreraam, I found this bug when testing your patch, although it is not caused by it, so you may hit it when passing TYPE(*) deferred shape of to assumed size TYPE(*) with a different rank.
1 parent a529b6e commit 839435c

File tree

4 files changed

+37
-18
lines changed

4 files changed

+37
-18
lines changed

flang/include/flang/Optimizer/Dialect/FIRType.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,9 @@ bool isPolymorphicType(mlir::Type ty);
330330
/// value.
331331
bool isUnlimitedPolymorphicType(mlir::Type ty);
332332

333-
/// Return true iff `ty` is the type of an assumed type.
333+
/// Return true iff `ty` is the type of an assumed type. In FIR,
334+
/// assumed types are of the form `[fir.ref|ptr|heap]fir.box<[fir.array]none>`,
335+
/// or `fir.ref|ptr|heap<[fir.array]none>`.
334336
bool isAssumedType(mlir::Type ty);
335337

336338
/// Return true iff `ty` is the type of an assumed shape array.

flang/lib/Optimizer/Dialect/FIRType.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -302,13 +302,16 @@ bool isScalarBoxedRecordType(mlir::Type ty) {
302302
}
303303

304304
bool isAssumedType(mlir::Type ty) {
305-
if (auto boxTy = ty.dyn_cast<fir::BoxType>()) {
306-
if (boxTy.getEleTy().isa<mlir::NoneType>())
307-
return true;
308-
if (auto seqTy = boxTy.getEleTy().dyn_cast<fir::SequenceType>())
309-
return seqTy.getEleTy().isa<mlir::NoneType>();
310-
}
311-
return false;
305+
// Rule out CLASS(*) which are `fir.class<[fir.array] none>`.
306+
if (mlir::isa<fir::ClassType>(ty))
307+
return false;
308+
mlir::Type valueType = fir::unwrapPassByRefType(fir::unwrapRefType(ty));
309+
// Refuse raw `none` or `fir.array<none>` since assumed type
310+
// should be in memory variables.
311+
if (valueType == ty)
312+
return false;
313+
mlir::Type inner = fir::unwrapSequenceType(valueType);
314+
return mlir::isa<mlir::NoneType>(inner);
312315
}
313316

314317
bool isAssumedShape(mlir::Type ty) {
@@ -331,20 +334,16 @@ bool isAllocatableOrPointerArray(mlir::Type ty) {
331334
}
332335

333336
bool isPolymorphicType(mlir::Type ty) {
334-
if (auto refTy = fir::dyn_cast_ptrEleTy(ty))
335-
ty = refTy;
336-
// CLASS(*)
337-
if (ty.isa<fir::ClassType>())
337+
// CLASS(T) or CLASS(*)
338+
if (mlir::isa<fir::ClassType>(fir::unwrapRefType(ty)))
338339
return true;
339340
// assumed type are polymorphic.
340341
return isAssumedType(ty);
341342
}
342343

343344
bool isUnlimitedPolymorphicType(mlir::Type ty) {
344-
if (auto refTy = fir::dyn_cast_ptrEleTy(ty))
345-
ty = refTy;
346345
// CLASS(*)
347-
if (auto clTy = ty.dyn_cast<fir::ClassType>()) {
346+
if (auto clTy = mlir::dyn_cast<fir::ClassType>(fir::unwrapRefType(ty))) {
348347
if (clTy.getEleTy().isa<mlir::NoneType>())
349348
return true;
350349
mlir::Type innerType = clTy.unwrapInnerType();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
! Test passing rank 2 CLASS(*) deferred shape to assumed size assumed type
2+
! This requires copy-in/copy-out logic.
3+
! RUN: bbc -emit-hlfir -polymorphic-type -o - %s | FileCheck %s
4+
5+
subroutine pass_poly_to_assumed_type_assumed_size(x)
6+
class(*), target :: x(:,:)
7+
interface
8+
subroutine assumed_type_assumed_size(x)
9+
type(*), target :: x(*)
10+
end subroutine
11+
end interface
12+
call assumed_type_assumed_size(x)
13+
end subroutine
14+
! CHECK-LABEL: func.func @_QPpass_poly_to_assumed_type_assumed_size(
15+
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0:[a-z0-9]*]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFpass_poly_to_assumed_type_assumed_sizeEx"} : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, !fir.class<!fir.array<?x?xnone>>)
16+
! CHECK: %[[VAL_2:.*]]:2 = hlfir.copy_in %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> (!fir.class<!fir.array<?x?xnone>>, i1)
17+
! CHECK: %[[VAL_3:.*]] = fir.box_addr %[[VAL_2]]#0 : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?x?xnone>>
18+
! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?xnone>>
19+
! CHECK: fir.call @_QPassumed_type_assumed_size(%[[VAL_4]]) fastmath<contract> : (!fir.ref<!fir.array<?xnone>>) -> ()
20+
! CHECK: hlfir.copy_out %[[VAL_2]]#0, %[[VAL_2]]#1 to %[[VAL_1]]#0 : (!fir.class<!fir.array<?x?xnone>>, i1, !fir.class<!fir.array<?x?xnone>>) -> ()

flang/test/Lower/polymorphic.f90

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -839,9 +839,7 @@ subroutine test_call_with_null()
839839
! CHECK: %[[IS_ALLOCATED_OR_ASSOCIATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_I64]], %[[C0]] : i64
840840
! CHECK: %[[ABSENT:.*]] = fir.absent !fir.class<none>
841841
! CHECK: %[[PTR_LOAD2:.*]] = fir.load %[[NULL_PTR]] : !fir.ref<!fir.box<!fir.ptr<none>>>
842-
! CHECK: %[[BOX_ADDR2:.*]] = fir.box_addr %[[PTR_LOAD2]] : (!fir.box<!fir.ptr<none>>) -> !fir.ptr<none>
843-
! CHECK: %[[BOX_NONE:.*]] = fir.embox %[[BOX_ADDR2]] : (!fir.ptr<none>) -> !fir.box<none>
844-
! CHECK: %[[CLASS_NONE:.*]] = fir.convert %[[BOX_NONE]] : (!fir.box<none>) -> !fir.class<none>
842+
! CHECK: %[[CLASS_NONE:.*]] = fir.rebox %[[PTR_LOAD2]] : (!fir.box<!fir.ptr<none>>) -> !fir.class<none>
845843
! CHECK: %[[ARG:.*]] = arith.select %[[IS_ALLOCATED_OR_ASSOCIATED]], %[[CLASS_NONE]], %[[ABSENT]] : !fir.class<none>
846844
! CHECK: fir.call @_QMpolymorphic_testPsub_with_poly_optional(%[[ARG]]) {{.*}} : (!fir.class<none>) -> ()
847845

0 commit comments

Comments
 (0)