[flang-commits] [flang] [flang] Fix ignore_tkr(c) passing descriptor instead of base address for non-descriptor dummies (PR #186894)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Mon Mar 16 17:00:07 PDT 2026


https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/186894

>From 179b89bd5bd13b258a8ad86ee7c2fcff3085462e Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Mon, 16 Mar 2026 14:50:48 -0700
Subject: [PATCH 1/2] [flang] Fix ignore_tkr(c) passing descriptor instead of
 base address for non-descriptor dummies

---
 flang/lib/Lower/ConvertCall.cpp               |  2 +-
 .../Lower/HLFIR/ignore-tkr-c-base-addr.f90    | 40 +++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Lower/HLFIR/ignore-tkr-c-base-addr.f90

diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index d72f74b440c53..ae9d1733d053d 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -1349,7 +1349,7 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
   hlfir::Entity actual = preparedActual.getActual(loc, builder);
 
   if (arg.testTKR(Fortran::common::IgnoreTKR::Contiguous) &&
-      actual.isBoxAddress()) {
+      actual.isBoxAddress() && fir::isBoxAddressOrValue(dummyType)) {
     // With ignore_tkr(c), pointer to a descriptor should be passed as is
     return PreparedDummyArgument{actual, /*cleanups=*/{}};
   }
diff --git a/flang/test/Lower/HLFIR/ignore-tkr-c-base-addr.f90 b/flang/test/Lower/HLFIR/ignore-tkr-c-base-addr.f90
new file mode 100644
index 0000000000000..fc9905a49c83b
--- /dev/null
+++ b/flang/test/Lower/HLFIR/ignore-tkr-c-base-addr.f90
@@ -0,0 +1,40 @@
+! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
+
+! Test that ignore_tkr(c) with a non-descriptor dummy (assumed-size) extracts
+! the base address from allocatable/pointer actual arguments instead of passing
+! the descriptor. This pattern is used by CUDA library interfaces like cuFFT.
+
+module m_ignore_tkr_c_base_addr
+  interface
+    subroutine pass_assumed_size(a) bind(c, name="pass_assumed_size")
+      !dir$ ignore_tkr(c) a
+      real :: a(*)
+    end subroutine
+  end interface
+contains
+  ! CHECK-LABEL: func.func @_QMm_ignore_tkr_c_base_addrPtest_allocatable(
+  ! CHECK-SAME: %[[ARR:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+  subroutine test_allocatable(arr)
+    real, allocatable :: arr(:)
+    ! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARR]]
+    ! CHECK: %[[LOAD:.*]] = fir.load %[[DECL]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+    ! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+    ! CHECK: %[[CONV:.*]] = fir.convert %[[ADDR]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
+    ! CHECK: fir.call @pass_assumed_size(%[[CONV]]) {{.*}} : (!fir.ref<!fir.array<?xf32>>) -> ()
+    call pass_assumed_size(arr)
+  end subroutine
+
+  ! CHECK-LABEL: func.func @_QMm_ignore_tkr_c_base_addrPtest_pointer(
+  ! CHECK-SAME: %[[ARR:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+  subroutine test_pointer(arr)
+    real, pointer :: arr(:)
+    ! CHECK: %[[DECL:.*]]:2 = hlfir.declare %[[ARR]]
+    ! CHECK: %[[LOAD:.*]] = fir.load %[[DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+    ! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.ptr<!fir.array<?xf32>>
+    ! CHECK: %[[CONV:.*]] = fir.convert %[[ADDR]] : (!fir.ptr<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
+    ! CHECK: fir.call @pass_assumed_size(%[[CONV]]) {{.*}} : (!fir.ref<!fir.array<?xf32>>) -> ()
+    call pass_assumed_size(arr)
+  end subroutine
+
+  ! CHECK: func.func private @pass_assumed_size(!fir.ref<!fir.array<?xf32>>)
+end module

>From 44b0a50e94b7d5bebb85f42d3bfdf52b2491c85e Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Mon, 16 Mar 2026 16:59:54 -0700
Subject: [PATCH 2/2] Remove bind c as it is not necessary

---
 flang/test/Lower/HLFIR/ignore-tkr-c-base-addr.f90 | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/flang/test/Lower/HLFIR/ignore-tkr-c-base-addr.f90 b/flang/test/Lower/HLFIR/ignore-tkr-c-base-addr.f90
index fc9905a49c83b..e04e8d1a2140f 100644
--- a/flang/test/Lower/HLFIR/ignore-tkr-c-base-addr.f90
+++ b/flang/test/Lower/HLFIR/ignore-tkr-c-base-addr.f90
@@ -6,7 +6,7 @@
 
 module m_ignore_tkr_c_base_addr
   interface
-    subroutine pass_assumed_size(a) bind(c, name="pass_assumed_size")
+    subroutine pass_assumed_size(a)
       !dir$ ignore_tkr(c) a
       real :: a(*)
     end subroutine
@@ -20,7 +20,7 @@ subroutine test_allocatable(arr)
     ! CHECK: %[[LOAD:.*]] = fir.load %[[DECL]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
     ! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
     ! CHECK: %[[CONV:.*]] = fir.convert %[[ADDR]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
-    ! CHECK: fir.call @pass_assumed_size(%[[CONV]]) {{.*}} : (!fir.ref<!fir.array<?xf32>>) -> ()
+    ! CHECK: fir.call @_QPpass_assumed_size(%[[CONV]]) {{.*}} : (!fir.ref<!fir.array<?xf32>>) -> ()
     call pass_assumed_size(arr)
   end subroutine
 
@@ -32,9 +32,9 @@ subroutine test_pointer(arr)
     ! CHECK: %[[LOAD:.*]] = fir.load %[[DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
     ! CHECK: %[[ADDR:.*]] = fir.box_addr %[[LOAD]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.ptr<!fir.array<?xf32>>
     ! CHECK: %[[CONV:.*]] = fir.convert %[[ADDR]] : (!fir.ptr<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
-    ! CHECK: fir.call @pass_assumed_size(%[[CONV]]) {{.*}} : (!fir.ref<!fir.array<?xf32>>) -> ()
+    ! CHECK: fir.call @_QPpass_assumed_size(%[[CONV]]) {{.*}} : (!fir.ref<!fir.array<?xf32>>) -> ()
     call pass_assumed_size(arr)
   end subroutine
 
-  ! CHECK: func.func private @pass_assumed_size(!fir.ref<!fir.array<?xf32>>)
+  ! CHECK: func.func private @_QPpass_assumed_size(!fir.ref<!fir.array<?xf32>>)
 end module



More information about the flang-commits mailing list