[flang-commits] [flang] [flang] Added hlfir.reshape definition/lowering/codegen. (PR #124226)
via flang-commits
flang-commits at lists.llvm.org
Thu Jan 23 21:02:35 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Slava Zakharin (vzakhari)
<details>
<summary>Changes</summary>
Lower Fortran RESHAPE intrinsic into hlfir.reshape, and then lower
hlfir.reshape into a runtime call.
A later patch will add hlfir.reshape inlining as hlfir.elemental.
---
Patch is 80.55 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/124226.diff
9 Files Affected:
- (modified) flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td (+9)
- (modified) flang/include/flang/Optimizer/HLFIR/HLFIROps.td (+26)
- (modified) flang/lib/Lower/HlfirIntrinsics.cpp (+25)
- (modified) flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp (+57)
- (modified) flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp (+41-7)
- (modified) flang/test/HLFIR/invalid.fir (+112)
- (added) flang/test/HLFIR/reshape-lowering.fir (+443)
- (added) flang/test/HLFIR/reshape.fir (+73)
- (added) flang/test/Lower/HLFIR/reshape.f90 (+143)
``````````diff
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
index 404ab5f633bf78..1b1ac61d4550f0 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td
@@ -125,6 +125,11 @@ def IsFortranNumericalArrayObjectPred
def AnyFortranNumericalArrayObject : Type<IsFortranNumericalArrayObjectPred,
"any array-like object containing a numerical type">;
+def AnyFortranNumericalArrayEntity
+ : Type<And<[AnyFortranNumericalArrayObject.predicate,
+ AnyFortranEntity.predicate]>,
+ "any array-like entity containing a numerical type">;
+
def IsFortranNumericalOrLogicalArrayObjectPred
: CPred<"::hlfir::isFortranNumericalOrLogicalArrayObject($_self)">;
def AnyFortranNumericalOrLogicalArrayObject : Type<IsFortranNumericalOrLogicalArrayObjectPred,
@@ -135,6 +140,10 @@ def IsFortranArrayObjectPred
def AnyFortranArrayObject : Type<IsFortranArrayObjectPred,
"any array-like object">;
+def AnyFortranArrayEntity
+ : Type<And<[AnyFortranArrayObject.predicate, AnyFortranEntity.predicate]>,
+ "any array-like entity">;
+
def IsPassByRefOrIntegerTypePred
: CPred<"::hlfir::isPassByRefOrIntegerType($_self)">;
def AnyPassByRefOrIntegerType : Type<IsPassByRefOrIntegerTypePred,
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
index 48764580d526d2..f4102538efc3c2 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
@@ -720,6 +720,32 @@ def hlfir_CShiftOp
let hasVerifier = 1;
}
+def hlfir_ReshapeOp
+ : hlfir_Op<
+ "reshape", [AttrSizedOperandSegments,
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ let summary = "RESHAPE transformational intrinsic";
+ let description = [{
+ Reshapes an ARRAY to correspond to the given SHAPE.
+ If PAD is specified the new array may be padded with elements
+ from PAD array.
+ If ORDER is specified the new array may be permuted accordingly.
+ }];
+
+ let arguments = (ins AnyFortranArrayEntity:$array,
+ AnyFortranNumericalArrayEntity:$shape,
+ Optional<AnyFortranArrayEntity>:$pad,
+ Optional<AnyFortranNumericalArrayEntity>:$order);
+
+ let results = (outs hlfir_ExprType);
+
+ let assemblyFormat = [{
+ $array $shape (`pad` $pad^)? (`order` $order^)? attr-dict `:` functional-type(operands, results)
+ }];
+
+ let hasVerifier = 1;
+}
+
// An allocation effect is needed because the value produced by the associate
// is "deallocated" by hlfir.end_associate (the end_associate must not be
// removed, and there must be only one hlfir.end_associate).
diff --git a/flang/lib/Lower/HlfirIntrinsics.cpp b/flang/lib/Lower/HlfirIntrinsics.cpp
index 9d3cd3a5c8fa13..8b96b209ddb00e 100644
--- a/flang/lib/Lower/HlfirIntrinsics.cpp
+++ b/flang/lib/Lower/HlfirIntrinsics.cpp
@@ -170,6 +170,17 @@ class HlfirCShiftLowering : public HlfirTransformationalIntrinsic {
mlir::Type stmtResultType) override;
};
+class HlfirReshapeLowering : public HlfirTransformationalIntrinsic {
+public:
+ using HlfirTransformationalIntrinsic::HlfirTransformationalIntrinsic;
+
+protected:
+ mlir::Value
+ lowerImpl(const Fortran::lower::PreparedActualArguments &loweredActuals,
+ const fir::IntrinsicArgumentLoweringRules *argLowering,
+ mlir::Type stmtResultType) override;
+};
+
} // namespace
mlir::Value HlfirTransformationalIntrinsic::loadBoxAddress(
@@ -419,6 +430,17 @@ mlir::Value HlfirCShiftLowering::lowerImpl(
return createOp<hlfir::CShiftOp>(resultType, operands);
}
+mlir::Value HlfirReshapeLowering::lowerImpl(
+ const Fortran::lower::PreparedActualArguments &loweredActuals,
+ const fir::IntrinsicArgumentLoweringRules *argLowering,
+ mlir::Type stmtResultType) {
+ auto operands = getOperandVector(loweredActuals, argLowering);
+ assert(operands.size() == 4);
+ mlir::Type resultType = computeResultType(operands[0], stmtResultType);
+ return createOp<hlfir::ReshapeOp>(resultType, operands[0], operands[1],
+ operands[2], operands[3]);
+}
+
std::optional<hlfir::EntityWithAttributes> Fortran::lower::lowerHlfirIntrinsic(
fir::FirOpBuilder &builder, mlir::Location loc, const std::string &name,
const Fortran::lower::PreparedActualArguments &loweredActuals,
@@ -467,6 +489,9 @@ std::optional<hlfir::EntityWithAttributes> Fortran::lower::lowerHlfirIntrinsic(
if (name == "cshift")
return HlfirCShiftLowering{builder, loc}.lower(loweredActuals, argLowering,
stmtResultType);
+ if (name == "reshape")
+ return HlfirReshapeLowering{builder, loc}.lower(loweredActuals, argLowering,
+ stmtResultType);
if (mlir::isa<fir::CharacterType>(stmtResultType)) {
if (name == "min")
return HlfirCharExtremumLowering{builder, loc,
diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
index d93e25280237f1..add3ff9140d6b6 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -1444,6 +1444,63 @@ void hlfir::CShiftOp::getEffects(
getIntrinsicEffects(getOperation(), effects);
}
+//===----------------------------------------------------------------------===//
+// ReshapeOp
+//===----------------------------------------------------------------------===//
+
+llvm::LogicalResult hlfir::ReshapeOp::verify() {
+ auto results = this->getOperation()->getResultTypes();
+ assert(results.size() == 1);
+ hlfir::ExprType resultType = mlir::cast<hlfir::ExprType>(results[0]);
+ mlir::Value array = this->getArray();
+ auto arrayType = mlir::cast<fir::SequenceType>(
+ hlfir::getFortranElementOrSequenceType(array.getType()));
+ if (hlfir::getFortranElementType(resultType) != arrayType.getElementType())
+ return this->emitOpError(
+ "ARRAY and the result must have the same element type");
+ if (hlfir::isPolymorphicType(resultType) !=
+ hlfir::isPolymorphicType(array.getType()))
+ return this->emitOpError(
+ "ARRAY must be polymorphic iff result is polymorphic");
+
+ mlir::Value shape = this->getShape();
+ auto shapeArrayType = mlir::cast<fir::SequenceType>(
+ hlfir::getFortranElementOrSequenceType(shape.getType()));
+ if (shapeArrayType.getDimension() != 1)
+ return this->emitOpError("SHAPE must be an array of rank 1");
+ if (!mlir::isa<mlir::IntegerType>(shapeArrayType.getElementType()))
+ return this->emitOpError("SHAPE must be an integer array");
+ if (shapeArrayType.hasDynamicExtents())
+ return this->emitOpError("SHAPE must have known size");
+ if (shapeArrayType.getConstantArraySize() != resultType.getRank())
+ return this->emitOpError("SHAPE's extent must match the result rank");
+
+ if (mlir::Value pad = this->getPad()) {
+ auto padArrayType = mlir::cast<fir::SequenceType>(
+ hlfir::getFortranElementOrSequenceType(pad.getType()));
+ if (arrayType.getElementType() != padArrayType.getElementType())
+ return this->emitOpError("ARRAY and PAD must be of the same type");
+ }
+
+ if (mlir::Value order = this->getOrder()) {
+ auto orderArrayType = mlir::cast<fir::SequenceType>(
+ hlfir::getFortranElementOrSequenceType(order.getType()));
+ if (orderArrayType.getDimension() != 1)
+ return this->emitOpError("ORDER must be an array of rank 1");
+ if (!mlir::isa<mlir::IntegerType>(orderArrayType.getElementType()))
+ return this->emitOpError("ORDER must be an integer array");
+ }
+
+ return mlir::success();
+}
+
+void hlfir::ReshapeOp::getEffects(
+ llvm::SmallVectorImpl<
+ mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
+ &effects) {
+ getIntrinsicEffects(getOperation(), effects);
+}
+
//===----------------------------------------------------------------------===//
// AssociateOp
//===----------------------------------------------------------------------===//
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp
index 091ed7ed999df2..bd12700f138386 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp
@@ -494,6 +494,41 @@ class CShiftOpConversion : public HlfirIntrinsicConversion<hlfir::CShiftOp> {
}
};
+class ReshapeOpConversion : public HlfirIntrinsicConversion<hlfir::ReshapeOp> {
+ using HlfirIntrinsicConversion<hlfir::ReshapeOp>::HlfirIntrinsicConversion;
+
+ llvm::LogicalResult
+ matchAndRewrite(hlfir::ReshapeOp reshape,
+ mlir::PatternRewriter &rewriter) const override {
+ fir::FirOpBuilder builder{rewriter, reshape.getOperation()};
+ const mlir::Location &loc = reshape->getLoc();
+
+ llvm::SmallVector<IntrinsicArgument, 4> inArgs;
+ mlir::Value array = reshape.getArray();
+ inArgs.push_back({array, array.getType()});
+ mlir::Value shape = reshape.getShape();
+ inArgs.push_back({shape, shape.getType()});
+ mlir::Type noneType = builder.getNoneType();
+ mlir::Value pad = reshape.getPad();
+ inArgs.push_back({pad, pad ? pad.getType() : noneType});
+ mlir::Value order = reshape.getOrder();
+ inArgs.push_back({order, order ? order.getType() : noneType});
+
+ auto *argLowering = fir::getIntrinsicArgumentLowering("reshape");
+ llvm::SmallVector<fir::ExtendedValue, 4> args =
+ lowerArguments(reshape, inArgs, rewriter, argLowering);
+
+ mlir::Type scalarResultType =
+ hlfir::getFortranElementType(reshape.getType());
+
+ auto [resultExv, mustBeFreed] =
+ fir::genIntrinsicCall(builder, loc, "reshape", scalarResultType, args);
+
+ processReturnValue(reshape, resultExv, mustBeFreed, builder, rewriter);
+ return mlir::success();
+ }
+};
+
class LowerHLFIRIntrinsics
: public hlfir::impl::LowerHLFIRIntrinsicsBase<LowerHLFIRIntrinsics> {
public:
@@ -501,13 +536,12 @@ class LowerHLFIRIntrinsics
mlir::ModuleOp module = this->getOperation();
mlir::MLIRContext *context = &getContext();
mlir::RewritePatternSet patterns(context);
- patterns
- .insert<MatmulOpConversion, MatmulTransposeOpConversion,
- AllOpConversion, AnyOpConversion, SumOpConversion,
- ProductOpConversion, TransposeOpConversion, CountOpConversion,
- DotProductOpConversion, MaxvalOpConversion, MinvalOpConversion,
- MinlocOpConversion, MaxlocOpConversion, CShiftOpConversion>(
- context);
+ patterns.insert<
+ MatmulOpConversion, MatmulTransposeOpConversion, AllOpConversion,
+ AnyOpConversion, SumOpConversion, ProductOpConversion,
+ TransposeOpConversion, CountOpConversion, DotProductOpConversion,
+ MaxvalOpConversion, MinvalOpConversion, MinlocOpConversion,
+ MaxlocOpConversion, CShiftOpConversion, ReshapeOpConversion>(context);
// While conceptually this pass is performing dialect conversion, we use
// pattern rewrites here instead of dialect conversion because this pass
diff --git a/flang/test/HLFIR/invalid.fir b/flang/test/HLFIR/invalid.fir
index b35bec4b2a8999..8cddc5a5961a85 100644
--- a/flang/test/HLFIR/invalid.fir
+++ b/flang/test/HLFIR/invalid.fir
@@ -1423,3 +1423,115 @@ func.func @bad_cshift9(%arg0: !hlfir.expr<?x!fir.char<1,1>>, %arg1: i32) {
%0 = hlfir.cshift %arg0 %arg1 : (!hlfir.expr<?x!fir.char<1,1>>, i32) -> !hlfir.expr<?x!fir.char<1,2>>
return
}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<1xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op ARRAY and the result must have the same element type}}
+ %0 = hlfir.reshape %arg0 %arg0 : (!hlfir.expr<1xi32>, !hlfir.expr<1xi32>) -> !hlfir.expr<?xf32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<?x!fir.type<whatever>?>, %arg1: !hlfir.expr<1xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op ARRAY must be polymorphic iff result is polymorphic}}
+ %0 = hlfir.reshape %arg0 %arg1 : (!hlfir.expr<?x!fir.type<whatever>?>, !hlfir.expr<1xi32>) -> !hlfir.expr<?x!fir.type<whatever>>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<?x!fir.type<whatever>>, %arg1: !hlfir.expr<1xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op ARRAY must be polymorphic iff result is polymorphic}}
+ %0 = hlfir.reshape %arg0 %arg1 : (!hlfir.expr<?x!fir.type<whatever>>, !hlfir.expr<1xi32>) -> !hlfir.expr<?x!fir.type<whatever>?>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<1x1xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op SHAPE must be an array of rank 1}}
+ %0 = hlfir.reshape %arg0 %arg0 : (!hlfir.expr<1x1xi32>, !hlfir.expr<1x1xi32>) -> !hlfir.expr<?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<1xf32>) {
+ // expected-error at +1 {{'hlfir.reshape' op SHAPE must be an integer array}}
+ %0 = hlfir.reshape %arg0 %arg0 : (!hlfir.expr<1xf32>, !hlfir.expr<1xf32>) -> !hlfir.expr<?xf32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<?xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op SHAPE must have known size}}
+ %0 = hlfir.reshape %arg0 %arg0 : (!hlfir.expr<?xi32>, !hlfir.expr<?xi32>) -> !hlfir.expr<?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<1xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op SHAPE's extent must match the result rank}}
+ %0 = hlfir.reshape %arg0 %arg0 : (!hlfir.expr<1xi32>, !hlfir.expr<1xi32>) -> !hlfir.expr<?x?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<1xi32>, %arg1: !hlfir.expr<?xi16>) {
+ // expected-error at +1 {{'hlfir.reshape' op ARRAY and PAD must be of the same type}}
+ %0 = hlfir.reshape %arg0 %arg0 pad %arg1 : (!hlfir.expr<1xi32>, !hlfir.expr<1xi32>, !hlfir.expr<?xi16>) -> !hlfir.expr<?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<1xi32>, %arg1: !hlfir.expr<?x?xi16>) {
+ // expected-error at +1 {{'hlfir.reshape' op ORDER must be an array of rank 1}}
+ %0 = hlfir.reshape %arg0 %arg0 order %arg1 : (!hlfir.expr<1xi32>, !hlfir.expr<1xi32>, !hlfir.expr<?x?xi16>) -> !hlfir.expr<?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !hlfir.expr<1xi32>, %arg1: !hlfir.expr<?xf16>) {
+ // expected-error at +1 {{'hlfir.reshape' op ORDER must be an integer array}}
+ %0 = hlfir.reshape %arg0 %arg0 order %arg1 : (!hlfir.expr<1xi32>, !hlfir.expr<1xi32>, !hlfir.expr<?xf16>) -> !hlfir.expr<?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !fir.ref<!fir.array<?xi32>>, %arg1: !hlfir.expr<1xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op operand #0 must be any array-like entity}}
+ %0 = hlfir.reshape %arg0 %arg1 : (!fir.ref<!fir.array<?xi32>>, !hlfir.expr<1xi32>) -> !hlfir.expr<?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !fir.ref<!fir.array<?xi32>>, %arg1: !hlfir.expr<?xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op operand #1 must be any array-like entity containing a numerical type}}
+ %0 = hlfir.reshape %arg1 %arg0 : (!hlfir.expr<?xi32>, !fir.ref<!fir.array<?xi32>>) -> !hlfir.expr<?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !fir.ref<!fir.array<?xi32>>, %arg1: !hlfir.expr<1xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op operand #2 must be any array-like entity}}
+ %0 = hlfir.reshape %arg1 %arg1 pad %arg0 : (!hlfir.expr<1xi32>, !hlfir.expr<1xi32>, !fir.ref<!fir.array<?xi32>>) -> !hlfir.expr<?xi32>
+ return
+}
+
+// -----
+
+func.func @bad_reshape(%arg0: !fir.ref<!fir.array<?xi32>>, %arg1: !hlfir.expr<1xi32>) {
+ // expected-error at +1 {{'hlfir.reshape' op operand #3 must be any array-like entity containing a numerical type}}
+ %0 = hlfir.reshape %arg1 %arg1 pad %arg1 order %arg0 : (!hlfir.expr<1xi32>, !hlfir.expr<1xi32>, !hlfir.expr<1xi32>, !fir.ref<!fir.array<?xi32>>) -> !hlfir.expr<?xi32>
+ return
+}
diff --git a/flang/test/HLFIR/reshape-lowering.fir b/flang/test/HLFIR/reshape-lowering.fir
new file mode 100644
index 00000000000000..c2f060efc5044f
--- /dev/null
+++ b/flang/test/HLFIR/reshape-lowering.fir
@@ -0,0 +1,443 @@
+// Test hlfir.reshape operation lowering to fir runtime call
+// RUN: fir-opt %s -lower-hlfir-intrinsics | FileCheck %s
+
+// reshape(x, y)
+func.func @_QPreshape1(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.array<1xi32>> {fir.bindc_name = "y"}) {
+ %c1 = arith.constant 1 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFreshape1Ex"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
+ %2 = fir.shape %c1 : (index) -> !fir.shape<1>
+ %3:2 = hlfir.declare %arg1(%2) dummy_scope %0 {uniq_name = "_QFreshape1Ey"} : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<1xi32>>, !fir.ref<!fir.array<1xi32>>)
+ %4 = hlfir.reshape %1#0 %3#0 : (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<1xi32>>) -> !hlfir.expr<?xf32>
+ hlfir.assign %4 to %1#0 : !hlfir.expr<?xf32>, !fir.box<!fir.array<?xf32>>
+ hlfir.destroy %4 : !hlfir.expr<?xf32>
+ return
+}
+// CHECK-LABEL: func.func @_QPreshape1(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"},
+// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.array<1xi32>> {fir.bindc_name = "y"}) {
+// CHECK: %[[VAL_2:.*]] = arith.constant true
+// CHECK: %[[VAL_3:.*]] = arith.constant {{[0-9]*}} : i32
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>>
+// CHECK: %[[VAL_7:.*]] = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_7]] {uniq_name = "_QFreshape1Ex"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
+// CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_9]]) dummy_scope %[[VAL_7]] {uniq_name = "_QFreshape1Ey"} : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<1xi32>>, !fir.ref<!fir.array<1xi32>>)
+// CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_10]]#1(%[[VAL_11]]) : (!fir.ref<!fir.array<1xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi32>>
+// CHECK: %[[VAL_13:.*]] = fir.absent !fir.box<i1>
+// CHECK: %[[VAL_14:.*]] = fir.absent !fir.box<i1>
+// CHECK: %[[VAL_15:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
+// CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_15]](%[[VAL_16]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+// CHECK: fir.store %[[VAL_17]] to %[[VAL_6]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK: %[[VAL_18:.*]] = fir.address_of(@_QQcl
+// CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_8]]#1 : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.array<1xi32>>) -> !fir.box<none>
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_13]] : (!fir.box<i1>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_14]] : (!fir.box<i1>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_18]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAReshape(%[[VAL_19]], %[[VAL_20]], %[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_6]] : !fir.ref<!fir.box<...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/124226
More information about the flang-commits
mailing list