[flang-commits] [flang] [flang][hlfir] Add hlfir.minval intrinsic (PR #66306)
via flang-commits
flang-commits at lists.llvm.org
Wed Sep 13 17:15:48 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
<details>
<summary>Changes</summary>
Adds a new HLFIR operation for the MINVAL intrinsic according to the design set out in flang/docs/HighLevelFIR.md.
--
Patch is 63.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66306.diff
9 Files Affected:
- (modified) flang/include/flang/Optimizer/HLFIR/HLFIROps.td (+27)
- (modified) flang/lib/Lower/HlfirIntrinsics.cpp (+4)
- (modified) flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp (+25)
- (modified) flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp (+9-3)
- (modified) flang/test/HLFIR/invalid.fir (+78)
- (modified) flang/test/HLFIR/memory-effects.fir (+15)
- (added) flang/test/HLFIR/minval-lowering.fir (+218)
- (added) flang/test/HLFIR/minval.fir (+249)
- (added) flang/test/Lower/HLFIR/minval.f90 (+262)
<pre>
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
index aef3b1d976f16d9..1f584d6afd8fbcb 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
@@ -431,6 +431,33 @@ def hlfir_MaxvalOp : hlfir_Op<"maxval", [AttrSizedOperandSegments,
let hasVerifier = 1;
}
+def hlfir_MinvalOp : hlfir_Op<"minval", [AttrSizedOperandSegments,
+ DeclareOpInterfaceMethods<ArithFastMathInterface>,
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ let summary = "MINVAL transformational intrinsic";
+ let description = [{
+ Minimum value(s) of an array.
+ If DIM is absent, the result is a scalar.
+ If DIM is present, the result is an array of rank n-1, where n is the rank of ARRAY.
+ }];
+
+ let arguments = (ins
+ AnyFortranArrayObject:$array,
+ Optional<AnyIntegerType>:$dim,
+ Optional<AnyFortranLogicalOrI1ArrayObject>:$mask,
+ DefaultValuedAttr<Arith_FastMathAttr,
+ "::mlir::arith::FastMathFlags::none">:$fastmath
+ );
+
+ let results = (outs AnyFortranValue);
+
+ let assemblyFormat = [{
+ $array (`dim` $dim^)? (`mask` $mask^)? attr-dict `:` functional-type(operands, results)
+ }];
+
+ let hasVerifier = 1;
+}
+
def hlfir_ProductOp : hlfir_Op<"product", [AttrSizedOperandSegments,
DeclareOpInterfaceMethods<ArithFastMathInterface>,
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
diff --git a/flang/lib/Lower/HlfirIntrinsics.cpp b/flang/lib/Lower/HlfirIntrinsics.cpp
index 4d25c59bf79ca6c..62f63e376c815df 100644
--- a/flang/lib/Lower/HlfirIntrinsics.cpp
+++ b/flang/lib/Lower/HlfirIntrinsics.cpp
@@ -89,6 +89,7 @@ class HlfirReductionIntrinsic : public HlfirTransformationalIntrinsic {
using HlfirSumLowering = HlfirReductionIntrinsic<hlfir::SumOp, true>;
using HlfirProductLowering = HlfirReductionIntrinsic<hlfir::ProductOp, true>;
using HlfirMaxvalLowering = HlfirReductionIntrinsic<hlfir::MaxvalOp, true>;
+using HlfirMinvalLowering = HlfirReductionIntrinsic<hlfir::MinvalOp, true>;
using HlfirAnyLowering = HlfirReductionIntrinsic<hlfir::AnyOp, false>;
using HlfirAllLowering = HlfirReductionIntrinsic<hlfir::AllOp, false>;
@@ -356,6 +357,9 @@ std::optional<hlfir::EntityWithAttributes> Fortran::lower::lowerHlfirIntrinsic(
if (name == "maxval")
return HlfirMaxvalLowering{builder, loc}.lower(loweredActuals, argLowering,
stmtResultType);
+ if (name == "minval")
+ return HlfirMinvalLowering{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 531a40c8dd4f920..760f7b343bdc736 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -845,6 +845,31 @@ void hlfir::MaxvalOp::getEffects(
getIntrinsicEffects(getOperation(), effects);
}
+//===----------------------------------------------------------------------===//
+// MinvalOp
+//===----------------------------------------------------------------------===//
+
+mlir::LogicalResult hlfir::MinvalOp::verify() {
+ mlir::Operation *op = getOperation();
+
+ auto results = op->getResultTypes();
+ assert(results.size() == 1);
+
+ auto resultExpr = mlir::dyn_cast<hlfir::ExprType>(results[0]);
+ if (resultExpr && mlir::isa<fir::CharacterType>(resultExpr.getEleTy())) {
+ return verifyCharacterReductionOp<hlfir::MinvalOp *>(this);
+ } else {
+ return verifyNumericalReductionOp<hlfir::MinvalOp *>(this);
+ }
+}
+
+void hlfir::MinvalOp::getEffects(
+ llvm::SmallVectorImpl<
+ mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
+ &effects) {
+ getIntrinsicEffects(getOperation(), effects);
+}
+
//===----------------------------------------------------------------------===//
// SetLengthOp
//===----------------------------------------------------------------------===//
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp
index b6045fdef0987c0..f2628fcb970bc47 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp
@@ -222,6 +222,8 @@ class HlfirReductionIntrinsicConversion : public HlfirIntrinsicConversion<OP> {
opName = "product";
} else if constexpr (std::is_same_v<OP, hlfir::MaxvalOp>) {
opName = "maxval";
+ } else if constexpr (std::is_same_v<OP, hlfir::MinvalOp>) {
+ opName = "minval";
} else if constexpr (std::is_same_v<OP, hlfir::AnyOp>) {
opName = "any";
} else if constexpr (std::is_same_v<OP, hlfir::AllOp>) {
@@ -241,7 +243,8 @@ class HlfirReductionIntrinsicConversion : public HlfirIntrinsicConversion<OP> {
if constexpr (std::is_same_v<OP, hlfir::SumOp> ||
std::is_same_v<OP, hlfir::ProductOp> ||
- std::is_same_v<OP, hlfir::MaxvalOp>) {
+ std::is_same_v<OP, hlfir::MaxvalOp> ||
+ std::is_same_v<OP, hlfir::MinvalOp>) {
args = buildNumericalArgs(operation, i32, logicalType, rewriter, opName);
} else {
args = buildLogicalArgs(operation, i32, logicalType, rewriter, opName);
@@ -264,6 +267,8 @@ using ProductOpConversion = HlfirReductionIntrinsicConversion<hlfir::ProductOp>;
using MaxvalOpConversion = HlfirReductionIntrinsicConversion<hlfir::MaxvalOp>;
+using MinvalOpConversion = HlfirReductionIntrinsicConversion<hlfir::MinvalOp>;
+
using AnyOpConversion = HlfirReductionIntrinsicConversion<hlfir::AnyOp>;
using AllOpConversion = HlfirReductionIntrinsicConversion<hlfir::AllOp>;
@@ -440,7 +445,8 @@ class LowerHLFIRIntrinsics
.insert<MatmulOpConversion, MatmulTransposeOpConversion,
AllOpConversion, AnyOpConversion, SumOpConversion,
ProductOpConversion, TransposeOpConversion, CountOpConversion,
- DotProductOpConversion, MaxvalOpConversion>(context);
+ DotProductOpConversion, MaxvalOpConversion, MinvalOpConversion>(
+ context);
mlir::ConversionTarget target(*context);
target.addLegalDialect<mlir::BuiltinDialect, mlir::arith::ArithDialect,
mlir::func::FuncDialect, fir::FIROpsDialect,
@@ -448,7 +454,7 @@ class LowerHLFIRIntrinsics
target.addIllegalOp<hlfir::MatmulOp, hlfir::MatmulTransposeOp, hlfir::SumOp,
hlfir::ProductOp, hlfir::TransposeOp, hlfir::AnyOp,
hlfir::AllOp, hlfir::DotProductOp, hlfir::CountOp,
- hlfir::MaxvalOp>();
+ hlfir::MaxvalOp, hlfir::MinvalOp>();
target.markUnknownOpDynamicallyLegal(
[](mlir::Operation *) { return true; });
if (mlir::failed(
diff --git a/flang/test/HLFIR/invalid.fir b/flang/test/HLFIR/invalid.fir
index 00fe30988439542..112ab4be57f6bfc 100644
--- a/flang/test/HLFIR/invalid.fir
+++ b/flang/test/HLFIR/invalid.fir
@@ -470,6 +470,84 @@ func.func @bad_maxval13(%arg0: !hlfir.expr<?x?x!fir.char<1,?>>, %arg1: i32){
%0 = hlfir.maxval %arg0 dim %arg1 : (!hlfir.expr<?x?x!fir.char<1,?>>, i32) -> !hlfir.expr<!fir.char<1,?>>
}
+// -----
+func.func @bad_minval1(%arg0: !hlfir.expr<?xi32>, %arg1: i32, %arg2: !fir.box<!fir.logical<4>>) {
+ // expected-error at +1 {{'hlfir.minval' op result must have the same element type as ARRAY argument}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?xi32>, i32, !fir.box<!fir.logical<4>>) -> f32
+}
+
+// -----
+func.func @bad_minval2(%arg0: !hlfir.expr<?xi32>, %arg1: i32, %arg2: !fir.box<!fir.array<?x?x?x?x?x!fir.logical<4>>>) {
+ // expected-warning at +1 {{MASK must be conformable to ARRAY}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?xi32>, i32, !fir.box<!fir.array<?x?x?x?x?x!fir.logical<4>>>) -> !hlfir.expr<i32>
+}
+
+// -----
+func.func @bad_minval3(%arg0: !hlfir.expr<?x5x?xi32>, %arg1: i32, %arg2: !fir.box<!fir.array<2x6x?x!fir.logical<4>>>) {
+ // expected-warning at +1 {{MASK must be conformable to ARRAY}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?x5x?xi32>, i32, !fir.box<!fir.array<2x6x?x!fir.logical<4>>>) -> !hlfir.expr<i32>
+}
+
+// -----
+func.func @bad_minval4(%arg0: !hlfir.expr<?x?xi32>, %arg1: i32, %arg2: !fir.box<!fir.logical<4>>) {
+ // expected-error at +1 {{'hlfir.minval' op result rank must be one less than ARRAY}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?x?xi32>, i32, !fir.box<!fir.logical<4>>) -> !hlfir.expr<?x?xi32>
+}
+
+// -----
+func.func @bad_minval5(%arg0: !hlfir.expr<?xi32>, %arg1: i32, %arg2: !fir.box<!fir.logical<4>>) {
+ // expected-error at +1 {{'hlfir.minval' op result must be of numerical scalar type}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?xi32>, i32, !fir.box<!fir.logical<4>>) -> !fir.logical<4>
+}
+
+// -----
+func.func @bad_minval6(%arg0: !hlfir.expr<?x?xi32>, %arg1: i32){
+ // expected-error at +1 {{'hlfir.minval' op result must be an array}}
+ %0 = hlfir.minval %arg0 dim %arg1 : (!hlfir.expr<?x?xi32>, i32) -> !hlfir.expr<i32>
+}
+
+// -----
+func.func @bad_minval7(%arg0: !hlfir.expr<?xi32>){
+ // expected-error at +1 {{'hlfir.minval' op result must be of numerical scalar type}}
+ %0 = hlfir.minval %arg0 : (!hlfir.expr<?xi32>) -> !hlfir.expr<i32>
+}
+
+// -----
+func.func @bad_minval8(%arg0: !hlfir.expr<?x!fir.char<1,?>>, %arg1: i32, %arg2: !fir.box<!fir.logical<4>>) {
+ // expected-error at +1 {{'hlfir.minval' op result must have the same element type as ARRAY argument}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?x!fir.char<1,?>>, i32, !fir.box<!fir.logical<4>>) -> i32
+}
+
+// -----
+func.func @bad_minval9(%arg0: !hlfir.expr<?x!fir.char<1,?>>, %arg1: i32, %arg2: !fir.box<!fir.array<?x?x?x?x?x!fir.logical<4>>>) {
+ // expected-warning at +1 {{MASK must be conformable to ARRAY}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?x!fir.char<1,?>>, i32, !fir.box<!fir.array<?x?x?x?x?x!fir.logical<4>>>) -> !hlfir.expr<!fir.char<1,?>>
+}
+
+// -----
+func.func @bad_minval10(%arg0: !hlfir.expr<?x5x?x!fir.char<1,?>>, %arg1: i32, %arg2: !fir.box<!fir.array<2x6x?x!fir.logical<4>>>) {
+ // expected-warning at +1 {{MASK must be conformable to ARRAY}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?x5x?x!fir.char<1,?>>, i32, !fir.box<!fir.array<2x6x?x!fir.logical<4>>>) -> !hlfir.expr<!fir.char<1,?>>
+}
+
+// -----
+func.func @bad_minval11(%arg0: !hlfir.expr<?x?x!fir.char<1,?>>, %arg1: i32, %arg2: !fir.box<!fir.logical<4>>) {
+ // expected-error at +1 {{'hlfir.minval' op result rank must be one less than ARRAY}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?x?x!fir.char<1,?>>, i32, !fir.box<!fir.logical<4>>) -> !hlfir.expr<?x?x!fir.char<1,?>>
+}
+
+// -----
+func.func @bad_minval12(%arg0: !hlfir.expr<?x!fir.char<1,?>>, %arg1: i32, %arg2: !fir.box<!fir.logical<4>>) {
+ // expected-error at +1 {{'hlfir.minval' op result must be scalar character}}
+ %0 = hlfir.minval %arg0 dim %arg1 mask %arg2 : (!hlfir.expr<?x!fir.char<1,?>>, i32, !fir.box<!fir.logical<4>>) -> !hlfir.expr<?x!fir.char<1,?>>
+}
+
+// -----
+func.func @bad_minval13(%arg0: !hlfir.expr<?x?x!fir.char<1,?>>, %arg1: i32){
+ // expected-error at +1 {{'hlfir.minval' op result must be an array}}
+ %0 = hlfir.minval %arg0 dim %arg1 : (!hlfir.expr<?x?x!fir.char<1,?>>, i32) -> !hlfir.expr<!fir.char<1,?>>
+}
+
// -----
func.func @bad_product1(%arg0: !hlfir.expr<?xi32>, %arg1: i32, %arg2: !fir.box<!fir.logical<4>>) {
// expected-error at +1 {{'hlfir.product' op result must have the same element type as ARRAY argument}}
diff --git a/flang/test/HLFIR/memory-effects.fir b/flang/test/HLFIR/memory-effects.fir
index f30d1b86c4d862a..4b2a0d575db1ac5 100644
--- a/flang/test/HLFIR/memory-effects.fir
+++ b/flang/test/HLFIR/memory-effects.fir
@@ -107,6 +107,21 @@ func.func @maxval_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
return
}
+func.func @minval_no_effects(%arg0: !hlfir.expr<?xf32>) {
+// expected-remark at +1 {{operation has no memory effects}}
+ %minval = hlfir.minval %arg0 : (!hlfir.expr<?xf32>) -> f32
+// expected-remark at +1 {{operation has no memory effects}}
+ return
+}
+
+func.func @minval_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
+// expected-remark at +2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
+// expected-remark at +1 {{found an instance of 'read' on a value, on resource '<Default>'}}
+ %minval = hlfir.minval %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xf32>
+// expected-remark at +1 {{operation has no memory effects}}
+ return
+}
+
func.func @dot_product_no_effects(%arg0: !hlfir.expr<?xf32>, %arg1: !hlfir.expr<?xf32>) {
// expected-remark at +1 {{operation has no memory effects}}
%0 = hlfir.dot_product %arg0 %arg1 : (!hlfir.expr<?xf32>, !hlfir.expr<?xf32>) -> f32
diff --git a/flang/test/HLFIR/minval-lowering.fir b/flang/test/HLFIR/minval-lowering.fir
new file mode 100644
index 000000000000000..fc8fe92dc08a251
--- /dev/null
+++ b/flang/test/HLFIR/minval-lowering.fir
@@ -0,0 +1,218 @@
+// Test hlfir.minval operation lowering to fir runtime call
+// RUN: fir-opt %s -lower-hlfir-intrinsics | FileCheck %s
+
+// simple one argument minval
+func.func @_QPminval1(%arg0: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "a"}, %arg1: !fir.ref<i32> {fir.bindc_name = "s"}) {
+ %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminval1Ea"} : (!fir.box<!fir.array<?xi32>>) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
+ %1:2 = hlfir.declare %arg1 {uniq_name = "_QFminval1Es"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ %2 = hlfir.minval %0#0 {fastmath = #arith.fastmath<contract>} : (!fir.box<!fir.array<?xi32>>) -> i32
+ hlfir.assign %2 to %1#0 : i32, !fir.ref<i32>
+ return
+}
+// CHECK-LABEL: func.func @_QPminval1(
+// CHECK: %[[ARG0:.*]]: !fir.box<!fir.array<?xi32>>
+// CHECK: %[[ARG1:.*]]: !fir.ref<i32>
+// CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]]
+// CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[ARG1]]
+// CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box<i1>
+// CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
+// CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box<i1>) -> !fir.box<none>
+// CHECK: %[[RET:.*]] = fir.call @_FortranAMinvalInteger4(%[[ARRAY_ARG]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[INT:.*]], %[[MASK_ARG]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
+// CHECK-NEXT: hlfir.assign %[[RET]] to %[[RES]]#0 : i32, !fir.ref<i32>
+// CHECK-NEXT: return
+// CHECK-NEXT: }
+
+// minval with a by-ref dimension of index type
+func.func @_QPminval2(%arg0: !fir.box<!fir.array<?x?xi32>> {fir.bindc_name = "a"}, %arg1: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "s"}, %arg2: !fir.ref<index> {fir.bindc_name = "d"}) {
+ %0:2 = hlfir.declare %arg0 {uniq_name = "_QFminval2Ea"} : (!fir.box<!fir.array<?x?xi32>>) -> (!fir.box<!fir.array<?x?xi32>>, !fir.box<!fir.array<?x?xi32>>)
+ %1:2 = hlfir.declare %arg2 {uniq_name = "_QFminval2Ed"} : (!fir.ref<index>) -> (!fir.ref<index>, !fir.ref<index>)
+ %2:2 = hlfir.declare %arg1 {uniq_name = "_QFminval2Es"} : (!fir.box<!fir.array<?xi32>>) -> (!fir.box<!fir.array<?xi32>>, !fir.box<!fir.array<?xi32>>)
+ %3 = fir.load %1#0 : !fir.ref<index>
+ %4 = hlfir.minval %0#0 dim %3#0 {fastmath = #arith.fastmath<contract>} : (!fir.box<!fir.array<?x?xi32>>, index) -> !hlfir.expr<?xi32>
+ hlfir.assign %4 to %2#0 : !hlfir.expr<?xi32>, !fir.box<!fir.array<?xi32>>
+ hlfir.destroy %4 : !hlfir.expr<?xi32>
+ return
+}
+// CHECK-LABEL: func.func @_QPminval2(
+// CHECK: %[[ARG0:.*]]: !fir.box<!fir.array<?x?xi32>>
+// CHECK: %[[ARG1:.*]]: !fir.box<!fir.array<?xi32>>
+// CHECK: %[[ARG2:.*]]: !fir.ref<index>
+// CHECK-DAG: %[[ARRAY:.*]]:2 = hlfir.declare %[[ARG0]]
+// CHECK-DAG: %[[RES:.*]]:2 = hlfir.declare %[[ARG1]]
+// CHECK-DAG: %[[DIM_VAR:.*]]:2 = hlfir.declare %[[ARG2]]
+
+// CHECK-DAG: %[[RET_BOX:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
+// CHECK-DAG: %[[RET_ADDR:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
+// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
+// CHECK-DAG: %[[RET_SHAPE:.*]] = fir.shape %[[C0]] : (index) -> !fir.shape<1>
+// CHECK-DAG: %[[RET_EMBOX:.*]] = fir.embox %[[RET_ADDR]](%[[RET_SHAPE]])
+// CHECK-DAG: fir.store %[[RET_EMBOX]] to %[[RET_BOX]]
+
+// CHECK-DAG: %[[MASK:.*]] = fir.absent !fir.box<i1>
+// CHECK-DAG: %[[DIM_IDX:.*]] = fir.load %[[DIM_VAR]]#0 : !fir.ref<index>
+// CHECK-DAG: %[[DIM:.*]] = fir.convert %[[DIM_IDX]] : (index) -> i32
+
+// CHECK-DAG: %[[RET_ARG:.*]] = fir.convert %[[RET_BOX]]
+// CHECK-DAG: %[[ARRAY_ARG:.*]] = fir.convert %[[ARRAY]]#1 : (!fir.box<!fir.array<?x?xi32>>) -> !fir.box<none>
+// CHECK-DAG: %[[MASK_ARG:.*]] = fir.convert %[[MASK]] : (!fir.box<i1>) -> !fir.box<none>
+// CHECK: %[[NONE:.*]] = fir.call @_FortranAMinvalDim(%[[RET_ARG]], %[[ARRAY_ARG]], %[[DIM]], %[[LOC_STR:.*]], %[[LOC_N:.*]], %[[MASK_ARG]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32, !fir.ref<i8>, i32, !fir.box<none>) -> none
+
+// CHECK: %[[RET:.*]] = fir.load %[[RET_BOX]]
+// CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[RET]]
+// CHECK-NEXT: %[[ADDR:.*]] = fir.box_addr %[[RET]]
+// CHECK-NEXT: %[[SHIFT:.*]] = fir.shape_shift %[[BOX_DIMS]]#0, %[[BOX_DIMS]]#1
+// TODO: fix alias analysis in hlfir.assign bufferization
+// CHECK-N...
<truncated>
</pre>
</details>
https://github.com/llvm/llvm-project/pull/66306
More information about the flang-commits
mailing list