[flang-commits] [flang] [flang] FIR AliasAnalysis: two global TARGET vars cannot alias. (PR #172550)
via flang-commits
flang-commits at lists.llvm.org
Tue Dec 16 12:46:10 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Slava Zakharin (vzakhari)
<details>
<summary>Changes</summary>
I think this change should be equivalent to #<!-- -->170908 at MLIR level,
i.e. two distinct global variables cannot alias each other
even if they both have TARGET attribute.
---
Full diff: https://github.com/llvm/llvm-project/pull/172550.diff
3 Files Affected:
- (modified) flang/lib/Optimizer/Analysis/AliasAnalysis.cpp (+6)
- (modified) flang/test/Analysis/AliasAnalysis/ptr-component.fir (+7-11)
- (modified) flang/test/HLFIR/inline-hlfir-assign.fir (+56)
``````````diff
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index c1ea88c96e43f..d2656fa7b8ea8 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -349,6 +349,12 @@ AliasResult AliasAnalysis::alias(Source lhsSrc, Source rhsSrc, mlir::Value lhs,
// of non-data is included below.
if (src1->isTargetOrPointer() && src2->isTargetOrPointer() &&
src1->isData() && src2->isData()) {
+ // Two distinct TARGET globals may not alias.
+ if (!src1->isPointer() && !src2->isPointer() &&
+ src1->kind == SourceKind::Global && src2->kind == SourceKind::Global &&
+ src1->origin.u != src2->origin.u) {
+ return AliasResult::NoAlias;
+ }
LLVM_DEBUG(llvm::dbgs() << " aliasing because of target or pointer\n");
return AliasResult::MayAlias;
}
diff --git a/flang/test/Analysis/AliasAnalysis/ptr-component.fir b/flang/test/Analysis/AliasAnalysis/ptr-component.fir
index cdd18832b113e..83cc4d36a7395 100644
--- a/flang/test/Analysis/AliasAnalysis/ptr-component.fir
+++ b/flang/test/Analysis/AliasAnalysis/ptr-component.fir
@@ -629,10 +629,6 @@ func.func private @_QMmFparentPtest.fir(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.
// end subroutine
// end module
-// TODO: All glob0 vs. glob1 cases can be NoAlias. However, AliasAnalysis
-// currently indiscriminately treats all targets that are data (addresses of
-// glob[01] and glob[01]%r but not glob[01]%p and glob[01]%a) as aliasing.
-
// Check composite vs. composite.
//
// CHECK-DAG: arg0#0 <-> arg1#0: MayAlias
@@ -641,8 +637,8 @@ func.func private @_QMmFparentPtest.fir(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.
// CHECK-DAG: arg0#0 <-> glob0#0: MayAlias
// CHECK-DAG: arg0.fir#0 <-> glob0.fir#0: MayAlias
//
-// CHECK-DAG: glob0#0 <-> glob1#0: MayAlias
-// CHECK-DAG: glob0.fir#0 <-> glob1.fir#0: MayAlias
+// CHECK-DAG: glob0#0 <-> glob1#0: NoAlias
+// CHECK-DAG: glob0.fir#0 <-> glob1.fir#0: NoAlias
// Check component vs. composite.
//
@@ -662,10 +658,10 @@ func.func private @_QMmFparentPtest.fir(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.
//
// CHECK-DAG: glob0%p#0 <-> glob1#0: NoAlias
// CHECK-DAG: glob0%a#0 <-> glob1#0: NoAlias
-// CHECK-DAG: glob0%r#0 <-> glob1#0: MayAlias
+// CHECK-DAG: glob0%r#0 <-> glob1#0: NoAlias
// CHECK-DAG: glob0%p.fir#0 <-> glob1.fir#0: NoAlias
// CHECK-DAG: glob0%a.fir#0 <-> glob1.fir#0: NoAlias
-// CHECK-DAG: glob0%r.fir#0 <-> glob1.fir#0: MayAlias
+// CHECK-DAG: glob0%r.fir#0 <-> glob1.fir#0: NoAlias
// Check composite vs. component.
//
@@ -685,10 +681,10 @@ func.func private @_QMmFparentPtest.fir(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.
//
// CHECK-DAG: glob0#0 <-> glob1%p#0: NoAlias
// CHECK-DAG: glob0#0 <-> glob1%a#0: NoAlias
-// CHECK-DAG: glob0#0 <-> glob1%r#0: MayAlias
+// CHECK-DAG: glob0#0 <-> glob1%r#0: NoAlias
// CHECK-DAG: glob0.fir#0 <-> glob1%p.fir#0: NoAlias
// CHECK-DAG: glob0.fir#0 <-> glob1%a.fir#0: NoAlias
-// CHECK-DAG: glob0.fir#0 <-> glob1%r.fir#0: MayAlias
+// CHECK-DAG: glob0.fir#0 <-> glob1%r.fir#0: NoAlias
// Check component vs. component.
//
@@ -705,7 +701,7 @@ func.func private @_QMmFparentPtest.fir(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.
//
// CHECK-DAG: glob0%p.fir#0 <-> glob1%p.fir#0: NoAlias
// CHECK-DAG: glob0%a.fir#0 <-> glob1%a.fir#0: NoAlias
-// CHECK-DAG: glob0%r.fir#0 <-> glob1%r.fir#0: MayAlias
+// CHECK-DAG: glob0%r.fir#0 <-> glob1%r.fir#0: NoAlias
func.func @_QMmPtest(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>> {fir.bindc_name = "arg0", fir.target}, %arg1: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>> {fir.bindc_name = "arg1", fir.target}) {
%0 = fir.dummy_scope : !fir.dscope
diff --git a/flang/test/HLFIR/inline-hlfir-assign.fir b/flang/test/HLFIR/inline-hlfir-assign.fir
index db71720119e71..5f728bf140ea3 100644
--- a/flang/test/HLFIR/inline-hlfir-assign.fir
+++ b/flang/test/HLFIR/inline-hlfir-assign.fir
@@ -351,3 +351,59 @@ func.func @_QPtest_expr_rhs(%arg0: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.
// CHECK: hlfir.destroy %[[VAL_10]] : !hlfir.expr<?x!fir.logical<4>>
// CHECK: return
// CHECK: }
+
+// Test that two ALLOCATABLE TARGET globals do not alias,
+// thus hlfir.assign may be inlined.
+// Original code (compiled with -fno-realloc-lhs):
+// module test_global_allocatable_target
+// real, allocatable, target :: a(:)
+// real, allocatable, target :: b(:)
+// contains
+// subroutine test
+// a = b
+// end subroutine test
+// end module test_global_allocatable_target
+
+// CHECK-LABEL: func.func @_QMtest_global_allocatable_targetPtest() {
+// CHECK-NOT: hlfir.assign{{.*}}!fir.array
+func.func @_QMtest_global_allocatable_targetPtest() {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMtest_global_allocatable_targetEa) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %2:2 = hlfir.declare %1 {fortran_attrs = #fir.var_attrs<allocatable, target>, uniq_name = "_QMtest_global_allocatable_targetEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
+ %3 = fir.address_of(@_QMtest_global_allocatable_targetEb) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %4:2 = hlfir.declare %3 {fortran_attrs = #fir.var_attrs<allocatable, target>, uniq_name = "_QMtest_global_allocatable_targetEb"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>)
+ %5 = fir.load %4#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %6 = fir.load %2#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ hlfir.assign %5 to %6 : !fir.box<!fir.heap<!fir.array<?xf32>>>, !fir.box<!fir.heap<!fir.array<?xf32>>>
+ return
+}
+fir.global @_QMtest_global_allocatable_targetEa target : !fir.box<!fir.heap<!fir.array<?xf32>>>
+fir.global @_QMtest_global_allocatable_targetEb target : !fir.box<!fir.heap<!fir.array<?xf32>>>
+
+// Test that two TARGET global arrays do not alias,
+// thus hlfir.assign may be inlined.
+// Original code:
+// module test_global_shaped_target
+// real, target :: a1(100)
+// real, target :: b1(100)
+// contains
+// subroutine test
+// a1 = b1
+// end subroutine test
+// end module test_global_shaped_target
+
+// CHECK-LABEL: func.func @_QMtest_global_shaped_targetPtest() {
+// CHECK-NOT: hlfir.assign{{.*}}!fir.array
+func.func @_QMtest_global_shaped_targetPtest() {
+ %c100 = arith.constant 100 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.address_of(@_QMtest_global_shaped_targetEa1) : !fir.ref<!fir.array<100xf32>>
+ %2 = fir.shape %c100 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %1(%2) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMtest_global_shaped_targetEa1"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
+ %4 = fir.address_of(@_QMtest_global_shaped_targetEb1) : !fir.ref<!fir.array<100xf32>>
+ %5:2 = hlfir.declare %4(%2) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMtest_global_shaped_targetEb1"} : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>)
+ hlfir.assign %5#0 to %3#0 : !fir.ref<!fir.array<100xf32>>, !fir.ref<!fir.array<100xf32>>
+ return
+}
+fir.global @_QMtest_global_shaped_targetEa1 target : !fir.array<100xf32>
+fir.global @_QMtest_global_shaped_targetEb1 target : !fir.array<100xf32>
``````````
</details>
https://github.com/llvm/llvm-project/pull/172550
More information about the flang-commits
mailing list