[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
Tue Dec 23 22:56:24 PST 2025
https://github.com/eugeneepshteyn created https://github.com/llvm/llvm-project/pull/173461
Originally, the argument to show_descriptor() intrinsic was declared as "asBox". This "encouraged" the lowering implementation to wrap incoming parameters into descriptors in many cases. For example, the following would be wrapped into a descriptor:
```
integer :: i
call show_descriptor(i)
```
Here, `i` doesn't need a descriptor, but one would be helpfully created for it.
The current change modifies the argument to show_intrinsic() to "asInquired". The lowering of show_intrinsic() now passes the reference to a descriptor directly to the runtime routine. If descriptor is passed as a value in SSA register, then it's spilled on the stack and its address is passed to the runtime routine. In all other cases, null is passed to the runtime routine, which now prints "NULL or not a descriptor".
An additional benefit is that the descriptor passed to show_descriptor() is no longer copied. In the original implementation, `fir.load` instruction was emitted to pass descriptor "asBox", which resulted in extra llvm.memcpy in LLVM IR. The current change eliminates this, so that show_descriptor() prints information about the original descriptor, not about its copy.
show_descriptor() LIT test was modified to correspond to the new implementation.
>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/4] [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/4] 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/4] 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/4] 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);
}
More information about the flang-commits
mailing list