[flang-commits] [flang] [OpenMP][Flang] Enable alias analysis inside omp target region (PR #111670)

Dominik Adamski via flang-commits flang-commits at lists.llvm.org
Fri Oct 11 02:14:50 PDT 2024


https://github.com/DominikAdamski updated https://github.com/llvm/llvm-project/pull/111670

>From 9931359283d88f737ece5d259e0d5c2a0d93f39a Mon Sep 17 00:00:00 2001
From: Dominik Adamski <dominik.adamski at amd.com>
Date: Wed, 9 Oct 2024 04:35:14 -0500
Subject: [PATCH 1/3] [OpenMP][Flang] Enable alias analysis inside omp target
 region

At present, alias analysis does not work for operations inside
OMP target regions because the FIR declare operations within OMP target
do not offer sufficient information for alias analysis.
Consequently, it is necessary to examine the FIR code outside
the OMP target region.
---
 .../lib/Optimizer/Analysis/AliasAnalysis.cpp  | 37 +++++++++++
 flang/lib/Optimizer/Analysis/CMakeLists.txt   |  2 +
 .../alias-analysis-omp-target-1.fir           | 66 +++++++++++++++++++
 3 files changed, 105 insertions(+)
 create mode 100644 flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-1.fir

diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index e88da5a8ebae19..c168eee69bf7d0 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -13,6 +13,8 @@
 #include "flang/Optimizer/Dialect/FortranVariableInterface.h"
 #include "flang/Optimizer/HLFIR/HLFIROps.h"
 #include "mlir/Analysis/AliasAnalysis.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/Value.h"
 #include "mlir/Interfaces/SideEffectInterfaces.h"
@@ -296,6 +298,15 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
             defOp = v.getDefiningOp();
             return;
           }
+          // If load is inside target and it points to mapped item,
+          // continue tracking.
+          Operation *loadMemrefOp = op.getMemref().getDefiningOp();
+          if (llvm::isa<fir::DeclareOp>(loadMemrefOp) &&
+              llvm::isa<omp::TargetOp>(loadMemrefOp->getParentOp())) {
+            v = op.getMemref();
+            defOp = v.getDefiningOp();
+            return;
+          }
           // No further tracking for addresses loaded from memory for now.
           type = SourceKind::Indirect;
           breakFromLoop = true;
