[flang-commits] [flang] 5933d0b - [flang] Add support for fir.absent to AliasAnalysis (#195938)
via flang-commits
flang-commits at lists.llvm.org
Wed May 6 07:24:49 PDT 2026
Author: Razvan Lupusoru
Date: 2026-05-06T07:24:45-07:00
New Revision: 5933d0bec78893804b0e8327381c9e1cadcb12eb
URL: https://github.com/llvm/llvm-project/commit/5933d0bec78893804b0e8327381c9e1cadcb12eb
DIFF: https://github.com/llvm/llvm-project/commit/5933d0bec78893804b0e8327381c9e1cadcb12eb.diff
LOG: [flang] Add support for fir.absent to AliasAnalysis (#195938)
Each fir.absent is classified like a distinct allocation so it does not
alias other real storage, another absent, or a global.
Added:
flang/test/Analysis/AliasAnalysis/alias-analysis-absent.fir
Modified:
flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index 9335ab688128b..2d19e07d9d7ce 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -894,6 +894,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