[flang-commits] [flang] [llvm] [flang] Enhance show_descriptor intrinsic to avoid extra copies and extra descriptor creation (PR #173461)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Wed Dec 24 10:31:30 PST 2025


https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/173461

>From b2d10b48c33fd43d77d01a8a999f6330dfca0467 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 24 Dec 2025 00:16:02 -0500
Subject: [PATCH 1/5] [flang] Avoid descriptor copy in show_descriptor()

Change show_descriptor() lowering to avoid fir.load, which causes
descriptor copy. Also, if non-descriptor entity is passed to
show_descriptor() treat is as null.
---
 flang-rt/lib/runtime/extensions.cpp           |  2 +-
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 18 ++++++++++++++----
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index 100046fc7bbf7..675d46b078288 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -471,7 +471,7 @@ void RTNAME(ShowDescriptor)(const Fortran::runtime::Descriptor *descr) {
   if (descr) {
     descr->Dump(stderr, /*dumpRawType=*/false);
   } else {
-    std::fprintf(stderr, "NULL\n");
+    std::fprintf(stderr, "NULL or not a descriptor\n");
   }
 }
 
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 75a74eeb18417..77b0e9d2efaeb 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -729,7 +729,7 @@ static constexpr IntrinsicHandler handlers[]{
     {"shiftr", &I::genShift<mlir::arith::ShRUIOp>},
     {"show_descriptor",
      &I::genShowDescriptor,
-     {{{"d", asBox}}},
+     {{{"d", asInquired}}},
      /*isElemental=*/false},
     {"sign", &I::genSign},
     {"signal",
@@ -7893,9 +7893,19 @@ void IntrinsicLibrary::genShowDescriptor(
   assert(args.size() == 1 && "expected single argument for show_descriptor");
   const mlir::Value descriptor = fir::getBase(args[0]);
 
-  assert(fir::isa_box_type(descriptor.getType()) &&
-         "argument must have been lowered to box type");
-  fir::runtime::genShowDescriptor(builder, loc, descriptor);
+  // If it's already a reference to a box, pass it directly.
+  if (fir::isa_ref_type(descriptor.getType()) &&
+      fir::isa_box_type(fir::unwrapRefType(descriptor.getType()))) {
+    fir::runtime::genShowDescriptor(builder, loc, descriptor);
+    return;
+  }
+
+  assert(!fir::isa_box_type(descriptor.getType()) &&
+         "argument must be a reference to a box type");
+
+  // If descriptor is not a box type (and not ref<box>), pass null.
+  mlir::Value nullValue = builder.createNullConstant(loc, fir::BoxType::get(builder.getNoneType()));
+  fir::runtime::genShowDescriptor(builder, loc, nullValue);
 }
 
 // SIGNAL

>From 2ddb3c34c724ae5f7274f9ed3bfbbf4e70c12c43 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 24 Dec 2025 01:08:04 -0500
Subject: [PATCH 2/5] Handle case of fir.box in a register that needs to be
 spilled to the stack.

---
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 77b0e9d2efaeb..495ae875ab167 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -7900,12 +7900,16 @@ void IntrinsicLibrary::genShowDescriptor(
     return;
   }
 
-  assert(!fir::isa_box_type(descriptor.getType()) &&
-         "argument must be a reference to a box type");
-
-  // If descriptor is not a box type (and not ref<box>), pass null.
-  mlir::Value nullValue = builder.createNullConstant(loc, fir::BoxType::get(builder.getNoneType()));
-  fir::runtime::genShowDescriptor(builder, loc, nullValue);
+  mlir::Value descrAddr = nullptr;
+  if (fir::isa_box_type(descriptor.getType())) {
+    // Spill it to the stack
+    descrAddr = builder.createTemporary(loc, descriptor.getType());
+    builder.createStoreWithConvert(loc, descriptor, descrAddr);
+  } else {
+    // If descriptor is not a box type (and not ref<box>), pass null.
+    descrAddr = builder.createNullConstant(loc, fir::BoxType::get(builder.getNoneType()));
+  }
+  fir::runtime::genShowDescriptor(builder, loc, descrAddr);
 }
 
 // SIGNAL

>From 1189c7f80034e20f649720268535db42b8e5862d Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 24 Dec 2025 01:40:46 -0500
Subject: [PATCH 3/5] Updated show_descriptor.f90 LIT test to the new
 show_descriptor() implementation

---
 .../test/Lower/Intrinsics/show_descriptor.f90 | 84 ++++++-------------
 1 file changed, 25 insertions(+), 59 deletions(-)

diff --git a/flang/test/Lower/Intrinsics/show_descriptor.f90 b/flang/test/Lower/Intrinsics/show_descriptor.f90
index a0b8d3eb4348f..d4a5c635b047e 100644
--- a/flang/test/Lower/Intrinsics/show_descriptor.f90
+++ b/flang/test/Lower/Intrinsics/show_descriptor.f90
@@ -10,8 +10,7 @@ subroutine test_int
   integer,allocatable :: a(:)
   n = 5
   allocate(a(n))
-! CHECK:           %[[C3:.*]] = arith.constant 3 : index
-! CHECK:           %[[C1:.*]] = arith.constant 1 : index
+! CHECK:           %[[C0_I64:.*]] = arith.constant 0 : i64
 ! CHECK:           %[[C5:.*]] = arith.constant 5 : i32
 ! CHECK:           %[[C0:.*]] = arith.constant 0 : index
 ! CHECK:           %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
@@ -34,20 +33,11 @@ subroutine test_int
 ! CHECK:           %[[SHAPE_1:.*]] = fir.shape %[[SELECT_0]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[EMBOX_1:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
 ! CHECK:           fir.store %[[EMBOX_1]] to %[[DECLARE_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK:           %[[LOAD_1:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[LOAD_1]]) fastmath<contract> : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[DECLARE_0]]) fastmath<contract> : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> ()
 
   call show_descriptor(a(1:3))
-! CHECK:           %[[LOAD_2:.*]] = fir.load %[[DECLARE_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK:           %[[SHAPE_2:.*]] = fir.shape %[[C3]] : (index) -> !fir.shape<1>
-! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_2]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK:           %[[CONSTANT_4:.*]] = arith.constant 0 : index
-! CHECK:           %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_2]], %[[CONSTANT_4]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
-! CHECK:           %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_0]]#0, %[[BOX_DIMS_0]]#1 : (index, index) -> !fir.shapeshift<1>
-! CHECK:           %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[BOX_ADDR_0]](%[[SHAPE_SHIFT_0]]) %[[C1]] : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
-! CHECK:           %[[CONVERT_1:.*]] = fir.convert %[[ARRAY_COOR_0]] : (!fir.ref<i32>) -> !fir.ref<!fir.array<3xi32>>
-! CHECK:           %[[EMBOX_2:.*]] = fir.embox %[[CONVERT_1]](%[[SHAPE_2]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_2]]) fastmath<contract> : (!fir.box<!fir.array<3xi32>>) -> ()
+! CHECK:           %[[ZERO_BITS_1:.*]] = fir.zero_bits !fir.box<none>
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_1]]) fastmath<contract> : (!fir.box<none>) -> ()
   deallocate(a)
 end subroutine test_int
 
