[flang-commits] [flang] [flang] handle intrinsic interfaces in FunctionRef::GetType (PR #89583)

via flang-commits flang-commits at lists.llvm.org
Mon Apr 22 02:34:40 PDT 2024


https://github.com/jeanPerier created https://github.com/llvm/llvm-project/pull/89583

User functions may be declared with an interface that is a specific intrinsic. In such case, there is no result type available from the procedure symbol (at least without using evaluate::Probe), and FunctionRef::GetType() returned nullopt. This caused lowering to crash.
The result type of specific intrinsic procedures is always a lengthless intrinsic type, so it is fully defined in the template argument of FunctionRef. Use it.

>From 6d1189e6f2bf955b4c1acf1ad40def6ddcd3541c Mon Sep 17 00:00:00 2001
From: Jean Perier <jperier at nvidia.com>
Date: Mon, 22 Apr 2024 02:26:27 -0700
Subject: [PATCH] [flang] handle intrinsic interfaces in FunctionRef::GetType

User functions may be declared with an interface that is a specific intrinsic.
In such case, there is no result type available from the procedure
symbol (at least without using evaluate::Probe), and FunctionRef::GetType()
returned nullopt. This caused lowering to crash.
The result type of specific intrinsic procedures is always a lengthless
intrinsic type, so it is fully defined in the template argument of
FunctionRef. Use it.
---
 flang/include/flang/Evaluate/call.h  | 20 ++++++++++++--------
 flang/test/Lower/HLFIR/calls-f77.f90 | 13 +++++++++++++
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/flang/include/flang/Evaluate/call.h b/flang/include/flang/Evaluate/call.h
index 3d766bc08e58d4..7317ab099c1cc4 100644
--- a/flang/include/flang/Evaluate/call.h
+++ b/flang/include/flang/Evaluate/call.h
@@ -287,15 +287,19 @@ template <typename A> class FunctionRef : public ProcedureRef {
       : ProcedureRef{std::move(p), std::move(a)} {}
 
   std::optional<DynamicType> GetType() const {
-    if (auto type{proc_.GetType()}) {
-      // TODO: Non constant explicit length parameters of PDTs result should
-      // likely be dropped too. This is not as easy as for characters since some
-      // long lived DerivedTypeSpec pointer would need to be created here. It is
-      // not clear if this is causing any issue so far since the storage size of
-      // PDTs is independent of length parameters.
-      return type->DropNonConstantCharacterLength();
+    if constexpr (IsLengthlessIntrinsicType<A>) {
+      return A::GetType();
+    } else {
+      if (auto type{proc_.GetType()}) {
+        // TODO: Non constant explicit length parameters of PDTs result should
+        // likely be dropped too. This is not as easy as for characters since
+        // some long lived DerivedTypeSpec pointer would need to be created
+        // here. It is not clear if this is causing any issue so far since the
+        // storage size of PDTs is independent of length parameters.
+        return type->DropNonConstantCharacterLength();
+      }
+      return std::nullopt;
     }
-    return std::nullopt;
   }
 };
 } // namespace Fortran::evaluate
diff --git a/flang/test/Lower/HLFIR/calls-f77.f90 b/flang/test/Lower/HLFIR/calls-f77.f90
index ac5be007eb838c..cefe379a45d353 100644
--- a/flang/test/Lower/HLFIR/calls-f77.f90
+++ b/flang/test/Lower/HLFIR/calls-f77.f90
@@ -186,3 +186,16 @@ subroutine alternate_return_call(n1, n2, k)
   ! CHECK: ^[[block2]]: // pred: ^bb0
 7 k =  1; return
 end
+
+! -----------------------------------------------------------------------------
+!     Test calls to user procedures with intrinsic interfaces
+! -----------------------------------------------------------------------------
+
+! CHECK-NAME: func.func @_QPintrinsic_iface()
+subroutine intrinsic_iface()
+  intrinsic acos
+  real :: x
+  procedure(acos) :: proc
+  x = proc(1.0)
+end subroutine
+! CHECK" fir.call @_QPproc(%{{.*}}) {{.*}}: (!fir.ref<f32>) -> f32



More information about the flang-commits mailing list