[flang-commits] [flang] ee8c653 - [flang] Add hlfir.designate codegen for Fortran ArrayRef

Jean Perier via flang-commits flang-commits at lists.llvm.org
Mon Nov 21 01:18:18 PST 2022


Author: Jean Perier
Date: 2022-11-21T10:17:38+01:00
New Revision: ee8c653c21dc58f5e528ae140c7735fc76c95d39

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

LOG: [flang] Add hlfir.designate codegen for Fortran ArrayRef

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

Added: 
    flang/test/HLFIR/designate-codegen.fir

Modified: 
    flang/include/flang/Optimizer/Builder/HLFIRTools.h
    flang/lib/Optimizer/Builder/HLFIRTools.cpp
    flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
index 0bc868e7863e3..b2da7c51cff6d 100644
--- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h
+++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h
@@ -166,6 +166,14 @@ void genLengthParameters(mlir::Location loc, fir::FirOpBuilder &builder,
                          Entity entity,
                          llvm::SmallVectorImpl<mlir::Value> &result);
 
+/// Return the fir base, shape, and type parameters for a variable. Note that
+/// type parameters are only added if the entity is not a box and the type
+/// parameters is not a constant in the base type. This matches the arguments
+/// expected by fir.embox/fir.array_coor.
+std::pair<mlir::Value, mlir::Value> genVariableFirBaseShapeAndParams(
+    mlir::Location loc, fir::FirOpBuilder &builder, Entity entity,
+    llvm::SmallVectorImpl<mlir::Value> &typeParams);
+
 } // namespace hlfir
 
 #endif // FORTRAN_OPTIMIZER_BUILDER_HLFIRTOOLS_H

diff  --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index 026e3fd317da3..c32ca2958ab08 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -225,3 +225,19 @@ void hlfir::genLengthParameters(mlir::Location loc, fir::FirOpBuilder &builder,
   }
   TODO(loc, "inquire PDTs length parameters in HLFIR");
 }
