[flang-commits] [flang] [flang][debug] Add fake use ops for dynamic array dimension variables (PR #200061)
via flang-commits
flang-commits at lists.llvm.org
Fri Jun 19 11:51:11 PDT 2026
https://github.com/timsmith78 updated https://github.com/llvm/llvm-project/pull/200061
>From 144098d6858732f30bb3c7a1992484af32a90989 Mon Sep 17 00:00:00 2001
From: Timothy Smith <timothy.smith at hpe.com>
Date: Fri, 15 May 2026 15:17:51 -0500
Subject: [PATCH 1/6] Add fake use ops for dynamic array dimension variables
In cases where the upper or lower bounds of a dynamic array are not
explicitly referenced in code, flang can optimize away the internal
variables that represent these values. This causes missing values to
appear in the debugger when examining the dynamic array's type. Adding
an llvm.fake.use op for each bound preserves it for use by a debugger,
similar to the fix for #185432.
Resolves #119474
---
.../flang/Optimizer/Transforms/Passes.td | 4 +-
flang/lib/Optimizer/Passes/Pipelines.cpp | 2 +-
.../lib/Optimizer/Transforms/AddDebugInfo.cpp | 63 +++++--
.../debug-fake-use-multiple-dimensions.fir | 165 ++++++++++++++++++
.../debug-fake-use-multiple-returns.fir | 125 +++++++++++++
flang/test/Transforms/debug-fake-use.fir | 52 +++++-
6 files changed, 391 insertions(+), 20 deletions(-)
create mode 100644 flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
create mode 100644 flang/test/Transforms/debug-fake-use-multiple-returns.fir
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index d9072e7aab4f7..8c082fb073451 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -267,9 +267,9 @@ def AddDebugInfo : Pass<"add-debug-info", "mlir::ModuleOp"> {
Option<"dwarfDebugFlags", "dwarf-debug-flags",
"std::string", /*default=*/"std::string{}",
"Command-line flags to append to DWARF producer">,
- Option<"emitFakeUseForArguments", "emit-fake-use-for-arguments",
+ Option<"emitFakeUseForDebugVars", "emit-fake-use-for-debug-vars",
"bool", /*default=*/"false",
- "Emit fake use for function arguments to extend their lifetime">
+ "Emit fake use for debug variables to extend their lifetime">
];
}
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index c6d531ce50762..c677962f30199 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -113,7 +113,7 @@ void addDebugInfoPass(mlir::PassManager &pm,
options.dwarfVersion = config.DwarfVersion;
options.splitDwarfFile = config.SplitDwarfFile;
options.dwarfDebugFlags = config.DwarfDebugFlags;
- options.emitFakeUseForArguments =
+ options.emitFakeUseForDebugVars =
(config.OptLevel == llvm::OptimizationLevel::O0) &&
!disableArgumentFakeUse;
addPassConditionally(pm, disableDebugInfo,
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index e0b570a908521..e5c1fc8279630 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -291,6 +291,27 @@ bool AddDebugInfoPass::createCommonBlockGlobal(
return true;
}
+// Create fake uses for compiler-generated internal variables that represent
+// values needed by a debugger. This prevents values from being optimized out
+// such as the count and lower bound of dynamic arrays.
+template <typename Op>
+static void InsertFakeUseForDebugVar(mlir::OpBuilder &builder, Op declOp,
+ mlir::Value var) {
+ if (auto funcOp = declOp->template getParentOfType<mlir::func::FuncOp>()) {
+ if (declOp->getBlock() == &funcOp.getBody().front()) {
+ for (mlir::Block &block : funcOp.getBody()) {
+ if (auto returnOp =
+ mlir::dyn_cast<mlir::func::ReturnOp>(block.getTerminator())) {
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ builder.setInsertionPoint(returnOp);
+ if (!fir::getIntIfConstant(var))
+ fir::FakeUseOp::create(builder, declOp.getLoc(), var);
+ }
+ }
+ }
+ }
+}
+
template <typename Op>
void AddDebugInfoPass::handleLocalVariable(Op declOp, llvm::StringRef name,
mlir::LLVM::DIFileAttr fileAttr,
@@ -307,22 +328,9 @@ void AddDebugInfoPass::handleLocalVariable(Op declOp, llvm::StringRef name,
if (dummyScope && declOp.getDummyScope() == dummyScope) {
if (auto argNoOpt = declOp.getDummyArgNo()) {
argNo = *argNoOpt;
- if (emitFakeUseForArguments) {
+ if (emitFakeUseForDebugVars) {
if constexpr (std::is_same_v<Op, fir::cg::XDeclareOp>) {
- if (auto funcOp =
- declOp->template getParentOfType<mlir::func::FuncOp>()) {
- if (declOp->getBlock() == &funcOp.getBody().front()) {
- for (mlir::Block &block : funcOp.getBody()) {
- if (auto returnOp = mlir::dyn_cast<mlir::func::ReturnOp>(
- block.getTerminator())) {
- mlir::OpBuilder::InsertionGuard guard(builder);
- builder.setInsertionPoint(returnOp);
- fir::FakeUseOp::create(builder, declOp.getLoc(),
- declOp.getMemref());
- }
- }
- }
- }
+ InsertFakeUseForDebugVar(builder, declOp, declOp.getMemref());
}
}
}
@@ -331,6 +339,31 @@ void AddDebugInfoPass::handleLocalVariable(Op declOp, llvm::StringRef name,
auto tyAttr =
typeGen.convertType(typeToConvert, fileAttr, scopeAttr, typeGenDeclOp);
+ if (emitFakeUseForDebugVars) {
+ // Create fake uses for internal variables that represent count and lower
+ // bound of dynamic arrays to ensure they are not optimized out.
+ if (auto arrayTy =
+ mlir::dyn_cast<mlir::LLVM::DICompositeTypeAttr>(tyAttr)) {
+ if (arrayTy.getTag() == llvm::dwarf::DW_TAG_array_type) {
+ if constexpr (std::is_same_v<Op, fir::cg::XDeclareOp>) {
+ // Count is represented as a value in the shape attribute
+ for (auto val : declOp.getShape())
+ InsertFakeUseForDebugVar(builder, declOp, val);
+ // Lower bound is represented as a value in the shift attribute
+ for (auto val : declOp.getShift())
+ InsertFakeUseForDebugVar(builder, declOp, val);
+ }
+ }
+ }
+
+ // Create fake uses for the length of character arrays to ensure they
+ // are not optimized out.
+ if constexpr (std::is_same_v<Op, fir::cg::XDeclareOp>) {
+ for (auto val : declOp.getTypeparams())
+ InsertFakeUseForDebugVar(builder, declOp, val);
+ }
+ }
+
auto localVarAttr = mlir::LLVM::DILocalVariableAttr::get(
context, scopeAttr, mlir::StringAttr::get(context, name), fileAttr,
getLineFromLoc(declOp.getLoc()), argNo, /* alignInBits*/ 0, tyAttr,
diff --git a/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir b/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
new file mode 100644
index 0000000000000..e97cf1df67c2f
--- /dev/null
+++ b/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
@@ -0,0 +1,165 @@
+// RUN: fir-opt --add-debug-info="emit-fake-use-for-debug-vars=true" %s | FileCheck %s --check-prefix=FAKE-USE
+// RUN: fir-opt --add-debug-info="emit-fake-use-for-debug-vars=false" %s | FileCheck %s --check-prefix=NO-FAKE-USE
+
+// Test that fir.fake_use ops are inserted for count and lower bound variables
+// in each dimension of a multi-dimensional dynamic array.
+
+// FAKE-USE-LABEL: func.func @test_2d_dynamic_array
+// FAKE-USE: fircg.ext_declare %arg0(%[[COUNT1:.*]], %[[COUNT2:.*]]) origin %[[LB1:.*]], %[[LB2:.*]] dummy_scope
+// FAKE-USE: fir.call @foo() : () -> ()
+// FAKE-USE: fir.fake_use %arg0
+// FAKE-USE: fir.fake_use %[[COUNT1]]
+// FAKE-USE: fir.fake_use %[[COUNT2]]
+// FAKE-USE: fir.fake_use %[[LB1]]
+// FAKE-USE: fir.fake_use %[[LB2]]
+// FAKE-USE: return
+
+// NO-FAKE-USE-LABEL: func.func @test_2d_dynamic_array
+// NO-FAKE-USE: fircg.ext_declare %arg0(%{{.*}}, %{{.*}}) origin %{{.*}}, %{{.*}} dummy_scope
+// NO-FAKE-USE: fir.call @foo() : () -> ()
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+
+// FAKE-USE-LABEL: func.func @test_3d_dynamic_array
+// FAKE-USE: fircg.ext_declare %arg0(%[[C1:.*]], %[[C2:.*]], %[[C3:.*]]) origin %[[L1:.*]], %[[L2:.*]], %[[L3:.*]] dummy_scope
+// FAKE-USE: fir.call @foo() : () -> ()
+// FAKE-USE: fir.fake_use %arg0
+// FAKE-USE: fir.fake_use %[[C1]]
+// FAKE-USE: fir.fake_use %[[C2]]
+// FAKE-USE: fir.fake_use %[[C3]]
+// FAKE-USE: fir.fake_use %[[L1]]
+// FAKE-USE: fir.fake_use %[[L2]]
+// FAKE-USE: fir.fake_use %[[L3]]
+// FAKE-USE: return
+
+// NO-FAKE-USE-LABEL: func.func @test_3d_dynamic_array
+// NO-FAKE-USE: fircg.ext_declare %arg0(%{{.*}}, %{{.*}}, %{{.*}}) origin %{{.*}}, %{{.*}}, %{{.*}} dummy_scope
+// NO-FAKE-USE: fir.call @foo() : () -> ()
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+
+// FAKE-USE-LABEL: func.func @test_2d_dynamic_array_multi_ret
+// FAKE-USE: fircg.ext_declare %arg0(%[[MR_COUNT1:.*]], %[[MR_COUNT2:.*]]) origin %[[MR_LB1:.*]], %[[MR_LB2:.*]] dummy_scope
+// FAKE-USE: cf.cond_br %{{.*}}, ^bb1, ^bb2
+// FAKE-USE: ^bb1:
+// FAKE-USE: fir.fake_use %arg0
+// FAKE-USE: fir.fake_use %[[MR_COUNT1]]
+// FAKE-USE: fir.fake_use %[[MR_COUNT2]]
+// FAKE-USE: fir.fake_use %[[MR_LB1]]
+// FAKE-USE: fir.fake_use %[[MR_LB2]]
+// FAKE-USE: return
+// FAKE-USE: ^bb2:
+// FAKE-USE: fir.fake_use %arg0
+// FAKE-USE: fir.fake_use %[[MR_COUNT1]]
+// FAKE-USE: fir.fake_use %[[MR_COUNT2]]
+// FAKE-USE: fir.fake_use %[[MR_LB1]]
+// FAKE-USE: fir.fake_use %[[MR_LB2]]
+// FAKE-USE: return
+
+// NO-FAKE-USE-LABEL: func.func @test_2d_dynamic_array_multi_ret
+// NO-FAKE-USE: fircg.ext_declare %arg0(%{{.*}}, %{{.*}}) origin %{{.*}}, %{{.*}} dummy_scope
+// NO-FAKE-USE: cf.cond_br %{{.*}}, ^bb1, ^bb2
+// NO-FAKE-USE: ^bb1:
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+// NO-FAKE-USE: ^bb2:
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+
+#loc1 = loc("debug-fake-use-multiple-dimensions.f90":1:1)
+#loc3 = loc("debug-fake-use-multiple-dimensions.f90":3:14)
+#loc4 = loc("debug-fake-use-multiple-dimensions.f90":4:14)
+#loc5 = loc("debug-fake-use-multiple-dimensions.f90":5:1)
+#loc6 = loc("debug-fake-use-multiple-dimensions.f90":6:1)
+#loc = loc("debug-fake-use-multiple-dimensions.f90":0:0)
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i32 = dense<32> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, i8 = dense<8> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.mangling_mode" = "e", "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", fir.target_cpu = "x86-64", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func private @foo()
+
+ // 2D dynamically-sized array with a single return.
+ func.func @test_2d_dynamic_array(%arg0: !fir.ref<!fir.array<?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: !fir.ref<i32> {fir.bindc_name = "n2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: !fir.ref<i32> {fir.bindc_name = "lb2"} loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_2d_dynamic_array"} {
+ %c0 = arith.constant 0 : index
+ %0 = fir.undefined !fir.dscope loc(#loc1)
+ %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_2d_dynamic_arrayEn1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_2d_dynamic_arrayElb1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %3 = fircg.ext_declare %arg3 dummy_scope %0 arg 4 {uniq_name = "_QFtest_2d_dynamic_arrayEn2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
+ %4 = fircg.ext_declare %arg4 dummy_scope %0 arg 5 {uniq_name = "_QFtest_2d_dynamic_arrayElb2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
+ %5 = fir.load %1 : !fir.ref<i32>
+ %6 = fir.convert %5 : (i32) -> index
+ %7 = arith.cmpi sgt, %6, %c0 : index
+ %8 = arith.select %7, %6, %c0 : index
+ %9 = fir.load %2 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.load %3 : !fir.ref<i32>
+ %12 = fir.convert %11 : (i32) -> index
+ %13 = arith.cmpi sgt, %12, %c0 : index
+ %14 = arith.select %13, %12, %c0 : index
+ %15 = fir.load %4 : !fir.ref<i32>
+ %16 = fir.convert %15 : (i32) -> index
+ %17 = fircg.ext_declare %arg0(%8, %14) origin %10, %16 dummy_scope %0 arg 1 {uniq_name = "_QFtest_2d_dynamic_arrayEarr"} : (!fir.ref<!fir.array<?x?xi32>>, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<?x?xi32>> loc(#loc3)
+ fir.call @foo() : () -> ()
+ return loc(#loc5)
+ } loc(#loc1)
+
+ // 3D dynamically-sized array with a single return.
+ func.func @test_3d_dynamic_array(%arg0: !fir.ref<!fir.array<?x?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: !fir.ref<i32> {fir.bindc_name = "n2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: !fir.ref<i32> {fir.bindc_name = "lb2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg5: !fir.ref<i32> {fir.bindc_name = "n3"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg6: !fir.ref<i32> {fir.bindc_name = "lb3"} loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_3d_dynamic_array"} {
+ %c0 = arith.constant 0 : index
+ %0 = fir.undefined !fir.dscope loc(#loc1)
+ %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_3d_dynamic_arrayEn1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_3d_dynamic_arrayElb1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %3 = fircg.ext_declare %arg3 dummy_scope %0 arg 4 {uniq_name = "_QFtest_3d_dynamic_arrayEn2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
+ %4 = fircg.ext_declare %arg4 dummy_scope %0 arg 5 {uniq_name = "_QFtest_3d_dynamic_arrayElb2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
+ %5 = fircg.ext_declare %arg5 dummy_scope %0 arg 6 {uniq_name = "_QFtest_3d_dynamic_arrayEn3"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %6 = fircg.ext_declare %arg6 dummy_scope %0 arg 7 {uniq_name = "_QFtest_3d_dynamic_arrayElb3"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %7 = fir.load %1 : !fir.ref<i32>
+ %8 = fir.convert %7 : (i32) -> index
+ %9 = arith.cmpi sgt, %8, %c0 : index
+ %10 = arith.select %9, %8, %c0 : index
+ %11 = fir.load %2 : !fir.ref<i32>
+ %12 = fir.convert %11 : (i32) -> index
+ %13 = fir.load %3 : !fir.ref<i32>
+ %14 = fir.convert %13 : (i32) -> index
+ %15 = arith.cmpi sgt, %14, %c0 : index
+ %16 = arith.select %15, %14, %c0 : index
+ %17 = fir.load %4 : !fir.ref<i32>
+ %18 = fir.convert %17 : (i32) -> index
+ %19 = fir.load %5 : !fir.ref<i32>
+ %20 = fir.convert %19 : (i32) -> index
+ %21 = arith.cmpi sgt, %20, %c0 : index
+ %22 = arith.select %21, %20, %c0 : index
+ %23 = fir.load %6 : !fir.ref<i32>
+ %24 = fir.convert %23 : (i32) -> index
+ %25 = fircg.ext_declare %arg0(%10, %16, %22) origin %12, %18, %24 dummy_scope %0 arg 1 {uniq_name = "_QFtest_3d_dynamic_arrayEarr"} : (!fir.ref<!fir.array<?x?x?xi32>>, index, index, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<?x?x?xi32>> loc(#loc3)
+ fir.call @foo() : () -> ()
+ return loc(#loc5)
+ } loc(#loc1)
+
+ // 2D dynamically-sized array with multiple returns.
+ func.func @test_2d_dynamic_array_multi_ret(%arg0: !fir.ref<!fir.array<?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: !fir.ref<i32> {fir.bindc_name = "n2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: !fir.ref<i32> {fir.bindc_name = "lb2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg5: i1 loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_2d_dynamic_array_multi_ret"} {
+ %c0 = arith.constant 0 : index
+ %0 = fir.undefined !fir.dscope loc(#loc1)
+ %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_2d_dynamic_array_multi_retEn1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_2d_dynamic_array_multi_retElb1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %3 = fircg.ext_declare %arg3 dummy_scope %0 arg 4 {uniq_name = "_QFtest_2d_dynamic_array_multi_retEn2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
+ %4 = fircg.ext_declare %arg4 dummy_scope %0 arg 5 {uniq_name = "_QFtest_2d_dynamic_array_multi_retElb2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
+ %5 = fir.load %1 : !fir.ref<i32>
+ %6 = fir.convert %5 : (i32) -> index
+ %7 = arith.cmpi sgt, %6, %c0 : index
+ %8 = arith.select %7, %6, %c0 : index
+ %9 = fir.load %2 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.load %3 : !fir.ref<i32>
+ %12 = fir.convert %11 : (i32) -> index
+ %13 = arith.cmpi sgt, %12, %c0 : index
+ %14 = arith.select %13, %12, %c0 : index
+ %15 = fir.load %4 : !fir.ref<i32>
+ %16 = fir.convert %15 : (i32) -> index
+ %17 = fircg.ext_declare %arg0(%8, %14) origin %10, %16 dummy_scope %0 arg 1 {uniq_name = "_QFtest_2d_dynamic_array_multi_retEarr"} : (!fir.ref<!fir.array<?x?xi32>>, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<?x?xi32>> loc(#loc3)
+ fir.call @foo() : () -> ()
+ cf.cond_br %arg5, ^bb1, ^bb2
+ ^bb1:
+ return loc(#loc5)
+ ^bb2:
+ return loc(#loc6)
+ } loc(#loc1)
+} loc(#loc)
diff --git a/flang/test/Transforms/debug-fake-use-multiple-returns.fir b/flang/test/Transforms/debug-fake-use-multiple-returns.fir
new file mode 100644
index 0000000000000..fdd90dbcb809d
--- /dev/null
+++ b/flang/test/Transforms/debug-fake-use-multiple-returns.fir
@@ -0,0 +1,125 @@
+// RUN: fir-opt --add-debug-info="emit-fake-use-for-debug-vars=true" %s | FileCheck %s --check-prefix=FAKE-USE
+// RUN: fir-opt --add-debug-info="emit-fake-use-for-debug-vars=false" %s | FileCheck %s --check-prefix=NO-FAKE-USE
+
+// Test that fir.fake_use ops are inserted before every return in functions with
+// multiple return locations.
+
+// FAKE-USE-LABEL: func.func @test_dummy_arg_multi_ret
+// FAKE-USE: %[[UNDEF:.*]] = fir.undefined !fir.dscope
+// FAKE-USE: %[[DECL:.*]] = fircg.ext_declare %arg0 dummy_scope %[[UNDEF]] arg 1
+// FAKE-USE: cf.cond_br %{{.*}}, ^bb1, ^bb2
+// FAKE-USE: ^bb1:
+// FAKE-USE: fir.fake_use %arg0
+// FAKE-USE: return
+// FAKE-USE: ^bb2:
+// FAKE-USE: fir.fake_use %arg0
+// FAKE-USE: return
+
+// NO-FAKE-USE-LABEL: func.func @test_dummy_arg_multi_ret
+// NO-FAKE-USE: %[[UNDEF:.*]] = fir.undefined !fir.dscope
+// NO-FAKE-USE: %[[DECL:.*]] = fircg.ext_declare %arg0 dummy_scope %[[UNDEF]] arg 1
+// NO-FAKE-USE: cf.cond_br %{{.*}}, ^bb1, ^bb2
+// NO-FAKE-USE: ^bb1:
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+// NO-FAKE-USE: ^bb2:
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+
+// FAKE-USE-LABEL: func.func @test_dynamic_array_multi_ret
+// FAKE-USE: fircg.ext_declare %arg0(%[[COUNT:.*]]) origin %[[LB:.*]] dummy_scope
+// FAKE-USE: cf.cond_br %{{.*}}, ^bb1, ^bb2
+// FAKE-USE: ^bb1:
+// FAKE-USE: fir.fake_use %[[COUNT]]
+// FAKE-USE: fir.fake_use %[[LB]]
+// FAKE-USE: return
+// FAKE-USE: ^bb2:
+// FAKE-USE: fir.fake_use %[[COUNT]]
+// FAKE-USE: fir.fake_use %[[LB]]
+// FAKE-USE: return
+
+// NO-FAKE-USE-LABEL: func.func @test_dynamic_array_multi_ret
+// NO-FAKE-USE: fircg.ext_declare %arg0(%{{.*}}) origin %{{.*}} dummy_scope
+// NO-FAKE-USE: cf.cond_br %{{.*}}, ^bb1, ^bb2
+// NO-FAKE-USE: ^bb1:
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+// NO-FAKE-USE: ^bb2:
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+
+// FAKE-USE-LABEL: func.func @test_char_array_multi_ret
+// FAKE-USE: fircg.ext_declare %arg0 typeparams %[[LEN:.*]] dummy_scope
+// FAKE-USE: cf.cond_br %{{.*}}, ^bb1, ^bb2
+// FAKE-USE: ^bb1:
+// FAKE-USE: fir.fake_use %[[LEN]]
+// FAKE-USE: return
+// FAKE-USE: ^bb2:
+// FAKE-USE: fir.fake_use %[[LEN]]
+// FAKE-USE: return
+
+// NO-FAKE-USE-LABEL: func.func @test_char_array_multi_ret
+// NO-FAKE-USE: fircg.ext_declare %arg0 typeparams %{{.*}} dummy_scope
+// NO-FAKE-USE: cf.cond_br %{{.*}}, ^bb1, ^bb2
+// NO-FAKE-USE: ^bb1:
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+// NO-FAKE-USE: ^bb2:
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+
+#loc1 = loc("debug-fake-use-multiple-returns.f90":1:1)
+#loc3 = loc("debug-fake-use-multiple-returns.f90":3:14)
+#loc4 = loc("debug-fake-use-multiple-returns.f90":4:14)
+#loc5 = loc("debug-fake-use-multiple-returns.f90":5:1)
+#loc6 = loc("debug-fake-use-multiple-returns.f90":6:1)
+#loc = loc("debug-fake-use-multiple-returns.f90":0:0)
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i32 = dense<32> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, i8 = dense<8> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.mangling_mode" = "e", "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", fir.target_cpu = "x86-64", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func private @foo()
+
+ // Function with a dummy argument and multiple returns.
+ func.func @test_dummy_arg_multi_ret(%arg0: !fir.ref<i32> {fir.bindc_name = "expected"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg1: i1 loc("debug-fake-use-multiple-returns.f90":1:1)) attributes {fir.internal_name = "_QPtest_dummy_arg_multi_ret"} {
+ %0 = fir.undefined !fir.dscope loc(#loc1)
+ %1 = fircg.ext_declare %arg0 dummy_scope %0 arg 1 {uniq_name = "_QFtest_dummy_arg_multi_retEexpected"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ fir.call @foo() : () -> ()
+ cf.cond_br %arg1, ^bb1, ^bb2
+ ^bb1:
+ return loc(#loc5)
+ ^bb2:
+ return loc(#loc6)
+ } loc(#loc1)
+
+ // Function with a dynamically-sized array and multiple returns.
+ func.func @test_dynamic_array_multi_ret(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg3: i1 loc("debug-fake-use-multiple-returns.f90":1:1)) attributes {fir.internal_name = "_QPtest_dynamic_array_multi_ret"} {
+ %c0 = arith.constant 0 : index
+ %0 = fir.undefined !fir.dscope loc(#loc1)
+ %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_dynamic_array_multi_retEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dynamic_array_multi_retElb"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
+ %3 = fir.load %1 : !fir.ref<i32>
+ %4 = fir.convert %3 : (i32) -> index
+ %5 = arith.cmpi sgt, %4, %c0 : index
+ %6 = arith.select %5, %4, %c0 : index
+ %7 = fir.load %2 : !fir.ref<i32>
+ %8 = fir.convert %7 : (i32) -> index
+ %9 = fircg.ext_declare %arg0(%6) origin %8 dummy_scope %0 arg 1 {uniq_name = "_QFtest_dynamic_array_multi_retEarr"} : (!fir.ref<!fir.array<?xi32>>, index, index, !fir.dscope) -> !fir.ref<!fir.array<?xi32>> loc(#loc3)
+ fir.call @foo() : () -> ()
+ cf.cond_br %arg3, ^bb1, ^bb2
+ ^bb1:
+ return loc(#loc5)
+ ^bb2:
+ return loc(#loc6)
+ } loc(#loc1)
+
+ // Function with a dynamically-sized character array and multiple returns.
+ func.func @test_char_array_multi_ret(%arg0: !fir.ref<!fir.char<1,?>> {fir.bindc_name = "str"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg1: index {fir.bindc_name = "n"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg2: i1 loc("debug-fake-use-multiple-returns.f90":1:1)) attributes {fir.internal_name = "_QPtest_char_array_multi_ret"} {
+ %0 = fir.undefined !fir.dscope loc(#loc1)
+ %1 = fircg.ext_declare %arg0 typeparams %arg1 dummy_scope %0 arg 1 {uniq_name = "_QFtest_char_array_multi_retEstr"} : (!fir.ref<!fir.char<1,?>>, index, !fir.dscope) -> !fir.ref<!fir.char<1,?>> loc(#loc3)
+ fir.call @foo() : () -> ()
+ cf.cond_br %arg2, ^bb1, ^bb2
+ ^bb1:
+ return loc(#loc5)
+ ^bb2:
+ return loc(#loc6)
+ } loc(#loc1)
+} loc(#loc)
diff --git a/flang/test/Transforms/debug-fake-use.fir b/flang/test/Transforms/debug-fake-use.fir
index d86cc9b3afee4..770286197ed4b 100644
--- a/flang/test/Transforms/debug-fake-use.fir
+++ b/flang/test/Transforms/debug-fake-use.fir
@@ -1,5 +1,5 @@
-// RUN: fir-opt --add-debug-info="emit-fake-use-for-arguments=true" %s | FileCheck %s --check-prefix=FAKE-USE
-// RUN: fir-opt --add-debug-info="emit-fake-use-for-arguments=false" %s | FileCheck %s --check-prefix=NO-FAKE-USE
+// RUN: fir-opt --add-debug-info="emit-fake-use-for-debug-vars=true" %s | FileCheck %s --check-prefix=FAKE-USE
+// RUN: fir-opt --add-debug-info="emit-fake-use-for-debug-vars=false" %s | FileCheck %s --check-prefix=NO-FAKE-USE
// FAKE-USE-LABEL: func.func @test_
// FAKE-USE: %[[UNDEF:.*]] = fir.undefined !fir.dscope
@@ -31,6 +31,31 @@
// NO-FAKE-USE-NOT: fir.fake_use
// NO-FAKE-USE: return
+// FAKE-USE-LABEL: func.func @test_dynamic_array
+// FAKE-USE: fircg.ext_declare %arg0(%[[COUNT:.*]]) origin %[[LB:.*]] dummy_scope
+// FAKE-USE: fir.call @foo() : () -> ()
+// FAKE-USE: fir.fake_use %[[COUNT]]
+// FAKE-USE: fir.fake_use %[[LB]]
+// FAKE-USE: return
+
+// NO-FAKE-USE-LABEL: func.func @test_dynamic_array
+// NO-FAKE-USE: fircg.ext_declare %arg0(%{{.*}}) origin %{{.*}} dummy_scope
+// NO-FAKE-USE: fir.call @foo() : () -> ()
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+
+// FAKE-USE-LABEL: func.func @test_char_array
+// FAKE-USE: fircg.ext_declare %arg0 typeparams %[[LEN:.*]] dummy_scope
+// FAKE-USE: fir.call @foo() : () -> ()
+// FAKE-USE: fir.fake_use %[[LEN]]
+// FAKE-USE: return
+
+// NO-FAKE-USE-LABEL: func.func @test_char_array
+// NO-FAKE-USE: fircg.ext_declare %arg0 typeparams %{{.*}} dummy_scope
+// NO-FAKE-USE: fir.call @foo() : () -> ()
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+
#loc1 = loc("debug-fake-use.f90":1:1)
#loc3 = loc("debug-fake-use.f90":3:14)
#loc4 = loc("debug-fake-use.f90":4:14)
@@ -53,4 +78,27 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<i128 = dense<128> : vector<2xi64
fir.call @foo() : () -> ()
return loc(#loc5)
} loc(#loc1)
+
+ func.func @test_dynamic_array(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n"} loc("debug-fake-use.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb"} loc("debug-fake-use.f90":1:1)) attributes {fir.internal_name = "_QPtest_dynamic_array"} {
+ %c0 = arith.constant 0 : index
+ %0 = fir.undefined !fir.dscope loc(#loc1)
+ %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_dynamic_arrayEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
+ %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dynamic_arrayElb"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
+ %3 = fir.load %1 : !fir.ref<i32>
+ %4 = fir.convert %3 : (i32) -> index
+ %5 = arith.cmpi sgt, %4, %c0 : index
+ %6 = arith.select %5, %4, %c0 : index
+ %7 = fir.load %2 : !fir.ref<i32>
+ %8 = fir.convert %7 : (i32) -> index
+ %9 = fircg.ext_declare %arg0(%6) origin %8 dummy_scope %0 arg 1 {uniq_name = "_QFtest_dynamic_arrayEarr"} : (!fir.ref<!fir.array<?xi32>>, index, index, !fir.dscope) -> !fir.ref<!fir.array<?xi32>> loc(#loc3)
+ fir.call @foo() : () -> ()
+ return loc(#loc5)
+ } loc(#loc1)
+
+ func.func @test_char_array(%arg0: !fir.ref<!fir.char<1,?>> {fir.bindc_name = "str"} loc("debug-fake-use.f90":1:1), %arg1: index {fir.bindc_name = "n"} loc("debug-fake-use.f90":1:1)) attributes {fir.internal_name = "_QPtest_char_array"} {
+ %0 = fir.undefined !fir.dscope loc(#loc1)
+ %1 = fircg.ext_declare %arg0 typeparams %arg1 dummy_scope %0 arg 1 {uniq_name = "_QFtest_char_arrayEstr"} : (!fir.ref<!fir.char<1,?>>, index, !fir.dscope) -> !fir.ref<!fir.char<1,?>> loc(#loc3)
+ fir.call @foo() : () -> ()
+ return loc(#loc5)
+ } loc(#loc1)
} loc(#loc)
>From 69b32ab2192f5c62543116079037c4f61089d13e Mon Sep 17 00:00:00 2001
From: Timothy Smith <timothy.smith at hpe.com>
Date: Thu, 18 Jun 2026 12:19:14 -0500
Subject: [PATCH 2/6] Remove unnecessary module attributes from tests
---
flang/test/Transforms/debug-fake-use-multiple-dimensions.fir | 2 +-
flang/test/Transforms/debug-fake-use-multiple-returns.fir | 2 +-
flang/test/Transforms/debug-fake-use.fir | 3 ++-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir b/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
index e97cf1df67c2f..1c6b58f7867db 100644
--- a/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
+++ b/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
@@ -73,7 +73,7 @@
#loc6 = loc("debug-fake-use-multiple-dimensions.f90":6:1)
#loc = loc("debug-fake-use-multiple-dimensions.f90":0:0)
-module attributes {dlti.dl_spec = #dlti.dl_spec<i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i32 = dense<32> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, i8 = dense<8> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.mangling_mode" = "e", "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", fir.target_cpu = "x86-64", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+module {
func.func private @foo()
// 2D dynamically-sized array with a single return.
diff --git a/flang/test/Transforms/debug-fake-use-multiple-returns.fir b/flang/test/Transforms/debug-fake-use-multiple-returns.fir
index fdd90dbcb809d..4ab533b471bad 100644
--- a/flang/test/Transforms/debug-fake-use-multiple-returns.fir
+++ b/flang/test/Transforms/debug-fake-use-multiple-returns.fir
@@ -75,7 +75,7 @@
#loc6 = loc("debug-fake-use-multiple-returns.f90":6:1)
#loc = loc("debug-fake-use-multiple-returns.f90":0:0)
-module attributes {dlti.dl_spec = #dlti.dl_spec<i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i32 = dense<32> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, i8 = dense<8> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.mangling_mode" = "e", "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", fir.target_cpu = "x86-64", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+module {
func.func private @foo()
// Function with a dummy argument and multiple returns.
diff --git a/flang/test/Transforms/debug-fake-use.fir b/flang/test/Transforms/debug-fake-use.fir
index 770286197ed4b..8057c9304ef63 100644
--- a/flang/test/Transforms/debug-fake-use.fir
+++ b/flang/test/Transforms/debug-fake-use.fir
@@ -62,7 +62,8 @@
#loc5 = loc("debug-fake-use.f90":5:1)
#loc = loc("debug-fake-use.f90":0:0)
-module attributes {dlti.dl_spec = #dlti.dl_spec<i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i32 = dense<32> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, i8 = dense<8> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.mangling_mode" = "e", "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", fir.target_cpu = "x86-64", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+//module attributes {dlti.dl_spec = #dlti.dl_spec<i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i32 = dense<32> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, i8 = dense<8> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.mangling_mode" = "e", "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", fir.target_cpu = "x86-64", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+module {
func.func private @foo()
func.func @test_(%arg0: !fir.ref<i32> {fir.bindc_name = "expected"} loc("debug-fake-use.f90":1:1)) attributes {fir.internal_name = "_QPtest"} {
%0 = fir.undefined !fir.dscope loc(#loc1)
>From ffd2bbd7d868911dbea35b386fcbade9fe7b916c Mon Sep 17 00:00:00 2001
From: Timothy Smith <timothy.smith at hpe.com>
Date: Fri, 19 Jun 2026 11:00:21 -0500
Subject: [PATCH 3/6] Minimize instructions in tests
---
.../debug-fake-use-multiple-dimensions.fir | 71 ++-----------------
.../debug-fake-use-multiple-returns.fir | 13 +---
flang/test/Transforms/debug-fake-use.fir | 14 +---
3 files changed, 10 insertions(+), 88 deletions(-)
diff --git a/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir b/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
index 1c6b58f7867db..e98616c2b806b 100644
--- a/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
+++ b/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
@@ -77,84 +77,25 @@ module {
func.func private @foo()
// 2D dynamically-sized array with a single return.
- func.func @test_2d_dynamic_array(%arg0: !fir.ref<!fir.array<?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: !fir.ref<i32> {fir.bindc_name = "n2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: !fir.ref<i32> {fir.bindc_name = "lb2"} loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_2d_dynamic_array"} {
- %c0 = arith.constant 0 : index
+ func.func @test_2d_dynamic_array(%arg0: !fir.ref<!fir.array<?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: index loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_2d_dynamic_array"} {
%0 = fir.undefined !fir.dscope loc(#loc1)
- %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_2d_dynamic_arrayEn1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_2d_dynamic_arrayElb1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %3 = fircg.ext_declare %arg3 dummy_scope %0 arg 4 {uniq_name = "_QFtest_2d_dynamic_arrayEn2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
- %4 = fircg.ext_declare %arg4 dummy_scope %0 arg 5 {uniq_name = "_QFtest_2d_dynamic_arrayElb2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
- %5 = fir.load %1 : !fir.ref<i32>
- %6 = fir.convert %5 : (i32) -> index
- %7 = arith.cmpi sgt, %6, %c0 : index
- %8 = arith.select %7, %6, %c0 : index
- %9 = fir.load %2 : !fir.ref<i32>
- %10 = fir.convert %9 : (i32) -> index
- %11 = fir.load %3 : !fir.ref<i32>
- %12 = fir.convert %11 : (i32) -> index
- %13 = arith.cmpi sgt, %12, %c0 : index
- %14 = arith.select %13, %12, %c0 : index
- %15 = fir.load %4 : !fir.ref<i32>
- %16 = fir.convert %15 : (i32) -> index
- %17 = fircg.ext_declare %arg0(%8, %14) origin %10, %16 dummy_scope %0 arg 1 {uniq_name = "_QFtest_2d_dynamic_arrayEarr"} : (!fir.ref<!fir.array<?x?xi32>>, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<?x?xi32>> loc(#loc3)
+ %1 = fircg.ext_declare %arg0(%arg1, %arg3) origin %arg2, %arg4 dummy_scope %0 arg 1 {uniq_name = "_QFtest_2d_dynamic_arrayEarr"} : (!fir.ref<!fir.array<?x?xi32>>, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<?x?xi32>> loc(#loc3)
fir.call @foo() : () -> ()
return loc(#loc5)
} loc(#loc1)
// 3D dynamically-sized array with a single return.
- func.func @test_3d_dynamic_array(%arg0: !fir.ref<!fir.array<?x?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: !fir.ref<i32> {fir.bindc_name = "n2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: !fir.ref<i32> {fir.bindc_name = "lb2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg5: !fir.ref<i32> {fir.bindc_name = "n3"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg6: !fir.ref<i32> {fir.bindc_name = "lb3"} loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_3d_dynamic_array"} {
- %c0 = arith.constant 0 : index
+ func.func @test_3d_dynamic_array(%arg0: !fir.ref<!fir.array<?x?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg5: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg6: index loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_3d_dynamic_array"} {
%0 = fir.undefined !fir.dscope loc(#loc1)
- %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_3d_dynamic_arrayEn1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_3d_dynamic_arrayElb1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %3 = fircg.ext_declare %arg3 dummy_scope %0 arg 4 {uniq_name = "_QFtest_3d_dynamic_arrayEn2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
- %4 = fircg.ext_declare %arg4 dummy_scope %0 arg 5 {uniq_name = "_QFtest_3d_dynamic_arrayElb2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
- %5 = fircg.ext_declare %arg5 dummy_scope %0 arg 6 {uniq_name = "_QFtest_3d_dynamic_arrayEn3"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %6 = fircg.ext_declare %arg6 dummy_scope %0 arg 7 {uniq_name = "_QFtest_3d_dynamic_arrayElb3"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %7 = fir.load %1 : !fir.ref<i32>
- %8 = fir.convert %7 : (i32) -> index
- %9 = arith.cmpi sgt, %8, %c0 : index
- %10 = arith.select %9, %8, %c0 : index
- %11 = fir.load %2 : !fir.ref<i32>
- %12 = fir.convert %11 : (i32) -> index
- %13 = fir.load %3 : !fir.ref<i32>
- %14 = fir.convert %13 : (i32) -> index
- %15 = arith.cmpi sgt, %14, %c0 : index
- %16 = arith.select %15, %14, %c0 : index
- %17 = fir.load %4 : !fir.ref<i32>
- %18 = fir.convert %17 : (i32) -> index
- %19 = fir.load %5 : !fir.ref<i32>
- %20 = fir.convert %19 : (i32) -> index
- %21 = arith.cmpi sgt, %20, %c0 : index
- %22 = arith.select %21, %20, %c0 : index
- %23 = fir.load %6 : !fir.ref<i32>
- %24 = fir.convert %23 : (i32) -> index
- %25 = fircg.ext_declare %arg0(%10, %16, %22) origin %12, %18, %24 dummy_scope %0 arg 1 {uniq_name = "_QFtest_3d_dynamic_arrayEarr"} : (!fir.ref<!fir.array<?x?x?xi32>>, index, index, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<?x?x?xi32>> loc(#loc3)
+ %1 = fircg.ext_declare %arg0(%arg1, %arg3, %arg5) origin %arg2, %arg4, %arg6 dummy_scope %0 arg 1 {uniq_name = "_QFtest_3d_dynamic_arrayEarr"} : (!fir.ref<!fir.array<?x?x?xi32>>, index, index, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<?x?x?xi32>> loc(#loc3)
fir.call @foo() : () -> ()
return loc(#loc5)
} loc(#loc1)
// 2D dynamically-sized array with multiple returns.
- func.func @test_2d_dynamic_array_multi_ret(%arg0: !fir.ref<!fir.array<?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb1"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: !fir.ref<i32> {fir.bindc_name = "n2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: !fir.ref<i32> {fir.bindc_name = "lb2"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg5: i1 loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_2d_dynamic_array_multi_ret"} {
- %c0 = arith.constant 0 : index
+ func.func @test_2d_dynamic_array_multi_ret(%arg0: !fir.ref<!fir.array<?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg5: i1 loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_2d_dynamic_array_multi_ret"} {
%0 = fir.undefined !fir.dscope loc(#loc1)
- %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_2d_dynamic_array_multi_retEn1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_2d_dynamic_array_multi_retElb1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %3 = fircg.ext_declare %arg3 dummy_scope %0 arg 4 {uniq_name = "_QFtest_2d_dynamic_array_multi_retEn2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
- %4 = fircg.ext_declare %arg4 dummy_scope %0 arg 5 {uniq_name = "_QFtest_2d_dynamic_array_multi_retElb2"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
- %5 = fir.load %1 : !fir.ref<i32>
- %6 = fir.convert %5 : (i32) -> index
- %7 = arith.cmpi sgt, %6, %c0 : index
- %8 = arith.select %7, %6, %c0 : index
- %9 = fir.load %2 : !fir.ref<i32>
- %10 = fir.convert %9 : (i32) -> index
- %11 = fir.load %3 : !fir.ref<i32>
- %12 = fir.convert %11 : (i32) -> index
- %13 = arith.cmpi sgt, %12, %c0 : index
- %14 = arith.select %13, %12, %c0 : index
- %15 = fir.load %4 : !fir.ref<i32>
- %16 = fir.convert %15 : (i32) -> index
- %17 = fircg.ext_declare %arg0(%8, %14) origin %10, %16 dummy_scope %0 arg 1 {uniq_name = "_QFtest_2d_dynamic_array_multi_retEarr"} : (!fir.ref<!fir.array<?x?xi32>>, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<?x?xi32>> loc(#loc3)
+ %1 = fircg.ext_declare %arg0(%arg1, %arg3) origin %arg2, %arg4 dummy_scope %0 arg 1 {uniq_name = "_QFtest_2d_dynamic_array_multi_retEarr"} : (!fir.ref<!fir.array<?x?xi32>>, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<?x?xi32>> loc(#loc3)
fir.call @foo() : () -> ()
cf.cond_br %arg5, ^bb1, ^bb2
^bb1:
diff --git a/flang/test/Transforms/debug-fake-use-multiple-returns.fir b/flang/test/Transforms/debug-fake-use-multiple-returns.fir
index 4ab533b471bad..ac379d0f587f7 100644
--- a/flang/test/Transforms/debug-fake-use-multiple-returns.fir
+++ b/flang/test/Transforms/debug-fake-use-multiple-returns.fir
@@ -91,18 +91,9 @@ module {
} loc(#loc1)
// Function with a dynamically-sized array and multiple returns.
- func.func @test_dynamic_array_multi_ret(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg3: i1 loc("debug-fake-use-multiple-returns.f90":1:1)) attributes {fir.internal_name = "_QPtest_dynamic_array_multi_ret"} {
- %c0 = arith.constant 0 : index
+ func.func @test_dynamic_array_multi_ret(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-returns.f90":1:1), %arg1: index loc("debug-fake-use-multiple-returns.f90":1:1), %arg2: index loc("debug-fake-use-multiple-returns.f90":1:1), %arg3: i1 loc("debug-fake-use-multiple-returns.f90":1:1)) attributes {fir.internal_name = "_QPtest_dynamic_array_multi_ret"} {
%0 = fir.undefined !fir.dscope loc(#loc1)
- %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_dynamic_array_multi_retEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dynamic_array_multi_retElb"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
- %3 = fir.load %1 : !fir.ref<i32>
- %4 = fir.convert %3 : (i32) -> index
- %5 = arith.cmpi sgt, %4, %c0 : index
- %6 = arith.select %5, %4, %c0 : index
- %7 = fir.load %2 : !fir.ref<i32>
- %8 = fir.convert %7 : (i32) -> index
- %9 = fircg.ext_declare %arg0(%6) origin %8 dummy_scope %0 arg 1 {uniq_name = "_QFtest_dynamic_array_multi_retEarr"} : (!fir.ref<!fir.array<?xi32>>, index, index, !fir.dscope) -> !fir.ref<!fir.array<?xi32>> loc(#loc3)
+ %1 = fircg.ext_declare %arg0(%arg1) origin %arg2 dummy_scope %0 arg 1 {uniq_name = "_QFtest_dynamic_array_multi_retEarr"} : (!fir.ref<!fir.array<?xi32>>, index, index, !fir.dscope) -> !fir.ref<!fir.array<?xi32>> loc(#loc3)
fir.call @foo() : () -> ()
cf.cond_br %arg3, ^bb1, ^bb2
^bb1:
diff --git a/flang/test/Transforms/debug-fake-use.fir b/flang/test/Transforms/debug-fake-use.fir
index 8057c9304ef63..9714f34abf36f 100644
--- a/flang/test/Transforms/debug-fake-use.fir
+++ b/flang/test/Transforms/debug-fake-use.fir
@@ -62,7 +62,6 @@
#loc5 = loc("debug-fake-use.f90":5:1)
#loc = loc("debug-fake-use.f90":0:0)
-//module attributes {dlti.dl_spec = #dlti.dl_spec<i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i32 = dense<32> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, i8 = dense<8> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.mangling_mode" = "e", "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", fir.target_cpu = "x86-64", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
module {
func.func private @foo()
func.func @test_(%arg0: !fir.ref<i32> {fir.bindc_name = "expected"} loc("debug-fake-use.f90":1:1)) attributes {fir.internal_name = "_QPtest"} {
@@ -80,18 +79,9 @@ module {
return loc(#loc5)
} loc(#loc1)
- func.func @test_dynamic_array(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use.f90":1:1), %arg1: !fir.ref<i32> {fir.bindc_name = "n"} loc("debug-fake-use.f90":1:1), %arg2: !fir.ref<i32> {fir.bindc_name = "lb"} loc("debug-fake-use.f90":1:1)) attributes {fir.internal_name = "_QPtest_dynamic_array"} {
- %c0 = arith.constant 0 : index
+ func.func @test_dynamic_array(%arg0: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use.f90":1:1), %arg1: index loc("debug-fake-use.f90":1:1), %arg2: index loc("debug-fake-use.f90":1:1)) attributes {fir.internal_name = "_QPtest_dynamic_array"} {
%0 = fir.undefined !fir.dscope loc(#loc1)
- %1 = fircg.ext_declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtest_dynamic_arrayEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc3)
- %2 = fircg.ext_declare %arg2 dummy_scope %0 arg 3 {uniq_name = "_QFtest_dynamic_arrayElb"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32> loc(#loc4)
- %3 = fir.load %1 : !fir.ref<i32>
- %4 = fir.convert %3 : (i32) -> index
- %5 = arith.cmpi sgt, %4, %c0 : index
- %6 = arith.select %5, %4, %c0 : index
- %7 = fir.load %2 : !fir.ref<i32>
- %8 = fir.convert %7 : (i32) -> index
- %9 = fircg.ext_declare %arg0(%6) origin %8 dummy_scope %0 arg 1 {uniq_name = "_QFtest_dynamic_arrayEarr"} : (!fir.ref<!fir.array<?xi32>>, index, index, !fir.dscope) -> !fir.ref<!fir.array<?xi32>> loc(#loc3)
+ %1 = fircg.ext_declare %arg0(%arg1) origin %arg2 dummy_scope %0 arg 1 {uniq_name = "_QFtest_dynamic_arrayEarr"} : (!fir.ref<!fir.array<?xi32>>, index, index, !fir.dscope) -> !fir.ref<!fir.array<?xi32>> loc(#loc3)
fir.call @foo() : () -> ()
return loc(#loc5)
} loc(#loc1)
>From fba4e1f23ea3ec07b597439c232ac3233376c8e9 Mon Sep 17 00:00:00 2001
From: Timothy Smith <timothy.smith at hpe.com>
Date: Fri, 19 Jun 2026 11:13:29 -0500
Subject: [PATCH 4/6] Add test case for arrays with both variable and constant
dimensions
---
.../debug-fake-use-multiple-dimensions.fir | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir b/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
index e98616c2b806b..a1479aa14cb00 100644
--- a/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
+++ b/flang/test/Transforms/debug-fake-use-multiple-dimensions.fir
@@ -66,6 +66,25 @@
// NO-FAKE-USE-NOT: fir.fake_use
// NO-FAKE-USE: return
+// FAKE-USE-LABEL: func.func @test_3d_mixed_array
+// FAKE-USE: %[[CST_COUNT:.*]] = arith.constant 10 : index
+// FAKE-USE: %[[CST_LB:.*]] = arith.constant 1 : index
+// FAKE-USE: fircg.ext_declare %arg0(%[[CST_COUNT]], %[[DYN_COUNT1:.*]], %[[DYN_COUNT2:.*]]) origin %[[CST_LB]], %[[DYN_LB1:.*]], %[[DYN_LB2:.*]] dummy_scope
+// FAKE-USE: fir.call @foo() : () -> ()
+// FAKE-USE: fir.fake_use %arg0
+// FAKE-USE: fir.fake_use %[[DYN_COUNT1]]
+// FAKE-USE: fir.fake_use %[[DYN_COUNT2]]
+// FAKE-USE: fir.fake_use %[[DYN_LB1]]
+// FAKE-USE: fir.fake_use %[[DYN_LB2]]
+// FAKE-USE-NOT: fir.fake_use
+// FAKE-USE: return
+
+// NO-FAKE-USE-LABEL: func.func @test_3d_mixed_array
+// NO-FAKE-USE: fircg.ext_declare %arg0(%{{.*}}, %{{.*}}, %{{.*}}) origin %{{.*}}, %{{.*}}, %{{.*}} dummy_scope
+// NO-FAKE-USE: fir.call @foo() : () -> ()
+// NO-FAKE-USE-NOT: fir.fake_use
+// NO-FAKE-USE: return
+
#loc1 = loc("debug-fake-use-multiple-dimensions.f90":1:1)
#loc3 = loc("debug-fake-use-multiple-dimensions.f90":3:14)
#loc4 = loc("debug-fake-use-multiple-dimensions.f90":4:14)
@@ -103,4 +122,14 @@ module {
^bb2:
return loc(#loc6)
} loc(#loc1)
+
+ // 3D array with mixed constant and dynamic dimensions.
+ func.func @test_3d_mixed_array(%arg0: !fir.ref<!fir.array<10x?x?xi32>> {fir.bindc_name = "arr"} loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg1: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg2: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg3: index loc("debug-fake-use-multiple-dimensions.f90":1:1), %arg4: index loc("debug-fake-use-multiple-dimensions.f90":1:1)) attributes {fir.internal_name = "_QPtest_3d_mixed_array"} {
+ %c10 = arith.constant 10 : index
+ %c1 = arith.constant 1 : index
+ %0 = fir.undefined !fir.dscope loc(#loc1)
+ %1 = fircg.ext_declare %arg0(%c10, %arg1, %arg3) origin %c1, %arg2, %arg4 dummy_scope %0 arg 1 {uniq_name = "_QFtest_3d_mixed_arrayEarr"} : (!fir.ref<!fir.array<10x?x?xi32>>, index, index, index, index, index, index, !fir.dscope) -> !fir.ref<!fir.array<10x?x?xi32>> loc(#loc3)
+ fir.call @foo() : () -> ()
+ return loc(#loc5)
+ } loc(#loc1)
} loc(#loc)
>From 3ea8f88ee89b7227f8e329f07e9bc95da3f22450 Mon Sep 17 00:00:00 2001
From: Timothy Smith <timothy.smith at hpe.com>
Date: Fri, 19 Jun 2026 11:38:59 -0500
Subject: [PATCH 5/6] Fix whitespace error
---
flang/test/Transforms/debug-fake-use.fir | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/test/Transforms/debug-fake-use.fir b/flang/test/Transforms/debug-fake-use.fir
index 9714f34abf36f..d16fa2f6ff028 100644
--- a/flang/test/Transforms/debug-fake-use.fir
+++ b/flang/test/Transforms/debug-fake-use.fir
@@ -62,7 +62,7 @@
#loc5 = loc("debug-fake-use.f90":5:1)
#loc = loc("debug-fake-use.f90":0:0)
-module {
+module {
func.func private @foo()
func.func @test_(%arg0: !fir.ref<i32> {fir.bindc_name = "expected"} loc("debug-fake-use.f90":1:1)) attributes {fir.internal_name = "_QPtest"} {
%0 = fir.undefined !fir.dscope loc(#loc1)
>From 7243257deddf5dcab538d61f10d0df0b600ab4a0 Mon Sep 17 00:00:00 2001
From: Timothy Smith <timothy.smith at hpe.com>
Date: Fri, 19 Jun 2026 13:50:55 -0500
Subject: [PATCH 6/6] empty commit to retry libcxx checks
More information about the flang-commits
mailing list