From 0c444ff514bfbeb9a4674fdb703c7708b118ebde Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Tue, 21 Feb 2023 10:12:07 +0100 Subject: [PATCH] [flang] Accept polymorphic scalar in elemental intrinsic lowering 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 --- flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 7 +++++-- flang/test/Lower/polymorphic-temp.f90 | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index ed8c00b..007d258 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -1702,9 +1702,12 @@ fir::ExtendedValue IntrinsicLibrary::genElementalCall( ExtendedGenerator generator, llvm::StringRef name, mlir::Type resultType, llvm::ArrayRef args, bool outline) { - for (const fir::ExtendedValue &arg : args) - if (!arg.getUnboxed() && !arg.getCharBox()) + for (const fir::ExtendedValue &arg : args) { + auto *box = arg.getBoxOf(); + 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); diff --git a/flang/test/Lower/polymorphic-temp.f90 b/flang/test/Lower/polymorphic-temp.f90 index e3021df..f8627ef 100644 --- a/flang/test/Lower/polymorphic-temp.f90 +++ b/flang/test/Lower/polymorphic-temp.f90 @@ -185,4 +185,26 @@ contains ! CHECK: %[[MATRIX_NONE:.*]] = fir.convert %[[MATRIX]] : (!fir.class>>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranATranspose(%[[RES_BOX_NONE]], %[[MATRIX_NONE]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.box, !fir.ref, 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.bindc_name = "a"}, %[[ARG1:.*]]: !fir.class> {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.field) -> !fir.ref +! CHECK: %[[LOAD_A1:.*]] = fir.load %[[COORD_A]] : !fir.ref +! 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.field) -> !fir.ref +! CHECK: %[[LOAD_A2:.*]] = fir.load %[[COORD_A]] : !fir.ref +! CHECK: %[[CMPI:.*]] = arith.cmpi sgt, %[[LOAD_A1]], %[[LOAD_A2]] : i32 +! CHECK: %[[SELECT:.*]] = arith.select %[[CMPI]], %[[ARG0]], %[[ARG1]] : !fir.class> +! CHECK: fir.call @_QMpoly_tmpPcheck_scalar(%[[SELECT]]) {{.*}} : (!fir.class>) -> () + end module -- 2.7.4