@@ -56,23 +46,15 @@ subroutine test_char
   implicit none
   character(len=9) :: c = 'Hey buddy'
   call show_descriptor(c)
-! CHECK:           %[[C3:.*]] = arith.constant 3 : index
-! CHECK:           %[[C1:.*]] = arith.constant 1 : index
 ! CHECK:           %[[C9:.*]] = arith.constant 9 : index
 ! CHECK:           %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[ADDRESS_OF_0:.*]] = fir.address_of(@_QMtest_show_descriptorFtest_charEc) : !fir.ref<!fir.char<1,9>>
 ! CHECK:           %[[DECLARE_0:.*]] = fir.declare %[[ADDRESS_OF_0]] typeparams %[[C9]] {uniq_name = "_QMtest_show_descriptorFtest_charEc"} : (!fir.ref<!fir.char<1,9>>, index) -> !fir.ref<!fir.char<1,9>>
-! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[DECLARE_0]] : (!fir.ref<!fir.char<1,9>>) -> !fir.box<!fir.char<1,9>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_0]]) fastmath<contract> : (!fir.box<!fir.char<1,9>>) -> ()
+! CHECK:           %[[ZERO_BITS_2:.*]] = fir.zero_bits !fir.box<none>
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_2]]) fastmath<contract> : (!fir.box<none>) -> ()
 
   call show_descriptor(c(1:3))
