[flang-commits] [flang] [flang][acc] Fix mappableTy.generateAccBounds to correctly handle dynamic-sized arrays (PR #155666)

via flang-commits flang-commits at lists.llvm.org
Wed Aug 27 19:16:29 PDT 2025


https://github.com/khaki3 updated https://github.com/llvm/llvm-project/pull/155666

>From b2b1ab85242d416d76a798f9266cbb2d11e7f4d1 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Wed, 27 Aug 2025 10:45:31 -0700
Subject: [PATCH 1/3] Fix mappableTy.generateAccBounds

---
 .../OpenACC/Support/FIROpenACCTypeInterfaces.cpp          | 8 +++-----
 flang/test/Fir/OpenACC/openacc-mappable.fir               | 4 ++--
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
index 5b6d904fb0d59..9b4db4900258b 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
@@ -243,8 +243,6 @@ generateSeqTyAccBounds(fir::SequenceType seqType, mlir::Value var,
               mlir::dyn_cast_if_present<fir::ShapeOp>(shape.getDefiningOp())) {
         mlir::Value cummulativeExtent = one;
         for (auto extent : shapeOp.getExtents()) {
-          mlir::Value upperbound =
-              mlir::arith::SubIOp::create(builder, loc, extent, one);
           mlir::Value stride = one;
           if (strideIncludeLowerExtent) {
             stride = cummulativeExtent;
@@ -254,7 +252,7 @@ generateSeqTyAccBounds(fir::SequenceType seqType, mlir::Value var,
           auto accBound = mlir::acc::DataBoundsOp::create(
               builder, loc,
               mlir::acc::DataBoundsType::get(builder.getContext()),
-              /*lowerbound=*/zero, /*upperbound=*/upperbound,
+              /*lowerbound=*/one, /*upperbound=*/extent,
               /*extent=*/extent, /*stride=*/stride, /*strideInBytes=*/false,
               /*startIdx=*/one);
           accBounds.push_back(accBound);
@@ -282,9 +280,9 @@ generateSeqTyAccBounds(fir::SequenceType seqType, mlir::Value var,
             auto accBound = mlir::acc::DataBoundsOp::create(
                 builder, loc,
                 mlir::acc::DataBoundsType::get(builder.getContext()),
-                /*lowerbound=*/zero, /*upperbound=*/upperbound,
+                /*lowerbound=*/lowerbound, /*upperbound=*/upperbound,
                 /*extent=*/extent, /*stride=*/stride, /*strideInBytes=*/false,
-                /*startIdx=*/lowerbound);
+                /*startIdx=*/one);
             accBounds.push_back(accBound);
           }
         }
diff --git a/flang/test/Fir/OpenACC/openacc-mappable.fir b/flang/test/Fir/OpenACC/openacc-mappable.fir
index 71576f4b71075..3535bfaae3c30 100644
--- a/flang/test/Fir/OpenACC/openacc-mappable.fir
+++ b/flang/test/Fir/OpenACC/openacc-mappable.fir
@@ -62,12 +62,12 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<f16 = dense<16> : vector<2xi64>,
   // CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> {name = "arr1", structured = false}
   // CHECK: Pointer-like and Mappable: !fir.ref<!fir.array<?xf32>>
   // CHECK: Type category: array
-  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
+  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c1{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
 
   // CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> {name = "arr2", structured = false}
   // CHECK: Pointer-like and Mappable: !fir.ref<!fir.array<?xf32>>
   // CHECK: Type category: array
-  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c2{{.*}} : index)
+  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c2{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
 
   // CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>> {name = "arr3", structured = false}
   // CHECK: Pointer-like and Mappable: !fir.ref<!fir.array<10xf32>>

>From 8e5f953aeaf9523e5998bb83c87c5abbb848d126 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Wed, 27 Aug 2025 14:29:57 -0700
Subject: [PATCH 2/3] Rework on the fix

---
 .../OpenACC/Support/FIROpenACCTypeInterfaces.cpp    | 10 +++++-----
 flang/test/Fir/OpenACC/openacc-mappable.fir         | 13 +++++++++++--
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
index 9b4db4900258b..c9aff592c95a3 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
@@ -243,6 +243,8 @@ generateSeqTyAccBounds(fir::SequenceType seqType, mlir::Value var,
               mlir::dyn_cast_if_present<fir::ShapeOp>(shape.getDefiningOp())) {
         mlir::Value cummulativeExtent = one;
         for (auto extent : shapeOp.getExtents()) {
+          mlir::Value upperbound =
+              mlir::arith::SubIOp::create(builder, loc, extent, one);
           mlir::Value stride = one;
           if (strideIncludeLowerExtent) {
             stride = cummulativeExtent;
@@ -252,7 +254,7 @@ generateSeqTyAccBounds(fir::SequenceType seqType, mlir::Value var,
           auto accBound = mlir::acc::DataBoundsOp::create(
               builder, loc,
               mlir::acc::DataBoundsType::get(builder.getContext()),
-              /*lowerbound=*/one, /*upperbound=*/extent,
+              /*lowerbound=*/zero, /*upperbound=*/upperbound,
               /*extent=*/extent, /*stride=*/stride, /*strideInBytes=*/false,
               /*startIdx=*/one);
           accBounds.push_back(accBound);
@@ -269,8 +271,6 @@ generateSeqTyAccBounds(fir::SequenceType seqType, mlir::Value var,
             mlir::Value extent = val;
             mlir::Value upperbound =
                 mlir::arith::SubIOp::create(builder, loc, extent, one);
-            upperbound = mlir::arith::AddIOp::create(builder, loc, lowerbound,
-                                                     upperbound);
             mlir::Value stride = one;
             if (strideIncludeLowerExtent) {
               stride = cummulativeExtent;
@@ -280,9 +280,9 @@ generateSeqTyAccBounds(fir::SequenceType seqType, mlir::Value var,
             auto accBound = mlir::acc::DataBoundsOp::create(
                 builder, loc,
                 mlir::acc::DataBoundsType::get(builder.getContext()),
-                /*lowerbound=*/lowerbound, /*upperbound=*/upperbound,
+                /*lowerbound=*/zero, /*upperbound=*/upperbound,
                 /*extent=*/extent, /*stride=*/stride, /*strideInBytes=*/false,
-                /*startIdx=*/one);
+                /*startIdx=*/lowerbound);
             accBounds.push_back(accBound);
           }
         }
diff --git a/flang/test/Fir/OpenACC/openacc-mappable.fir b/flang/test/Fir/OpenACC/openacc-mappable.fir
index 3535bfaae3c30..eefcb69a410d5 100644
--- a/flang/test/Fir/OpenACC/openacc-mappable.fir
+++ b/flang/test/Fir/OpenACC/openacc-mappable.fir
@@ -62,12 +62,12 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<f16 = dense<16> : vector<2xi64>,
   // CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> {name = "arr1", structured = false}
   // CHECK: Pointer-like and Mappable: !fir.ref<!fir.array<?xf32>>
   // CHECK: Type category: array
-  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c1{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
+  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
 
   // CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> {name = "arr2", structured = false}
   // CHECK: Pointer-like and Mappable: !fir.ref<!fir.array<?xf32>>
   // CHECK: Type category: array
-  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c2{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
+  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c2{{.*}} : index)
 
   // CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>> {name = "arr3", structured = false}
   // CHECK: Pointer-like and Mappable: !fir.ref<!fir.array<10xf32>>
@@ -75,4 +75,13 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<f16 = dense<16> : vector<2xi64>,
   // CHECK: Size: 40
   // CHECK: Offset: 0
   // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%c10{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
+
+  // CHECK: acc.copyin
+  // CHECK: acc.copyin
+  // CHECK: fir.shape_shift %c2, %[[EXTENT:.*]] : (index, index) -> !fir.shapeshift<1>
+  // CHECK: acc.copyin
+  // CHECK: %[[SUBI:.*]] = arith.subi %[[EXTENT]], %c1{{.*}} : index
+  // CHECK: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%[[SUBI]] : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c2{{.*}} : index)
+  // CHECK: acc.copyin
+  // CHECK: acc.copyin
 }

>From 811fafffe22d763523e6f23d58906b626f287223 Mon Sep 17 00:00:00 2001
From: Kazuaki Matsumura <kmatsumura at nvidia.com>
Date: Wed, 27 Aug 2025 19:16:16 -0700
Subject: [PATCH 3/3] Update TestOpenACCInterfaces.cpp to show shape,
 lowerbound, and upperbound

---
 flang/test/Fir/OpenACC/openacc-mappable.fir   | 24 +++++++++----------
 .../lib/OpenACC/TestOpenACCInterfaces.cpp     | 15 +++++++++++-
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/flang/test/Fir/OpenACC/openacc-mappable.fir b/flang/test/Fir/OpenACC/openacc-mappable.fir
index eefcb69a410d5..05df35a482907 100644
--- a/flang/test/Fir/OpenACC/openacc-mappable.fir
+++ b/flang/test/Fir/OpenACC/openacc-mappable.fir
@@ -62,26 +62,26 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<f16 = dense<16> : vector<2xi64>,
   // CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> {name = "arr1", structured = false}
   // CHECK: Pointer-like and Mappable: !fir.ref<!fir.array<?xf32>>
   // CHECK: Type category: array
-  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
+  // CHECK: Shape: %{{.*}} = fir.shape %[[EXTENT1:.*]] : (index) -> !fir.shape<1>
+  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%[[LB1:.*]] : index) upperbound(%[[UB1:.*]] : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
+  // CHECK: Lower bound: %[[LB1]] = arith.constant 0 : index
+  // CHECK: Upper bound: %[[UB1]] = arith.subi %[[EXTENT1]], %c1{{.*}} : index
 
   // CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>> {name = "arr2", structured = false}
   // CHECK: Pointer-like and Mappable: !fir.ref<!fir.array<?xf32>>
   // CHECK: Type category: array
-  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c2{{.*}} : index)
+  // CHECK: Shape: %{{.*}} = fir.shape_shift %c2{{.*}}, %[[EXTENT2:.*]] : (index, index) -> !fir.shapeshift<1>
+  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%[[LB2:.*]] : index) upperbound(%[[UB2:.*]] : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c2{{.*}} : index)
+  // CHECK: Lower bound: %[[LB2]] = arith.constant 0 : index
+  // CHECK: Upper bound: %[[UB2]] = arith.subi %[[EXTENT2]], %c1{{.*}} : index
 
   // CHECK: Visiting: %{{.*}} = acc.copyin varPtr(%{{.*}} : !fir.ref<!fir.array<10xf32>>) -> !fir.ref<!fir.array<10xf32>> {name = "arr3", structured = false}
   // CHECK: Pointer-like and Mappable: !fir.ref<!fir.array<10xf32>>
   // CHECK: Type category: array
   // CHECK: Size: 40
   // CHECK: Offset: 0
-  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%{{.*}} : index) extent(%c10{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
-
-  // CHECK: acc.copyin
-  // CHECK: acc.copyin
-  // CHECK: fir.shape_shift %c2, %[[EXTENT:.*]] : (index, index) -> !fir.shapeshift<1>
-  // CHECK: acc.copyin
-  // CHECK: %[[SUBI:.*]] = arith.subi %[[EXTENT]], %c1{{.*}} : index
-  // CHECK: %{{.*}} = acc.bounds lowerbound(%c0{{.*}} : index) upperbound(%[[SUBI]] : index) extent(%{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c2{{.*}} : index)
-  // CHECK: acc.copyin
-  // CHECK: acc.copyin
+  // CHECK: Shape: %{{.*}} = fir.shape %[[EXTENT3:.*]] : (index) -> !fir.shape<1>
+  // CHECK: Bound[0]: %{{.*}} = acc.bounds lowerbound(%[[LB3:.*]] : index) upperbound(%[[UB3:.*]] : index) extent(%c10{{.*}} : index) stride(%c1{{.*}} : index) startIdx(%c1{{.*}} : index)
+  // CHECK: Lower bound: %[[LB3]] = arith.constant 0 : index
+  // CHECK: Upper bound: %[[UB3]] = arith.subi %[[EXTENT3]], %c1{{.*}} : index
 }
diff --git a/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
index de6cb1d09080d..9a80e3b1a9aee 100644
--- a/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
+++ b/flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp
@@ -15,6 +15,7 @@
 #include "mlir/Support/LLVM.h"
 #include "flang/Optimizer/Dialect/FIRDialect.h"
 #include "flang/Optimizer/HLFIR/HLFIRDialect.h"
+#include "flang/Optimizer/HLFIR/HLFIROps.h"
 #include "flang/Optimizer/Support/DataLayout.h"
 
 using namespace mlir;
@@ -99,11 +100,23 @@ struct TestFIROpenACCInterfaces
             }
           }
 
+          if (auto declareOp =
+                  dyn_cast_if_present<hlfir::DeclareOp>(var.getDefiningOp())) {
+            llvm::errs() << "\t\tShape: " << declareOp.getShape() << "\n";
+          }
+
           builder.setInsertionPoint(op);
           auto bounds = mappableTy.generateAccBounds(acc::getVar(op), builder);
           if (!bounds.empty()) {
             for (auto [idx, bound] : llvm::enumerate(bounds)) {
-              llvm::errs() << "\t\tBound[" << idx << "]: " << bound << "\n";
+              if (auto boundOp = dyn_cast_if_present<acc::DataBoundsOp>(
+                      bound.getDefiningOp())) {
+                llvm::errs() << "\t\tBound[" << idx << "]: " << bound << "\n";
+                llvm::errs()
+                    << "\t\tLower bound: " << boundOp.getLowerbound() << "\n";
+                llvm::errs()
+                    << "\t\tUpper bound: " << boundOp.getUpperbound() << "\n";
+              }
             }
           }
         }



More information about the flang-commits mailing list