[flang-commits] [flang] bdc0689 - [flang] Avoid invalid declare_value for promoted dummy-scope variables (#202498)

via flang-commits flang-commits at lists.llvm.org
Fri Jun 12 08:25:56 PDT 2026


Author: Zhen Wang
Date: 2026-06-12T08:25:51-07:00
New Revision: bdc06892cdd37c0a52717373ad7774136ca72b63

URL: https://github.com/llvm/llvm-project/commit/bdc06892cdd37c0a52717373ad7774136ca72b63
DIFF: https://github.com/llvm/llvm-project/commit/bdc06892cdd37c0a52717373ad7774136ca72b63.diff

LOG: [flang] Avoid invalid declare_value for promoted dummy-scope variables (#202498)

This fixes a verifier failure in mem2reg after inlining a CUDA device
procedure. When a promoted FIR alloca had an associated fir.declare with
a dummy_scope, mem2reg could create a fir.declare_value at a loop header
where the original dummy scope did not dominate.

Skip creating block-argument fir.declare_value ops for such
declarations, matching the existing replaced-value handling. Add a FIR
mem2reg regression test for the loop-header block argument case.

Added: 
    

Modified: 
    flang/lib/Optimizer/Dialect/FIROps.cpp
    flang/test/Fir/mem2reg.mlir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index e41109cb835ea..a633cac95fbc3 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -271,11 +271,15 @@ void fir::AllocaOp::handleBlockArgument(const mlir::MemorySlot &slot,
   // no-ops like fir.declare (i.e., to replace the FIR specific
   // isSlotOrDeclaredSlot).
   for (mlir::Operation *user : getOperation()->getUsers())
-    if (auto declareOp = mlir::dyn_cast<fir::DeclareOp>(user))
+    if (auto declareOp = mlir::dyn_cast<fir::DeclareOp>(user)) {
+      // Inlined dummy scopes may not dominate block-argument debug values.
+      if (declareOp.getDummyScope())
+        continue;
       fir::DeclareValueOp::create(
           builder, declareOp.getLoc(), argument, declareOp.getDummyScope(),
           declareOp.getUniqNameAttr(), declareOp.getFortranAttrsAttr(),
           declareOp.getDataAttrAttr(), declareOp.getDummyArgNoAttr());
+    }
 }
 
 std::optional<mlir::PromotableAllocationOpInterface>

diff  --git a/flang/test/Fir/mem2reg.mlir b/flang/test/Fir/mem2reg.mlir
index 41f894a2f9473..154580c626e7c 100644
--- a/flang/test/Fir/mem2reg.mlir
+++ b/flang/test/Fir/mem2reg.mlir
@@ -233,3 +233,30 @@ func.func @dummy_scope(%arg : i32) {
   fir.call @use(%result) : (i32) -> ()
   return
 }
+
+// -----
+
+// Do not create block-argument fir.declare_value ops with non-dominating
+// dummy scopes.
+
+// CHECK-LABEL: func.func @dummy_scope_block_argument(
+// CHECK: ^bb1(%{{.*}}: i32):
+// CHECK-NOT: fir.declare_value
+func.func @dummy_scope_block_argument(%arg : i32, %cond : i1) {
+  %c1 = arith.constant 1 : i32
+  %alloca = fir.alloca i32 {adapt.valuebyref}
+  fir.store %arg to %alloca : !fir.ref<i32>
+  cf.br ^loop
+^loop:
+  %result = fir.load %alloca : !fir.ref<i32>
+  cf.cond_br %cond, ^body, ^exit
+^body:
+  %scope = fir.dummy_scope : !fir.dscope
+  %declare = fir.declare %alloca dummy_scope %scope arg 1 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "foo"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+  %next = arith.addi %result, %c1 : i32
+  fir.store %next to %alloca : !fir.ref<i32>
+  cf.br ^loop
+^exit:
+  fir.call @use(%result) : (i32) -> ()
+  return
+}


        


More information about the flang-commits mailing list