-! CHECK:           %[[C1_0:.*]] = arith.constant 1 : index
-! CHECK:           %[[SUBI_0:.*]] = arith.subi %[[C1]], %[[C1_0]] : index
-! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[DECLARE_0]] : (!fir.ref<!fir.char<1,9>>) -> !fir.ref<!fir.array<9x!fir.char<1>>>
-! CHECK:           %[[COORDINATE_OF_0:.*]] = fir.coordinate_of %[[CONVERT_0]], %[[SUBI_0]] : (!fir.ref<!fir.array<9x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
-! CHECK:           %[[CONVERT_1:.*]] = fir.convert %[[COORDINATE_OF_0]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,3>>
-! CHECK:           %[[EMBOX_1:.*]] = fir.embox %[[CONVERT_1]] : (!fir.ref<!fir.char<1,3>>) -> !fir.box<!fir.char<1,3>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_1]]) fastmath<contract> : (!fir.box<!fir.char<1,3>>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_2]]) fastmath<contract> : (!fir.box<none>) -> ()
 ! CHECK:           return
 end subroutine test_char
 
@@ -103,20 +85,17 @@ subroutine test_logical
   call show_descriptor(l2)
   pla2 => la2
 ! CHECK:           %[[DECLARE_3:.*]] = fir.declare %[[ALLOCA_0]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMtest_show_descriptorFtest_logicalEpla2"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<2>>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<2>>>>>
-! CHECK:           %[[EMBOX_1:.*]] = fir.embox %[[DECLARE_0]] : (!fir.ref<!fir.logical<1>>) -> !fir.box<!fir.logical<1>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_1]]) fastmath<contract> : (!fir.box<!fir.logical<1>>) -> ()
-! CHECK:           %[[EMBOX_2:.*]] = fir.embox %[[DECLARE_1]] : (!fir.ref<!fir.logical<2>>) -> !fir.box<!fir.logical<2>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_2]]) fastmath<contract> : (!fir.box<!fir.logical<2>>) -> ()
+! CHECK:           %[[ZERO_BITS_3:.*]] = fir.zero_bits !fir.box<none>
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_3]]) fastmath<contract> : (!fir.box<none>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_3]]) fastmath<contract> : (!fir.box<none>) -> ()
 
   call show_descriptor(la2)
   call show_descriptor(pla2)
 ! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[DECLARE_2]] : (!fir.ref<!fir.array<2x!fir.logical<2>>>) -> !fir.ref<!fir.array<?x!fir.logical<2>>>
 ! CHECK:           %[[EMBOX_3:.*]] = fir.embox %[[CONVERT_0]](%[[SHAPE_0]]) : (!fir.ref<!fir.array<?x!fir.logical<2>>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.logical<2>>>>
 ! CHECK:           fir.store %[[EMBOX_3]] to %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<2>>>>>
-! CHECK:           %[[EMBOX_4:.*]] = fir.embox %[[DECLARE_2]](%[[SHAPE_0]]) : (!fir.ref<!fir.array<2x!fir.logical<2>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.logical<2>>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_4]]) fastmath<contract> : (!fir.box<!fir.array<2x!fir.logical<2>>>) -> ()
-! CHECK:           %[[LOAD_0:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<2>>>>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[LOAD_0]]) fastmath<contract> : (!fir.box<!fir.ptr<!fir.array<?x!fir.logical<2>>>>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_3]]) fastmath<contract> : (!fir.box<none>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[DECLARE_3]]) fastmath<contract> : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<2>>>>>) -> ()
 ! CHECK:           return
 end subroutine test_logical
 
@@ -130,6 +109,7 @@ subroutine test_real
 ! CHECK:           %[[C1:.*]] = arith.constant 1 : index
 ! CHECK:           %[[C4:.*]] = arith.constant 4 : index
 ! CHECK:           %[[C3:.*]] = arith.constant 3 : index
