Skip to content

Commit c79a88e

Browse files
authored
[flang] Convert hlfir.designate with comp and contiguous result. (llvm#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.
1 parent 5abad32 commit c79a88e

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -490,15 +490,18 @@ class DesignateOpConversion
490490
}
491491
baseEleTy = hlfir::getFortranElementType(componentType);
492492
shape = designate.getComponentShape();
493-
} else {
494-
// array%component[(indices) substring|complex part] cases.
495-
// Component ref of array bases are dealt with below in embox/rebox.
496-
assert(mlir::isa<fir::BaseBoxType>(designateResultType));
497493
}
498494
}
499495

500-
if (mlir::isa<fir::BaseBoxType>(designateResultType)) {
501-
// Generate embox or rebox.
496+
if (mlir::isa<fir::BaseBoxType>(designateResultType) ||
497+
// Convert the component array slices using embox/rebox
498+
// even if the result is a contiguous array section, e.g.:
499+
// hlfir.designate %base{"i"} shape %shape :
500+
// (!fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>>,
501+
// !fir.shape<1>) -> !fir.ref<!fir.array<2xi32>>
502+
// fir.coordinate_of should probably be a better option, though.
503+
(fieldIndex && baseEntity.isArray())) {
504+
// Generate embox or rebox for slicing.
502505
mlir::Type eleTy = fir::unwrapPassByRefType(designateResultType);
503506
bool isScalarDesignator = !mlir::isa<fir::SequenceType>(eleTy);
504507
mlir::Value sourceBox;
@@ -575,8 +578,13 @@ class DesignateOpConversion
575578
else
576579
assert(sliceFields.empty() && substring.empty());
577580

578-
llvm::SmallVector<mlir::Type> resultType{
579-
fir::updateTypeWithVolatility(designateResultType, isVolatile)};
581+
// If the designate's result type is not a box, then create
582+
// a box type to be used for the result of the embox/rebox.
583+
mlir::Type resultType = designateResultType;
584+
if (!mlir::isa<fir::BaseBoxType>(resultType))
585+
resultType = fir::wrapInClassOrBoxType(resultType);
586+
587+
resultType = fir::updateTypeWithVolatility(resultType, isVolatile);
580588

581589
mlir::Value resultBox;
582590
if (mlir::isa<fir::BaseBoxType>(base.getType())) {
@@ -587,6 +595,13 @@ class DesignateOpConversion
587595
fir::EmboxOp::create(builder, loc, resultType, base, shape, slice,
588596
firBaseTypeParameters, sourceBox);
589597
}
598+
599+
if (!mlir::isa<fir::BaseBoxType>(designateResultType)) {
600+
// If the designate's result is not a box, use the raw address
601+
// as the new result.
602+
resultBox = fir::BoxAddrOp::create(rewriter, loc, resultBox);
603+
resultBox = builder.createConvert(loc, designateResultType, resultBox);
604+
}
590605
rewriter.replaceOp(designate, resultBox);
591606
return mlir::success();
592607
}

flang/test/HLFIR/designate-codegen-component-refs.fir

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,33 @@ func.func @test_array_comp_non_contiguous_slice(%arg0: !fir.ref<!fir.type<t_arra
220220
// CHECK: %[[VAL_12:.*]] = fir.undefined index
221221
// 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>
222222
// 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>>
223+
224+
func.func @test_array_comp_slice_contiguous(%arg0: !fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>, volatile>) {
225+
%c2 = arith.constant 2 : index
226+
%c0_i32 = arith.constant 0 : i32
227+
%4 = fir.shape %c2 : (index) -> !fir.shape<1>
228+
%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>
229+
hlfir.assign %c0_i32 to %5 : i32, !fir.ref<!fir.array<2xi32>, volatile>
230+
return
231+
}
232+
// CHECK-LABEL: func.func @test_array_comp_slice_contiguous(
233+
// CHECK-SAME: %[[ARG0:.*]]: !fir.box<!fir.array<2x!fir.type<_QMtypesTt{i:i32}>>, volatile>) {
234+
// CHECK: %[[VAL_0:.*]] = fir.alloca !fir.box<!fir.array<2xi32>, volatile>
235+
// CHECK: %[[VAL_1:.*]] = arith.constant 2 : index
236+
// CHECK: %[[VAL_2:.*]] = arith.constant 0 : i32
237+
// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
238+
// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
239+
// 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)
240+
// CHECK: %[[VAL_6:.*]] = fir.shift %[[VAL_5]]#0 : (index) -> !fir.shift<1>
241+
// CHECK: %[[VAL_7:.*]] = fir.field_index i, !fir.type<_QMtypesTt{i:i32}>
242+
// CHECK: %[[VAL_8:.*]] = arith.constant 1 : index
243+
// CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
244+
// 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)
245+
// CHECK: %[[VAL_11:.*]] = arith.constant 1 : index
246+
// CHECK: %[[VAL_12:.*]] = arith.constant 0 : index
247+
// 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)
248+
// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_10]]#0, %[[VAL_13]]#1 : index
249+
// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_14]], %[[VAL_11]] : index
250+
// CHECK: %[[VAL_16:.*]] = fir.slice %[[VAL_10]]#0, %[[VAL_15]], %[[VAL_8]] path %[[VAL_7]] : (index, index, index, !fir.field) -> !fir.slice<1>
251+
// 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>
252+
// CHECK: %[[VAL_18:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box<!fir.ref<!fir.array<2xi32>, volatile>, volatile>) -> !fir.ref<!fir.array<2xi32>, volatile>

0 commit comments

Comments
 (0)