@@ -319,6 +330,32 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
           breakFromLoop = true;
         })
         .Case<hlfir::DeclareOp, fir::DeclareOp>([&](auto op) {
+          // If declare operation is inside omp target region,
+          // continue alias analysis outside the target region
+          if (llvm::isa<omp::TargetOp>(op->getParentOp())) {
+            omp::TargetOp targetOp =
+                llvm::cast<omp::TargetOp>(op->getParentOp());
+            auto mapClauseOwner =
+                llvm::dyn_cast<omp::MapClauseOwningOpInterface>(
+                    targetOp.getOperation());
+            if (!mapClauseOwner) {
+              defOp = nullptr;
+              breakFromLoop = true;
+              return;
+            }
+            Block *targetEntryBlock = &targetOp->getRegion(0).front();
+            OperandRange mapVarsArr = mapClauseOwner.getMapVars();
+            assert(mapVarsArr.size() == targetEntryBlock->getNumArguments());
+            for (size_t i = 0; i < targetEntryBlock->getNumArguments(); i++) {
+              if (targetEntryBlock->getArgument(i) == op.getMemref()) {
+                omp::MapInfoOp mapInfo =
+                    llvm::cast<omp::MapInfoOp>(mapVarsArr[i].getDefiningOp());
+                defOp = mapInfo.getVarPtr().getDefiningOp();
+                v = mapInfo.getVarPtr();
+                return;
+              }
+            }
+          }
           auto varIf = llvm::cast<fir::FortranVariableOpInterface>(defOp);
           // While going through a declare operation collect
           // the variable attributes from it. Right now, some
diff --git a/flang/lib/Optimizer/Analysis/CMakeLists.txt b/flang/lib/Optimizer/Analysis/CMakeLists.txt
index 436d4d3f18969c..c000a9da99f871 100644
--- a/flang/lib/Optimizer/Analysis/CMakeLists.txt
+++ b/flang/lib/Optimizer/Analysis/CMakeLists.txt
@@ -6,6 +6,7 @@ add_flang_library(FIRAnalysis
   FIRDialect
   HLFIRDialect
   MLIRIR
+  MLIROpenMPDialect
 
   LINK_LIBS
   FIRBuilder
@@ -14,5 +15,6 @@ add_flang_library(FIRAnalysis
   MLIRFuncDialect
   MLIRLLVMDialect
   MLIRMathTransforms
+  MLIROpenMPDialect
   FIRSupport
 )
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-1.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-1.fir
new file mode 100644
index 00000000000000..38fe799d2618ee
--- /dev/null
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-1.fir
@@ -0,0 +1,66 @@
+// Use --mlir-disable-threading so that the AA queries are serialized
+// as well as its diagnostic output.
+// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
+
+// Fortran source code:
+//
+// program TestAllocatableArray
+// real(kind=8),  allocatable :: A(:)
+// real(kind=8),  allocatable :: B(:)
+// !$omp target
+//    A(0) = B(0)
+// !$omp end target
+// end TestAllocatableArray
+
+// CHECK-LABEL: Testing : "_QPTestAllocatableArray"
+// CHECK-DAG: ArrayA#0 <-> ArrayB#0: NoAlias
+func.func @_QPTestAllocatableArray() {
+  %0 = fir.address_of(@_QFEa) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+  %1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "ArrayA", test.ptr = "ArrayA" } : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>)
+  %2 = fir.address_of(@_QFEb) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+  %3:2 = hlfir.declare %2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "ArrayB", test.ptr = "ArrayB" } : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>)
+  %4 = fir.load %1#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+  %c1 = arith.constant 1 : index
+  %c0 = arith.constant 0 : index
+  %5 = fir.load %1#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+  %c0_0 = arith.constant 0 : index
+  %6:3 = fir.box_dims %5, %c0_0 : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> (index, index, index)
+  %7:3 = fir.box_dims %4, %c0 : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> (index, index, index)
+  %c0_1 = arith.constant 0 : index
+  %8 = arith.subi %7#1, %c1 : index
+  %9 = omp.map.bounds lower_bound(%c0_1 : index) upper_bound(%8 : index) extent(%7#1 : index) stride(%7#2 : index) start_idx(%6#0 : index) {stride_in_bytes = true}
+  %10 = fir.box_offset %1#1 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>>
+  %11 = omp.map.info var_ptr(%1#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.array<?xf64>) var_ptr_ptr(%10 : !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%9) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>> {name = ""}
+  %12 = omp.map.info var_ptr(%1#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.box<!fir.heap<!fir.array<?xf64>>>) map_clauses(implicit, tofrom) capture(ByRef) members(%11 : [0] : !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>> {name = "a"}
+  %13 = fir.load %3#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+  %c1_2 = arith.constant 1 : index
+  %c0_3 = arith.constant 0 : index
+  %14 = fir.load %3#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+  %c0_4 = arith.constant 0 : index
+  %15:3 = fir.box_dims %14, %c0_4 : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> (index, index, index)
+  %16:3 = fir.box_dims %13, %c0_3 : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> (index, index, index)
+  %c0_5 = arith.constant 0 : index
+  %17 = arith.subi %16#1, %c1_2 : index
+  %18 = omp.map.bounds lower_bound(%c0_5 : index) upper_bound(%17 : index) extent(%16#1 : index) stride(%16#2 : index) start_idx(%15#0 : index) {stride_in_bytes = true}
+  %19 = fir.box_offset %3#1 base_addr : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>>
+  %20 = omp.map.info var_ptr(%3#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.array<?xf64>) var_ptr_ptr(%19 : !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%18) -> !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>> {name = ""}
+  %21 = omp.map.info var_ptr(%3#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.box<!fir.heap<!fir.array<?xf64>>>) map_clauses(implicit, tofrom) capture(ByRef) members(%20 : [0] : !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>> {name = "b"}
+  omp.target map_entries(%11 -> %arg0, %12 -> %arg1, %20 -> %arg2, %21 -> %arg3 : !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.llvm_ptr<!fir.ref<!fir.array<?xf64>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) {
+    %22:2 = hlfir.declare %arg1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>)
+    %23:2 = hlfir.declare %arg3 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>)
+    %24 = fir.load %23#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+    %c0_6 = arith.constant 0 : index
+    %25 = hlfir.designate %24 (%c0_6)  : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> !fir.ref<f64>
+    %26 = fir.load %25 : !fir.ref<f64>
+    %27 = fir.load %22#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
+    %c0_7 = arith.constant 0 : index
+    %28 = hlfir.designate %27 (%c0_7)  : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> !fir.ref<f64>
+    hlfir.assign %26 to %28 : f64, !fir.ref<f64>
+    omp.terminator
+  }
+  return
+}
+fir.global internal @_QFEa : !fir.box<!fir.heap<!fir.array<?xf64>>> {
+}
+fir.global internal @_QFEb : !fir.box<!fir.heap<!fir.array<?xf64>>> {
+}

>From 698c2cf014db7ca8158d47dad964a618e8685956 Mon Sep 17 00:00:00 2001
From: Dominik Adamski <dominik.adamski at amd.com>
Date: Thu, 10 Oct 2024 06:37:28 -0500
Subject: [PATCH 2/3] Applied remarks

---
 .../lib/Optimizer/Analysis/AliasAnalysis.cpp  | 24 ++---
 .../alias-analysis-omp-target-2.fir           | 95 +++++++++++++++++++
 2 files changed, 102 insertions(+), 17 deletions(-)
 create mode 100644 flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-2.fir

diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index c168eee69bf7d0..c4a69364922b3f 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -332,24 +332,14 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
         .Case<hlfir::DeclareOp, fir::DeclareOp>([&](auto op) {
           // If declare operation is inside omp target region,
           // continue alias analysis outside the target region
-          if (llvm::isa<omp::TargetOp>(op->getParentOp())) {
-            omp::TargetOp targetOp =
-                llvm::cast<omp::TargetOp>(op->getParentOp());
-            auto mapClauseOwner =
-                llvm::dyn_cast<omp::MapClauseOwningOpInterface>(
-                    targetOp.getOperation());
-            if (!mapClauseOwner) {
-              defOp = nullptr;
-              breakFromLoop = true;
-              return;
-            }
-            Block *targetEntryBlock = &targetOp->getRegion(0).front();
-            OperandRange mapVarsArr = mapClauseOwner.getMapVars();
-            assert(mapVarsArr.size() == targetEntryBlock->getNumArguments());
-            for (size_t i = 0; i < targetEntryBlock->getNumArguments(); i++) {
-              if (targetEntryBlock->getArgument(i) == op.getMemref()) {
+          if (auto targetOp =
+                  llvm::dyn_cast<omp::TargetOp>(op->getParentOp())) {
+            auto argIface = cast<omp::BlockArgOpenMPOpInterface>(*targetOp);
+            for (auto [opArg, blockArg] : llvm::zip_equal(
+                     targetOp.getMapVars(), argIface.getMapBlockArgs())) {
+              if (opArg == op.getMemref()) {
                 omp::MapInfoOp mapInfo =
-                    llvm::cast<omp::MapInfoOp>(mapVarsArr[i].getDefiningOp());
+                    llvm::cast<omp::MapInfoOp>(blockArg.getDefiningOp());
                 defOp = mapInfo.getVarPtr().getDefiningOp();
                 v = mapInfo.getVarPtr();
                 return;
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-2.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-2.fir
new file mode 100644
index 00000000000000..65cb327e2919b1
--- /dev/null
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-2.fir
@@ -0,0 +1,95 @@
+// Use --mlir-disable-threading so that the AA queries are serialized
+// as well as its diagnostic output.
+// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
+
+// Fortran source code:
+//
+// subroutine TestTargetData(p, a, b)
+//   real    ::  p(10), a(10), b(10)
+//   !$omp target data map(from: p)
+//      !$omp target map(to: a )
+//            p(1) = a(1)
+//      !$omp end target
+//      !$omp target map(to: b )
+//            p(1) = b(1)
+//      !$omp end target
+//   !$omp end target data
+// end subroutine
+
+// CHECK-LABEL: Testing : "_QPTestTargetData"
+// CHECK-DAG: ArrayA#0 <-> ArrayB#0: NoAlias
+// CHECK-DAG: ArrayA#0 <-> ArrayP#0: NoAlias
+// CHECK-DAG: ArrayB#0 <-> ArrayP#0: NoAlias
+
+func.func @_QPTestTargetData(%arg0: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "p"}, %arg1: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "a"}, %arg2: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "b"}) {
+  %0 = fir.dummy_scope : !fir.dscope
+  %c10 = arith.constant 10 : index
+  %1 = fir.shape %c10 : (index) -> !fir.shape<1>
+  %2:2 = hlfir.declare %arg1(%1) dummy_scope %0 {uniq_name = "_QFtest_target_dataEa", test.ptr = "ArrayA"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+  %c10_0 = arith.constant 10 : index
+  %3 = fir.shape %c10_0 : (index) -> !fir.shape<1>
+  %4:2 = hlfir.declare %arg2(%3) dummy_scope %0 {uniq_name = "_QFtest_target_dataEb", test.ptr = "ArrayB"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+  %c10_1 = arith.constant 10 : index
+  %5 = fir.shape %c10_1 : (index) -> !fir.shape<1>
+  %6:2 = hlfir.declare %arg0(%5) dummy_scope %0 {uniq_name = "_QFtest_target_dataEp", test.ptr = "ArrayP"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+  %c1 = arith.constant 1 : index
+  %c0 = arith.constant 0 : index
+  %7 = arith.subi %c10_1, %c1 : index
+  %8 = omp.map.bounds lower_bound(%c0 : index) upper_bound(%7 : index) extent(%c10_1 : index) stride(%c1 : index) start_idx(%c1 : index)
+  %9 = omp.map.info var_ptr(%6#1 : !fir.ref<!fir.array<10xf32>>, !fir.array<10xf32>) map_clauses(from) capture(ByRef) bounds(%8) -> !fir.ref<!fir.array<10xf32>> {name = "p"}
+  omp.target_data map_entries(%9 : !fir.ref<!fir.array<10xf32>>) {
+    %c1_2 = arith.constant 1 : index
+    %c0_3 = arith.constant 0 : index
+    %10 = arith.subi %c10, %c1_2 : index
+    %11 = omp.map.bounds lower_bound(%c0_3 : index) upper_bound(%10 : index) extent(%c10 : index) stride(%c1_2 : index) start_idx(%c1_2 : index)
+    %12 = omp.map.info var_ptr(%2#1 : !fir.ref<!fir.array<10xf32>>, !fir.array<10xf32>) map_clauses(to) capture(ByRef) bounds(%11) -> !fir.ref<!fir.array<10xf32>> {name = "a"}
+    %c1_4 = arith.constant 1 : index
+    %c0_5 = arith.constant 0 : index
+    %13 = arith.subi %c10_1, %c1_4 : index
+    %14 = omp.map.bounds lower_bound(%c0_5 : index) upper_bound(%13 : index) extent(%c10_1 : index) stride(%c1_4 : index) start_idx(%c1_4 : index)
+    %15 = omp.map.info var_ptr(%6#1 : !fir.ref<!fir.array<10xf32>>, !fir.array<10xf32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%14) -> !fir.ref<!fir.array<10xf32>> {name = "p"}
+    omp.target map_entries(%12 -> %arg3, %15 -> %arg4 : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
+      %c10_10 = arith.constant 10 : index
+      %22 = fir.shape %c10_10 : (index) -> !fir.shape<1>
+      %23:2 = hlfir.declare %arg3(%22) {uniq_name = "_QFtest_target_dataEa"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+      %c10_11 = arith.constant 10 : index
+      %24 = fir.shape %c10_11 : (index) -> !fir.shape<1>
+      %25:2 = hlfir.declare %arg4(%24) {uniq_name = "_QFtest_target_dataEp"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+      %c1_12 = arith.constant 1 : index
+      %26 = hlfir.designate %23#0 (%c1_12)  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+      %27 = fir.load %26 : !fir.ref<f32>
+      %c1_13 = arith.constant 1 : index
+      %28 = hlfir.designate %25#0 (%c1_13)  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+      hlfir.assign %27 to %28 : f32, !fir.ref<f32>
+      omp.terminator
+    }
+    %c1_6 = arith.constant 1 : index
+    %c0_7 = arith.constant 0 : index
+    %16 = arith.subi %c10_0, %c1_6 : index
+    %17 = omp.map.bounds lower_bound(%c0_7 : index) upper_bound(%16 : index) extent(%c10_0 : index) stride(%c1_6 : index) start_idx(%c1_6 : index)
+    %18 = omp.map.info var_ptr(%4#1 : !fir.ref<!fir.array<10xf32>>, !fir.array<10xf32>) map_clauses(to) capture(ByRef) bounds(%17) -> !fir.ref<!fir.array<10xf32>> {name = "b"}
+    %c1_8 = arith.constant 1 : index
+    %c0_9 = arith.constant 0 : index
+    %19 = arith.subi %c10_1, %c1_8 : index
+    %20 = omp.map.bounds lower_bound(%c0_9 : index) upper_bound(%19 : index) extent(%c10_1 : index) stride(%c1_8 : index) start_idx(%c1_8 : index)
+    %21 = omp.map.info var_ptr(%6#1 : !fir.ref<!fir.array<10xf32>>, !fir.array<10xf32>) map_clauses(implicit, tofrom) capture(ByRef) bounds(%20) -> !fir.ref<!fir.array<10xf32>> {name = "p"}
+    omp.target map_entries(%18 -> %arg3, %21 -> %arg4 : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) {
+      %c10_10 = arith.constant 10 : index
+      %22 = fir.shape %c10_10 : (index) -> !fir.shape<1>
+      %23:2 = hlfir.declare %arg3(%22) {uniq_name = "_QFtest_target_dataEb"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+      %c10_11 = arith.constant 10 : index
+      %24 = fir.shape %c10_11 : (index) -> !fir.shape<1>
+      %25:2 = hlfir.declare %arg4(%24) {uniq_name = "_QFtest_target_dataEp"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+      %c1_12 = arith.constant 1 : index
+      %26 = hlfir.designate %23#0 (%c1_12)  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+      %27 = fir.load %26 : !fir.ref<f32>
+      %c1_13 = arith.constant 1 : index
+      %28 = hlfir.designate %25#0 (%c1_13)  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+      hlfir.assign %27 to %28 : f32, !fir.ref<f32>
+      omp.terminator
+    }
+    omp.terminator
+  }
+  return
+}
+

>From b6d58d859e43f3ecd9eefb7dffb21b6fe666e7ff Mon Sep 17 00:00:00 2001
From: Dominik Adamski <dominik.adamski at amd.com>
Date: Fri, 11 Oct 2024 03:07:01 -0500
Subject: [PATCH 3/3] Fixed tests.

test.ptr attribute should be attached to operation
inside target region.
---
 .../lib/Optimizer/Analysis/AliasAnalysis.cpp  | 10 +++++----
 .../alias-analysis-omp-target-1.fir           | 10 ++++-----
 .../alias-analysis-omp-target-2.fir           | 21 ++++++++++---------
 3 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index c4a69364922b3f..6ee4f0ff71057a 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -301,7 +301,9 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
           // If load is inside target and it points to mapped item,
           // continue tracking.
           Operation *loadMemrefOp = op.getMemref().getDefiningOp();
-          if (llvm::isa<fir::DeclareOp>(loadMemrefOp) &&
+          bool isDeclareOp = llvm::isa<fir::DeclareOp>(loadMemrefOp) ||
+                             llvm::isa<hlfir::DeclareOp>(loadMemrefOp);
+          if (isDeclareOp &&
               llvm::isa<omp::TargetOp>(loadMemrefOp->getParentOp())) {
             v = op.getMemref();
             defOp = v.getDefiningOp();
@@ -337,11 +339,11 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
             auto argIface = cast<omp::BlockArgOpenMPOpInterface>(*targetOp);
             for (auto [opArg, blockArg] : llvm::zip_equal(
                      targetOp.getMapVars(), argIface.getMapBlockArgs())) {
-              if (opArg == op.getMemref()) {
+              if (blockArg == op.getMemref()) {
                 omp::MapInfoOp mapInfo =
-                    llvm::cast<omp::MapInfoOp>(blockArg.getDefiningOp());
-                defOp = mapInfo.getVarPtr().getDefiningOp();
+                    llvm::cast<omp::MapInfoOp>(opArg.getDefiningOp());
                 v = mapInfo.getVarPtr();
+                defOp = v.getDefiningOp();
                 return;
               }
             }
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-1.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-1.fir
index 38fe799d2618ee..88f411847172a0 100644
--- a/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-1.fir
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-1.fir
@@ -13,12 +13,12 @@
 // end TestAllocatableArray
 
 // CHECK-LABEL: Testing : "_QPTestAllocatableArray"
-// CHECK-DAG: ArrayA#0 <-> ArrayB#0: NoAlias
+// CHECK-DAG: targetArrayB#0 <-> targetArrayA#0: NoAlias
 func.func @_QPTestAllocatableArray() {
   %0 = fir.address_of(@_QFEa) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
-  %1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "ArrayA", test.ptr = "ArrayA" } : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>)
+  %1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "ArrayA" } : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>)
   %2 = fir.address_of(@_QFEb) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
-  %3:2 = hlfir.declare %2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "ArrayB", test.ptr = "ArrayB" } : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>)
+  %3:2 = hlfir.declare %2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "ArrayB" } : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>)
   %4 = fir.load %1#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
   %c1 = arith.constant 1 : index
   %c0 = arith.constant 0 : index
@@ -50,11 +50,11 @@ func.func @_QPTestAllocatableArray() {
     %23:2 = hlfir.declare %arg3 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFEb"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>)
     %24 = fir.load %23#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
     %c0_6 = arith.constant 0 : index
-    %25 = hlfir.designate %24 (%c0_6)  : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> !fir.ref<f64>
+    %25 = hlfir.designate %24 (%c0_6) {test.ptr = "targetArrayB"} : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> !fir.ref<f64>
     %26 = fir.load %25 : !fir.ref<f64>
     %27 = fir.load %22#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>
     %c0_7 = arith.constant 0 : index
-    %28 = hlfir.designate %27 (%c0_7)  : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> !fir.ref<f64>
+    %28 = hlfir.designate %27 (%c0_7) {test.ptr = "targetArrayA"} : (!fir.box<!fir.heap<!fir.array<?xf64>>>, index) -> !fir.ref<f64>
     hlfir.assign %26 to %28 : f64, !fir.ref<f64>
     omp.terminator
   }
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-2.fir b/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-2.fir
index 65cb327e2919b1..c6b2e29a7188a9 100644
--- a/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-2.fir
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-omp-target-2.fir
@@ -17,21 +17,22 @@
 // end subroutine
 
 // CHECK-LABEL: Testing : "_QPTestTargetData"
-// CHECK-DAG: ArrayA#0 <-> ArrayB#0: NoAlias
-// CHECK-DAG: ArrayA#0 <-> ArrayP#0: NoAlias
-// CHECK-DAG: ArrayB#0 <-> ArrayP#0: NoAlias
+
+// CHECK-DAG: targetArrayA#0 <-> targetArrayP#0: NoAlias
+// CHECK-DAG: targetArrayA#0 <-> targetArrayB#0: NoAlias
+// CHECK-DAG: targetArrayP#0 <-> targetArrayB#0: NoAlias
 
 func.func @_QPTestTargetData(%arg0: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "p"}, %arg1: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "a"}, %arg2: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "b"}) {
   %0 = fir.dummy_scope : !fir.dscope
   %c10 = arith.constant 10 : index
   %1 = fir.shape %c10 : (index) -> !fir.shape<1>
-  %2:2 = hlfir.declare %arg1(%1) dummy_scope %0 {uniq_name = "_QFtest_target_dataEa", test.ptr = "ArrayA"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+  %2:2 = hlfir.declare %arg1(%1) dummy_scope %0 {uniq_name = "_QFtest_target_dataEa"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
   %c10_0 = arith.constant 10 : index
   %3 = fir.shape %c10_0 : (index) -> !fir.shape<1>
-  %4:2 = hlfir.declare %arg2(%3) dummy_scope %0 {uniq_name = "_QFtest_target_dataEb", test.ptr = "ArrayB"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+  %4:2 = hlfir.declare %arg2(%3) dummy_scope %0 {uniq_name = "_QFtest_target_dataEb"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
   %c10_1 = arith.constant 10 : index
   %5 = fir.shape %c10_1 : (index) -> !fir.shape<1>
-  %6:2 = hlfir.declare %arg0(%5) dummy_scope %0 {uniq_name = "_QFtest_target_dataEp", test.ptr = "ArrayP"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+  %6:2 = hlfir.declare %arg0(%5) dummy_scope %0 {uniq_name = "_QFtest_target_dataEp"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
   %c1 = arith.constant 1 : index
   %c0 = arith.constant 0 : index
   %7 = arith.subi %c10_1, %c1 : index
@@ -56,10 +57,10 @@ func.func @_QPTestTargetData(%arg0: !fir.ref<!fir.array<10xf32>> {fir.bindc_name
       %24 = fir.shape %c10_11 : (index) -> !fir.shape<1>
       %25:2 = hlfir.declare %arg4(%24) {uniq_name = "_QFtest_target_dataEp"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
       %c1_12 = arith.constant 1 : index
-      %26 = hlfir.designate %23#0 (%c1_12)  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+      %26 = hlfir.designate %23#0 (%c1_12) {test.ptr = "targetArrayA"}  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
       %27 = fir.load %26 : !fir.ref<f32>
       %c1_13 = arith.constant 1 : index
-      %28 = hlfir.designate %25#0 (%c1_13)  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+      %28 = hlfir.designate %25#0 (%c1_13) {test.ptr = "targetArrayP"}  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
       hlfir.assign %27 to %28 : f32, !fir.ref<f32>
       omp.terminator
     }
@@ -81,10 +82,10 @@ func.func @_QPTestTargetData(%arg0: !fir.ref<!fir.array<10xf32>> {fir.bindc_name
       %24 = fir.shape %c10_11 : (index) -> !fir.shape<1>
       %25:2 = hlfir.declare %arg4(%24) {uniq_name = "_QFtest_target_dataEp"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
       %c1_12 = arith.constant 1 : index
-      %26 = hlfir.designate %23#0 (%c1_12)  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+      %26 = hlfir.designate %23#0 (%c1_12) {test.ptr = "targetArrayB"}  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
       %27 = fir.load %26 : !fir.ref<f32>
       %c1_13 = arith.constant 1 : index
-      %28 = hlfir.designate %25#0 (%c1_13)  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+      %28 = hlfir.designate %25#0 (%c1_13) {test.ptr = "targetArrayP"}  : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
       hlfir.assign %27 to %28 : f32, !fir.ref<f32>
       omp.terminator
     }



More information about the flang-commits mailing list