[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