+! CHECK:           %[[ALLOCA_BOX:.*]] = fir.alloca !fir.box<!fir.array<2xf64>>
 ! CHECK:           %[[DUMMY_SCOPE_2:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[ADDRESS_OF_4:.*]] = fir.address_of(@_QMtest_show_descriptorFtest_realEhalf) : !fir.ref<f32>
 ! CHECK:           %[[DECLARE_5:.*]] = fir.declare %[[ADDRESS_OF_4]] {uniq_name = "_QMtest_show_descriptorFtest_realEhalf"} : (!fir.ref<f32>) -> !fir.ref<f32>
@@ -139,22 +119,21 @@ subroutine test_real
 ! CHECK:           %[[ADDRESS_OF_6:.*]] = fir.address_of(@_QMtest_show_descriptorFtest_realEw) : !fir.ref<!fir.array<4xf64>>
 ! CHECK:           %[[SHAPE_3:.*]] = fir.shape %[[C4]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[DECLARE_7:.*]] = fir.declare %[[ADDRESS_OF_6]](%[[SHAPE_3]]) {uniq_name = "_QMtest_show_descriptorFtest_realEw"} : (!fir.ref<!fir.array<4xf64>>, !fir.shape<1>) -> !fir.ref<!fir.array<4xf64>>
+! CHECK:           %[[ZERO_BITS_4:.*]] = fir.zero_bits !fir.box<none>
 
   call show_descriptor(half)
   call show_descriptor(row)
   call show_descriptor(w)
   call show_descriptor(w(1:4:2))
-! CHECK:           %[[EMBOX_7:.*]] = fir.embox %[[DECLARE_5]] : (!fir.ref<f32>) -> !fir.box<f32>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_7]]) fastmath<contract> : (!fir.box<f32>) -> ()
-! CHECK:           %[[EMBOX_8:.*]] = fir.embox %[[DECLARE_6]](%[[SHAPE_2]]) : (!fir.ref<!fir.array<3xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xf32>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_8]]) fastmath<contract> : (!fir.box<!fir.array<3xf32>>) -> ()
-! CHECK:           %[[EMBOX_9:.*]] = fir.embox %[[DECLARE_7]](%[[SHAPE_3]]) : (!fir.ref<!fir.array<4xf64>>, !fir.shape<1>) -> !fir.box<!fir.array<4xf64>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_9]]) fastmath<contract> : (!fir.box<!fir.array<4xf64>>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_4]]) fastmath<contract> : (!fir.box<none>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_4]]) fastmath<contract> : (!fir.box<none>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_4]]) fastmath<contract> : (!fir.box<none>) -> ()
 ! CHECK:           %[[SHAPE_4:.*]] = fir.shape %[[C2]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[UNDEFINED_0:.*]] = fir.undefined index
 ! CHECK:           %[[SLICE_0:.*]] = fir.slice %[[C1]], %[[C4]], %[[C2]] : (index, index, index) -> !fir.slice<1>
 ! CHECK:           %[[EMBOX_10:.*]] = fir.embox %[[DECLARE_7]](%[[SHAPE_3]]) {{\[}}%[[SLICE_0]]] : (!fir.ref<!fir.array<4xf64>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<2xf64>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_10]]) fastmath<contract> : (!fir.box<!fir.array<2xf64>>) -> ()
+! CHECK:           fir.store %[[EMBOX_10]] to %[[ALLOCA_BOX]] : !fir.ref<!fir.box<!fir.array<2xf64>>>
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ALLOCA_BOX]]) fastmath<contract> : (!fir.ref<!fir.box<!fir.array<2xf64>>>) -> ()
 ! CHECK:           return
 end subroutine test_real
 
@@ -166,11 +145,7 @@ subroutine test_complex
   complex :: c1 = hr
   complex :: c2 = hi
   complex :: a2(2) = (/ hr, hi /)
-! CHECK:           %[[CST_0:.*]] = arith.constant 0.000000e+00 : f32
-! CHECK:           %[[CST_1:.*]] = arith.constant 5.000000e-01 : f32
 ! CHECK:           %[[C2:.*]] = arith.constant 2 : index
