[flang-commits] [flang] 752bd78 - [flang][hlfir] Apply component lower bounds in hlfir.designate codegen

Jean Perier via flang-commits flang-commits at lists.llvm.org
Wed Apr 19 00:02:28 PDT 2023


Author: Jean Perier
Date: 2023-04-19T09:01:37+02:00
New Revision: 752bd78f06d7db1af98a9ae41668b084874d7081

URL: https://github.com/llvm/llvm-project/commit/752bd78f06d7db1af98a9ae41668b084874d7081
DIFF: https://github.com/llvm/llvm-project/commit/752bd78f06d7db1af98a9ae41668b084874d7081.diff

LOG: [flang][hlfir] Apply component lower bounds in hlfir.designate codegen

The array component indices in the "path" of a fir.slice are zero based
because FIR does not know about the component lower bounds.
When lowering hlfir.designate to FIR for `array%x(i, j)`, convert `i` and
`j` to zero based indices before generating the fir.slice.

Differential Revision: https://reviews.llvm.org/D148627

Added: 
    

Modified: 
    flang/include/flang/Optimizer/Builder/HLFIRTools.h
    flang/lib/Optimizer/Builder/HLFIRTools.cpp
    flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
    flang/test/HLFIR/designate-codegen-component-refs.fir

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
index 389f5ce1c3f25..d82999fdb7dd9 100644
--- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h
+++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
@@ -289,6 +289,12 @@ genBounds(mlir::Location loc, fir::FirOpBuilder &builder, Entity entity);
 llvm::SmallVector<std::pair<mlir::Value, mlir::Value>>
 genBounds(mlir::Location loc, fir::FirOpBuilder &builder, mlir::Value shape);
 
+/// Generate lower bounds from a shape. If \p shape is null or is a fir.shape,
+/// the returned vector will contain \p rank ones.
+llvm::SmallVector<mlir::Value> genLowerbounds(mlir::Location loc,
+                                              fir::FirOpBuilder &builder,
+                                              mlir::Value shape, unsigned rank);
+
 /// Compute fir.shape<> (no lower bounds) for an entity.
 mlir::Value genShape(mlir::Location loc, fir::FirOpBuilder &builder,
                      Entity entity);

diff  --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index 4603c6d0e256d..9b9174eea80ae 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -409,6 +409,20 @@ hlfir::genBounds(mlir::Location loc, fir::FirOpBuilder &builder,
   return result;
 }
 
