[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