-! CHECK:           %[[ALLOCA_1:.*]] = fir.alloca complex<f32>
-! CHECK:           %[[ALLOCA_2:.*]] = fir.alloca complex<f32>
 ! CHECK:           %[[DUMMY_SCOPE_3:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[ADDRESS_OF_7:.*]] = fir.address_of(@_QMtest_show_descriptorFtest_complexEa2) : !fir.ref<!fir.array<2xcomplex<f32>>>
 ! CHECK:           %[[SHAPE_5:.*]] = fir.shape %[[C2]] : (index) -> !fir.shape<1>
@@ -183,25 +158,16 @@ subroutine test_complex
 ! CHECK:           %[[DECLARE_11:.*]] = fir.declare %[[ADDRESS_OF_10]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QMtest_show_descriptorFtest_complexEChi"} : (!fir.ref<complex<f32>>) -> !fir.ref<complex<f32>>
 ! CHECK:           %[[ADDRESS_OF_11:.*]] = fir.address_of(@_QMtest_show_descriptorFtest_complexEChr) : !fir.ref<complex<f32>>
 ! CHECK:           %[[DECLARE_12:.*]] = fir.declare %[[ADDRESS_OF_11]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QMtest_show_descriptorFtest_complexEChr"} : (!fir.ref<complex<f32>>) -> !fir.ref<complex<f32>>
-! CHECK:           %[[UNDEFINED_1:.*]] = fir.undefined complex<f32>
-! CHECK:           %[[INSERT_VALUE_0:.*]] = fir.insert_value %[[UNDEFINED_1]], %[[CST_1]], [0 : index] : (complex<f32>, f32) -> complex<f32>
-! CHECK:           %[[INSERT_VALUE_1:.*]] = fir.insert_value %[[INSERT_VALUE_0]], %[[CST_0]], [1 : index] : (complex<f32>, f32) -> complex<f32>
-! CHECK:           fir.store %[[INSERT_VALUE_1]] to %[[ALLOCA_2]] : !fir.ref<complex<f32>>
+! CHECK:           %[[ZERO_BITS_5:.*]] = fir.zero_bits !fir.box<none>
 
   call show_descriptor(hr)
-! CHECK:           %[[EMBOX_11:.*]] = fir.embox %[[ALLOCA_2]] : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_11]]) fastmath<contract> : (!fir.box<complex<f32>>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_5]]) fastmath<contract> : (!fir.box<none>) -> ()
 
   call show_descriptor(hi)
-! CHECK:           %[[INSERT_VALUE_2:.*]] = fir.insert_value %[[UNDEFINED_1]], %[[CST_0]], [0 : index] : (complex<f32>, f32) -> complex<f32>
-! CHECK:           %[[INSERT_VALUE_3:.*]] = fir.insert_value %[[INSERT_VALUE_2]], %[[CST_1]], [1 : index] : (complex<f32>, f32) -> complex<f32>
-! CHECK:           fir.store %[[INSERT_VALUE_3]] to %[[ALLOCA_1]] : !fir.ref<complex<f32>>
-! CHECK:           %[[EMBOX_12:.*]] = fir.embox %[[ALLOCA_1]] : (!fir.ref<complex<f32>>) -> !fir.box<complex<f32>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_12]]) fastmath<contract> : (!fir.box<complex<f32>>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_5]]) fastmath<contract> : (!fir.box<none>) -> ()
 
   call show_descriptor(a2)
-! CHECK:           %[[EMBOX_13:.*]] = fir.embox %[[DECLARE_8]](%[[SHAPE_5]]) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.box<!fir.array<2xcomplex<f32>>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_13]]) fastmath<contract> : (!fir.box<!fir.array<2xcomplex<f32>>>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_5]]) fastmath<contract> : (!fir.box<none>) -> ()
 ! CHECK:           return
 end subroutine test_complex
 
