Skip to content

Commit

Permalink
[flang] Support polymorphic inputs for the TRANSPOSE intrinsic
Browse files Browse the repository at this point in the history
Force TRANSPOSE with polymorphic inputs through the runtime call
and carry the polymorphic type information from the matrix to
the result.

Reviewed By: jeanPerier

Differential Revision: https://reviews.llvm.org/D143709
  • Loading branch information
clementval committed Feb 12, 2023
1 parent 1bb95a3 commit fe65571
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 6 deletions.
9 changes: 7 additions & 2 deletions flang/lib/Lower/ConvertExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,8 +621,13 @@ isOptimizableTranspose(const Fortran::evaluate::ProcedureRef &procRef,
const Fortran::lower::AbstractConverter &converter) {
const Fortran::evaluate::SpecificIntrinsic *intrin =
procRef.proc().GetSpecificIntrinsic();
return isTransposeOptEnabled(converter) && intrin &&
intrin->name == "transpose";
if (isTransposeOptEnabled(converter) && intrin &&
intrin->name == "transpose") {
const std::optional<Fortran::evaluate::ActualArgument> matrix =
procRef.arguments().at(0);
return !(matrix && matrix->GetType() && matrix->GetType()->IsPolymorphic());
}
return false;
}

template <typename T>
Expand Down
5 changes: 3 additions & 2 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4967,8 +4967,9 @@ IntrinsicLibrary::genTranspose(mlir::Type resultType,

// Create mutable fir.box to be passed to the runtime for the result.
mlir::Type resultArrayType = builder.getVarLenSeqTy(resultType, 2);
fir::MutableBoxValue resultMutableBox =
fir::factory::createTempMutableBox(builder, loc, resultArrayType);
fir::MutableBoxValue resultMutableBox = fir::factory::createTempMutableBox(
builder, loc, resultArrayType, {},
fir::isPolymorphicType(source.getType()) ? source : mlir::Value{});
mlir::Value resultIrBox =
fir::factory::getMutableIRBox(builder, loc, resultMutableBox);
// Call runtime. The runtime is allocating the result.
Expand Down
16 changes: 14 additions & 2 deletions flang/test/Lower/polymorphic-temp.f90
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ subroutine test_temp_from_intrinsic_pack(i, mask)
! CHECK: %[[MASK_BOX_NONE:.*]] = fir.convert %[[EMBOXED_MASK]] : (!fir.box<!fir.array<20x20x!fir.logical<4>>>) -> !fir.box<none>
! CHECK: %{{.*}} = fir.call @_FortranAPack(%[[RES_BOX_NONE]], %[[I_BOX_NONE]], %[[MASK_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none

subroutine check_unpack(r)
subroutine check_rank2(r)
class(p1), intent(in) :: r(:,:)
end subroutine

subroutine test_temp_from_unpack(v, m, f)
class(p1), intent(in) :: v(:), f(:,:)
logical, intent(in) :: m(:,:)
call check_unpack(unpack(v,m,f))
call check_rank2(unpack(v,m,f))
end subroutine

! CHECK-LABEL: func.func @_QMpoly_tmpPtest_temp_from_unpack(
Expand Down Expand Up @@ -173,4 +173,16 @@ subroutine test_temp_from_intrinsic_transfer(source, mold)
! CHECK: %[[MOLD_NONE:.*]] = fir.convert %[[MOLD]] : (!fir.class<!fir.array<?x!fir.type<_QMpoly_tmpTp1{a:i32}>>>) -> !fir.box<none>
! CHECK: %{{.*}} = fir.call @_FortranATransfer(%[[RES_BOX_NONE]], %[[SOURCE_NONE]], %[[MOLD_NONE]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> none

subroutine test_temp_from_intrinsic_transpose(matrix)
class(p1), intent(in) :: matrix(:,:)
call check_rank2(transpose(matrix))
end subroutine

! CHECK-LABEL: func.func @_QMpoly_tmpPtest_temp_from_intrinsic_transpose(
! CHECK-SAME: %[[MATRIX:.*]]: !fir.class<!fir.array<?x?x!fir.type<_QMpoly_tmpTp1{a:i32}>>> {fir.bindc_name = "matrix"}) {
! CHECK: %[[TMP_RES:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMpoly_tmpTp1{a:i32}>>>>
! CHECK: %[[RES_BOX_NONE:.*]] = fir.convert %[[TMP_RES]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMpoly_tmpTp1{a:i32}>>>>>) -> !fir.ref<!fir.box<none>>
! 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

end module

0 comments on commit fe65571

Please sign in to comment.