Skip to content

Commit 1b41074

Browse files
committed
[flang] Embox derived-type when passed to element procedure as passed object
In elemental procedure lowering the passed object is always emboxed. The current code was not correctly dealing with scalar derived-type used as passed object. Reviewed By: jeanPerier, PeteSteinfeld Differential Revision: https://reviews.llvm.org/D139667
1 parent 99b95bd commit 1b41074

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

flang/lib/Lower/ConvertExpr.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4718,8 +4718,21 @@ class ArrayExprLowering {
47184718
emptyRange, tdesc);
47194719
});
47204720
} else {
4721-
PushSemantics(ConstituentSemantics::BoxValue);
4722-
operands.emplace_back(genElementalArgument(*expr));
4721+
ExtValue exv = asScalarRef(*expr);
4722+
if (fir::getBase(exv).getType().isa<fir::BaseBoxType>()) {
4723+
operands.emplace_back(
4724+
[=](IterSpace iters) -> ExtValue { return exv; });
4725+
} else {
4726+
mlir::Type baseTy =
4727+
fir::dyn_cast_ptrOrBoxEleTy(fir::getBase(exv).getType());
4728+
operands.emplace_back([=](IterSpace iters) -> ExtValue {
4729+
mlir::Value empty;
4730+
mlir::ValueRange emptyRange;
4731+
return builder.create<fir::EmboxOp>(
4732+
loc, fir::ClassType::get(baseTy), fir::getBase(exv), empty,
4733+
empty, emptyRange);
4734+
});
4735+
}
47234736
}
47244737
break;
47254738
}

flang/test/Lower/polymorphic.f90

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ module polymorphic_test
1414
procedure, pass(this) :: elemental_sub_pass
1515
generic :: assignment(=) => assign_p1_int
1616
procedure :: host_assoc
17+
procedure, pass(poly) :: lt
18+
generic :: operator(<) => lt
1719
end type
1820

1921
type, extends(p1) :: p2
@@ -34,6 +36,10 @@ module polymorphic_test
3436
class(p3), pointer :: p(:)
3537
end type
3638

39+
type outer
40+
type(p1) :: inner
41+
end type
42+
3743
contains
3844

3945
elemental subroutine assign_p1_int(lhs, rhs)
@@ -67,6 +73,12 @@ elemental subroutine elemental_sub_pass(c, this)
6773
this%a = this%a * this%b + c
6874
end subroutine
6975

76+
logical elemental function lt(i, poly)
77+
integer, intent(in) :: i
78+
class(p1), intent(in) :: poly
79+
lt = i < poly%a
80+
End Function
81+
7082
! Test correct access to polymorphic entity component.
7183
subroutine component_access(p)
7284
class(p1) :: p
@@ -670,3 +682,25 @@ subroutine test_elemental_sub_poly_array_assumed(p)
670682
! CHECK: }
671683

672684
end module
685+
686+
program test
687+
use polymorphic_test
688+
type(outer), allocatable :: o
689+
integer :: i(5)
690+
logical :: l(5)
691+
allocate(o)
692+
693+
l = i < o%inner
694+
end program
695+
696+
! CHECK-LABEL: func.func @_QQmain() {
697+
! CHECK: %[[ADDR_O:.*]] = fir.address_of(@_QFEo) : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTouter{inner:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>}>>>>
698+
! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ADDR_O]] : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTouter{inner:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>}>>>>) -> !fir.ref<!fir.box<none>>
699+
! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
700+
! CHECK: %[[O:.*]] = fir.load %[[ADDR_O]] : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTouter{inner:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>}>>>>
701+
! CHECK: %[[FIELD_INNER:.*]] = fir.field_index inner, !fir.type<_QMpolymorphic_testTouter{inner:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>}>
702+
! CHECK: %[[COORD_INNER:.*]] = fir.coordinate_of %[[O]], %[[FIELD_INNER]] : (!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTouter{inner:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>}>>>, !fir.field) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
703+
! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%arg1 = %9) -> (!fir.array<5x!fir.logical<4>>) {
704+
! CHECK: %[[EMBOXED:.*]] = fir.embox %[[COORD_INNER]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
705+
! CHECK: %{{.*}} = fir.call @_QMpolymorphic_testPlt(%17, %[[EMBOXED]]) {{.*}} : (!fir.ref<i32>, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.logical<4>
706+
! CHECK: }

0 commit comments

Comments
 (0)