@@ -232,10 +198,10 @@ subroutine test_derived
 ! CHECK:           %[[DECLARE_17:.*]] = fir.declare %[[ADDRESS_OF_16]] typeparams %[[C2]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMtest_show_descriptorFtest_derivedE.n.t2"} : (!fir.ref<!fir.char<1,2>>, index) -> !fir.ref<!fir.char<1,2>>
 ! CHECK:           %[[ADDRESS_OF_17:.*]] = fir.address_of(@_QMtest_show_descriptorFtest_derivedEvt2) : !fir.ref<!fir.type<_QMtest_show_descriptorFtest_derivedTt2{t1:!fir.type<_QMtest_show_descriptorFtest_derivedTt1{a:i32,b:i32}>,c:i32}>>
 ! CHECK:           %[[DECLARE_18:.*]] = fir.declare %[[ADDRESS_OF_17]] {uniq_name = "_QMtest_show_descriptorFtest_derivedEvt2"} : (!fir.ref<!fir.type<_QMtest_show_descriptorFtest_derivedTt2{t1:!fir.type<_QMtest_show_descriptorFtest_derivedTt1{a:i32,b:i32}>,c:i32}>>) -> !fir.ref<!fir.type<_QMtest_show_descriptorFtest_derivedTt2{t1:!fir.type<_QMtest_show_descriptorFtest_derivedTt1{a:i32,b:i32}>,c:i32}>>
+! CHECK:           %[[ZERO_BITS_6:.*]] = fir.zero_bits !fir.box<none>
 
   call show_descriptor(vt2)
-! CHECK:           %[[EMBOX_16:.*]] = fir.embox %[[DECLARE_18]] : (!fir.ref<!fir.type<_QMtest_show_descriptorFtest_derivedTt2{t1:!fir.type<_QMtest_show_descriptorFtest_derivedTt1{a:i32,b:i32}>,c:i32}>>) -> !fir.box<!fir.type<_QMtest_show_descriptorFtest_derivedTt2{t1:!fir.type<_QMtest_show_descriptorFtest_derivedTt1{a:i32,b:i32}>,c:i32}>>
-! CHECK:           fir.call @_FortranAShowDescriptor(%[[EMBOX_16]]) fastmath<contract> : (!fir.box<!fir.type<_QMtest_show_descriptorFtest_derivedTt2{t1:!fir.type<_QMtest_show_descriptorFtest_derivedTt1{a:i32,b:i32}>,c:i32}>>) -> ()
+! CHECK:           fir.call @_FortranAShowDescriptor(%[[ZERO_BITS_6]]) fastmath<contract> : (!fir.box<none>) -> ()
 ! CHECK:           return
 end subroutine test_derived
 end module test_show_descriptor

>From f47a8f2c60c6e8ff6bc783e73ef0b525ccba90c6 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 24 Dec 2025 01:41:41 -0500
Subject: [PATCH 4/5] clang-format

---
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 495ae875ab167..e73212ab25203 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -7907,7 +7907,8 @@ void IntrinsicLibrary::genShowDescriptor(
     builder.createStoreWithConvert(loc, descriptor, descrAddr);
   } else {
     // If descriptor is not a box type (and not ref<box>), pass null.
-    descrAddr = builder.createNullConstant(loc, fir::BoxType::get(builder.getNoneType()));
+    descrAddr = builder.createNullConstant(
+        loc, fir::BoxType::get(builder.getNoneType()));
   }
   fir::runtime::genShowDescriptor(builder, loc, descrAddr);
 }

>From fa1edea2d3545df930eb21ee7161c30c7ace1642 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 24 Dec 2025 13:31:21 -0500
Subject: [PATCH 5/5] Apply suggestion from @vzakhari

Comment change

Co-authored-by: Slava Zakharin <szakharin at nvidia.com>
---
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index e73212ab25203..efd78ae796d26 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -7906,7 +7906,7 @@ void IntrinsicLibrary::genShowDescriptor(
     descrAddr = builder.createTemporary(loc, descriptor.getType());
     builder.createStoreWithConvert(loc, descriptor, descrAddr);
   } else {
-    // If descriptor is not a box type (and not ref<box>), pass null.
+    // If argument is not a box type (and not ref<box>), pass null.
     descrAddr = builder.createNullConstant(
         loc, fir::BoxType::get(builder.getNoneType()));
   }



More information about the flang-commits mailing list