Skip to content

Commit

Permalink
[flang] Accept polymorphic scalar in elemental intrinsic lowering
Browse files Browse the repository at this point in the history
When lowering an elemental intrinsic like MERGE, a scalar
polymorphic entity was not recognized as a scalar. Update the check
so polyrmorphic entity can be used.

Reviewed By: PeteSteinfeld

Differential Revision: https://reviews.llvm.org/D144417
  • Loading branch information
clementval committed Feb 21, 2023
1 parent fd85a64 commit 0c444ff
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
7 changes: 5 additions & 2 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1702,9 +1702,12 @@ fir::ExtendedValue
IntrinsicLibrary::genElementalCall<IntrinsicLibrary::ExtendedGenerator>(
ExtendedGenerator generator, llvm::StringRef name, mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args, bool outline) {
for (const fir::ExtendedValue &arg : args)
if (!arg.getUnboxed() && !arg.getCharBox())
for (const fir::ExtendedValue &arg : args) {
auto *box = arg.getBoxOf<fir::BoxValue>();
if (!arg.getUnboxed() && !arg.getCharBox() &&
!(box && fir::isPolymorphicType(fir::getBase(*box).getType())))
fir::emitFatalError(loc, "nonscalar intrinsic argument");
}
if (outline)
return outlineInExtendedWrapper(generator, name, resultType, args);
return std::invoke(generator, *this, resultType, args);
Expand Down
22 changes: 22 additions & 0 deletions flang/test/Lower/polymorphic-temp.f90
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,26 @@ subroutine test_temp_from_intrinsic_transpose(matrix)
! CHECK: %[[MATRIX_NONE:.*]] = fir.convert %[[MATRIX]] : (!fir.class<!fir.array<?x?x!fir.type<_QMpoly_tmpTp1{a:i32}>>>) -> !fir.box<none>
! CHECK: %{{.*}} = fir.call @_FortranATranspose(%[[RES_BOX_NONE]], %[[MATRIX_NONE]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none

subroutine check_scalar(a)
class(p1), intent(in) :: a
end subroutine

subroutine test_merge_intrinsic(a, b)
class(p1), intent(in) :: a, b

call check_scalar(merge(a, b, a%a > b%a))
end subroutine

! CHECK-LABEL: func.func @_QMpoly_tmpPtest_merge_intrinsic(
! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMpoly_tmpTp1{a:i32}>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.class<!fir.type<_QMpoly_tmpTp1{a:i32}>> {fir.bindc_name = "b"}) {
! CHECK: %[[FIELD_A:.*]] = fir.field_index a, !fir.type<_QMpoly_tmpTp1{a:i32}>
! CHECK: %[[COORD_A:.*]] = fir.coordinate_of %[[ARG0]], %[[FIELD_A]] : (!fir.class<!fir.type<_QMpoly_tmpTp1{a:i32}>>, !fir.field) -> !fir.ref<i32>
! CHECK: %[[LOAD_A1:.*]] = fir.load %[[COORD_A]] : !fir.ref<i32>
! CHECK: %[[FIELD_A:.*]] = fir.field_index a, !fir.type<_QMpoly_tmpTp1{a:i32}>
! CHECK: %[[COORD_A:.*]] = fir.coordinate_of %[[ARG1]], %[[FIELD_A]] : (!fir.class<!fir.type<_QMpoly_tmpTp1{a:i32}>>, !fir.field) -> !fir.ref<i32>
! CHECK: %[[LOAD_A2:.*]] = fir.load %[[COORD_A]] : !fir.ref<i32>
! CHECK: %[[CMPI:.*]] = arith.cmpi sgt, %[[LOAD_A1]], %[[LOAD_A2]] : i32
! CHECK: %[[SELECT:.*]] = arith.select %[[CMPI]], %[[ARG0]], %[[ARG1]] : !fir.class<!fir.type<_QMpoly_tmpTp1{a:i32}>>
! CHECK: fir.call @_QMpoly_tmpPcheck_scalar(%[[SELECT]]) {{.*}} : (!fir.class<!fir.type<_QMpoly_tmpTp1{a:i32}>>) -> ()

end module

0 comments on commit 0c444ff

Please sign in to comment.