[flang-commits] [flang] c79a88e - [flang] Convert hlfir.designate with comp and contiguous result. (#154232)
via flang-commits
flang-commits at lists.llvm.org
Tue Aug 19 08:35:43 PDT 2025
Author: Slava Zakharin
Date: 2025-08-19T08:35:40-07:00
New Revision: c79a88ee0a170d10f860dea84c6216468e6a4acb
URL: https://github.com/llvm/llvm-project/commit/c79a88ee0a170d10f860dea84c6216468e6a4acb
DIFF: https://github.com/llvm/llvm-project/commit/c79a88ee0a170d10f860dea84c6216468e6a4acb.diff
LOG: [flang] Convert hlfir.designate with comp and contiguous result. (#154232)
Array sections like this have not been using the knowledge that
the result is contiguous:
```
type t
integer :: f
end type
type(t) :: a(:)
a%f = 0
```
Peter Klausler is working on a change that will result in the
corresponding
hlfir.designate having a component and a non-box result.
This patch fixes the issues found in HLFIR-to-FIR conversion.
Added:
Modified:
flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
flang/test/HLFIR/designate-codegen-component-refs.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
index 2e273243eeb2e..4e7de4732357d 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -490,15 +490,18 @@ class DesignateOpConversion
}
baseEleTy = hlfir::getFortranElementType(componentType);
shape = designate.getComponentShape();
- } else {
- // array%component[(indices) substring|complex part] cases.
- // Component ref of array bases are dealt with below in embox/rebox.
- assert(mlir::isa<fir::BaseBoxType>(designateResultType));
}
}
- if (mlir::isa<fir::BaseBoxType>(designateResultType)) {
- // Generate embox or rebox.
+ if (mlir::isa<fir::BaseBoxType>(designateResultType) ||
+ // Convert the component array slices using embox/rebox
+ // even if the result is a contiguous array section, e.g.:
+ // hlfir.designate %base{"i"} shape %shape :
+ // (!fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>>,
+ // !fir.shape<1>) -> !fir.ref<!fir.array<2xi32>>
+ // fir.coordinate_of should probably be a better option, though.
+ (fieldIndex && baseEntity.isArray())) {
+ // Generate embox or rebox for slicing.
mlir::Type eleTy = fir::unwrapPassByRefType(designateResultType);
bool isScalarDesignator = !mlir::isa<fir::SequenceType>(eleTy);
mlir::Value sourceBox;
@@ -575,8 +578,13 @@ class DesignateOpConversion
else
assert(sliceFields.empty() && substring.empty());
- llvm::SmallVector<mlir::Type> resultType{
- fir::updateTypeWithVolatility(designateResultType, isVolatile)};
+ // If the designate's result type is not a box, then create
+ // a box type to be used for the result of the embox/rebox.
+ mlir::Type resultType = designateResultType;
+ if (!mlir::isa<fir::BaseBoxType>(resultType))
+ resultType = fir::wrapInClassOrBoxType(resultType);
+
+ resultType = fir::updateTypeWithVolatility(resultType, isVolatile);
mlir::Value resultBox;
if (mlir::isa<fir::BaseBoxType>(base.getType())) {
@@ -587,6 +595,13 @@ class DesignateOpConversion
fir::EmboxOp::create(builder, loc, resultType, base, shape, slice,
firBaseTypeParameters, sourceBox);
}
+
+ if (!mlir::isa<fir::BaseBoxType>(designateResultType)) {
+ // If the designate's result is not a box, use the raw address
+ // as the new result.
+ resultBox = fir::BoxAddrOp::create(rewriter, loc, resultBox);
+ resultBox = builder.createConvert(loc, designateResultType, resultBox);
+ }
rewriter.replaceOp(designate, resultBox);
return mlir::success();
}
diff --git a/flang/test/HLFIR/designate-codegen-component-refs.fir b/flang/test/HLFIR/designate-codegen-component-refs.fir
index 278a7be0e2da1..5d90e325fdf98 100644
--- a/flang/test/HLFIR/designate-codegen-component-refs.fir
+++ b/flang/test/HLFIR/designate-codegen-component-refs.fir
@@ -220,3 +220,33 @@ func.func @test_array_comp_non_contiguous_slice(%arg0: !fir.ref<!fir.type<t_arra
// CHECK: %[[VAL_12:.*]] = fir.undefined index
// CHECK: %[[VAL_13:.*]] = fir.slice %[[VAL_5]], %[[VAL_6]], %[[VAL_5]], %[[VAL_7]], %[[VAL_3]], %[[VAL_5]] : (index, index, index, index, index, index) -> !fir.slice<2>
// CHECK: %[[VAL_14:.*]] = fir.embox %[[VAL_11]](%[[VAL_4]]) {{\[}}%[[VAL_13]]] : (!fir.ref<!fir.array<10x20xf32>>, !fir.shape<2>, !fir.slice<2>) -> !fir.box<!fir.array<6x17xf32>>
+
+func.func @test_array_comp_slice_contiguous(%arg0: !fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>, volatile>) {
+ %c2 = arith.constant 2 : index
+ %c0_i32 = arith.constant 0 : i32
+ %4 = fir.shape %c2 : (index) -> !fir.shape<1>
+ %5 = hlfir.designate %arg0{"i"} shape %4 : (!fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>, volatile>, !fir.shape<1>) -> !fir.ref<!fir.array<2xi32>, volatile>
+ hlfir.assign %c0_i32 to %5 : i32, !fir.ref<!fir.array<2xi32>, volatile>
+ return
+}
+// CHECK-LABEL: func.func @test_array_comp_slice_contiguous(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>, volatile>) {
+// CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box<!fir.array<2xi32>, volatile>
+// CHECK: %[[VAL_1:.*]] = arith.constant 2 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32
+// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_4]] : (!fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>, volatile>, index) -> (index, index, index)
+// CHECK: %[[VAL_6:.*]] = fir.shift %[[VAL_5]]#0 : (index) -> !fir.shift<1>
+// CHECK: %[[VAL_7:.*]] = fir.field_index i, !fir.type<_QMtypesTt{i:i32}>
+// CHECK: %[[VAL_8:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_9]] : (!fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>, volatile>, index) -> (index, index, index)
+// CHECK: %[[VAL_11:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_12:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[ARG0]], %[[VAL_12]] : (!fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>, volatile>, index) -> (index, index, index)
+// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_10]]#0, %[[VAL_13]]#1 : index
+// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_14]], %[[VAL_11]] : index
+// CHECK: %[[VAL_16:.*]] = fir.slice %[[VAL_10]]#0, %[[VAL_15]], %[[VAL_8]] path %[[VAL_7]] : (index, index, index, !fir.field) -> !fir.slice<1>
+// CHECK: %[[VAL_17:.*]] = fir.rebox %[[ARG0]](%[[VAL_6]]) {{\[}}%[[VAL_16]]] : (!fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>, volatile>, !fir.shift<1>, !fir.slice<1>) -> !fir.box<!fir.ref<!fir.array<2xi32>, volatile>, volatile>
+// CHECK: %[[VAL_18:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box<!fir.ref<!fir.array<2xi32>, volatile>, volatile>) -> !fir.ref<!fir.array<2xi32>, volatile>
More information about the flang-commits
mailing list