+llvm::SmallVector<mlir::Value> hlfir::genLowerbounds(mlir::Location loc,
+                                                     fir::FirOpBuilder &builder,
+                                                     mlir::Value shape,
+                                                     unsigned rank) {
+  llvm::SmallVector<mlir::Value> lbounds;
+  if (shape)
+    lbounds = getExplicitLboundsFromShape(shape);
+  if (!lbounds.empty())
+    return lbounds;
+  mlir::Value one =
+      builder.createIntegerConstant(loc, builder.getIndexType(), 1);
+  return llvm::SmallVector<mlir::Value>(rank, one);
+}
+
 static hlfir::Entity followShapeInducingSource(hlfir::Entity entity) {
   while (true) {
     if (auto reassoc = entity.getDefiningOp<hlfir::NoReassocOp>()) {

diff  --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
index fbf0a4f962d4e..de4ec72776436 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -429,8 +429,19 @@ class DesignateOpConversion
         triples = genFullSliceTriples(builder, loc, baseEntity);
         sliceFields.push_back(fieldIndex);
         // Add indices in the field path for "array%array_comp(indices)"
-        // case.
-        sliceFields.append(subscripts.begin(), subscripts.end());
+        // case. The indices of components provided to the sliceOp must
+        // be zero based (fir.slice has no knowledge of the component
+        // lower bounds). The component lower bounds are applied here.
+        if (!subscripts.empty()) {
+          llvm::SmallVector<mlir::Value> lbounds = hlfir::genLowerbounds(
+              loc, builder, designate.getComponentShape(), subscripts.size());
+          for (auto [i, lb] : llvm::zip(subscripts, lbounds)) {
+            mlir::Value iIdx = builder.createConvert(loc, idxTy, i);
+            mlir::Value lbIdx = builder.createConvert(loc, idxTy, lb);
+            sliceFields.emplace_back(
+                builder.create<mlir::arith::SubIOp>(loc, iIdx, lbIdx));
+          }
+        }
       } else {
         // Otherwise, this is an array section with triplets.
         auto undef = builder.create<fir::UndefOp>(loc, idxTy);

diff  --git a/flang/test/HLFIR/designate-codegen-component-refs.fir b/flang/test/HLFIR/designate-codegen-component-refs.fir
index 9f221bd8df2ac..3165bd59ea46c 100644
--- a/flang/test/HLFIR/designate-codegen-component-refs.fir
+++ b/flang/test/HLFIR/designate-codegen-component-refs.fir
@@ -126,9 +126,47 @@ func.func @test_array_array_comp_1(%arg0: !fir.ref<!fir.array<100x!fir.type<t_ar
 // CHECK:  %[[VAL_9:.*]] = fir.field_index array_comp, !fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>
 // CHECK:  %[[VAL_10:.*]] = arith.constant 1 : index
 // CHECK:  %[[VAL_11:.*]] = arith.constant 1 : index
-// CHECK:  %[[VAL_12:.*]] = fir.slice %[[VAL_11]], %[[VAL_1]], %[[VAL_10]] path %[[VAL_9]], %[[VAL_7]], %[[VAL_8]] : (index, index, index, !fir.field, index, index) -> !fir.slice<1>
+// CHECK:  %[[ANOTHER_ONE:.*]] = arith.constant 1 : index
+// CHECK:  %[[VAL_7B:.*]] = arith.subi %[[VAL_7]], %[[ANOTHER_ONE]] : index
+// CHECK:  %[[VAL_8B:.*]] = arith.subi %[[VAL_8]], %[[ANOTHER_ONE]] : index
+// CHECK:  %[[VAL_12:.*]] = fir.slice %[[VAL_11]], %[[VAL_1]], %[[VAL_10]] path %[[VAL_9]], %[[VAL_7B]], %[[VAL_8B]] : (index, index, index, !fir.field, index, index) -> !fir.slice<1>
 // CHECK:  %[[VAL_13:.*]] = fir.embox %[[VAL_3]](%[[VAL_2]]) {{\[}}%[[VAL_12]]] : (!fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<100xf32>>
 
+
+func.func @test_array_array_comp_1_with_lbs(%arg0: !fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>) {
+  %c100 = arith.constant 100 : index
+  %0 = fir.shape %c100 : (index) -> !fir.shape<1>
+  %1:2 = hlfir.declare %arg0(%0) {uniq_name = "a"} : (!fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>, !fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>)
+  %c10 = arith.constant 10 : index
+  %c20 = arith.constant 20 : index
+  %c42 = arith.constant 42 : index
+  %c43 = arith.constant 43 : index
+  %5 = fir.shape_shift %c42, %c10, %c43, %c20 : (index, index, index, index) -> !fir.shapeshift<2>
+  %c45 = arith.constant 45 : index
+  %c47 = arith.constant 47 : index
+  %6 = hlfir.designate %1#0{"array_comp"} <%5> (%c45, %c47)  shape %0 : (!fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>, !fir.shapeshift<2>, index, index, !fir.shape<1>) -> !fir.box<!fir.array<100xf32>>
+  return
+}
+// CHECK-LABEL:   func.func @test_array_array_comp_1_with_lbs(
+// CHECK:           %[[VAL_1:.*]] = arith.constant 100 : index
+// CHECK:           %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
+// CHECK:           %[[VAL_3:.*]] = fir.declare %{{.*}}(%[[VAL_2]]) {uniq_name = "a"} : (!fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>
+// CHECK:           %[[VAL_4:.*]] = arith.constant 10 : index
+// CHECK:           %[[VAL_5:.*]] = arith.constant 20 : index
+// CHECK:           %[[VAL_6:.*]] = arith.constant 42 : index
+// CHECK:           %[[VAL_7:.*]] = arith.constant 43 : index
+// CHECK:           %[[VAL_8:.*]] = fir.shape_shift %[[VAL_6]], %[[VAL_4]], %[[VAL_7]], %[[VAL_5]] : (index, index, index, index) -> !fir.shapeshift<2>
+// CHECK:           %[[VAL_9:.*]] = arith.constant 45 : index
+// CHECK:           %[[VAL_10:.*]] = arith.constant 47 : index
+// CHECK:           %[[VAL_11:.*]] = fir.field_index array_comp, !fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>
+// CHECK:           %[[VAL_12:.*]] = arith.constant 1 : index
+// CHECK:           %[[VAL_13:.*]] = arith.constant 1 : index
+// CHECK:           %[[VAL_14:.*]] = arith.subi %[[VAL_9]], %[[VAL_6]] : index
+// CHECK:           %[[VAL_15:.*]] = arith.subi %[[VAL_10]], %[[VAL_7]] : index
+// CHECK:           %[[VAL_16:.*]] = fir.slice %[[VAL_13]], %[[VAL_1]], %[[VAL_12]] path %[[VAL_11]], %[[VAL_14]], %[[VAL_15]] : (index, index, index, !fir.field, index, index) -> !fir.slice<1>
+// CHECK:           %[[VAL_17:.*]] = fir.embox %[[VAL_3]](%[[VAL_2]]) {{\[}}%[[VAL_16]]] : (!fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<100xf32>>
+
+
 func.func @test_array_comp_slice(%arg0: !fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>) {
   %0:2 = hlfir.declare %arg0 {uniq_name = "ga"} : (!fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>) -> (!fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>, !fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>)
   %c10 = arith.constant 10 : index


        


More information about the flang-commits mailing list