[flang-commits] [flang] 5459269 - [flang] Implement codegen of hlfir.designate with component refs
Jean Perier via flang-commits
flang-commits at lists.llvm.org
Fri Jan 13 02:06:34 PST 2023
Author: Jean Perier
Date: 2023-01-13T11:05:25+01:00
New Revision: 54592694eb505a529fb61741ea2cb4eb45e7da4b
URL: https://github.com/llvm/llvm-project/commit/54592694eb505a529fb61741ea2cb4eb45e7da4b
DIFF: https://github.com/llvm/llvm-project/commit/54592694eb505a529fb61741ea2cb4eb45e7da4b.diff
LOG: [flang] Implement codegen of hlfir.designate with component refs
Lower all the different kinds of hlfir.designate component refs to
FIR.
Differential Revision: https://reviews.llvm.org/D141476
Added:
flang/test/HLFIR/designate-codegen-component-refs.fir
Modified:
flang/lib/Optimizer/Builder/HLFIRTools.cpp
flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
flang/test/HLFIR/designate-codegen.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index 17bf90fff08bd..cc2b46c00c210 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -494,6 +494,22 @@ mlir::Value hlfir::genCharLength(mlir::Location loc, fir::FirOpBuilder &builder,
return lenParams[0];
}
+// Return a "shape" that can be used in fir.embox/fir.rebox with \p exv base.
+static mlir::Value asEmboxShape(mlir::Location loc, fir::FirOpBuilder &builder,
+ const fir::ExtendedValue &exv,
+ mlir::Value shape) {
+ if (!shape)
+ return shape;
+ // fir.rebox does not need and does not accept extents (fir.shape or
+ // fir.shape_shift) since this information is already in the input fir.box,
+ // it only accepts fir.shift because local lower bounds may not be reflected
+ // in the fir.box.
+ if (fir::getBase(exv).getType().isa<fir::BaseBoxType>() &&
+ !shape.getType().isa<fir::ShiftType>())
+ return builder.createShape(loc, exv);
+ return shape;
+}
+
std::pair<mlir::Value, mlir::Value> hlfir::genVariableFirBaseShapeAndParams(
mlir::Location loc, fir::FirOpBuilder &builder, Entity entity,
llvm::SmallVectorImpl<mlir::Value> &typeParams) {
@@ -506,7 +522,8 @@ std::pair<mlir::Value, mlir::Value> hlfir::genVariableFirBaseShapeAndParams(
if (entity.isScalar())
return {fir::getBase(exv), mlir::Value{}};
if (auto variableInterface = entity.getIfVariableInterface())
- return {fir::getBase(exv), variableInterface.getShape()};
+ return {fir::getBase(exv),
+ asEmboxShape(loc, builder, exv, variableInterface.getShape())};
return {fir::getBase(exv), builder.createShape(loc, exv)};
}
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
index 561f3e3c07b6d..c426cddbd135e 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -184,10 +184,11 @@ class DesignateOpConversion
auto module = designate->getParentOfType<mlir::ModuleOp>();
fir::FirOpBuilder builder(rewriter, fir::getKindMapping(module));
- if (designate.getComponent() || designate.getComplexPart())
- TODO(loc, "hlfir::designate with complex part or component");
+ if (designate.getComplexPart())
+ TODO(loc, "hlfir::designate with complex part");
hlfir::Entity baseEntity(designate.getMemref());
+
if (baseEntity.isMutableBox())
TODO(loc, "hlfir::designate load of pointer or allocatable");
@@ -195,23 +196,73 @@ class DesignateOpConversion
llvm::SmallVector<mlir::Value> firBaseTypeParameters;
auto [base, shape] = hlfir::genVariableFirBaseShapeAndParams(
loc, builder, baseEntity, firBaseTypeParameters);
- if (designateResultType.isa<fir::BoxType>()) {
+ mlir::Type baseEleTy = hlfir::getFortranElementType(base.getType());
+
+ mlir::Value fieldIndex;
+ if (designate.getComponent()) {
+ mlir::Type baseRecordType = baseEntity.getFortranElementType();
+ if (fir::isRecordWithTypeParameters(baseRecordType))
+ TODO(loc, "hlfir.designate with a parametrized derived type base");
+ fieldIndex = builder.create<fir::FieldIndexOp>(
+ loc, fir::FieldType::get(builder.getContext()),
+ designate.getComponent().value(), baseRecordType,
+ /*typeParams=*/mlir::ValueRange{});
+ if (baseEntity.isScalar()) {
+ // Component refs of scalar base right away:
+ // - scalar%scalar_component [substring|complex_part] or
+ // - scalar%static_size_array_comp
+ // - scalar%array(indices) [substring| complex part]
+ mlir::Type componentType = baseEleTy.cast<fir::RecordType>().getType(
+ designate.getComponent().value());
+ if (componentType.isa<fir::BaseBoxType>())
+ TODO(loc,
+ "addressing parametrized derived type automatic components");
+ mlir::Type coorTy = fir::ReferenceType::get(componentType);
+ base = builder.create<fir::CoordinateOp>(loc, coorTy, base, fieldIndex);
+ 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(designateResultType.isa<fir::BaseBoxType>());
+ }
+ }
+
+ if (designateResultType.isa<fir::BaseBoxType>()) {
// Generate embox or rebox.
- if (designate.getIndices().empty())
- TODO(loc, "hlfir::designate whole part");
- // Otherwise, this is an array section with triplets.
+ if (!fir::unwrapPassByRefType(designateResultType)
+ .isa<fir::SequenceType>())
+ TODO(loc, "addressing polymorphic arrays");
llvm::SmallVector<mlir::Value> triples;
- auto undef = builder.create<fir::UndefOp>(loc, builder.getIndexType());
+ llvm::SmallVector<mlir::Value> sliceFields;
+ mlir::Type idxTy = builder.getIndexType();
auto subscripts = designate.getIndices();
- unsigned i = 0;
- for (auto isTriplet : designate.getIsTriplet()) {
- triples.push_back(subscripts[i++]);
- if (isTriplet) {
- triples.push_back(subscripts[i++]);
+ if (fieldIndex && baseEntity.isArray()) {
+ // array%scalar_comp or array%array_comp(indices)
+ // Generate triples for array(:, :, ...).
+ auto one = builder.createIntegerConstant(loc, idxTy, 1);
+ for (auto [lb, ub] : hlfir::genBounds(loc, builder, baseEntity)) {
+ triples.push_back(builder.createConvert(loc, idxTy, lb));
+ triples.push_back(builder.createConvert(loc, idxTy, ub));
+ triples.push_back(one);
+ }
+ sliceFields.push_back(fieldIndex);
+ // Add indices in the field path for "array%array_comp(indices)"
+ // case.
+ sliceFields.append(subscripts.begin(), subscripts.end());
+ } else {
+ // Otherwise, this is an array section with triplets.
+ auto undef = builder.create<fir::UndefOp>(loc, idxTy);
+ unsigned i = 0;
+ for (auto isTriplet : designate.getIsTriplet()) {
triples.push_back(subscripts[i++]);
- } else {
- triples.push_back(undef);
- triples.push_back(undef);
+ if (isTriplet) {
+ triples.push_back(subscripts[i++]);
+ triples.push_back(subscripts[i++]);
+ } else {
+ triples.push_back(undef);
+ triples.push_back(undef);
+ }
}
}
llvm::SmallVector<mlir::Value, 2> substring;
@@ -226,11 +277,15 @@ class DesignateOpConversion
substring.push_back(designate.getTypeparams()[0]);
}
- mlir::Value slice = builder.create<fir::SliceOp>(
- loc, triples, /*fields=*/mlir::ValueRange{}, substring);
+ mlir::Value slice;
+ if (!triples.empty())
+ slice =
+ builder.create<fir::SliceOp>(loc, triples, sliceFields, substring);
+ else
+ assert(sliceFields.empty() && substring.empty());
llvm::SmallVector<mlir::Type> resultType{designateResultType};
mlir::Value resultBox;
- if (base.getType().isa<fir::BoxType>())
+ if (base.getType().isa<fir::BaseBoxType>())
resultBox =
builder.create<fir::ReboxOp>(loc, resultType, base, shape, slice);
else
@@ -240,23 +295,36 @@ class DesignateOpConversion
return mlir::success();
}
- // Otherwise, the result is the address of a scalar. The base may be an
- // array, or a scalar.
+ // Otherwise, the result is the address of a scalar, or the address of the
+ // first element of a contiguous array section with compile time constant
+ // shape. The base may be an array, or a scalar.
mlir::Type resultAddressType = designateResultType;
if (auto boxCharType = designateResultType.dyn_cast<fir::BoxCharType>())
resultAddressType = fir::ReferenceType::get(boxCharType.getEleTy());
// Array element indexing.
if (!designate.getIndices().empty()) {
- auto eleTy = hlfir::getFortranElementType(base.getType());
- auto arrayCoorType = fir::ReferenceType::get(eleTy);
- base = builder.create<fir::ArrayCoorOp>(loc, arrayCoorType, base, shape,
- /*slice=*/mlir::Value{},
- designate.getIndices(),
- firBaseTypeParameters);
+ // - array(indices) [substring|complex_part] or
+ // - scalar%array_comp(indices) [substring|complex_part]
+ // This may be a ranked contiguous array section in which case
+ // The first element address is being computed.
+ llvm::SmallVector<mlir::Value> firstElementIndices;
+ auto indices = designate.getIndices();
+ int i = 0;
+ for (auto isTriplet : designate.getIsTripletAttr().asArrayRef()) {
+ // Coordinate of the first element are the index and triplets lower
+ // bounds
+ firstElementIndices.push_back(indices[i]);
+ i = i + (isTriplet ? 3 : 1);
+ }
+ mlir::Type arrayCoorType = fir::ReferenceType::get(baseEleTy);
+ base = builder.create<fir::ArrayCoorOp>(
+ loc, arrayCoorType, base, shape,
+ /*slice=*/mlir::Value{}, firstElementIndices, firBaseTypeParameters);
}
- // Scalar substring (potentially on the previously built array element).
+ // Scalar substring (potentially on the previously built array element or
+ // component reference).
if (!designate.getSubstring().empty())
base = fir::factory::CharacterExprHelper{builder, loc}.genSubstringBase(
base, designate.getSubstring()[0], resultAddressType);
diff --git a/flang/test/HLFIR/designate-codegen-component-refs.fir b/flang/test/HLFIR/designate-codegen-component-refs.fir
new file mode 100644
index 0000000000000..9f221bd8df2ac
--- /dev/null
+++ b/flang/test/HLFIR/designate-codegen-component-refs.fir
@@ -0,0 +1,188 @@
+// Test code generation to FIR of hlfir.designate operations
+// with component reference.
+// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s
+
+func.func @test_scalar(%arg0: !fir.ref<!fir.type<t1{scalar_i:i32,scalar_x:f32}>>) {
+ %0:2 = hlfir.declare %arg0 {uniq_name = "a"} : (!fir.ref<!fir.type<t1{scalar_i:i32,scalar_x:f32}>>) -> (!fir.ref<!fir.type<t1{scalar_i:i32,scalar_x:f32}>>, !fir.ref<!fir.type<t1{scalar_i:i32,scalar_x:f32}>>)
+ %1 = hlfir.designate %0#0{"scalar_x"} : (!fir.ref<!fir.type<t1{scalar_i:i32,scalar_x:f32}>>) -> !fir.ref<f32>
+ return
+}
+// CHECK-LABEL: func.func @test_scalar(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<t1{scalar_i:i32,scalar_x:f32}>>) {
+// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "a"}
+// CHECK: %[[VAL_2:.*]] = fir.field_index scalar_x, !fir.type<t1{scalar_i:i32,scalar_x:f32}>
+// CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_2]] : (!fir.ref<!fir.type<t1{scalar_i:i32,scalar_x:f32}>>, !fir.field) -> !fir.ref<f32>
+
+func.func @test_array_char_comp_1(%arg0: !fir.ref<!fir.type<t_array_char{scalar_i:i32,array_char_comp:!fir.array<10x20x!fir.char<1,5>>}>>) {
+ %0:2 = hlfir.declare %arg0 {uniq_name = "a"} : (!fir.ref<!fir.type<t_array_char{scalar_i:i32,array_char_comp:!fir.array<10x20x!fir.char<1,5>>}>>) -> (!fir.ref<!fir.type<t_array_char{scalar_i:i32,array_char_comp:!fir.array<10x20x!fir.char<1,5>>}>>, !fir.ref<!fir.type<t_array_char{scalar_i:i32,array_char_comp:!fir.array<10x20x!fir.char<1,5>>}>>)
+ %c10 = arith.constant 10 : index
+ %c20 = arith.constant 20 : index
+ %1 = fir.shape %c10, %c20 : (index, index) -> !fir.shape<2>
+ %c5 = arith.constant 5 : index
+ %2 = hlfir.designate %0#0{"array_char_comp"} shape %1 typeparams %c5 : (!fir.ref<!fir.type<t_array_char{scalar_i:i32,array_char_comp:!fir.array<10x20x!fir.char<1,5>>}>>, !fir.shape<2>, index) -> !fir.ref<!fir.array<10x20x!fir.char<1,5>>>
+ return
+}
+// CHECK-LABEL: func.func @test_array_char_comp_1(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<t_array_char{scalar_i:i32,array_char_comp:!fir.array<10x20x!fir.char<1,5>>}>>) {
+// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "a"}
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 20 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_2]], %[[VAL_3]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_5:.*]] = arith.constant 5 : index
+// CHECK: %[[VAL_6:.*]] = fir.field_index array_char_comp, !fir.type<t_array_char{scalar_i:i32,array_char_comp:!fir.array<10x20x!fir.char<1,5>>}>
+// CHECK: %[[VAL_7:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_6]] : (!fir.ref<!fir.type<t_array_char{scalar_i:i32,array_char_comp:!fir.array<10x20x!fir.char<1,5>>}>>, !fir.field) -> !fir.ref<!fir.array<10x20x!fir.char<1,5>>>
+
+func.func @test_array(%arg0: !fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>) {
+ %0:2 = hlfir.declare %arg0 {uniq_name = "a"} : (!fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>) -> (!fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>, !fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>)
+ %c0 = arith.constant 0 : index
+ %4:3 = fir.box_dims %0#0, %c0 : (!fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>, index) -> (index, index, index)
+ %5 = fir.shape %4#1 : (index) -> !fir.shape<1>
+ %6 = hlfir.designate %0#0{"scalar_x"} shape %5 : (!fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+ return
+}
+// CHECK-LABEL: func.func @test_array(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>) {
+// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "a"}
+// CHECK: %[[VAL_2:.*]] = fir.rebox %[[VAL_1]] : (!fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>) -> !fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>
+// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_3]] : (!fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]]#1 : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_6:.*]] = fir.field_index scalar_x, !fir.type<t1{scalar_i:i32,scalar_x:f32}>
+// CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_8:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_9:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_9]] : (!fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_11:.*]] = fir.slice %[[VAL_8]], %[[VAL_10]]#1, %[[VAL_7]] path %[[VAL_6]] : (index, index, index, !fir.field) -> !fir.slice<1>
+// CHECK: %[[VAL_12:.*]] = fir.rebox %[[VAL_1]] {{\[}}%[[VAL_11]]] : (!fir.box<!fir.array<?x!fir.type<t1{scalar_i:i32,scalar_x:f32}>>>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
+
+func.func @test_array_char(%arg0: !fir.ref<!fir.array<?x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, %n : index) {
+ %5 = fir.shape %n : (index) -> !fir.shape<1>
+ %6:2 = hlfir.declare %arg0(%5) {uniq_name = "a"} : (!fir.ref<!fir.array<?x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, !fir.shape<1>) -> (!fir.box<!fir.array<?x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, !fir.ref<!fir.array<?x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>)
+ %c5 = arith.constant 5 : index
+ %10 = hlfir.designate %6#0{"scalar_char"} shape %5 typeparams %c5 : (!fir.box<!fir.array<?x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
+ return
+}
+// CHECK-LABEL: func.func @test_array_char(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<?x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>,
+// CHECK-SAME: %[[VAL_1:.*]]: index) {
+// CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_9:.*]] = fir.declare %[[VAL_0]](%[[VAL_8]]) {uniq_name = "a"}
+// CHECK: %[[VAL_10:.*]] = fir.embox %[[VAL_9]](%[[VAL_8]]) : (!fir.ref<!fir.array<?x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, !fir.shape<1>) -> !fir.box<!fir.array<?x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>
+// CHECK: %[[VAL_11:.*]] = arith.constant 5 : index
+// CHECK: %[[VAL_12:.*]] = fir.field_index scalar_char, !fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>
+// CHECK: %[[VAL_13:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_14:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_15:.*]] = fir.slice %[[VAL_14]], %[[VAL_1]], %[[VAL_13]] path %[[VAL_12]] : (index, index, index, !fir.field) -> !fir.slice<1>
+// CHECK: %[[VAL_16:.*]] = fir.embox %[[VAL_9]](%[[VAL_8]]) {{\[}}%[[VAL_15]]] : (!fir.ref<!fir.array<?x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
+
+func.func @test_array_char_substring(%arg0: !fir.ref<!fir.array<100x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>) {
+ %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_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, !fir.shape<1>) -> (!fir.ref<!fir.array<100x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, !fir.ref<!fir.array<100x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>)
+ %c3 = arith.constant 3 : index
+ %c5 = arith.constant 5 : index
+ %c3_0 = arith.constant 3 : index
+ %5 = hlfir.designate %1#0{"scalar_char"} substr %c3, %c5 shape %0 typeparams %c3_0 : (!fir.ref<!fir.array<100x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, index, index, !fir.shape<1>, index) -> !fir.box<!fir.array<100x!fir.char<1,3>>>
+ return
+}
+// CHECK-LABEL: func.func @test_array_char_substring(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<100x!fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>) {
+// CHECK: %[[VAL_1:.*]] = arith.constant 100 : index
+// CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_0]](%[[VAL_2]]) {uniq_name = "a"}
+// CHECK: %[[VAL_4:.*]] = arith.constant 3 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 5 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant 3 : index
+// CHECK: %[[VAL_7:.*]] = fir.field_index scalar_char, !fir.type<t_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>
+// CHECK: %[[VAL_8:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_9:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_10:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_11:.*]] = arith.subi %[[VAL_4]], %[[VAL_10]] : index
+// CHECK: %[[VAL_12:.*]] = fir.slice %[[VAL_9]], %[[VAL_1]], %[[VAL_8]] path %[[VAL_7]] substr %[[VAL_11]], %[[VAL_6]] : (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_char{scalar_i:i32,scalar_char:!fir.char<1,5>}>>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<100x!fir.char<1,3>>>
+
+func.func @test_array_array_comp_1(%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
+ %5 = fir.shape %c10, %c20 : (index, index) -> !fir.shape<2>
+ %c4 = arith.constant 4 : index
+ %c5 = arith.constant 5 : index
+ %6 = hlfir.designate %1#0{"array_comp"} <%5> (%c4, %c5) shape %0 : (!fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>, !fir.shape<2>, index, index, !fir.shape<1>) -> !fir.box<!fir.array<100xf32>>
+ return
+}
+// CHECK-LABEL: func.func @test_array_array_comp_1(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<100x!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>>) {
+// CHECK: %[[VAL_1:.*]] = arith.constant 100 : index
+// CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_3:.*]] = fir.declare %[[VAL_0]](%[[VAL_2]]) {uniq_name = "a"}
+// CHECK: %[[VAL_4:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 20 : index
+// CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_4]], %[[VAL_5]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_7:.*]] = arith.constant 4 : index
+// CHECK: %[[VAL_8:.*]] = arith.constant 5 : index
+// 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: %[[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_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
+ %c20 = arith.constant 20 : index
+ %1 = fir.shape %c10, %c20 : (index, index) -> !fir.shape<2>
+ %c1 = arith.constant 1 : index
+ %c4 = arith.constant 4 : index
+ %c17 = arith.constant 17 : index
+ %2 = fir.shape %c10, %c17 : (index, index) -> !fir.shape<2>
+ %3 = hlfir.designate %0#0{"array_comp"} <%1> (%c1:%c10:%c1, %c4:%c20:%c1) shape %2 : (!fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>, !fir.shape<2>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.ref<!fir.array<10x17xf32>>
+ return
+}
+// CHECK-LABEL: func.func @test_array_comp_slice(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>) {
+// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {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>}>>
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 20 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_2]], %[[VAL_3]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant 4 : index
+// CHECK: %[[VAL_7:.*]] = arith.constant 17 : index
+// CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_2]], %[[VAL_7]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_9:.*]] = fir.field_index array_comp, !fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>
+// CHECK: %[[VAL_10:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_9]] : (!fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>, !fir.field) -> !fir.ref<!fir.array<10x20xf32>>
+// CHECK: %[[VAL_11:.*]] = fir.array_coor %[[VAL_10]](%[[VAL_4]]) %[[VAL_5]], %[[VAL_6]] : (!fir.ref<!fir.array<10x20xf32>>, !fir.shape<2>, index, index) -> !fir.ref<f32>
+// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.ref<f32>) -> !fir.ref<!fir.array<10x17xf32>>
+
+
+func.func @test_array_comp_non_contiguous_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
+ %c20 = arith.constant 20 : index
+ %4 = fir.shape %c10, %c20 : (index, index) -> !fir.shape<2>
+ %c1 = arith.constant 1 : index
+ %c6 = arith.constant 6 : index
+ %c4 = arith.constant 4 : index
+ %c17 = arith.constant 17 : index
+ %5 = fir.shape %c6, %c17 : (index, index) -> !fir.shape<2>
+ %6 = hlfir.designate %0#0{"array_comp"} <%4> (%c1:%c6:%c1, %c4:%c20:%c1) shape %5 : (!fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>, !fir.shape<2>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box<!fir.array<6x17xf32>>
+ return
+}
+// CHECK-LABEL: func.func @test_array_comp_non_contiguous_slice(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>) {
+// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {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>}>>
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 20 : index
+// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_2]], %[[VAL_3]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant 6 : index
+// CHECK: %[[VAL_7:.*]] = arith.constant 4 : index
+// CHECK: %[[VAL_8:.*]] = arith.constant 17 : index
+// CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_6]], %[[VAL_8]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_10:.*]] = fir.field_index array_comp, !fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>
+// CHECK: %[[VAL_11:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_10]] : (!fir.ref<!fir.type<t_array{scalar_i:i32,array_comp:!fir.array<10x20xf32>}>>, !fir.field) -> !fir.ref<!fir.array<10x20xf32>>
+// 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>>
diff --git a/flang/test/HLFIR/designate-codegen.fir b/flang/test/HLFIR/designate-codegen.fir
index 804e86f3bba39..3a5bd70978b13 100644
--- a/flang/test/HLFIR/designate-codegen.fir
+++ b/flang/test/HLFIR/designate-codegen.fir
@@ -1,4 +1,5 @@
-// Test hlfir.designate operation code generation to FIR
+// Test code generation to FIR of hlfir.designate operations
+// without component reference.
// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s
func.func @array_ref(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: !fir.ref<i64>) {
More information about the flang-commits
mailing list