Skip to content

Commit 6db45cc

Browse files
committed
[flang][hlfir] Fixed actual argument type for passing to poly dummy.
The `none` type cannot be used for creating AssociateOp for the actual argument. I think it should be always okay to compute the storage data type based on the actual argument expression.
1 parent 797594a commit 6db45cc

File tree

2 files changed

+57
-9
lines changed

2 files changed

+57
-9
lines changed

flang/lib/Lower/ConvertCall.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,10 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
854854
const PreparedActualArgument &preparedActual, mlir::Type dummyType,
855855
const Fortran::lower::CallerInterface::PassedEntity &arg,
856856
const Fortran::lower::SomeExpr &expr,
857-
Fortran::evaluate::FoldingContext &foldingContext) {
857+
Fortran::lower::AbstractConverter &converter) {
858+
859+
Fortran::evaluate::FoldingContext &foldingContext =
860+
converter.getFoldingContext();
858861

859862
// Step 1: get the actual argument, which includes addressing the
860863
// element if this is an array in an elemental call.
@@ -931,8 +934,9 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
931934
if (mustSetDynamicTypeToDummyType)
932935
TODO(loc, "passing polymorphic array expression to non polymorphic "
933936
"contiguous dummy");
937+
mlir::Type storageType = converter.genType(expr);
934938
hlfir::AssociateOp associate = hlfir::genAssociateExpr(
935-
loc, builder, entity, dummyType, "adapt.valuebyref");
939+
loc, builder, entity, storageType, "adapt.valuebyref");
936940
entity = hlfir::Entity{associate.getBase()};
937941
preparedDummy.setExprAssociateCleanUp(associate.getFirBase(),
938942
associate.getMustFreeStrorageFlag());
@@ -983,10 +987,10 @@ static PreparedDummyArgument prepareUserCallActualArgument(
983987
const PreparedActualArgument &preparedActual, mlir::Type dummyType,
984988
const Fortran::lower::CallerInterface::PassedEntity &arg,
985989
const Fortran::lower::SomeExpr &expr,
986-
Fortran::evaluate::FoldingContext &foldingContext) {
990+
Fortran::lower::AbstractConverter &converter) {
987991
if (!preparedActual.handleDynamicOptional())
988992
return preparePresentUserCallActualArgument(
989-
loc, builder, preparedActual, dummyType, arg, expr, foldingContext);
993+
loc, builder, preparedActual, dummyType, arg, expr, converter);
990994

991995
// Conditional dummy argument preparation. The actual may be absent
992996
// at runtime, causing any addressing, copy, and packaging to have
@@ -1007,8 +1011,8 @@ static PreparedDummyArgument prepareUserCallActualArgument(
10071011
mlir::Block *preparationBlock = &badIfOp.getThenRegion().front();
10081012
builder.setInsertionPointToStart(preparationBlock);
10091013
PreparedDummyArgument unconditionalDummy =
1010-
preparePresentUserCallActualArgument(
1011-
loc, builder, preparedActual, dummyType, arg, expr, foldingContext);
1014+
preparePresentUserCallActualArgument(loc, builder, preparedActual,
1015+
dummyType, arg, expr, converter);
10121016
builder.restoreInsertionPoint(insertPt);
10131017

10141018
// TODO: when forwarding an optional to an optional of the same kind
@@ -1100,9 +1104,9 @@ genUserCall(PreparedActualArguments &loweredActuals,
11001104
case PassBy::Box:
11011105
case PassBy::BaseAddress:
11021106
case PassBy::BoxChar: {
1103-
PreparedDummyArgument preparedDummy = prepareUserCallActualArgument(
1104-
loc, builder, *preparedActual, argTy, arg, *expr,
1105-
callContext.converter.getFoldingContext());
1107+
PreparedDummyArgument preparedDummy =
1108+
prepareUserCallActualArgument(loc, builder, *preparedActual, argTy,
1109+
arg, *expr, callContext.converter);
11061110
if (preparedDummy.maybeCleanUp.has_value())
11071111
callCleanUps.emplace_back(std::move(*preparedDummy.maybeCleanUp));
11081112
caller.placeInput(arg, preparedDummy.dummy);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
! RUN: bbc -polymorphic-type -emit-fir -hlfir %s -o - | FileCheck %s
2+
3+
! Test passing arguments to subprograms with polymorphic dummy arguments.
4+
5+
! CHECK-LABEL: func.func @_QPtest1() {
6+
! CHECK: %[[VAL_0:.*]] = arith.constant 17 : i32
7+
! CHECK: %[[VAL_1:.*]]:3 = hlfir.associate %[[VAL_0]] {uniq_name = "adapt.valuebyref"} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
8+
! CHECK: %[[VAL_2:.*]] = fir.embox %[[VAL_1]]#0 : (!fir.ref<i32>) -> !fir.box<i32>
9+
! CHECK: %[[VAL_3:.*]] = fir.rebox %[[VAL_2]] : (!fir.box<i32>) -> !fir.class<none>
10+
! CHECK: fir.call @_QPcallee(%[[VAL_3]]) fastmath<contract> : (!fir.class<none>) -> ()
11+
! CHECK: hlfir.end_associate %[[VAL_1]]#1, %[[VAL_1]]#2 : !fir.ref<i32>, i1
12+
! CHECK: return
13+
! CHECK: }
14+
subroutine test1
15+
interface
16+
subroutine callee(x)
17+
class(*) x
18+
end subroutine callee
19+
end interface
20+
call callee(17)
21+
end subroutine test1
22+
23+
! CHECK-LABEL: func.func @_QPtest2(
24+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<f32> {fir.bindc_name = "x"}) {
25+
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest2Ex"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
26+
! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<f32>
27+
! CHECK: %[[VAL_3:.*]] = arith.constant 0.000000e+00 : f32
28+
! CHECK: %[[VAL_4:.*]] = arith.cmpf oeq, %[[VAL_2]], %[[VAL_3]] : f32
29+
! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i1) -> !fir.logical<4>
30+
! CHECK: %[[VAL_6:.*]]:3 = hlfir.associate %[[VAL_5]] {uniq_name = "adapt.valuebyref"} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
31+
! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_6]]#0 : (!fir.ref<!fir.logical<4>>) -> !fir.box<!fir.logical<4>>
32+
! CHECK: %[[VAL_8:.*]] = fir.rebox %[[VAL_7]] : (!fir.box<!fir.logical<4>>) -> !fir.class<none>
33+
! CHECK: fir.call @_QPcallee(%[[VAL_8]]) fastmath<contract> : (!fir.class<none>) -> ()
34+
! CHECK: hlfir.end_associate %[[VAL_6]]#1, %[[VAL_6]]#2 : !fir.ref<!fir.logical<4>>, i1
35+
! CHECK: return
36+
! CHECK: }
37+
subroutine test2(x)
38+
interface
39+
subroutine callee(x)
40+
class(*) x
41+
end subroutine callee
42+
end interface
43+
call callee(x.eq.0)
44+
end subroutine test2

0 commit comments

Comments
 (0)