[flang-commits] [flang] [flang][cuda] Avoid infinite loop while processing globals (PR #210805)

via flang-commits flang-commits at lists.llvm.org
Mon Jul 20 13:49:49 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: Valentin Clement (バレンタイン クレメン) (clementval)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/210805.diff


2 Files Affected:

- (modified) flang/lib/Optimizer/Transforms/CUDA/CUFDeviceGlobal.cpp (+11-8) 
- (added) flang/test/Fir/CUDA/cuda-device-global-cycle.fir (+25) 


``````````diff
diff --git a/flang/lib/Optimizer/Transforms/CUDA/CUFDeviceGlobal.cpp b/flang/lib/Optimizer/Transforms/CUDA/CUFDeviceGlobal.cpp
index 672f957f32ccb..2382b27f2b3cc 100644
--- a/flang/lib/Optimizer/Transforms/CUDA/CUFDeviceGlobal.cpp
+++ b/flang/lib/Optimizer/Transforms/CUDA/CUFDeviceGlobal.cpp
@@ -45,11 +45,14 @@ static void processAddrOfOp(fir::AddrOfOp addrOfOp,
           addrOfOp.getSymbol().getRootReference().getValue())) {
     // TO DO: limit candidates to non-scalars. Scalars appear to have been
     // folded in already.
+    // Insert before recursing so cycles among globals (e.g. mutually
+    // referencing type descriptors) do not cause infinite recursion.
+    if (!candidates.insert(globalOp).second)
+      return;
     if (recurseInGlobal)
       globalOp.walk([&](fir::AddrOfOp op) {
         processAddrOfOp(op, symbolTable, candidates, recurseInGlobal);
       });
-    candidates.insert(globalOp);
   }
 }
 
@@ -58,13 +61,13 @@ static void processTypeDescriptor(fir::RecordType recTy,
                                   llvm::DenseSet<fir::GlobalOp> &candidates) {
   if (auto globalOp = symbolTable.lookup<fir::GlobalOp>(
           fir::NameUniquer::getTypeDescriptorName(recTy.getName()))) {
-    if (!candidates.contains(globalOp)) {
-      globalOp.walk([&](fir::AddrOfOp op) {
-        processAddrOfOp(op, symbolTable, candidates,
-                        /*recurseInGlobal=*/true);
-      });
-      candidates.insert(globalOp);
-    }
+    // Insert before walking so cyclic addr_of chains terminate.
+    if (!candidates.insert(globalOp).second)
+      return;
+    globalOp.walk([&](fir::AddrOfOp op) {
+      processAddrOfOp(op, symbolTable, candidates,
+                      /*recurseInGlobal=*/true);
+    });
   }
 }
 
diff --git a/flang/test/Fir/CUDA/cuda-device-global-cycle.fir b/flang/test/Fir/CUDA/cuda-device-global-cycle.fir
new file mode 100644
index 0000000000000..517f6956969b6
--- /dev/null
+++ b/flang/test/Fir/CUDA/cuda-device-global-cycle.fir
@@ -0,0 +1,25 @@
+// RUN: fir-opt --cuf-device-global %s | FileCheck %s
+
+// Mutually referencing type-descriptor globals must not cause infinite
+// recursion in processAddrOfOp when recurseInGlobal is true.
+module attributes {gpu.container_module} {
+  fir.global linkonce @_QMmE.dt.t1 constant : i64 {
+    %0 = fir.address_of(@_QMmE.dt.t2) : !fir.ref<i64>
+    %1 = fir.convert %0 : (!fir.ref<i64>) -> i64
+    fir.has_value %1 : i64
+  }
+  fir.global linkonce @_QMmE.dt.t2 constant : i64 {
+    %0 = fir.address_of(@_QMmE.dt.t1) : !fir.ref<i64>
+    %1 = fir.convert %0 : (!fir.ref<i64>) -> i64
+    fir.has_value %1 : i64
+  }
+
+  func.func @_QMmPdev() attributes {cuf.proc_attr = #cuf.cuda_proc<global>} {
+    %0 = fir.alloca !fir.type<_QMmTt1{i:i32}>
+    return
+  }
+}
+
+// CHECK-LABEL: gpu.module @cuda_device_mod
+// CHECK-DAG: fir.global linkonce @_QMmE.dt.t1
+// CHECK-DAG: fir.global linkonce @_QMmE.dt.t2

``````````

</details>


https://github.com/llvm/llvm-project/pull/210805


More information about the flang-commits mailing list