From 9cbeb97024515e6c1fca506623c384b4876ac231 Mon Sep 17 00:00:00 2001 From: Tom Eccles Date: Fri, 17 Mar 2023 09:25:52 +0000 Subject: [PATCH] [flang][hlfir] move intrinsic lowering out of BufferizeHLFIR This move is useful for a few reasons: - It is easier to see what the intrinsic lowering is doing when the operations it creates are not immediately lowered - When lowering a HLFIR intrinsic generates an operation which needs to be lowered by another pattern matcher in the same pass, MLIR will run that other substitution before validating and finalizing the original changes. This means that the erasure of operations is not yet visible to subsequent matchers, which hugely complicates transformations (in this case, hlfir.exprs cannot be rewritten because they are still used by the now-erased HLFIR intrinsic op. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D145502 --- flang/include/flang/Optimizer/HLFIR/Passes.h | 1 + flang/include/flang/Optimizer/HLFIR/Passes.td | 5 + .../Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp | 220 +--------------- .../lib/Optimizer/HLFIR/Transforms/CMakeLists.txt | 1 + .../HLFIR/Transforms/LowerHLFIRIntrinsics.cpp | 286 +++++++++++++++++++++ ...atmul-bufferization.fir => matmul-lowering.fir} | 12 +- .../{sum-bufferization.fir => sum-lowering.fir} | 11 +- ...se-bufferization.fir => transpose-lowering.fir} | 11 +- 8 files changed, 310 insertions(+), 237 deletions(-) create mode 100644 flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp rename flang/test/HLFIR/{matmul-bufferization.fir => matmul-lowering.fir} (87%) rename flang/test/HLFIR/{sum-bufferization.fir => sum-lowering.fir} (96%) rename flang/test/HLFIR/{transpose-bufferization.fir => transpose-lowering.fir} (86%) diff --git a/flang/include/flang/Optimizer/HLFIR/Passes.h b/flang/include/flang/Optimizer/HLFIR/Passes.h index 53d2186..2d9ac0c 100644 --- a/flang/include/flang/Optimizer/HLFIR/Passes.h +++ b/flang/include/flang/Optimizer/HLFIR/Passes.h @@ -23,6 +23,7 @@ namespace hlfir { std::unique_ptr createConvertHLFIRtoFIRPass(); std::unique_ptr createBufferizeHLFIRPass(); +std::unique_ptr createLowerHLFIRIntrinsicsPass(); #define GEN_PASS_REGISTRATION #include "flang/Optimizer/HLFIR/Passes.h.inc" diff --git a/flang/include/flang/Optimizer/HLFIR/Passes.td b/flang/include/flang/Optimizer/HLFIR/Passes.td index 3fac0b2..faf5cd9 100644 --- a/flang/include/flang/Optimizer/HLFIR/Passes.td +++ b/flang/include/flang/Optimizer/HLFIR/Passes.td @@ -20,4 +20,9 @@ def BufferizeHLFIR : Pass<"bufferize-hlfir", "::mlir::ModuleOp"> { let constructor = "hlfir::createBufferizeHLFIRPass()"; } +def LowerHLFIRIntrinsics : Pass<"lower-hlfir-intrinsics", "::mlir::ModuleOp"> { + let summary = "Lower HLFIR transformational intrinsic operations"; + let constructor = "hlfir::createLowerHLFIRIntrinsicsPass()"; +} + #endif //FORTRAN_DIALECT_HLFIR_PASSES diff --git a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp index cc44e0e..44a61f0 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp @@ -15,8 +15,6 @@ #include "flang/Optimizer/Builder/Character.h" #include "flang/Optimizer/Builder/FIRBuilder.h" #include "flang/Optimizer/Builder/HLFIRTools.h" -#include "flang/Optimizer/Builder/IntrinsicCall.h" -#include "flang/Optimizer/Builder/MutableBox.h" #include "flang/Optimizer/Builder/Runtime/Assign.h" #include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Dialect/FIRDialect.h" @@ -31,7 +29,6 @@ #include "mlir/Pass/PassManager.h" #include "mlir/Transforms/DialectConversion.h" #include -#include namespace hlfir { #define GEN_PASS_DEF_BUFFERIZEHLFIR @@ -510,219 +507,6 @@ struct ElementalOpConversion } }; -/// Base class for passes converting transformational intrinsic operations into -/// runtime calls -template -class HlfirIntrinsicConversion : public mlir::OpConversionPattern { - using mlir::OpConversionPattern::OpConversionPattern; - -protected: - struct IntrinsicArgument { - mlir::Value val; // allowed to be null if the argument is absent - mlir::Type desiredType; - }; - - /// Lower the arguments to the intrinsic: adding nesecarry boxing and - /// conversion to match the signature of the intrinsic in the runtime library. - llvm::SmallVector - lowerArguments(mlir::Operation *op, - const llvm::ArrayRef &args, - mlir::ConversionPatternRewriter &rewriter, - const fir::IntrinsicArgumentLoweringRules *argLowering) const { - mlir::Location loc = op->getLoc(); - fir::KindMapping kindMapping{rewriter.getContext()}; - fir::FirOpBuilder builder{rewriter, kindMapping}; - - llvm::SmallVector ret; - - for (size_t i = 0; i < args.size(); ++i) { - mlir::Value arg = args[i].val; - mlir::Type desiredType = args[i].desiredType; - if (!arg) { - ret.emplace_back(fir::getAbsentIntrinsicArgument()); - continue; - } - hlfir::Entity entity{arg}; - - fir::ArgLoweringRule argRules = - fir::lowerIntrinsicArgumentAs(*argLowering, i); - switch (argRules.lowerAs) { - case fir::LowerIntrinsicArgAs::Value: { - if (args[i].desiredType != arg.getType()) { - arg = builder.createConvert(loc, desiredType, arg); - entity = hlfir::Entity{arg}; - } - auto [exv, cleanup] = hlfir::convertToValue(loc, builder, entity); - if (cleanup) - TODO(loc, "extended value cleanup"); - ret.emplace_back(exv); - } break; - case fir::LowerIntrinsicArgAs::Addr: { - auto [exv, cleanup] = - hlfir::convertToAddress(loc, builder, entity, desiredType); - if (cleanup) - TODO(loc, "extended value cleanup"); - ret.emplace_back(exv); - } break; - case fir::LowerIntrinsicArgAs::Box: { - auto [box, cleanup] = - hlfir::convertToBox(loc, builder, entity, desiredType); - if (cleanup) - TODO(loc, "extended value cleanup"); - ret.emplace_back(box); - } break; - case fir::LowerIntrinsicArgAs::Inquired: { - if (args[i].desiredType != arg.getType()) { - arg = builder.createConvert(loc, desiredType, arg); - entity = hlfir::Entity{arg}; - } - // Place hlfir.expr in memory, and unbox fir.boxchar. Other entities - // are translated to fir::ExtendedValue without transofrmation (notably, - // pointers/allocatable are not dereferenced). - // TODO: once lowering to FIR retires, UBOUND and LBOUND can be - // simplified since the fir.box lowered here are now guarenteed to - // contain the local lower bounds thanks to the hlfir.declare (the extra - // rebox can be removed). - auto [exv, cleanup] = - hlfir::translateToExtendedValue(loc, builder, entity); - if (cleanup) - TODO(loc, "extended value cleanup"); - ret.emplace_back(exv); - } break; - } - } - - return ret; - } - - void processReturnValue(mlir::Operation *op, - const fir::ExtendedValue &resultExv, bool mustBeFreed, - fir::FirOpBuilder &builder, - mlir::PatternRewriter &rewriter) const { - mlir::Location loc = op->getLoc(); - - mlir::Value firBase = fir::getBase(resultExv); - mlir::Type firBaseTy = firBase.getType(); - - std::optional resultEntity; - if (fir::isa_trivial(firBaseTy)) { - resultEntity = hlfir::EntityWithAttributes{firBase}; - } else { - resultEntity = - hlfir::genDeclare(loc, builder, resultExv, ".tmp.intrinsic_result", - fir::FortranVariableFlagsAttr{}); - } - - if (resultEntity->isVariable()) { - hlfir::AsExprOp asExpr = builder.create( - loc, *resultEntity, builder.createBool(loc, mustBeFreed)); - resultEntity = hlfir::EntityWithAttributes{asExpr.getResult()}; - } - - rewriter.replaceOp(op, resultEntity->getBase()); - } -}; - -struct SumOpConversion : public HlfirIntrinsicConversion { - using HlfirIntrinsicConversion::HlfirIntrinsicConversion; - - mlir::LogicalResult - matchAndRewrite(hlfir::SumOp sum, OpAdaptor adaptor, - mlir::ConversionPatternRewriter &rewriter) const override { - fir::KindMapping kindMapping{rewriter.getContext()}; - fir::FirOpBuilder builder{rewriter, kindMapping}; - const mlir::Location &loc = sum->getLoc(); - HLFIRListener listener{builder, rewriter}; - builder.setListener(&listener); - - mlir::Type i32 = builder.getI32Type(); - mlir::Type logicalType = fir::LogicalType::get( - builder.getContext(), builder.getKindMap().defaultLogicalKind()); - - llvm::SmallVector inArgs; - inArgs.push_back({sum.getArray(), sum.getArray().getType()}); - inArgs.push_back({sum.getDim(), i32}); - inArgs.push_back({sum.getMask(), logicalType}); - - auto *argLowering = fir::getIntrinsicArgumentLowering("sum"); - llvm::SmallVector args = - lowerArguments(sum, inArgs, rewriter, argLowering); - - mlir::Type scalarResultType = hlfir::getFortranElementType(sum.getType()); - - auto [resultExv, mustBeFreed] = - fir::genIntrinsicCall(builder, loc, "sum", scalarResultType, args); - - processReturnValue(sum, resultExv, mustBeFreed, builder, rewriter); - return mlir::success(); - } -}; - -struct MatmulOpConversion : public HlfirIntrinsicConversion { - using HlfirIntrinsicConversion::HlfirIntrinsicConversion; - - mlir::LogicalResult - matchAndRewrite(hlfir::MatmulOp matmul, OpAdaptor adaptor, - mlir::ConversionPatternRewriter &rewriter) const override { - fir::KindMapping kindMapping{rewriter.getContext()}; - fir::FirOpBuilder builder{rewriter, kindMapping}; - const mlir::Location &loc = matmul->getLoc(); - HLFIRListener listener{builder, rewriter}; - builder.setListener(&listener); - - mlir::Value lhs = matmul.getLhs(); - mlir::Value rhs = matmul.getRhs(); - llvm::SmallVector inArgs; - inArgs.push_back({lhs, lhs.getType()}); - inArgs.push_back({rhs, rhs.getType()}); - - auto *argLowering = fir::getIntrinsicArgumentLowering("matmul"); - llvm::SmallVector args = - lowerArguments(matmul, inArgs, rewriter, argLowering); - - mlir::Type scalarResultType = - hlfir::getFortranElementType(matmul.getType()); - - auto [resultExv, mustBeFreed] = - fir::genIntrinsicCall(builder, loc, "matmul", scalarResultType, args); - - processReturnValue(matmul, resultExv, mustBeFreed, builder, rewriter); - return mlir::success(); - } -}; - -class TransposeOpConversion - : public HlfirIntrinsicConversion { - using HlfirIntrinsicConversion::HlfirIntrinsicConversion; - - mlir::LogicalResult - matchAndRewrite(hlfir::TransposeOp transpose, OpAdaptor adaptor, - mlir::ConversionPatternRewriter &rewriter) const override { - fir::KindMapping kindMapping{rewriter.getContext()}; - fir::FirOpBuilder builder{rewriter, kindMapping}; - const mlir::Location &loc = transpose->getLoc(); - HLFIRListener listener{builder, rewriter}; - builder.setListener(&listener); - - mlir::Value arg = transpose.getArray(); - llvm::SmallVector inArgs; - inArgs.push_back({arg, arg.getType()}); - - auto *argLowering = fir::getIntrinsicArgumentLowering("transpose"); - llvm::SmallVector args = - lowerArguments(transpose, inArgs, rewriter, argLowering); - - mlir::Type scalarResultType = - hlfir::getFortranElementType(transpose.getType()); - - auto [resultExv, mustBeFreed] = fir::genIntrinsicCall( - builder, loc, "transpose", scalarResultType, args); - - processReturnValue(transpose, resultExv, mustBeFreed, builder, rewriter); - return mlir::success(); - } -}; - class BufferizeHLFIR : public hlfir::impl::BufferizeHLFIRBase { public: void runOnOperation() override { @@ -740,9 +524,7 @@ public: .insert( - context); + NoReassocOpConversion, SetLengthOpConversion>(context); mlir::ConversionTarget target(*context); target.addIllegalOp +#include + +namespace hlfir { +#define GEN_PASS_DEF_LOWERHLFIRINTRINSICS +#include "flang/Optimizer/HLFIR/Passes.h.inc" +} // namespace hlfir + +namespace { + +/// Base class for passes converting transformational intrinsic operations into +/// runtime calls +template +class HlfirIntrinsicConversion : public mlir::OpRewritePattern { + using mlir::OpRewritePattern::OpRewritePattern; + +protected: + struct IntrinsicArgument { + mlir::Value val; // allowed to be null if the argument is absent + mlir::Type desiredType; + }; + + /// Lower the arguments to the intrinsic: adding nesecarry boxing and + /// conversion to match the signature of the intrinsic in the runtime library. + llvm::SmallVector + lowerArguments(mlir::Operation *op, + const llvm::ArrayRef &args, + mlir::PatternRewriter &rewriter, + const fir::IntrinsicArgumentLoweringRules *argLowering) const { + mlir::Location loc = op->getLoc(); + fir::KindMapping kindMapping{rewriter.getContext()}; + fir::FirOpBuilder builder{rewriter, kindMapping}; + + llvm::SmallVector ret; + + for (size_t i = 0; i < args.size(); ++i) { + mlir::Value arg = args[i].val; + mlir::Type desiredType = args[i].desiredType; + if (!arg) { + ret.emplace_back(fir::getAbsentIntrinsicArgument()); + continue; + } + hlfir::Entity entity{arg}; + + fir::ArgLoweringRule argRules = + fir::lowerIntrinsicArgumentAs(*argLowering, i); + switch (argRules.lowerAs) { + case fir::LowerIntrinsicArgAs::Value: { + if (args[i].desiredType != arg.getType()) { + arg = builder.createConvert(loc, desiredType, arg); + entity = hlfir::Entity{arg}; + } + auto [exv, cleanup] = hlfir::convertToValue(loc, builder, entity); + if (cleanup) + TODO(loc, "extended value cleanup"); + ret.emplace_back(exv); + } break; + case fir::LowerIntrinsicArgAs::Addr: { + auto [exv, cleanup] = + hlfir::convertToAddress(loc, builder, entity, desiredType); + if (cleanup) + TODO(loc, "extended value cleanup"); + ret.emplace_back(exv); + } break; + case fir::LowerIntrinsicArgAs::Box: { + auto [box, cleanup] = + hlfir::convertToBox(loc, builder, entity, desiredType); + if (cleanup) + TODO(loc, "extended value cleanup"); + ret.emplace_back(box); + } break; + case fir::LowerIntrinsicArgAs::Inquired: { + if (args[i].desiredType != arg.getType()) { + arg = builder.createConvert(loc, desiredType, arg); + entity = hlfir::Entity{arg}; + } + // Place hlfir.expr in memory, and unbox fir.boxchar. Other entities + // are translated to fir::ExtendedValue without transofrmation (notably, + // pointers/allocatable are not dereferenced). + // TODO: once lowering to FIR retires, UBOUND and LBOUND can be + // simplified since the fir.box lowered here are now guarenteed to + // contain the local lower bounds thanks to the hlfir.declare (the extra + // rebox can be removed). + auto [exv, cleanup] = + hlfir::translateToExtendedValue(loc, builder, entity); + if (cleanup) + TODO(loc, "extended value cleanup"); + ret.emplace_back(exv); + } break; + } + } + + return ret; + } + + void processReturnValue(mlir::Operation *op, + const fir::ExtendedValue &resultExv, bool mustBeFreed, + fir::FirOpBuilder &builder, + mlir::PatternRewriter &rewriter) const { + mlir::Location loc = op->getLoc(); + + mlir::Value firBase = fir::getBase(resultExv); + mlir::Type firBaseTy = firBase.getType(); + + std::optional resultEntity; + if (fir::isa_trivial(firBaseTy)) { + resultEntity = hlfir::EntityWithAttributes{firBase}; + } else { + resultEntity = + hlfir::genDeclare(loc, builder, resultExv, ".tmp.intrinsic_result", + fir::FortranVariableFlagsAttr{}); + } + + if (resultEntity->isVariable()) { + hlfir::AsExprOp asExpr = builder.create( + loc, *resultEntity, builder.createBool(loc, mustBeFreed)); + resultEntity = hlfir::EntityWithAttributes{asExpr.getResult()}; + } + + mlir::Value base = resultEntity->getBase(); + if (!mlir::isa(base.getType())) { + for (mlir::Operation *use : op->getResult(0).getUsers()) { + if (mlir::isa(use)) + rewriter.eraseOp(use); + } + } + rewriter.replaceAllUsesWith(op->getResults(), {base}); + rewriter.replaceOp(op, base); + } +}; + +struct SumOpConversion : public HlfirIntrinsicConversion { + using HlfirIntrinsicConversion::HlfirIntrinsicConversion; + + mlir::LogicalResult + matchAndRewrite(hlfir::SumOp sum, + mlir::PatternRewriter &rewriter) const override { + fir::KindMapping kindMapping{rewriter.getContext()}; + fir::FirOpBuilder builder{rewriter, kindMapping}; + const mlir::Location &loc = sum->getLoc(); + + mlir::Type i32 = builder.getI32Type(); + mlir::Type logicalType = fir::LogicalType::get( + builder.getContext(), builder.getKindMap().defaultLogicalKind()); + + llvm::SmallVector inArgs; + inArgs.push_back({sum.getArray(), sum.getArray().getType()}); + inArgs.push_back({sum.getDim(), i32}); + inArgs.push_back({sum.getMask(), logicalType}); + + auto *argLowering = fir::getIntrinsicArgumentLowering("sum"); + llvm::SmallVector args = + lowerArguments(sum, inArgs, rewriter, argLowering); + + mlir::Type scalarResultType = hlfir::getFortranElementType(sum.getType()); + + auto [resultExv, mustBeFreed] = + fir::genIntrinsicCall(builder, loc, "sum", scalarResultType, args); + + processReturnValue(sum, resultExv, mustBeFreed, builder, rewriter); + return mlir::success(); + } +}; + +struct MatmulOpConversion : public HlfirIntrinsicConversion { + using HlfirIntrinsicConversion::HlfirIntrinsicConversion; + + mlir::LogicalResult + matchAndRewrite(hlfir::MatmulOp matmul, + mlir::PatternRewriter &rewriter) const override { + fir::KindMapping kindMapping{rewriter.getContext()}; + fir::FirOpBuilder builder{rewriter, kindMapping}; + const mlir::Location &loc = matmul->getLoc(); + + mlir::Value lhs = matmul.getLhs(); + mlir::Value rhs = matmul.getRhs(); + llvm::SmallVector inArgs; + inArgs.push_back({lhs, lhs.getType()}); + inArgs.push_back({rhs, rhs.getType()}); + + auto *argLowering = fir::getIntrinsicArgumentLowering("matmul"); + llvm::SmallVector args = + lowerArguments(matmul, inArgs, rewriter, argLowering); + + mlir::Type scalarResultType = + hlfir::getFortranElementType(matmul.getType()); + + auto [resultExv, mustBeFreed] = + fir::genIntrinsicCall(builder, loc, "matmul", scalarResultType, args); + + processReturnValue(matmul, resultExv, mustBeFreed, builder, rewriter); + return mlir::success(); + } +}; + +class TransposeOpConversion + : public HlfirIntrinsicConversion { + using HlfirIntrinsicConversion::HlfirIntrinsicConversion; + + mlir::LogicalResult + matchAndRewrite(hlfir::TransposeOp transpose, + mlir::PatternRewriter &rewriter) const override { + fir::KindMapping kindMapping{rewriter.getContext()}; + fir::FirOpBuilder builder{rewriter, kindMapping}; + const mlir::Location &loc = transpose->getLoc(); + + mlir::Value arg = transpose.getArray(); + llvm::SmallVector inArgs; + inArgs.push_back({arg, arg.getType()}); + + auto *argLowering = fir::getIntrinsicArgumentLowering("transpose"); + llvm::SmallVector args = + lowerArguments(transpose, inArgs, rewriter, argLowering); + + mlir::Type scalarResultType = + hlfir::getFortranElementType(transpose.getType()); + + auto [resultExv, mustBeFreed] = fir::genIntrinsicCall( + builder, loc, "transpose", scalarResultType, args); + + processReturnValue(transpose, resultExv, mustBeFreed, builder, rewriter); + return mlir::success(); + } +}; + +class LowerHLFIRIntrinsics + : public hlfir::impl::LowerHLFIRIntrinsicsBase { +public: + void runOnOperation() override { + // TODO: make this a pass operating on FuncOp. The issue is that + // FirOpBuilder helpers may generate new FuncOp because of runtime/llvm + // intrinsics calls creation. This may create race conflict if the pass is + // scheduled on FuncOp. A solution could be to provide an optional mutex + // when building a FirOpBuilder and locking around FuncOp and GlobalOp + // creation, but this needs a bit more thinking, so at this point the pass + // is scheduled on the moduleOp. + mlir::ModuleOp module = this->getOperation(); + mlir::MLIRContext *context = &getContext(); + mlir::RewritePatternSet patterns(context); + patterns.insert( + context); + mlir::ConversionTarget target(*context); + target.addLegalDialect(); + target.addIllegalOp(); + target.markUnknownOpDynamicallyLegal( + [](mlir::Operation *) { return true; }); + if (mlir::failed( + mlir::applyFullConversion(module, target, std::move(patterns)))) { + mlir::emitError(mlir::UnknownLoc::get(context), + "failure in HLFIR intrinsic lowering"); + signalPassFailure(); + } + } +}; +} // namespace + +std::unique_ptr hlfir::createLowerHLFIRIntrinsicsPass() { + return std::make_unique(); +} diff --git a/flang/test/HLFIR/matmul-bufferization.fir b/flang/test/HLFIR/matmul-lowering.fir similarity index 87% rename from flang/test/HLFIR/matmul-bufferization.fir rename to flang/test/HLFIR/matmul-lowering.fir index 54da40c..d4819f1 100644 --- a/flang/test/HLFIR/matmul-bufferization.fir +++ b/flang/test/HLFIR/matmul-lowering.fir @@ -1,5 +1,5 @@ // Test hlfir.matmul operation lowering to fir runtime call -// RUN: fir-opt %s -bufferize-hlfir | FileCheck %s +// RUN: fir-opt %s -lower-hlfir-intrinsics | FileCheck %s func.func @_QPmatmul1(%arg0: !fir.box> {fir.bindc_name = "lhs"}, %arg1: !fir.box> {fir.bindc_name = "rhs"}, %arg2: !fir.box> {fir.bindc_name = "res"}) { %0:2 = hlfir.declare %arg0 {uniq_name = "_QFmatmul1Elhs"} : (!fir.box>) -> (!fir.box>, !fir.box>) @@ -36,10 +36,10 @@ func.func @_QPmatmul1(%arg0: !fir.box> {fir.bindc_name = "lh // CHECK-NEXT: %[[SHIFT:.*]] = fir.shape_shift %[[BOX_DIMS]]#0, %[[BOX_DIMS]]#1 // TODO: fix alias analysis in hlfir.assign bufferization // CHECK-NEXT: %[[TMP:.*]]:2 = hlfir.declare %[[ADDR]](%[[SHIFT]]) {uniq_name = ".tmp.intrinsic_result"} -// CHECK: %[[TUPLE0:.*]] = fir.undefined tuple>, i1> -// CHECK: %[[TUPLE1:.*]] = fir.insert_value %[[TUPLE0]], %[[TRUE:.*]], [1 : index] -// CHECK: %[[TUPLE2:.*]] = fir.insert_value %[[TUPLE1]], %[[TMP]]#0, [0 : index] -// CHECK: hlfir.assign %[[TMP]]#0 to %[[RES_VAR]]#0 -// CHECK: fir.freemem %[[TMP]]#1 +// TODO: add shape information from original intrinsic op +// CHECK: %[[TRUE:.*]] = arith.constant true +// CHECK: %[[ASEXPR:.*]] = hlfir.as_expr %[[TMP]]#0 move %[[TRUE]] : (!fir.box>, i1) -> !hlfir.expr +// CHECK: hlfir.assign %[[ASEXPR]] to %[[RES_VAR]]#0 +// CHECK: hlfir.destroy %[[ASEXPR]] // CHECK-NEXT: return // CHECK-NEXT: } diff --git a/flang/test/HLFIR/sum-bufferization.fir b/flang/test/HLFIR/sum-lowering.fir similarity index 96% rename from flang/test/HLFIR/sum-bufferization.fir rename to flang/test/HLFIR/sum-lowering.fir index d1bdd9f..c031f6d 100644 --- a/flang/test/HLFIR/sum-bufferization.fir +++ b/flang/test/HLFIR/sum-lowering.fir @@ -1,5 +1,5 @@ // Test hlfir.sum operation lowering to fir runtime call -// RUN: fir-opt %s -bufferize-hlfir | FileCheck %s +// RUN: fir-opt %s -lower-hlfir-intrinsics | FileCheck %s // simple one argument sum func.func @_QPsum1(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s"}) { @@ -64,11 +64,10 @@ func.func @_QPsum2(%arg0: !fir.box> {fir.bindc_name = "a"}, // CHECK-NEXT: %[[SHIFT:.*]] = fir.shape_shift %[[BOX_DIMS]]#0, %[[BOX_DIMS]]#1 // TODO: fix alias analysis in hlfir.assign bufferization // CHECK-NEXT: %[[TMP:.*]]:2 = hlfir.declare %[[ADDR]](%[[SHIFT]]) {uniq_name = ".tmp.intrinsic_result"} -// CHECK: %[[TUPLE0:.*]] = fir.undefined tuple>, i1> -// CHECK: %[[TUPLE1:.*]] = fir.insert_value %[[TUPLE0]], %[[TRUE:.*]], [1 : index] -// CHECK: %[[TUPLE2:.*]] fir.insert_value %[[TUPLE1]], %[[TMP]]#0, [0 : index] -// CHECK: hlfir.assign %[[TMP]]#0 to %[[RES]]#0 -// CHECK: fir.freemem %[[TMP]]#1 +// CHECK: %[[TRUE:.*]] = arith.constant true +// CHECK: %[[ASEXPR:.*]] = hlfir.as_expr %[[TMP]]#0 move %[[TRUE]] : (!fir.box>, i1) -> !hlfir.expr +// CHECK: hlfir.assign %[[ASEXPR]] to %[[RES]]#0 +// CHECK: hlfir.destroy %[[ASEXPR]] // CHECK-NEXT: return // CHECK-NEXT: } diff --git a/flang/test/HLFIR/transpose-bufferization.fir b/flang/test/HLFIR/transpose-lowering.fir similarity index 86% rename from flang/test/HLFIR/transpose-bufferization.fir rename to flang/test/HLFIR/transpose-lowering.fir index 0db359a..733e6f1 100644 --- a/flang/test/HLFIR/transpose-bufferization.fir +++ b/flang/test/HLFIR/transpose-lowering.fir @@ -1,5 +1,5 @@ // Test hlfir.transpose operation lowering to fir runtime call -// RUN: fir-opt %s -bufferize-hlfir | FileCheck %s +// RUN: fir-opt %s -lower-hlfir-intrinsics | FileCheck %s func.func @_QPtranspose1(%arg0: !fir.ref> {fir.bindc_name = "m"}, %arg1: !fir.ref> {fir.bindc_name = "res"}) { %c1 = arith.constant 1 : index @@ -40,10 +40,9 @@ func.func @_QPtranspose1(%arg0: !fir.ref> {fir.bindc_name = // CHECK-NEXT: %[[SHIFT:.*]] = fir.shape_shift %[[BOX_DIMS]]#0, %[[BOX_DIMS]]#1 // TODO: fix alias analysis in hlfir.assign bufferization // CHECK-NEXT: %[[TMP:.*]]:2 = hlfir.declare %[[ADDR]](%[[SHIFT]]) {uniq_name = ".tmp.intrinsic_result"} -// CHECK: %[[TUPLE0:.*]] = fir.undefined tuple>, i1> -// CHECK: %[[TUPLE1:.*]] = fir.insert_value %[[TUPLE0]], %[[TRUE:.*]], [1 : index] -// CHECK: %[[TUPLE2:.*]] = fir.insert_value %[[TUPLE1]], %[[TMP]]#0, [0 : index] -// CHECK: hlfir.assign %[[TMP]]#0 to %[[RES_VAR]]#0 -// CHECK: fir.freemem %[[TMP]]#1 +// CHECK: %[[TRUE:.*]] = arith.constant true +// CHECK: %[[ASEXPR:.*]] = hlfir.as_expr %[[TMP]]#0 move %[[TRUE]] : (!fir.box>, i1) -> !hlfir.expr +// CHECK: hlfir.assign %[[ASEXPR]] to %[[RES_VAR]]#0 +// CHECK: hlfir.destroy %[[ASEXPR]] // CHECK-NEXT: return // CHECK-NEXT: } -- 2.7.4