[flang-commits] [flang] [flang] Add support for fir.absent to AliasAnalysis (PR #195938)
Razvan Lupusoru via flang-commits
flang-commits at lists.llvm.org
Tue May 5 14:00:32 PDT 2026
https://github.com/razvanlupusoru created https://github.com/llvm/llvm-project/pull/195938
Each fir.absent is classified like a distinct allocation so it does not alias other real storage, another absent, or a global.
>From 7a146b233800a3ad30d8d81b96d6c12e417be417 Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Tue, 5 May 2026 13:59:35 -0700
Subject: [PATCH] [flang] Add support for fir.absent to AliasAnalysis
Each fir.absent is classified like a distinct allocation so it
does not alias other real storage, another absent, or a global.
---
.../lib/Optimizer/Analysis/AliasAnalysis.cpp | 8 +++
.../AliasAnalysis/alias-analysis-absent.fir | 60 +++++++++++++++++++
2 files changed, 68 insertions(+)
create mode 100644 flang/test/Analysis/AliasAnalysis/alias-analysis-absent.fir
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index 2509334b8ec4a..b4b48d19d9a1c 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -869,6 +869,14 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
defOp = v.getDefiningOp();
approximateSource = true;
})
+ .Case([&](fir::AbsentOp op) {
+ // Although fir.absent is not a local allocation, we treat it
+ // similarly so that it can be disambiguated that it doesn't alias any
+ // other values. Two entities coming from separate fir.absent ops
+ // also do not alias each other.
+ type = SourceKind::Allocate;
+ breakFromLoop = true;
+ })
.Case([&](fir::LoadOp op) {
// If load is inside target and it points to mapped item,
// continue tracking.
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-absent.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-absent.fir
new file mode 100644
index 0000000000000..f8c97d48a3594
--- /dev/null
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-absent.fir
@@ -0,0 +1,60 @@
+// Exercise FIR alias analysis for values rooted at fir.absent.
+// Each fir.absent is classified like a distinct allocation so it
+// does not alias real storage, another absent, or a global; it only
+// aliases itself.
+
+// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' \
+// RUN: -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
+
+// CHECK-LABEL: Testing : "_QPtest_absent"
+// CHECK-DAG: absent1#0 <-> absent2#0: NoAlias
+// CHECK-DAG: real#0 <-> absent1#0: NoAlias
+// CHECK-DAG: real#0 <-> absent2#0: NoAlias
+
+func.func @_QPtest_absent() {
+ %c10 = arith.constant 10 : index
+ %shape = fir.shape %c10 : (index) -> !fir.shape<1>
+ %alloc = fir.alloca !fir.array<10xf32>
+ %real = fir.declare %alloc(%shape) {uniq_name = "_QPtest_absentEx", test.ptr = "real"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+ %abs1 = fir.absent !fir.ref<!fir.array<10xf32>> {test.ptr = "absent1"}
+ %abs2 = fir.absent !fir.ref<!fir.array<10xf32>> {test.ptr = "absent2"}
+ return
+}
+
+// -----
+
+// Same fir.absent via fir.convert and fir.declare
+// CHECK-LABEL: Testing : "_QPtest_absent_same_through_convert"
+// CHECK-DAG: abs_slot#0 <-> via_convert#0: MustAlias
+// CHECK-DAG: abs_slot#0 <-> direct_abs#0: MustAlias
+// CHECK-DAG: via_convert#0 <-> direct_abs#0: MustAlias
+
+func.func @_QPtest_absent_same_through_convert() {
+ %c10 = arith.constant 10 : index
+ %shape = fir.shape %c10 : (index) -> !fir.shape<1>
+ %abs = fir.absent !fir.ref<!fir.array<10xf32>> {test.ptr = "abs_slot"}
+ %conv = fir.convert %abs : (!fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>>
+ %via = fir.declare %conv(%shape) {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QPtest_absent_sameEv", test.ptr = "via_convert"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+ %direct = fir.declare %abs(%shape) {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QPtest_absent_sameEd", test.ptr = "direct_abs"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+ return
+}
+
+// -----
+
+// Global array storage must not alias an absent.
+// CHECK-LABEL: Testing : "_QPtest_absent_vs_global"
+// CHECK-DAG: {{(absent_g#0 <-> global#0|global#0 <-> absent_g#0)}}: NoAlias
+
+fir.global @_QPtest_absent_vs_global_g : !fir.array<10xf32> {
+ %0 = fir.undefined !fir.array<10xf32>
+ fir.has_value %0 : !fir.array<10xf32>
+}
+
+func.func @_QPtest_absent_vs_global() {
+ %c10 = arith.constant 10 : index
+ %shape = fir.shape %c10 : (index) -> !fir.shape<1>
+ %gaddr = fir.address_of(@_QPtest_absent_vs_global_g) : !fir.ref<!fir.array<10xf32>>
+ %g = fir.declare %gaddr(%shape) {uniq_name = "_QPtest_absent_vs_globalEg", test.ptr = "global"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+ %abs = fir.absent !fir.ref<!fir.array<10xf32>> {test.ptr = "absent_g"}
+ return
+}
More information about the flang-commits
mailing list