+
+std::pair<mlir::Value, mlir::Value> hlfir::genVariableFirBaseShapeAndParams(
+    mlir::Location loc, fir::FirOpBuilder &builder, Entity entity,
+    llvm::SmallVectorImpl<mlir::Value> &typeParams) {
+  auto [exv, cleanup] = translateToExtendedValue(loc, builder, entity);
+  assert(!cleanup && "variable to Exv should not produce cleanup");
+  if (entity.hasLengthParameters()) {
+    auto params = fir::getTypeParams(exv);
+    typeParams.append(params.begin(), params.end());
+  }
+  if (entity.isScalar())
+    return {fir::getBase(exv), mlir::Value{}};
+  if (auto variableInterface = entity.getIfVariableInterface())
+    return {fir::getBase(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 0b87ab0d0a54a..cf0f703151d11 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -91,6 +91,94 @@ class DeclareOpConversion : public mlir::OpRewritePattern<hlfir::DeclareOp> {
   }
 };
 
+class DesignateOpConversion
+    : public mlir::OpRewritePattern<hlfir::DesignateOp> {
+public:
+  explicit DesignateOpConversion(mlir::MLIRContext *ctx)
+      : OpRewritePattern{ctx} {}
+
+  mlir::LogicalResult
+  matchAndRewrite(hlfir::DesignateOp designate,
+                  mlir::PatternRewriter &rewriter) const override {
+    mlir::Location loc = designate.getLoc();
+    auto module = designate->getParentOfType<mlir::ModuleOp>();
+    fir::FirOpBuilder builder(rewriter, fir::getKindMapping(module));
+
+    if (designate.getComponent() || designate.getComplexPart() ||
+        !designate.getSubstring().empty()) {
+      // build path.
+      TODO(loc, "hlfir::designate with complex part or substring or component");
+    }
+
+    hlfir::Entity baseEntity(designate.getMemref());
+    if (baseEntity.isMutableBox())
+      TODO(loc, "hlfir::designate load of pointer or allocatable");
+
+    mlir::Type designateResultType = designate.getResult().getType();
+    llvm::SmallVector<mlir::Value> firBaseTypeParameters;
+    auto [base, shape] = hlfir::genVariableFirBaseShapeAndParams(
+        loc, builder, baseEntity, firBaseTypeParameters);
+    if (designateResultType.isa<fir::BoxType>()) {
+      // Generate embox or rebox.
+      if (designate.getIndices().empty())
+        TODO(loc, "hlfir::designate whole part");
+      // Otherwise, this is an array section with triplets.
+      llvm::SmallVector<mlir::Value> triples;
+      auto undef = builder.create<fir::UndefOp>(loc, 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++]);
+          triples.push_back(subscripts[i++]);
+        } else {
+          triples.push_back(undef);
+          triples.push_back(undef);
+        }
+      }
+      mlir::Value slice = builder.create<fir::SliceOp>(
+          loc, triples, /*path=*/mlir::ValueRange{});
+      llvm::SmallVector<mlir::Type> resultType{designateResultType};
+      mlir::Value resultBox;
+      if (base.getType().isa<fir::BoxType>())
+        resultBox =
+            builder.create<fir::ReboxOp>(loc, resultType, base, shape, slice);
+      else
+        resultBox = builder.create<fir::EmboxOp>(loc, resultType, base, shape,
+                                                 slice, firBaseTypeParameters);
+      rewriter.replaceOp(designate, resultBox);
+      return mlir::success();
+    }
+
+    // Indexing a single element (use fir.array_coor of fir.coordinate_of).
+
+    if (designate.getIndices().empty()) {
+      // Scalar substring or complex part.
+      // generate fir.coordinate_of.
+      TODO(loc, "hlfir::designate to fir.coordinate_of");
+    }
+
+    // Generate fir.array_coor
+    mlir::Type resultType = designateResultType;
+    if (auto boxCharType = designateResultType.dyn_cast<fir::BoxCharType>())
+      resultType = fir::ReferenceType::get(boxCharType.getEleTy());
+    auto arrayCoor = builder.create<fir::ArrayCoorOp>(
+        loc, resultType, base, shape,
+        /*slice=*/mlir::Value{}, designate.getIndices(), firBaseTypeParameters);
+    if (designateResultType.isa<fir::BoxCharType>()) {
+      assert(designate.getTypeparams().size() == 1 &&
+             "must have character length");
+      auto emboxChar = builder.create<fir::EmboxCharOp>(
+          loc, designateResultType, arrayCoor, designate.getTypeparams()[0]);
+      rewriter.replaceOp(designate, emboxChar.getResult());
+    } else {
+      rewriter.replaceOp(designate, arrayCoor.getResult());
+    }
+    return mlir::success();
+  }
+};
+
 class ConvertHLFIRtoFIR
     : public hlfir::impl::ConvertHLFIRtoFIRBase<ConvertHLFIRtoFIR> {
 public:
@@ -98,7 +186,7 @@ class ConvertHLFIRtoFIR
     auto func = this->getOperation();
     auto *context = &getContext();
     mlir::RewritePatternSet patterns(context);
-    patterns.insert<DeclareOpConversion>(context);
+    patterns.insert<DeclareOpConversion, DesignateOpConversion>(context);
     mlir::ConversionTarget target(*context);
     target.addIllegalDialect<hlfir::hlfirDialect>();
     target.markUnknownOpDynamicallyLegal(

diff  --git a/flang/test/HLFIR/designate-codegen.fir b/flang/test/HLFIR/designate-codegen.fir
new file mode 100644
index 0000000000000..804e86f3bba39
--- /dev/null
+++ b/flang/test/HLFIR/designate-codegen.fir
@@ -0,0 +1,192 @@
+// Test hlfir.designate operation code generation to FIR
+// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s
+
+func.func @array_ref(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: !fir.ref<i64>) {
+  %0:2 = hlfir.declare %arg1 {uniq_name = "n"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
+  %1:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
+  %2 = fir.load %0#0 : !fir.ref<i64>
+  %3 = hlfir.designate %1#0 (%2)  : (!fir.box<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
+  return
+}
+// CHECK-LABEL:   func.func @array_ref(
+// CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>,
+// CHECK-SAME:    %[[VAL_1:.*]]: !fir.ref<i64>) {
+// CHECK:  %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "n"} : (!fir.ref<i64>) -> !fir.ref<i64>
+// CHECK:  %[[VAL_3:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.array<?xf32>>
+// CHECK:  %[[VAL_5:.*]] = fir.load %[[VAL_2]] : !fir.ref<i64>
+// CHECK:  %[[VAL_6:.*]] = fir.array_coor %[[VAL_3]] %[[VAL_5]] : (!fir.box<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
+
+
+func.func @char_array_ref(%arg0: !fir.box<!fir.array<?x!fir.char<1,?>>>, %arg1: !fir.ref<i32>) {
+  %0:2 = hlfir.declare %arg1 {uniq_name = "n"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %1:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.box<!fir.array<?x!fir.char<1,?>>>)
+  %2 = fir.box_elesize %1#1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
+  %c10 = arith.constant 10 : index
+  %3 = hlfir.designate %1#0 (%c10)  typeparams %2 : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index, index) -> !fir.boxchar<1>
+  return
+}
+// CHECK-LABEL:   func.func @char_array_ref(
+// CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<1,?>>>,
+// CHECK-SAME:    %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK:  %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "n"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK:  %[[VAL_3:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
+// CHECK:  %[[VAL_5:.*]] = fir.box_elesize %[[VAL_3]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
+// CHECK:  %[[VAL_6:.*]] = arith.constant 10 : index
+// CHECK:  %[[VAL_7:.*]] = fir.array_coor %[[VAL_3]] %[[VAL_6]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index) -> !fir.ref<!fir.char<1,?>>
+// CHECK:  %[[VAL_8:.*]] = fir.emboxchar %[[VAL_7]], %[[VAL_5]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
+
+
+func.func @char_array_ref_cst_len(%arg0: !fir.box<!fir.array<?x!fir.char<1,5>>>, %arg1: !fir.ref<i32>) {
+  %0:2 = hlfir.declare %arg1 {uniq_name = "n"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %c5 = arith.constant 5 : index
+  %1:2 = hlfir.declare %arg0 typeparams %c5 {uniq_name = "x"} : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index) -> (!fir.box<!fir.array<?x!fir.char<1,5>>>, !fir.box<!fir.array<?x!fir.char<1,5>>>)
+  %c10 = arith.constant 10 : index
+  %2 = hlfir.designate %1#0 (%c10)  typeparams %c5 : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index, index) -> !fir.ref<!fir.char<1,5>>
+  return
+}
+// CHECK-LABEL:   func.func @char_array_ref_cst_len(
+// CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<1,5>>>,
+// CHECK-SAME:    %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK:  %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "n"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK:  %[[VAL_3:.*]] = arith.constant 5 : index
+// CHECK:  %[[VAL_4:.*]] = fir.declare %[[VAL_0]] typeparams %[[VAL_3]] {uniq_name = "x"} : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
+// CHECK:  %[[VAL_6:.*]] = arith.constant 10 : index
+// CHECK:  %[[VAL_7:.*]] = fir.array_coor %[[VAL_4]] %[[VAL_6]] : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index) -> !fir.ref<!fir.char<1,5>>
+
+
+func.func @char_array_ref_3(%arg0: !fir.ref<!fir.array<100x!fir.char<1,?>>>, %arg1: !fir.ref<i32>) {
+  %0:2 = hlfir.declare %arg1 {uniq_name = "n"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %c5 = arith.constant 5 : index
+  %c100 = arith.constant 100 : index
+  %sh = fir.shape %c100 : (index) -> !fir.shape<1>
+  %1:2 = hlfir.declare %arg0(%sh) typeparams %c5 {uniq_name = "x"} : (!fir.ref<!fir.array<100x!fir.char<1,?>>>, !fir.shape<1>, index) -> (!fir.box<!fir.array<100x!fir.char<1,?>>>, !fir.ref<!fir.array<100x!fir.char<1,?>>>)
+  %c10 = arith.constant 10 : index
+  %3 = hlfir.designate %1#0 (%c10)  typeparams %c5 : (!fir.box<!fir.array<100x!fir.char<1,?>>>, index, index) -> !fir.boxchar<1>
+  return
+}
+// CHECK-LABEL:   func.func @char_array_ref_3(
+// CHECK-SAME:    %[[VAL_0:.*]]: !fir.ref<!fir.array<100x!fir.char<1,?>>>,
+// CHECK-SAME:    %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK:  %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "n"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK:  %[[VAL_3:.*]] = arith.constant 5 : index
+// CHECK:  %[[VAL_4:.*]] = arith.constant 100 : index
+// CHECK:  %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
+// CHECK:  %[[VAL_6:.*]] = fir.declare %[[VAL_0]](%[[VAL_5]]) typeparams %[[VAL_3]] {uniq_name = "x"} : (!fir.ref<!fir.array<100x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.ref<!fir.array<100x!fir.char<1,?>>>
+// CHECK:  %[[VAL_8:.*]] = arith.constant 10 : index
+// CHECK:  %[[VAL_9:.*]] = fir.array_coor %[[VAL_6]](%[[VAL_5]]) %[[VAL_8]] typeparams %[[VAL_3]] : (!fir.ref<!fir.array<100x!fir.char<1,?>>>, !fir.shape<1>, index, index) -> !fir.ref<!fir.char<1,?>>
+// CHECK:  %[[VAL_10:.*]] = fir.emboxchar %[[VAL_9]], %[[VAL_3]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
+
+
+func.func @array_section(%arg0: !fir.ref<!fir.array<10xf32>>) {
+  %c10 = arith.constant 10 : index
+  %0 = fir.shape %c10 : (index) -> !fir.shape<1>
+  %1:2 = hlfir.declare %arg0(%0) {uniq_name = "x"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)
+  %c2 = arith.constant 2 : index
+  %c8 = arith.constant 8 : index
+  %c3 = arith.constant 3 : index
+  %2 = fir.shape %c3 : (index) -> !fir.shape<1>
+  %3 = hlfir.designate %1#0 (%c2:%c8:%c3)  shape %2 : (!fir.ref<!fir.array<10xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<3xf32>>
+  return
+}
+// CHECK-LABEL:   func.func @array_section(
+// CHECK-SAME:    %[[VAL_0:.*]]: !fir.ref<!fir.array<10xf32>>) {
+// CHECK:  %[[VAL_1:.*]] = arith.constant 10 : index
+// CHECK:  %[[VAL_2:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1>
+// CHECK:  %[[VAL_3:.*]] = fir.declare %[[VAL_0]](%[[VAL_2]]) {uniq_name = "x"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+// CHECK:  %[[VAL_4:.*]] = arith.constant 2 : index
+// CHECK:  %[[VAL_5:.*]] = arith.constant 8 : index
+// CHECK:  %[[VAL_6:.*]] = arith.constant 3 : index
+// CHECK:  %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
+// CHECK:  %[[VAL_8:.*]] = fir.undefined index
+// CHECK:  %[[VAL_9:.*]] = fir.slice %[[VAL_4]], %[[VAL_5]], %[[VAL_6]] : (index, index, index) -> !fir.slice<1>
+// CHECK:  %[[VAL_10:.*]] = fir.embox %[[VAL_3]](%[[VAL_2]]) {{\[}}%[[VAL_9]]] : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<3xf32>>
+
+
+func.func @array_section_2(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: !fir.ref<i64>) {
+  %0:2 = hlfir.declare %arg1 {uniq_name = "n"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>)
+  %1:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
+  %2 = fir.load %0#0 : !fir.ref<i64>
+  %c0 = arith.constant 0 : index
+  %3:3 = fir.box_dims %1#1, %c0 : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+  %4 = fir.convert %2 : (i64) -> index
+  %c3 = arith.constant 3 : index
+  %c42 = arith.constant 42 : index
+  %5 = fir.shape %c42 : (index) -> !fir.shape<1>
+  %6 = hlfir.designate %1#0 (%4:%3#1:%c3)  shape %5 : (!fir.box<!fir.array<?xf32>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+  return
+}
+// CHECK-LABEL:   func.func @array_section_2(
+// CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>,
+// CHECK-SAME:    %[[VAL_1:.*]]: !fir.ref<i64>) {
+// CHECK:  %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "n"} : (!fir.ref<i64>) -> !fir.ref<i64>
+// CHECK:  %[[VAL_3:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.array<?xf32>>
+// CHECK:  %[[VAL_5:.*]] = fir.load %[[VAL_2]] : !fir.ref<i64>
+// CHECK:  %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK:  %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_3]], %[[VAL_6]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+// CHECK:  %[[VAL_8:.*]] = fir.convert %[[VAL_5]] : (i64) -> index
+// CHECK:  %[[VAL_9:.*]] = arith.constant 3 : index
+// CHECK:  %[[VAL_10:.*]] = arith.constant 42 : index
+// CHECK:  %[[VAL_11:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1>
+// CHECK:  %[[VAL_12:.*]] = fir.undefined index
+// CHECK:  %[[VAL_13:.*]] = fir.slice %[[VAL_8]], %[[VAL_7]]#1, %[[VAL_9]] : (index, index, index) -> !fir.slice<1>
+// CHECK:  %[[VAL_14:.*]] = fir.rebox %[[VAL_3]] {{\[}}%[[VAL_13]]] : (!fir.box<!fir.array<?xf32>>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
+
+
+func.func @char_array_section(%arg0: !fir.box<!fir.array<?x!fir.char<1,?>>>, %arg1: !fir.ref<i32>) {
+  %0:2 = hlfir.declare %arg1 {uniq_name = "n"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %1:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.box<!fir.array<?x!fir.char<1,?>>>)
+  %2 = fir.box_elesize %1#1 : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
+  %c1 = arith.constant 1 : index
+  %c0 = arith.constant 0 : index
+  %3:3 = fir.box_dims %1#1, %c0 : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index) -> (index, index, index)
+  %c3 = arith.constant 3 : index
+  %c42 = arith.constant 42 : index
+  %4 = fir.shape %c42 : (index) -> !fir.shape<1>
+  %5 = hlfir.designate %1#0 (%c1:%3#1:%c3)  shape %4 typeparams %2 : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index, index, index, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
+  return
+}
+// CHECK-LABEL:   func.func @char_array_section(
+// CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<1,?>>>,
+// CHECK-SAME:    %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK:  %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "n"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK:  %[[VAL_3:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
+// CHECK:  %[[VAL_5:.*]] = fir.box_elesize %[[VAL_3]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
+// CHECK:  %[[VAL_6:.*]] = arith.constant 1 : index
+// CHECK:  %[[VAL_7:.*]] = arith.constant 0 : index
+// CHECK:  %[[VAL_8:.*]]:3 = fir.box_dims %[[VAL_3]], %[[VAL_7]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK:  %[[VAL_9:.*]] = arith.constant 3 : index
+// CHECK:  %[[VAL_10:.*]] = arith.constant 42 : index
+// CHECK:  %[[VAL_11:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1>
+// CHECK:  %[[VAL_12:.*]] = fir.undefined index
+// CHECK:  %[[VAL_13:.*]] = fir.slice %[[VAL_6]], %[[VAL_8]]#1, %[[VAL_9]] : (index, index, index) -> !fir.slice<1>
+// CHECK:  %[[VAL_14:.*]] = fir.rebox %[[VAL_3]] {{\[}}%[[VAL_13]]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.slice<1>) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
+
+
+func.func @char_array_section_cst_len(%arg0: !fir.box<!fir.array<?x!fir.char<1,5>>>, %arg1: !fir.ref<i32>) {
+  %0:2 = hlfir.declare %arg1 {uniq_name = "n"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+  %c5 = arith.constant 5 : index
+  %1:2 = hlfir.declare %arg0 typeparams %c5 {uniq_name = "x"} : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index) -> (!fir.box<!fir.array<?x!fir.char<1,5>>>, !fir.box<!fir.array<?x!fir.char<1,5>>>)
+  %c1 = arith.constant 1 : index
+  %c0 = arith.constant 0 : index
+  %2:3 = fir.box_dims %1#1, %c0 : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index) -> (index, index, index)
+  %c3 = arith.constant 3 : index
+  %c42 = arith.constant 42 : index
+  %3 = fir.shape %c42 : (index) -> !fir.shape<1>
+  %4 = hlfir.designate %1#0 (%c1:%2#1:%c3)  shape %3 typeparams %c5 : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index, index, index, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
+  return
+}
+// CHECK-LABEL:   func.func @char_array_section_cst_len(
+// CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<1,5>>>,
+// CHECK-SAME:    %[[VAL_1:.*]]: !fir.ref<i32>) {
+// CHECK:  %[[VAL_2:.*]] = fir.declare %[[VAL_1]] {uniq_name = "n"} : (!fir.ref<i32>) -> !fir.ref<i32>
+// CHECK:  %[[VAL_3:.*]] = arith.constant 5 : index
+// CHECK:  %[[VAL_4:.*]] = fir.declare %[[VAL_0]] typeparams %[[VAL_3]] {uniq_name = "x"} : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
+// CHECK:  %[[VAL_6:.*]] = arith.constant 1 : index
+// CHECK:  %[[VAL_7:.*]] = arith.constant 0 : index
+// CHECK:  %[[VAL_8:.*]]:3 = fir.box_dims %[[VAL_4]], %[[VAL_7]] : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index) -> (index, index, index)
+// CHECK:  %[[VAL_9:.*]] = arith.constant 3 : index
+// CHECK:  %[[VAL_10:.*]] = arith.constant 42 : index
+// CHECK:  %[[VAL_11:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1>
+// CHECK:  %[[VAL_12:.*]] = fir.undefined index
+// CHECK:  %[[VAL_13:.*]] = fir.slice %[[VAL_6]], %[[VAL_8]]#1, %[[VAL_9]] : (index, index, index) -> !fir.slice<1>
+// CHECK:  %[[VAL_14:.*]] = fir.rebox %[[VAL_4]] {{\[}}%[[VAL_13]]] : (!fir.box<!fir.array<?x!fir.char<1,5>>>, !fir.slice<1>) -> !fir.box<!fir.array<?x!fir.char<1,5>>>


        


More information about the flang-commits mailing list