[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