[flang-commits] [flang] [flang] Fixed MemAlloc/Free effects handling in FIR ModRef. (PR #177728)

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Fri Jan 23 19:04:31 PST 2026


https://github.com/vzakhari created https://github.com/llvm/llvm-project/pull/177728

We should ignore MemAlloc/Free effects as they are not
modifying/reading ones. This is what LocalAliasAnalysis
does. This patch also removes the operation-wide MemFree
effect from `fir.freemem`.


>From d87c86269f0486b835f9228c2f721369174b63db Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Fri, 23 Jan 2026 18:53:34 -0800
Subject: [PATCH] [flang] Fixed MemAlloc/Free effects handling in FIR ModRef.

We should ignore MemAlloc/Free effects as they are not
modifying/reading ones. This is what LocalAliasAnalysis
does. This patch also removes the operation-wide MemFree
effect from `fir.freemem`.
---
 .../include/flang/Optimizer/Dialect/FIROps.td |  2 +-
 .../lib/Optimizer/Analysis/AliasAnalysis.cpp  |  3 ++
 .../modref-alloc-free-effects.fir             | 37 +++++++++++++++++++
 3 files changed, 41 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Analysis/AliasAnalysis/modref-alloc-free-effects.fir

diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td
index a177fc483109e..30f5dcc37b0f3 100644
--- a/flang/include/flang/Optimizer/Dialect/FIROps.td
+++ b/flang/include/flang/Optimizer/Dialect/FIROps.td
@@ -270,7 +270,7 @@ def fir_AllocMemOp : fir_Op<"allocmem", [AttrSizedOperandSegments]> {
   }];
 }
 
-def fir_FreeMemOp : fir_Op<"freemem", [MemoryEffects<[MemFree]>]> {
+def fir_FreeMemOp : fir_Op<"freemem", []> {
   let summary = "free a heap object";
 
   let description = [{
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index 388fb60fcda35..7d2845810bac8 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -566,6 +566,9 @@ ModRefResult AliasAnalysis::getModRef(Operation *op, Value location) {
   interface.getEffects(effects);
 
   for (const MemoryEffects::EffectInstance &effect : effects) {
+    // MemAlloc and MemFree are not mod-ref effects.
+    if (isa<MemoryEffects::Allocate, MemoryEffects::Free>(effect.getEffect()))
+      continue;
 
     // Check for an alias between the effect and our memory location.
     AliasResult aliasResult = AliasResult::MayAlias;
diff --git a/flang/test/Analysis/AliasAnalysis/modref-alloc-free-effects.fir b/flang/test/Analysis/AliasAnalysis/modref-alloc-free-effects.fir
new file mode 100644
index 0000000000000..892a9796eaac8
--- /dev/null
+++ b/flang/test/Analysis/AliasAnalysis/modref-alloc-free-effects.fir
@@ -0,0 +1,37 @@
+// RUN:  fir-opt -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis-modref))' \
+// RUN:  --mlir-disable-threading %s -o /dev/null 2>&1 | FileCheck %s
+
+// If LocalAliasAnalysis cannot deduce NoModRef (e.g. due to
+// a store unknown to it), then MemAlloc and and MemFree
+// effects should be ignored in FIR AliasAnalysis.
+// They used to be treated as Mod effect.
+
+// CHECK-LABEL: Testing : "test_alloc_effect"
+// CHECK: test_effect -> test_decl#0: Ref
+func.func @test_alloc_effect(%arg0: !fir.ref<i32>, %arg1: !fir.ref<i32>, %arg2: i1) {
+  %0 = fir.dummy_scope : !fir.dscope
+  %1 = fir.declare %arg0 dummy_scope %0 arg 1 {uniq_name = "arg0", test.ptr = "test_decl"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+  fir.if %arg2 {
+    %2 = fir.load %1 : !fir.ref<i32>
+    // fir.declare has MemAlloc effect on the DebuggingResource:
+    %3 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "arg1"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+    fir.store %2 to %3 : !fir.ref<i32>
+  } {test.ptr = "test_effect"}
+  return
+}
+
+// CHECK-LABEL: Testing : "test_free_effect"
+// CHECK: test_effect -> test_decl#0: Ref
+func.func @test_free_effect(%arg0: !fir.ref<i32>, %arg1: !fir.heap<i32>, %arg2: i1) {
+  %0 = fir.dummy_scope : !fir.dscope
+  %1 = fir.declare %arg0 dummy_scope %0 arg 1 {uniq_name = "arg0", test.ptr = "test_decl"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+  %2 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "arg1"} : (!fir.heap<i32>, !fir.dscope) -> !fir.heap<i32>
+  fir.if %arg2 {
+    %3 = fir.load %1 : !fir.ref<i32>
+    fir.store %3 to %2 : !fir.heap<i32>
+    // fir.freemem used to report operation-wide MemFree effect,
+    // i.e. without specifying the freed value.
+    fir.freemem %2 : !fir.heap<i32>
+  } {test.ptr = "test_effect"}
+  return
+}



More information about the flang-commits mailing list