diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h index 93eca7842477..1675c1536386 100644 --- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h +++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h @@ -385,6 +385,15 @@ public: mlir::FunctionType ty, mlir::SymbolTable *); + /// Returns a named function for a Fortran runtime API, creating + /// it, if it does not exist in the module yet. + /// If \p isIO is set to true, then the function corresponds + /// to one of Fortran runtime IO APIs. + mlir::func::FuncOp createRuntimeFunction(mlir::Location loc, + llvm::StringRef name, + mlir::FunctionType ty, + bool isIO = false); + /// Cast the input value to IndexType. mlir::Value convertToIndexType(mlir::Location loc, mlir::Value val) { return createConvert(loc, getIndexType(), val); diff --git a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h index 1ffc354d6b80..5158abaa31ed 100644 --- a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h @@ -21,6 +21,7 @@ #include "flang/Optimizer/Builder/FIRBuilder.h" #include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Runtime/io-api-consts.h" #include "flang/Runtime/reduce.h" #include "flang/Support/Fortran.h" #include "mlir/IR/BuiltinTypes.h" @@ -586,6 +587,33 @@ constexpr TypeBuilderFunc getModel() { }; } +// Define additional runtime type models specific to IO. +template <> +constexpr TypeBuilderFunc getModel() { + return getModel(); +} +template <> +constexpr TypeBuilderFunc getModel() { + return [](mlir::MLIRContext *context) -> mlir::Type { + return mlir::IntegerType::get(context, + 8 * sizeof(Fortran::runtime::io::Iostat)); + }; +} +template <> +constexpr TypeBuilderFunc +getModel() { + return [](mlir::MLIRContext *context) -> mlir::Type { + return fir::ReferenceType::get(mlir::TupleType::get(context)); + }; +} +template <> +constexpr TypeBuilderFunc +getModel() { + return [](mlir::MLIRContext *context) -> mlir::Type { + return fir::ReferenceType::get(mlir::TupleType::get(context)); + }; +} + REDUCTION_REF_OPERATION_MODEL(std::int8_t) REDUCTION_VALUE_OPERATION_MODEL(std::int8_t) REDUCTION_REF_OPERATION_MODEL(std::int16_t) @@ -778,16 +806,22 @@ struct RuntimeTableEntry, RuntimeIdentifier> { /// argument is intended to be of the form: . template static mlir::func::FuncOp getRuntimeFunc(mlir::Location loc, - fir::FirOpBuilder &builder) { + fir::FirOpBuilder &builder, + bool isIO = false) { using namespace Fortran::runtime; auto name = RuntimeEntry::name; auto func = builder.getNamedFunction(name); if (func) return func; auto funTy = RuntimeEntry::getTypeModel()(builder.getContext()); - func = builder.createFunction(loc, name, funTy); - func->setAttr(FIROpsDialect::getFirRuntimeAttrName(), builder.getUnitAttr()); - return func; + return builder.createRuntimeFunction(loc, name, funTy, isIO); +} + +/// Get (or generate) the MLIR FuncOp for a given IO runtime function. +template +static mlir::func::FuncOp getIORuntimeFunc(mlir::Location loc, + fir::FirOpBuilder &builder) { + return getRuntimeFunc(loc, builder, /*isIO=*/true); } namespace helper { diff --git a/flang/include/flang/Optimizer/Dialect/FIRDialect.td b/flang/include/flang/Optimizer/Dialect/FIRDialect.td index 0dfb3eda585c..b05f4e731bc7 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRDialect.td +++ b/flang/include/flang/Optimizer/Dialect/FIRDialect.td @@ -56,6 +56,18 @@ def FIROpsDialect : Dialect { static constexpr llvm::StringRef getFirRuntimeAttrName() { return "fir.runtime"; } + // Return string name of fir.memory attributes. + // It is attached to fir.call operations to convey + // llvm.memory attributes to LLVM IR. + // Its value is intended to be mlir::LLVM::MemoryEffectsAttr. + // TODO: we should probably make it an inherent attribute + // of fir.call, though, it is supposed to be a short-lived + // attribute that appears right before CodeGen and only + // meaningful for LLVM, so it is unclear if embedding + // it into fir.call makes sense. + static constexpr llvm::StringRef getFirCallMemoryAttrName() { + return "fir.llvm_memory"; + } }]; } diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index 10e1c999d453..afbbeb55632f 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -60,6 +60,8 @@ namespace fir { #define GEN_PASS_DECL_FUNCTIONATTR #define GEN_PASS_DECL_CONSTANTARGUMENTGLOBALISATIONOPT #define GEN_PASS_DECL_COMPILERGENERATEDNAMESCONVERSION +#define GEN_PASS_DECL_SETRUNTIMECALLATTRIBUTES +#define GEN_PASS_DECL_GENRUNTIMECALLSFORTEST #include "flang/Optimizer/Transforms/Passes.h.inc" diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index 0b6e0119c16c..64341b42bd1e 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -453,4 +453,37 @@ def CUFGPUToLLVMConversion : Pass<"cuf-gpu-convert-to-llvm", "mlir::ModuleOp"> { ]; } +def SetRuntimeCallAttributes + : Pass<"set-runtime-call-attrs", "mlir::func::FuncOp"> { + let summary = "Set Fortran runtime fir.call attributes targeting LLVM IR"; + let description = [{ + This pass sets different attributes for Fortran runtime calls + that enable more optimizations in LLVM backend. + For the time being, the meaning of these attributes is not + strictly defined for HLFIR/FIR. + }]; + let dependentDialects = ["fir::FIROpsDialect", "mlir::LLVM::LLVMDialect"]; +} + +def GenRuntimeCallsForTest + : Pass<"gen-runtime-calls-for-test", "mlir::ModuleOp"> { + let summary = + "Print FIR containing declarations/calls of Fortran runtime functions"; + let description = [{ + This pass is only for developers to be able to print FIR + that declares and calls Fortran runtime functions. + It helps producing/updating tests for passes that modify + the func/call operations based on some knowledge of + Fortran runtime. + }]; + let options = + [Option<"doGenerateCalls", "do-generate-calls", "bool", + /*default=*/"false", + "Generate thin wrapper functions that call Fortran runtime " + "functions. If it is set to false, then only the declarations " + "are generated.">, + ]; + let dependentDialects = ["fir::FIROpsDialect", "mlir::func::FuncDialect"]; +} + #endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES diff --git a/flang/include/flang/Optimizer/Transforms/RuntimeFunctions.inc b/flang/include/flang/Optimizer/Transforms/RuntimeFunctions.inc new file mode 100644 index 000000000000..cb4bf4ecf559 --- /dev/null +++ b/flang/include/flang/Optimizer/Transforms/RuntimeFunctions.inc @@ -0,0 +1,111 @@ +//===-- Optimizer/Transforms/RuntimeFunctions.inc ---------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef KNOWN_IO_FUNC +#error "Define KNOWN_IO_FUNC before including this file" +#endif +#ifndef KNOWN_RUNTIME_FUNC +#error "Define KNOWN_RUNTIME_FUNC before including this file" +#endif + +// Fortran runtime functions that SetRuntimeCallAttributesPass recognizes. +// WARNING: if you add a function entry here, you must make sure +// that the attribute computation callbacks that end up being +// used are correct for this function. If needed, add +// specializations for the types that provide attribute +// computation callbacks in SetRuntimeCallAttributesPass. + +// clang-format off +KNOWN_IO_FUNC(BeginBackspace), +KNOWN_IO_FUNC(BeginClose), +KNOWN_IO_FUNC(BeginEndfile), +KNOWN_IO_FUNC(BeginExternalFormattedInput), +KNOWN_IO_FUNC(BeginExternalFormattedOutput), +KNOWN_IO_FUNC(BeginExternalListInput), +KNOWN_IO_FUNC(BeginExternalListOutput), +KNOWN_IO_FUNC(BeginFlush), +KNOWN_IO_FUNC(BeginInquireFile), +KNOWN_IO_FUNC(BeginInquireIoLength), +KNOWN_IO_FUNC(BeginInquireUnit), +KNOWN_IO_FUNC(BeginInternalArrayFormattedInput), +KNOWN_IO_FUNC(BeginInternalArrayFormattedOutput), +KNOWN_IO_FUNC(BeginInternalArrayListInput), +KNOWN_IO_FUNC(BeginInternalArrayListOutput), +KNOWN_IO_FUNC(BeginInternalFormattedInput), +KNOWN_IO_FUNC(BeginInternalFormattedOutput), +KNOWN_IO_FUNC(BeginInternalListInput), +KNOWN_IO_FUNC(BeginInternalListOutput), +KNOWN_IO_FUNC(BeginOpenNewUnit), +KNOWN_IO_FUNC(BeginOpenUnit), +KNOWN_IO_FUNC(BeginRewind), +KNOWN_IO_FUNC(BeginUnformattedInput), +KNOWN_IO_FUNC(BeginUnformattedOutput), +KNOWN_IO_FUNC(BeginWait), +KNOWN_IO_FUNC(BeginWaitAll), +KNOWN_IO_FUNC(CheckUnitNumberInRange128), +KNOWN_IO_FUNC(CheckUnitNumberInRange64), +KNOWN_IO_FUNC(EnableHandlers), +KNOWN_IO_FUNC(EndIoStatement), +KNOWN_IO_FUNC(GetAsynchronousId), +KNOWN_IO_FUNC(GetIoLength), +KNOWN_IO_FUNC(GetIoMsg), +KNOWN_IO_FUNC(GetNewUnit), +KNOWN_IO_FUNC(GetSize), +KNOWN_IO_FUNC(InputAscii), +KNOWN_IO_FUNC(InputComplex32), +KNOWN_IO_FUNC(InputComplex64), +KNOWN_IO_FUNC(InputDerivedType), +KNOWN_IO_FUNC(InputDescriptor), +KNOWN_IO_FUNC(InputInteger), +KNOWN_IO_FUNC(InputLogical), +KNOWN_IO_FUNC(InputNamelist), +KNOWN_IO_FUNC(InputReal32), +KNOWN_IO_FUNC(InputReal64), +KNOWN_IO_FUNC(InquireCharacter), +KNOWN_IO_FUNC(InquireInteger64), +KNOWN_IO_FUNC(InquireLogical), +KNOWN_IO_FUNC(InquirePendingId), +KNOWN_IO_FUNC(OutputAscii), +KNOWN_IO_FUNC(OutputComplex32), +KNOWN_IO_FUNC(OutputComplex64), +KNOWN_IO_FUNC(OutputDerivedType), +KNOWN_IO_FUNC(OutputDescriptor), +KNOWN_IO_FUNC(OutputInteger128), +KNOWN_IO_FUNC(OutputInteger16), +KNOWN_IO_FUNC(OutputInteger32), +KNOWN_IO_FUNC(OutputInteger64), +KNOWN_IO_FUNC(OutputInteger8), +KNOWN_IO_FUNC(OutputLogical), +KNOWN_IO_FUNC(OutputNamelist), +KNOWN_IO_FUNC(OutputReal32), +KNOWN_IO_FUNC(OutputReal64), +KNOWN_IO_FUNC(SetAccess), +KNOWN_IO_FUNC(SetAction), +KNOWN_IO_FUNC(SetAdvance), +KNOWN_IO_FUNC(SetAsynchronous), +KNOWN_IO_FUNC(SetBlank), +KNOWN_IO_FUNC(SetCarriagecontrol), +KNOWN_IO_FUNC(SetConvert), +KNOWN_IO_FUNC(SetDecimal), +KNOWN_IO_FUNC(SetDelim), +KNOWN_IO_FUNC(SetEncoding), +KNOWN_IO_FUNC(SetFile), +KNOWN_IO_FUNC(SetForm), +KNOWN_IO_FUNC(SetPad), +KNOWN_IO_FUNC(SetPos), +KNOWN_IO_FUNC(SetPosition), +KNOWN_IO_FUNC(SetRec), +KNOWN_IO_FUNC(SetRecl), +KNOWN_IO_FUNC(SetRound), +KNOWN_IO_FUNC(SetSign), +KNOWN_IO_FUNC(SetStatus) + +// clang-format on + +#undef KNOWN_IO_FUNC +#undef KNOWN_RUNTIME_FUNC diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp index 515ceb8e89c8..16e6d05bd3b1 100644 --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -43,35 +43,6 @@ #define DEBUG_TYPE "flang-lower-io" -// Define additional runtime type models specific to IO. -namespace fir::runtime { -template <> -constexpr TypeBuilderFunc getModel() { - return getModel(); -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return mlir::IntegerType::get(context, - 8 * sizeof(Fortran::runtime::io::Iostat)); - }; -} -template <> -constexpr TypeBuilderFunc -getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return fir::ReferenceType::get(mlir::TupleType::get(context)); - }; -} -template <> -constexpr TypeBuilderFunc -getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return fir::ReferenceType::get(mlir::TupleType::get(context)); - }; -} -} // namespace fir::runtime - using namespace Fortran::runtime::io; #define mkIOKey(X) FirmkKey(IONAME(X)) @@ -172,22 +143,6 @@ inline int64_t getLength(mlir::Type argTy) { return mlir::cast(argTy).getShape()[0]; } -/// Get (or generate) the MLIR FuncOp for a given IO runtime function. -template -static mlir::func::FuncOp getIORuntimeFunc(mlir::Location loc, - fir::FirOpBuilder &builder) { - llvm::StringRef name = getName(); - mlir::func::FuncOp func = builder.getNamedFunction(name); - if (func) - return func; - auto funTy = getTypeModel()(builder.getContext()); - func = builder.createFunction(loc, name, funTy); - func->setAttr(fir::FIROpsDialect::getFirRuntimeAttrName(), - builder.getUnitAttr()); - func->setAttr("fir.io", builder.getUnitAttr()); - return func; -} - /// Generate calls to end an IO statement. Return the IOSTAT value, if any. /// It is the caller's responsibility to generate branches on that value. static mlir::Value genEndIO(Fortran::lower::AbstractConverter &converter, @@ -197,7 +152,7 @@ static mlir::Value genEndIO(Fortran::lower::AbstractConverter &converter, fir::FirOpBuilder &builder = converter.getFirOpBuilder(); if (csi.ioMsg) { mlir::func::FuncOp getIoMsg = - getIORuntimeFunc(loc, builder); + fir::runtime::getIORuntimeFunc(loc, builder); builder.create( loc, getIoMsg, mlir::ValueRange{ @@ -208,7 +163,7 @@ static mlir::Value genEndIO(Fortran::lower::AbstractConverter &converter, fir::getLen(*csi.ioMsg))}); } mlir::func::FuncOp endIoStatement = - getIORuntimeFunc(loc, builder); + fir::runtime::getIORuntimeFunc(loc, builder); auto call = builder.create(loc, endIoStatement, mlir::ValueRange{cookie}); mlir::Value iostat = call.getResult(0); @@ -659,45 +614,57 @@ static mlir::func::FuncOp getOutputFunc(mlir::Location loc, fir::FirOpBuilder &builder, mlir::Type type, bool isFormatted) { if (mlir::isa(fir::unwrapPassByRefType(type))) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); if (!isFormatted) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); if (auto ty = mlir::dyn_cast(type)) { if (!ty.isUnsigned()) { switch (ty.getWidth()) { case 1: - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); case 8: - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); case 16: - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc( + loc, builder); case 32: - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc( + loc, builder); case 64: - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc( + loc, builder); case 128: - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc( + loc, builder); } llvm_unreachable("unknown OutputInteger kind"); } } if (auto ty = mlir::dyn_cast(type)) { if (auto width = ty.getWidth(); width == 32) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); else if (width == 64) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); } auto kindMap = fir::getKindMapping(builder.getModule()); if (auto ty = mlir::dyn_cast(type)) { // COMPLEX(KIND=k) corresponds to a pair of REAL(KIND=k). auto width = mlir::cast(ty.getElementType()).getWidth(); if (width == 32) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); else if (width == 64) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); } if (mlir::isa(type)) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); if (fir::factory::CharacterExprHelper::isCharacterScalar(type)) { // TODO: What would it mean if the default CHARACTER KIND is set to a wide // character encoding scheme? How do we handle UTF-8? Is it a distinct KIND @@ -706,9 +673,10 @@ static mlir::func::FuncOp getOutputFunc(mlir::Location loc, auto asciiKind = kindMap.defaultCharacterKind(); if (kindMap.getCharacterBitsize(asciiKind) == 8 && fir::factory::CharacterExprHelper::getCharacterKind(type) == asciiKind) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); } /// Generate a sequence of output data transfer calls. @@ -778,39 +746,46 @@ static mlir::func::FuncOp getInputFunc(mlir::Location loc, fir::FirOpBuilder &builder, mlir::Type type, bool isFormatted) { if (mlir::isa(fir::unwrapPassByRefType(type))) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); if (!isFormatted) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); if (auto ty = mlir::dyn_cast(type)) { if (type.isUnsignedInteger()) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); return ty.getWidth() == 1 - ? getIORuntimeFunc(loc, builder) - : getIORuntimeFunc(loc, builder); + ? fir::runtime::getIORuntimeFunc(loc, + builder) + : fir::runtime::getIORuntimeFunc(loc, + builder); } if (auto ty = mlir::dyn_cast(type)) { if (auto width = ty.getWidth(); width == 32) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); else if (width == 64) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } auto kindMap = fir::getKindMapping(builder.getModule()); if (auto ty = mlir::dyn_cast(type)) { auto width = mlir::cast(ty.getElementType()).getWidth(); if (width == 32) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); else if (width == 64) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, + builder); } if (mlir::isa(type)) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); if (fir::factory::CharacterExprHelper::isCharacterScalar(type)) { auto asciiKind = kindMap.defaultCharacterKind(); if (kindMap.getCharacterBitsize(asciiKind) == 8 && fir::factory::CharacterExprHelper::getCharacterKind(type) == asciiKind) - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } /// Interpret the lowest byte of a LOGICAL and store that value into the full @@ -1145,7 +1120,7 @@ mlir::Value genIntIOOption(Fortran::lower::AbstractConverter &converter, const B &spec) { Fortran::lower::StatementContext localStatementCtx; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - mlir::func::FuncOp ioFunc = getIORuntimeFunc(loc, builder); + mlir::func::FuncOp ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType ioFuncTy = ioFunc.getFunctionType(); mlir::Value expr = fir::getBase(converter.genExprValue( loc, Fortran::semantics::GetExpr(spec.v), localStatementCtx)); @@ -1162,7 +1137,7 @@ mlir::Value genCharIOOption(Fortran::lower::AbstractConverter &converter, const B &spec) { Fortran::lower::StatementContext localStatementCtx; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - mlir::func::FuncOp ioFunc = getIORuntimeFunc(loc, builder); + mlir::func::FuncOp ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType ioFuncTy = ioFunc.getFunctionType(); std::tuple tup = lowerStringLit(converter, loc, localStatementCtx, spec, @@ -1194,7 +1169,8 @@ mlir::Value genIOOption( Fortran::lower::StatementContext localStatementCtx; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); // has an extra KIND argument - mlir::func::FuncOp ioFunc = getIORuntimeFunc(loc, builder); + mlir::func::FuncOp ioFunc = + fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType ioFuncTy = ioFunc.getFunctionType(); std::tuple tup = lowerStringLit(converter, loc, localStatementCtx, spec, @@ -1212,46 +1188,48 @@ mlir::Value genIOOption( mlir::func::FuncOp ioFunc; switch (std::get(spec.t)) { case Fortran::parser::ConnectSpec::CharExpr::Kind::Access: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Action: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Asynchronous: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = + fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Blank: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Decimal: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Delim: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Encoding: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Form: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Pad: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Position: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Round: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Sign: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Carriagecontrol: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc( + loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Convert: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::ConnectSpec::CharExpr::Kind::Dispose: TODO(loc, "DISPOSE not part of the runtime::io interface"); @@ -1289,25 +1267,25 @@ mlir::Value genIOOption( mlir::func::FuncOp ioFunc; switch (std::get(spec.t)) { case Fortran::parser::IoControlSpec::CharExpr::Kind::Advance: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::IoControlSpec::CharExpr::Kind::Blank: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::IoControlSpec::CharExpr::Kind::Decimal: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::IoControlSpec::CharExpr::Kind::Delim: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::IoControlSpec::CharExpr::Kind::Pad: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::IoControlSpec::CharExpr::Kind::Round: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; case Fortran::parser::IoControlSpec::CharExpr::Kind::Sign: - ioFunc = getIORuntimeFunc(loc, builder); + ioFunc = fir::runtime::getIORuntimeFunc(loc, builder); break; } Fortran::lower::StatementContext localStatementCtx; @@ -1351,7 +1329,8 @@ static void genIOGetVar(Fortran::lower::AbstractConverter &converter, mlir::Location loc, mlir::Value cookie, const VAR &parserVar) { fir::FirOpBuilder &builder = converter.getFirOpBuilder(); - mlir::func::FuncOp ioFunc = getIORuntimeFunc(loc, builder); + mlir::func::FuncOp ioFunc = + fir::runtime::getIORuntimeFunc(loc, builder); mlir::Value value = builder.create(loc, ioFunc, mlir::ValueRange{cookie}) .getResult(0); @@ -1478,7 +1457,7 @@ genConditionHandlerCall(Fortran::lower::AbstractConverter &converter, return; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); mlir::func::FuncOp enableHandlers = - getIORuntimeFunc(loc, builder); + fir::runtime::getIORuntimeFunc(loc, builder); mlir::Type boolType = enableHandlers.getFunctionType().getInput(1); auto boolValue = [&](bool specifierIsPresent) { return builder.create( @@ -1793,9 +1772,10 @@ static mlir::Value genIOUnitNumber(Fortran::lower::AbstractConverter &converter, if (rawUnitWidth > runtimeArgWidth) { mlir::func::FuncOp check = rawUnitWidth <= 64 - ? getIORuntimeFunc(loc, builder) - : getIORuntimeFunc(loc, - builder); + ? fir::runtime::getIORuntimeFunc( + loc, builder) + : fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType funcTy = check.getFunctionType(); llvm::SmallVector args; args.push_back(builder.createConvert(loc, funcTy.getInput(0), rawUnit)); @@ -1870,7 +1850,8 @@ static mlir::Value genBasicIOStmt(Fortran::lower::AbstractConverter &converter, Fortran::lower::StatementContext stmtCtx; mlir::Location loc = converter.getCurrentLocation(); ConditionSpecInfo csi = lowerErrorSpec(converter, loc, stmt.v); - mlir::func::FuncOp beginFunc = getIORuntimeFunc(loc, builder); + mlir::func::FuncOp beginFunc = + fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType beginFuncTy = beginFunc.getFunctionType(); mlir::Value unit = genIOUnitNumber( converter, loc, getExpr(stmt), @@ -1924,7 +1905,7 @@ genNewunitSpec(Fortran::lower::AbstractConverter &converter, mlir::Location loc, Fortran::lower::StatementContext stmtCtx; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); mlir::func::FuncOp ioFunc = - getIORuntimeFunc(loc, builder); + fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType ioFuncTy = ioFunc.getFunctionType(); const auto *var = Fortran::semantics::GetExpr(newunit->v); mlir::Value addr = builder.createConvert( @@ -1949,7 +1930,8 @@ Fortran::lower::genOpenStatement(Fortran::lower::AbstractConverter &converter, ConditionSpecInfo csi = lowerErrorSpec(converter, loc, stmt.v); bool hasNewunitSpec = false; if (hasSpec(stmt)) { - beginFunc = getIORuntimeFunc(loc, builder); + beginFunc = + fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType beginFuncTy = beginFunc.getFunctionType(); mlir::Value unit = genIOUnitNumber( converter, loc, getExpr(stmt), @@ -1960,7 +1942,8 @@ Fortran::lower::genOpenStatement(Fortran::lower::AbstractConverter &converter, } else { hasNewunitSpec = hasSpec(stmt); assert(hasNewunitSpec && "missing unit specifier"); - beginFunc = getIORuntimeFunc(loc, builder); + beginFunc = + fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType beginFuncTy = beginFunc.getFunctionType(); beginArgs.push_back(locToFilename(converter, loc, beginFuncTy.getInput(0))); beginArgs.push_back(locToLineNo(converter, loc, beginFuncTy.getInput(1))); @@ -1992,8 +1975,9 @@ Fortran::lower::genWaitStatement(Fortran::lower::AbstractConverter &converter, ConditionSpecInfo csi = lowerErrorSpec(converter, loc, stmt.v); bool hasId = hasSpec(stmt); mlir::func::FuncOp beginFunc = - hasId ? getIORuntimeFunc(loc, builder) - : getIORuntimeFunc(loc, builder); + hasId + ? fir::runtime::getIORuntimeFunc(loc, builder) + : fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType beginFuncTy = beginFunc.getFunctionType(); mlir::Value unit = genIOUnitNumber( converter, loc, getExpr(stmt), @@ -2038,45 +2022,49 @@ getBeginDataTransferFunc(mlir::Location loc, fir::FirOpBuilder &builder, if (isInternal) { if (isInternalWithDesc) { if (isListOrNml) - return getIORuntimeFunc( - loc, builder); - return getIORuntimeFunc( - loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } if (isListOrNml) - return getIORuntimeFunc(loc, - builder); - return getIORuntimeFunc(loc, - builder); + return fir::runtime::getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } if (isListOrNml) - return getIORuntimeFunc(loc, builder); - return getIORuntimeFunc(loc, - builder); + return fir::runtime::getIORuntimeFunc( + loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc( + loc, builder); } else { if (isFormatted || isListOrNml) { if (isInternal) { if (isInternalWithDesc) { if (isListOrNml) - return getIORuntimeFunc( - loc, builder); - return getIORuntimeFunc( - loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } if (isListOrNml) - return getIORuntimeFunc(loc, - builder); - return getIORuntimeFunc(loc, - builder); + return fir::runtime::getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } if (isListOrNml) - return getIORuntimeFunc(loc, builder); - return getIORuntimeFunc(loc, - builder); + return fir::runtime::getIORuntimeFunc( + loc, builder); + return fir::runtime::getIORuntimeFunc(loc, builder); } - return getIORuntimeFunc(loc, builder); + return fir::runtime::getIORuntimeFunc( + loc, builder); } } @@ -2203,19 +2191,21 @@ genDataTransferStmt(Fortran::lower::AbstractConverter &converter, // Generate data transfer list calls. if constexpr (isInput) { // READ if (isNml) - genNamelistIO(converter, cookie, - getIORuntimeFunc(loc, builder), - *getIOControl(stmt)->symbol, - csi.hasTransferConditionSpec(), ok, stmtCtx); + genNamelistIO( + converter, cookie, + fir::runtime::getIORuntimeFunc(loc, builder), + *getIOControl(stmt)->symbol, + csi.hasTransferConditionSpec(), ok, stmtCtx); else genInputItemList(converter, cookie, stmt.items, isFormatted, csi.hasTransferConditionSpec(), ok, /*inLoop=*/false); } else if constexpr (std::is_same_v) { if (isNml) - genNamelistIO(converter, cookie, - getIORuntimeFunc(loc, builder), - *getIOControl(stmt)->symbol, - csi.hasTransferConditionSpec(), ok, stmtCtx); + genNamelistIO( + converter, cookie, + fir::runtime::getIORuntimeFunc(loc, builder), + *getIOControl(stmt)->symbol, + csi.hasTransferConditionSpec(), ok, stmtCtx); else genOutputItemList(converter, cookie, stmt.items, isFormatted, csi.hasTransferConditionSpec(), ok, @@ -2307,7 +2297,7 @@ mlir::Value genInquireSpec( return {}; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); mlir::func::FuncOp specFunc = - getIORuntimeFunc(loc, builder); + fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType specFuncTy = specFunc.getFunctionType(); const auto *varExpr = Fortran::semantics::GetExpr( std::get(var.t)); @@ -2337,7 +2327,7 @@ mlir::Value genInquireSpec( return {}; fir::FirOpBuilder &builder = converter.getFirOpBuilder(); mlir::func::FuncOp specFunc = - getIORuntimeFunc(loc, builder); + fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType specFuncTy = specFunc.getFunctionType(); const auto *varExpr = Fortran::semantics::GetExpr( std::get(var.t)); @@ -2374,8 +2364,10 @@ mlir::Value genInquireSpec( idExpr && logVarKind == Fortran::parser::InquireSpec::LogVar::Kind::Pending; mlir::func::FuncOp specFunc = - pendId ? getIORuntimeFunc(loc, builder) - : getIORuntimeFunc(loc, builder); + pendId ? fir::runtime::getIORuntimeFunc( + loc, builder) + : fir::runtime::getIORuntimeFunc(loc, + builder); mlir::FunctionType specFuncTy = specFunc.getFunctionType(); mlir::Value addr = fir::getBase(converter.genExprAddr( loc, @@ -2460,7 +2452,8 @@ mlir::Value Fortran::lower::genInquireStatement( // Make one of three BeginInquire calls. if (inquireFileUnit()) { // Inquire by unit -- [UNIT=]file-unit-number. - beginFunc = getIORuntimeFunc(loc, builder); + beginFunc = + fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType beginFuncTy = beginFunc.getFunctionType(); mlir::Value unit = genIOUnitNumber(converter, loc, exprPair.first, beginFuncTy.getInput(0), csi, stmtCtx); @@ -2468,7 +2461,8 @@ mlir::Value Fortran::lower::genInquireStatement( locToLineNo(converter, loc, beginFuncTy.getInput(2))}; } else if (inquireFileName()) { // Inquire by file -- FILE=file-name-expr. - beginFunc = getIORuntimeFunc(loc, builder); + beginFunc = + fir::runtime::getIORuntimeFunc(loc, builder); mlir::FunctionType beginFuncTy = beginFunc.getFunctionType(); fir::ExtendedValue file = converter.genExprAddr(loc, exprPair.first, stmtCtx); @@ -2482,7 +2476,8 @@ mlir::Value Fortran::lower::genInquireStatement( const auto *ioLength = std::get_if(&stmt.u); assert(ioLength && "must have an IOLENGTH specifier"); - beginFunc = getIORuntimeFunc(loc, builder); + beginFunc = fir::runtime::getIORuntimeFunc( + loc, builder); mlir::FunctionType beginFuncTy = beginFunc.getFunctionType(); beginArgs = {locToFilename(converter, loc, beginFuncTy.getInput(0)), locToLineNo(converter, loc, beginFuncTy.getInput(1))}; @@ -2501,7 +2496,10 @@ mlir::Value Fortran::lower::genInquireStatement( mlir::Value length = builder .create( - loc, getIORuntimeFunc(loc, builder), args) + loc, + fir::runtime::getIORuntimeFunc(loc, + builder), + args) .getResult(0); mlir::Value length1 = builder.createConvert(loc, converter.genType(*ioLengthVar), length); diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp index d9779c46ae79..0f338270fc98 100644 --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -16,6 +16,7 @@ #include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Dialect/CUF/CUFOps.h" #include "flang/Optimizer/Dialect/FIRAttr.h" +#include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/Dialect/FIROpsSupport.h" #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Optimizer/Support/DataLayout.h" @@ -46,6 +47,17 @@ fir::FirOpBuilder::createFunction(mlir::Location loc, mlir::ModuleOp module, return fir::createFuncOp(loc, module, name, ty, /*attrs*/ {}, symbolTable); } +mlir::func::FuncOp +fir::FirOpBuilder::createRuntimeFunction(mlir::Location loc, + llvm::StringRef name, + mlir::FunctionType ty, bool isIO) { + mlir::func::FuncOp func = createFunction(loc, name, ty); + func->setAttr(fir::FIROpsDialect::getFirRuntimeAttrName(), getUnitAttr()); + if (isIO) + func->setAttr("fir.io", getUnitAttr()); + return func; +} + mlir::func::FuncOp fir::FirOpBuilder::getNamedFunction(mlir::ModuleOp modOp, const mlir::SymbolTable *symbolTable, diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index d5dadac00a47..aaefe675730e 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -17,6 +17,7 @@ #include "flang/Optimizer/CodeGen/FIROpPatterns.h" #include "flang/Optimizer/CodeGen/TypeConverter.h" #include "flang/Optimizer/Dialect/FIRAttr.h" +#include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/Dialect/FIROps.h" #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Optimizer/Support/DataLayout.h" @@ -585,6 +586,11 @@ struct CallOpConversion : public fir::FIROpConversion { matchAndRewrite(fir::CallOp call, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const override { llvm::SmallVector resultTys; + mlir::Attribute memAttr = + call->getAttr(fir::FIROpsDialect::getFirCallMemoryAttrName()); + if (memAttr) + call->removeAttr(fir::FIROpsDialect::getFirCallMemoryAttrName()); + for (auto r : call.getResults()) resultTys.push_back(convertType(r.getType())); // Convert arith::FastMathFlagsAttr to LLVM::FastMathFlagsAttr. @@ -626,6 +632,10 @@ struct CallOpConversion : public fir::FIROpConversion { } if (mlir::ArrayAttr resAttrs = call.getResAttrsAttr()) llvmCall.setResAttrsAttr(resAttrs); + + if (memAttr) + llvmCall.setMemoryEffectsAttr( + mlir::cast(memAttr)); return mlir::success(); } }; diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index afb50a9a79a4..518be347fff8 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -211,6 +211,9 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm, pm.addPass(fir::createSimplifyRegionLite()); pm.addPass(mlir::createCSEPass()); + if (pc.OptLevel.isOptimizingForSpeed()) + pm.addPass(fir::createSetRuntimeCallAttributes()); + // Last Optimizer EP Callback pc.invokeFIROptLastEPCallbacks(pm, pc.OptLevel); } diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt index 50994fbb2170..da4fc9cb716b 100644 --- a/flang/lib/Optimizer/Transforms/CMakeLists.txt +++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt @@ -29,6 +29,8 @@ add_flang_library(FIRTransforms VScaleAttr.cpp FunctionAttr.cpp DebugTypeGenerator.cpp + SetRuntimeCallAttributes.cpp + GenRuntimeCallsForTest.cpp DEPENDS CUFAttrs diff --git a/flang/lib/Optimizer/Transforms/GenRuntimeCallsForTest.cpp b/flang/lib/Optimizer/Transforms/GenRuntimeCallsForTest.cpp new file mode 100644 index 000000000000..8d1d62e334d8 --- /dev/null +++ b/flang/lib/Optimizer/Transforms/GenRuntimeCallsForTest.cpp @@ -0,0 +1,106 @@ +//===- GenRuntimeCallsForTest.cpp -----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +/// \file +/// This pass is only for developers to generate declarations/calls +/// of Fortran runtime function recognized in +/// flang/Optimizer/Transforms/RuntimeFunctions.inc table. +/// Sample of the generated FIR: +/// func.func private +/// @_FortranAioSetStatus(!fir.ref, !fir.ref, i64) -> +/// i1 attributes {fir.io, fir.runtime} +/// +/// func.func @test__FortranAioSetStatus( +/// %arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { +/// %0 = fir.call @_FortranAioSetStatus(%arg0, %arg1, %arg2) : +/// (!fir.ref, !fir.ref, i64) -> i1 +/// return %0 : i1 +/// } +//===----------------------------------------------------------------------===// +#include "flang/Common/static-multimap-view.h" +#include "flang/Optimizer/Builder/Runtime/RTBuilder.h" +#include "flang/Optimizer/Dialect/FIRDialect.h" +#include "flang/Optimizer/Dialect/FIROpsSupport.h" +#include "flang/Optimizer/Support/InternalNames.h" +#include "flang/Optimizer/Transforms/Passes.h" +#include "flang/Runtime/io-api-consts.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" + +namespace fir { +#define GEN_PASS_DEF_GENRUNTIMECALLSFORTEST +#include "flang/Optimizer/Transforms/Passes.h.inc" +} // namespace fir + +#define DEBUG_TYPE "gen-runtime-calls-for-test" + +using namespace Fortran::runtime; +using namespace Fortran::runtime::io; + +#define mkIOKey(X) FirmkKey(IONAME(X)) +#define mkRTKey(X) FirmkKey(RTNAME(X)) + +namespace { +class GenRuntimeCallsForTestPass + : public fir::impl::GenRuntimeCallsForTestBase { + using GenRuntimeCallsForTestBase< + GenRuntimeCallsForTestPass>::GenRuntimeCallsForTestBase; + +public: + void runOnOperation() override; +}; +} // end anonymous namespace + +static constexpr llvm::StringRef testPrefix = "test_"; + +void GenRuntimeCallsForTestPass::runOnOperation() { + mlir::ModuleOp moduleOp = getOperation(); + mlir::OpBuilder mlirBuilder(moduleOp.getRegion()); + fir::FirOpBuilder builder(mlirBuilder, moduleOp); + mlir::Location loc = mlir::UnknownLoc::get(builder.getContext()); + +#define KNOWN_IO_FUNC(X) \ + fir::runtime::getIORuntimeFunc(loc, builder) +#define KNOWN_RUNTIME_FUNC(X) \ + fir::runtime::getRuntimeFunc(loc, builder) + + mlir::func::FuncOp runtimeFuncsTable[] = { +#include "flang/Optimizer/Transforms/RuntimeFunctions.inc" + }; + + if (!doGenerateCalls) + return; + + // Generate thin wrapper functions calling the known Fortran + // runtime functions. + llvm::SmallVector newFuncs; + for (unsigned i = 0; + i < sizeof(runtimeFuncsTable) / sizeof(runtimeFuncsTable[0]); ++i) { + mlir::func::FuncOp funcOp = runtimeFuncsTable[i]; + mlir::FunctionType funcTy = funcOp.getFunctionType(); + std::string name = (llvm::Twine(testPrefix) + funcOp.getName()).str(); + mlir::func::FuncOp callerFunc = builder.createFunction(loc, name, funcTy); + callerFunc.setVisibility(mlir::SymbolTable::Visibility::Public); + mlir::OpBuilder::InsertPoint insertPt = builder.saveInsertionPoint(); + + // Generate the wrapper function body that consists of a call and return. + builder.setInsertionPointToStart(callerFunc.addEntryBlock()); + mlir::Block::BlockArgListType args = callerFunc.front().getArguments(); + auto callOp = builder.create(loc, funcOp, args); + builder.create(loc, callOp.getResults()); + + newFuncs.push_back(callerFunc.getOperation()); + builder.restoreInsertionPoint(insertPt); + } + + // Make sure all wrapper functions are at the beginning + // of the module. + auto moduleBegin = moduleOp.getBody()->begin(); + for (auto func : newFuncs) + func->moveBefore(moduleOp.getBody(), moduleBegin); +} diff --git a/flang/lib/Optimizer/Transforms/SetRuntimeCallAttributes.cpp b/flang/lib/Optimizer/Transforms/SetRuntimeCallAttributes.cpp new file mode 100644 index 000000000000..1c33e8183997 --- /dev/null +++ b/flang/lib/Optimizer/Transforms/SetRuntimeCallAttributes.cpp @@ -0,0 +1,258 @@ +//===- SetRuntimeCallAttributes.cpp ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +/// \file +/// SetRuntimeCallAttributesPass looks for fir.call operations +/// that are calling into Fortran runtime, and tries to set different +/// attributes on them to enable more optimizations in LLVM backend +/// (granted that they are preserved all the way to LLVM IR). +/// This pass is currently only attaching fir.call wide atttributes, +/// such as ones corresponding to llvm.memory, nosync, nocallbac, etc. +/// It is not designed to attach attributes to the arguments and the results +/// of a call. +//===----------------------------------------------------------------------===// +#include "flang/Common/static-multimap-view.h" +#include "flang/Optimizer/Builder/Runtime/RTBuilder.h" +#include "flang/Optimizer/Dialect/FIRDialect.h" +#include "flang/Optimizer/Dialect/FIROpsSupport.h" +#include "flang/Optimizer/Support/InternalNames.h" +#include "flang/Optimizer/Transforms/Passes.h" +#include "flang/Runtime/io-api-consts.h" +#include "mlir/Dialect/LLVMIR/LLVMAttrs.h" + +namespace fir { +#define GEN_PASS_DEF_SETRUNTIMECALLATTRIBUTES +#include "flang/Optimizer/Transforms/Passes.h.inc" +} // namespace fir + +#define DEBUG_TYPE "set-runtime-call-attrs" + +using namespace Fortran::runtime; +using namespace Fortran::runtime::io; + +#define mkIOKey(X) FirmkKey(IONAME(X)) +#define mkRTKey(X) FirmkKey(RTNAME(X)) + +// Return LLVM dialect MemoryEffectsAttr for the given Fortran runtime call. +// This function is computing a generic value of this attribute +// by analyzing the arguments and their types. +// It tries to figure out if an "indirect" memory access is possible +// during this call. If it is not possible, then the memory effects +// are: +// * other = NoModRef +// * argMem = ModRef +// * inaccessibleMem = ModRef +// +// Otherwise, it returns an empty attribute meaning ModRef for all kinds +// of memory. +// +// The attribute deduction is conservative in a sense that it applies +// to most of the runtime calls, but it may still be incorrect for some +// runtime calls. +static mlir::LLVM::MemoryEffectsAttr getGenericMemoryAttr(fir::CallOp callOp) { + bool maybeIndirectAccess = false; + for (auto arg : callOp.getArgOperands()) { + mlir::Type argType = arg.getType(); + if (mlir::isa(argType)) { + // If it is a null/absent box, then this particular call + // cannot access memory indirectly through the box's + // base_addr. + auto def = arg.getDefiningOp(); + if (!mlir::isa_and_nonnull(def)) { + maybeIndirectAccess = true; + break; + } + } + if (auto refType = mlir::dyn_cast(argType)) { + if (!fir::isa_trivial(refType.getElementType())) { + maybeIndirectAccess = true; + break; + } + } + if (auto ptrType = mlir::dyn_cast(argType)) { + maybeIndirectAccess = true; + break; + } + } + if (!maybeIndirectAccess) { + return mlir::LLVM::MemoryEffectsAttr::get( + callOp->getContext(), + {/*other=*/mlir::LLVM::ModRefInfo::NoModRef, + /*argMem=*/mlir::LLVM::ModRefInfo::ModRef, + /*inaccessibleMem=*/mlir::LLVM::ModRefInfo::ModRef}); + } + + return {}; +} + +namespace { +class SetRuntimeCallAttributesPass + : public fir::impl::SetRuntimeCallAttributesBase< + SetRuntimeCallAttributesPass> { +public: + void runOnOperation() override; +}; + +// A helper to match a type against a list of types. +template +constexpr bool IsAny = std::disjunction_v...>; +} // end anonymous namespace + +// MemoryAttrDesc type provides get() method for computing +// mlir::LLVM::MemoryEffectsAttr for the given Fortran runtime call. +// If needed, add specializations for particular runtime calls. +namespace { +// Default implementation just uses getGenericMemoryAttr(). +// Note that it may be incorrect for some runtime calls. +template +struct MemoryAttrDesc { + static mlir::LLVM::MemoryEffectsAttr get(fir::CallOp callOp) { + return getGenericMemoryAttr(callOp); + } +}; +} // end anonymous namespace + +// NosyncAttrDesc type provides get() method for computing +// LLVM nosync attribute for the given call. +namespace { +// Default implementation always returns LLVM nosync. +// This should be true for the majority of the Fortran runtime calls. +template +struct NosyncAttrDesc { + static std::optional get(fir::CallOp callOp) { + // TODO: replace llvm.nosync with an LLVM dialect callback. + return mlir::NamedAttribute("llvm.nosync", + mlir::UnitAttr::get(callOp->getContext())); + } +}; +} // end anonymous namespace + +// NocallbackAttrDesc type provides get() method for computing +// LLVM nocallback attribute for the given call. +namespace { +// Default implementation always returns LLVM nocallback. +// It must be specialized for Fortran runtime functions that may call +// user functions during their execution (e.g. defined IO, assignment). +template +struct NocallbackAttrDesc { + static std::optional get(fir::CallOp callOp) { + // TODO: replace llvm.nocallback with an LLVM dialect callback. + return mlir::NamedAttribute("llvm.nocallback", + mlir::UnitAttr::get(callOp->getContext())); + } +}; + +// Derived types IO may call back into a Fortran module. +// This specialization is conservative for Input/OutputDerivedType, +// and it might be improved by checking if the NonTbpDefinedIoTable +// pointer argument is null. +template +struct NocallbackAttrDesc< + KEY, std::enable_if_t< + IsAny>> { + static std::optional get(fir::CallOp) { + return std::nullopt; + } +}; +} // end anonymous namespace + +namespace { +// RuntimeFunction provides different callbacks that compute values +// of fir.call attributes for a Fortran runtime function. +struct RuntimeFunction { + using MemoryAttrGeneratorTy = mlir::LLVM::MemoryEffectsAttr (*)(fir::CallOp); + using NamedAttrGeneratorTy = + std::optional (*)(fir::CallOp); + using Key = std::string_view; + constexpr operator Key() const { return key; } + Key key; + MemoryAttrGeneratorTy memoryAttrGenerator; + NamedAttrGeneratorTy nosyncAttrGenerator; + NamedAttrGeneratorTy nocallbackAttrGenerator; +}; + +// Helper type to create a RuntimeFunction descriptor given +// the KEY and a function name. +template +struct RuntimeFactory { + static constexpr RuntimeFunction create(const char name[]) { + // GCC 7 does not recognize this as a constant expression: + // ((const char *)RuntimeFunction<>::name) == nullptr + // This comparison comes from the basic_string_view(const char *) + // constructor. We have to use the other constructor + // that takes explicit length parameter. + return RuntimeFunction{ + std::string_view{name, std::char_traits::length(name)}, + MemoryAttrDesc::get, NosyncAttrDesc::get, + NocallbackAttrDesc::get}; + } +}; +} // end anonymous namespace + +#define KNOWN_IO_FUNC(X) RuntimeFactory::create(mkIOKey(X)::name) +#define KNOWN_RUNTIME_FUNC(X) \ + RuntimeFactory::create(mkRTKey(X)::name) + +// A table of RuntimeFunction descriptors for all recognized +// Fortran runtime functions. +static constexpr RuntimeFunction runtimeFuncsTable[] = { +#include "flang/Optimizer/Transforms/RuntimeFunctions.inc" +}; + +static constexpr Fortran::common::StaticMultimapView + runtimeFuncs(runtimeFuncsTable); +static_assert(runtimeFuncs.Verify() && "map must be sorted"); + +// Set attributes for the given Fortran runtime call. +// The symbolTable is used to cache the name lookups in the module. +static void setRuntimeCallAttributes(fir::CallOp callOp, + mlir::SymbolTableCollection &symbolTable) { + auto iface = mlir::cast(callOp.getOperation()); + auto funcOp = mlir::dyn_cast_or_null( + iface.resolveCallableInTable(&symbolTable)); + + if (!funcOp || !funcOp->hasAttrOfType( + fir::FIROpsDialect::getFirRuntimeAttrName())) + return; + + llvm::StringRef name = funcOp.getName(); + if (auto range = runtimeFuncs.equal_range(name); + range.first != range.second) { + // There should not be duplicate entries. + assert(range.first + 1 == range.second); + const RuntimeFunction &desc = *range.first; + LLVM_DEBUG(llvm::dbgs() + << "Identified runtime function call: " << desc.key << '\n'); + if (mlir::LLVM::MemoryEffectsAttr memoryAttr = + desc.memoryAttrGenerator(callOp)) + callOp->setAttr(fir::FIROpsDialect::getFirCallMemoryAttrName(), + memoryAttr); + if (auto attr = desc.nosyncAttrGenerator(callOp)) + callOp->setAttr(attr->getName(), attr->getValue()); + if (auto attr = desc.nocallbackAttrGenerator(callOp)) + callOp->setAttr(attr->getName(), attr->getValue()); + LLVM_DEBUG(llvm::dbgs() << "Operation with attrs: " << callOp << '\n'); + } +} + +void SetRuntimeCallAttributesPass::runOnOperation() { + mlir::func::FuncOp funcOp = getOperation(); + // Exit early for declarations to skip the debug output for them. + if (funcOp.isDeclaration()) + return; + LLVM_DEBUG(llvm::dbgs() << "=== Begin " DEBUG_TYPE " ===\n"); + LLVM_DEBUG(llvm::dbgs() << "Func-name:" << funcOp.getSymName() << "\n"); + + mlir::SymbolTableCollection symbolTable; + funcOp.walk([&](fir::CallOp callOp) { + setRuntimeCallAttributes(callOp, symbolTable); + }); + LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n"); +} diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90 index dd46aecb3274..740897786dd3 100644 --- a/flang/test/Driver/mlir-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-pass-pipeline.f90 @@ -123,6 +123,8 @@ end program ! ALL-NEXT: CSE ! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd +! O2-NEXT: 'func.func' Pipeline +! O2-NEXT: SetRuntimeCallAttributes ! ALL-NEXT: BoxedProcedurePass ! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir index 51e68d215763..8b299674208f 100644 --- a/flang/test/Fir/basic-program.fir +++ b/flang/test/Fir/basic-program.fir @@ -121,6 +121,8 @@ func.func @_QQmain() { // PASSES-NEXT: CSE // PASSES-NEXT: (S) 0 num-cse'd - Number of operations CSE'd // PASSES-NEXT: (S) 0 num-dce'd - Number of operations DCE'd +// PASSES-NEXT: 'func.func' Pipeline +// PASSES-NEXT: SetRuntimeCallAttributes // PASSES-NEXT: BoxedProcedurePass // PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] diff --git a/flang/test/Lower/array-temp.f90 b/flang/test/Lower/array-temp.f90 index 718aef84a4e8..6a67fb55be2a 100644 --- a/flang/test/Lower/array-temp.f90 +++ b/flang/test/Lower/array-temp.f90 @@ -122,7 +122,7 @@ end ! CHECK: %[[V_50:[0-9]+]] = fir.slice %[[C_1]], %[[C_2]], %[[C_1]] : (index, index, index) -> !fir.slice<1> ! CHECK: %[[V_51:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_50]]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>) -> !fir.box> ! CHECK: %[[V_52:[0-9]+]] = fir.convert %[[V_51:[0-9]+]] : (!fir.box>) -> !fir.box -! CHECK: %[[V_53:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_49]], %[[V_52]]) fastmath : (!fir.ref, !fir.box) -> i1 +! CHECK: %[[V_53:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_49]], %[[V_52]]) fastmath {{.*}}: (!fir.ref, !fir.box) -> i1 ! CHECK: %[[V_54:[0-9]+]] = fir.load %arg0 : !fir.ref ! CHECK: %[[V_55:[0-9]+]] = arith.subi %[[V_54]], %[[C_1_i32]] : i32 ! CHECK: %[[V_56:[0-9]+]] = fir.convert %[[V_55:[0-9]+]] : (i32) -> index @@ -130,8 +130,8 @@ end ! CHECK: %[[V_58:[0-9]+]] = fir.slice %[[V_56]], %[[V_57]], %[[C_1]] : (index, index, index) -> !fir.slice<1> ! CHECK: %[[V_59:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_58]]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>) -> !fir.box> ! CHECK: %[[V_60:[0-9]+]] = fir.convert %[[V_59:[0-9]+]] : (!fir.box>) -> !fir.box -! CHECK: %[[V_61:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_49]], %[[V_60]]) fastmath : (!fir.ref, !fir.box) -> i1 -! CHECK: %[[V_62:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_49]]) fastmath : (!fir.ref) -> i32 +! CHECK: %[[V_61:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_49]], %[[V_60]]) fastmath {{.*}}: (!fir.ref, !fir.box) -> i1 +! CHECK: %[[V_62:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_49]]) fastmath {{.*}}: (!fir.ref) -> i32 ! CHECK: return ! CHECK: } @@ -248,7 +248,7 @@ end ! CHECK: %[[V_74:[0-9]+]] = fir.slice %[[C_1]], %[[C_2]], %[[C_1]], %[[C_1]], %[[C_2]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2> ! CHECK: %[[V_75:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_74]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.box> ! CHECK: %[[V_76:[0-9]+]] = fir.convert %[[V_75:[0-9]+]] : (!fir.box>) -> !fir.box -! CHECK: %[[V_77:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_76]]) fastmath : (!fir.ref, !fir.box) -> i1 +! CHECK: %[[V_77:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_76]]) fastmath {{.*}}: (!fir.ref, !fir.box) -> i1 ! CHECK: %[[V_78:[0-9]+]] = fir.load %arg0 : !fir.ref ! CHECK: %[[V_79:[0-9]+]] = arith.subi %[[V_78]], %[[C_1_i32]] : i32 ! CHECK: %[[V_80:[0-9]+]] = fir.convert %[[V_79:[0-9]+]] : (i32) -> index @@ -256,8 +256,8 @@ end ! CHECK: %[[V_82:[0-9]+]] = fir.slice %[[C_1]], %[[C_2]], %[[C_1]], %[[V_80]], %[[V_81]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2> ! CHECK: %[[V_83:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_82]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.box> ! CHECK: %[[V_84:[0-9]+]] = fir.convert %[[V_83:[0-9]+]] : (!fir.box>) -> !fir.box -! CHECK: %[[V_85:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_84]]) fastmath : (!fir.ref, !fir.box) -> i1 -! CHECK: %[[V_86:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_73]]) fastmath : (!fir.ref) -> i32 +! CHECK: %[[V_85:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_84]]) fastmath {{.*}}: (!fir.ref, !fir.box) -> i1 +! CHECK: %[[V_86:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_73]]) fastmath {{.*}}: (!fir.ref) -> i32 ! CHECK: return ! CHECK: } @@ -374,7 +374,7 @@ end ! CHECK: %[[V_74:[0-9]+]] = fir.slice %[[C_1]], %[[C_2]], %[[C_1]], %[[C_1]], %[[C_2]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2> ! CHECK: %[[V_75:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_74]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.box> ! CHECK: %[[V_76:[0-9]+]] = fir.convert %[[V_75:[0-9]+]] : (!fir.box>) -> !fir.box -! CHECK: %[[V_77:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_76]]) fastmath : (!fir.ref, !fir.box) -> i1 +! CHECK: %[[V_77:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_76]]) fastmath {{.*}}: (!fir.ref, !fir.box) -> i1 ! CHECK: %[[V_78:[0-9]+]] = fir.load %arg0 : !fir.ref ! CHECK: %[[V_79:[0-9]+]] = arith.subi %[[V_78]], %[[C_1_i32]] : i32 ! CHECK: %[[V_80:[0-9]+]] = fir.convert %[[V_79:[0-9]+]] : (i32) -> index @@ -382,8 +382,8 @@ end ! CHECK: %[[V_82:[0-9]+]] = fir.slice %[[V_80]], %[[V_81]], %[[C_1]], %[[C_1]], %[[C_2]], %[[C_1]] : (index, index, index, index, index, index) -> !fir.slice<2> ! CHECK: %[[V_83:[0-9]+]] = fir.embox %[[V_4]](%[[V_5]]) [%[[V_82]]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>) -> !fir.box> ! CHECK: %[[V_84:[0-9]+]] = fir.convert %[[V_83:[0-9]+]] : (!fir.box>) -> !fir.box -! CHECK: %[[V_85:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_84]]) fastmath : (!fir.ref, !fir.box) -> i1 -! CHECK: %[[V_86:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_73]]) fastmath : (!fir.ref) -> i32 +! CHECK: %[[V_85:[0-9]+]] = fir.call @_FortranAioOutputDescriptor(%[[V_73]], %[[V_84]]) fastmath {{.*}}: (!fir.ref, !fir.box) -> i1 +! CHECK: %[[V_86:[0-9]+]] = fir.call @_FortranAioEndIoStatement(%[[V_73]]) fastmath {{.*}}: (!fir.ref) -> i32 ! CHECK: return ! CHECK: } diff --git a/flang/test/Transforms/set-runtime-call-attributes.fir b/flang/test/Transforms/set-runtime-call-attributes.fir new file mode 100644 index 000000000000..ecb2dd53ea4d --- /dev/null +++ b/flang/test/Transforms/set-runtime-call-attributes.fir @@ -0,0 +1,1039 @@ +// RUN: fir-opt -set-runtime-call-attrs %s | FileCheck %s + +// Test that SetRuntimeCallAttributesPass sets the expected attributes +// on the calls of Fortran runtime functions. +// +// Updates in flang/Optimizer/Transforms/RuntimeFunctions.inc table +// and in SetRuntimeCallAttributesPass may require updating this test. +// The following commands might be used: +// echo "module {}" | fir-opt --gen-runtime-calls-for-test="do-generate-calls" >tmp +// fir-opt tmp -set-runtime-call-attrs | generate-test-checks.py \ +// --source tmp --source_delim_regex "func.func.*@test_" | \ +// grep -v "CHECK.*func.func.*@_Fortran" + +// NOTE: Assertions have been autogenerated by utils/generate-test-checks.py + +// The script is designed to make adding checks to +// a test case fast, it is *not* designed to be authoritative +// about what constitutes a good test! The CHECK should be +// minimized and named to reflect the test intent. + +module { +// CHECK-LABEL: func.func @test__FortranAioBeginBackspace( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginBackspace(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginBackspace(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginBackspace(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginClose( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginClose(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginClose(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginClose(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginEndfile( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginEndfile(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginEndfile(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginEndfile(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginExternalFormattedInput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_6:.*]] = fir.call @_FortranAioBeginExternalFormattedInput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) {llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.box, i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_6]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginExternalFormattedInput(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.box, %arg3: i32, %arg4: !fir.ref, %arg5: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginExternalFormattedInput(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5) : (!fir.ref, i64, !fir.box, i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginExternalFormattedOutput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_6:.*]] = fir.call @_FortranAioBeginExternalFormattedOutput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) {llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.box, i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_6]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginExternalFormattedOutput(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.box, %arg3: i32, %arg4: !fir.ref, %arg5: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginExternalFormattedOutput(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5) : (!fir.ref, i64, !fir.box, i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginExternalListInput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginExternalListInput(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginExternalListInput(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginExternalListOutput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginExternalListOutput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginExternalListOutput(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginExternalListOutput(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginFlush( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginFlush(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginFlush(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginFlush(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInquireFile( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_4:.*]] = fir.call @_FortranAioBeginInquireFile(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_4]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInquireFile(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.ref, %arg3: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInquireFile(%arg0, %arg1, %arg2, %arg3) : (!fir.ref, i64, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInquireIoLength( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioBeginInquireIoLength(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_2]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInquireIoLength(%arg0: !fir.ref, %arg1: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInquireIoLength(%arg0, %arg1) : (!fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInquireUnit( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginInquireUnit(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInquireUnit(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInquireUnit(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInternalArrayFormattedInput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_6:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_7:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_8:.*]] = fir.call @_FortranAioBeginInternalArrayFormattedInput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]], %[[VAL_6]], %[[VAL_7]]) {llvm.nocallback, llvm.nosync} : (!fir.box, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_8]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInternalArrayFormattedInput(%arg0: !fir.box, %arg1: !fir.ref, %arg2: i64, %arg3: !fir.box, %arg4: !fir.ref>, %arg5: i64, %arg6: !fir.ref, %arg7: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInternalArrayFormattedInput(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7) : (!fir.box, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInternalArrayFormattedOutput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_6:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_7:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_8:.*]] = fir.call @_FortranAioBeginInternalArrayFormattedOutput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]], %[[VAL_6]], %[[VAL_7]]) {llvm.nocallback, llvm.nosync} : (!fir.box, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_8]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInternalArrayFormattedOutput(%arg0: !fir.box, %arg1: !fir.ref, %arg2: i64, %arg3: !fir.box, %arg4: !fir.ref>, %arg5: i64, %arg6: !fir.ref, %arg7: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInternalArrayFormattedOutput(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7) : (!fir.box, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInternalArrayListInput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_5:.*]] = fir.call @_FortranAioBeginInternalArrayListInput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]]) {llvm.nocallback, llvm.nosync} : (!fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_5]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInternalArrayListInput(%arg0: !fir.box, %arg1: !fir.ref>, %arg2: i64, %arg3: !fir.ref, %arg4: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInternalArrayListInput(%arg0, %arg1, %arg2, %arg3, %arg4) : (!fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInternalArrayListOutput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_5:.*]] = fir.call @_FortranAioBeginInternalArrayListOutput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]]) {llvm.nocallback, llvm.nosync} : (!fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_5]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInternalArrayListOutput(%arg0: !fir.box, %arg1: !fir.ref>, %arg2: i64, %arg3: !fir.ref, %arg4: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInternalArrayListOutput(%arg0, %arg1, %arg2, %arg3, %arg4) : (!fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInternalFormattedInput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>, +// CHECK-SAME: %[[VAL_6:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_7:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_8:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_9:.*]] = fir.call @_FortranAioBeginInternalFormattedInput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]], %[[VAL_6]], %[[VAL_7]], %[[VAL_8]]) {llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_9]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInternalFormattedInput(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.ref, %arg3: i64, %arg4: !fir.box, %arg5: !fir.ref>, %arg6: i64, %arg7: !fir.ref, %arg8: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInternalFormattedInput(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8) : (!fir.ref, i64, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInternalFormattedOutput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>, +// CHECK-SAME: %[[VAL_6:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_7:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_8:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_9:.*]] = fir.call @_FortranAioBeginInternalFormattedOutput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]], %[[VAL_6]], %[[VAL_7]], %[[VAL_8]]) {llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_9]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInternalFormattedOutput(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.ref, %arg3: i64, %arg4: !fir.box, %arg5: !fir.ref>, %arg6: i64, %arg7: !fir.ref, %arg8: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInternalFormattedOutput(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6, %arg7, %arg8) : (!fir.ref, i64, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInternalListInput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_6:.*]] = fir.call @_FortranAioBeginInternalListInput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) {llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_6]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInternalListInput(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.ref>, %arg3: i64, %arg4: !fir.ref, %arg5: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInternalListInput(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5) : (!fir.ref, i64, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginInternalListOutput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_6:.*]] = fir.call @_FortranAioBeginInternalListOutput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) {llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_6]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginInternalListOutput(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.ref>, %arg3: i64, %arg4: !fir.ref, %arg5: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginInternalListOutput(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5) : (!fir.ref, i64, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginOpenNewUnit( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioBeginOpenNewUnit(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_2]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginOpenNewUnit(%arg0: !fir.ref, %arg1: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginOpenNewUnit(%arg0, %arg1) : (!fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginOpenUnit( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginOpenUnit(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginOpenUnit(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginOpenUnit(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginRewind( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginRewind(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginRewind(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginRewind(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginUnformattedInput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginUnformattedInput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginUnformattedInput(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginUnformattedInput(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginUnformattedOutput( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginUnformattedOutput(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginUnformattedOutput(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginUnformattedOutput(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginWait( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_4:.*]] = fir.call @_FortranAioBeginWait(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_4]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginWait(%arg0: i32, %arg1: i32, %arg2: !fir.ref, %arg3: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginWait(%arg0, %arg1, %arg2, %arg3) : (i32, i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioBeginWaitAll( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> !fir.ref { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioBeginWaitAll(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i32, !fir.ref, i32) -> !fir.ref +// CHECK: return %[[VAL_3]] : !fir.ref +// CHECK: } + func.func @test__FortranAioBeginWaitAll(%arg0: i32, %arg1: !fir.ref, %arg2: i32) -> !fir.ref { + %0 = fir.call @_FortranAioBeginWaitAll(%arg0, %arg1, %arg2) : (i32, !fir.ref, i32) -> !fir.ref + return %0 : !fir.ref + } +// CHECK-LABEL: func.func @test__FortranAioCheckUnitNumberInRange128( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i128, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i1, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> i32 { +// CHECK: %[[VAL_6:.*]] = fir.call @_FortranAioCheckUnitNumberInRange128(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i128, i1, !fir.ref, i64, !fir.ref, i32) -> i32 +// CHECK: return %[[VAL_6]] : i32 +// CHECK: } + func.func @test__FortranAioCheckUnitNumberInRange128(%arg0: i128, %arg1: i1, %arg2: !fir.ref, %arg3: i64, %arg4: !fir.ref, %arg5: i32) -> i32 { + %0 = fir.call @_FortranAioCheckUnitNumberInRange128(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5) : (i128, i1, !fir.ref, i64, !fir.ref, i32) -> i32 + return %0 : i32 + } +// CHECK-LABEL: func.func @test__FortranAioCheckUnitNumberInRange64( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i1, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> i32 { +// CHECK: %[[VAL_6:.*]] = fir.call @_FortranAioCheckUnitNumberInRange64(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (i64, i1, !fir.ref, i64, !fir.ref, i32) -> i32 +// CHECK: return %[[VAL_6]] : i32 +// CHECK: } + func.func @test__FortranAioCheckUnitNumberInRange64(%arg0: i64, %arg1: i1, %arg2: !fir.ref, %arg3: i64, %arg4: !fir.ref, %arg5: i32) -> i32 { + %0 = fir.call @_FortranAioCheckUnitNumberInRange64(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5) : (i64, i1, !fir.ref, i64, !fir.ref, i32) -> i32 + return %0 : i32 + } +// CHECK-LABEL: func.func @test__FortranAioEnableHandlers( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i1, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i1, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i1, +// CHECK-SAME: %[[VAL_4:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i1, +// CHECK-SAME: %[[VAL_5:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i1) { +// CHECK: fir.call @_FortranAioEnableHandlers(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]], %[[VAL_5]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i1, i1, i1, i1, i1) -> () +// CHECK: return +// CHECK: } + func.func @test__FortranAioEnableHandlers(%arg0: !fir.ref, %arg1: i1, %arg2: i1, %arg3: i1, %arg4: i1, %arg5: i1) { + fir.call @_FortranAioEnableHandlers(%arg0, %arg1, %arg2, %arg3, %arg4, %arg5) : (!fir.ref, i1, i1, i1, i1, i1) -> () + return + } +// CHECK-LABEL: func.func @test__FortranAioEndIoStatement( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i32 { +// CHECK: %[[VAL_1:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_0]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref) -> i32 +// CHECK: return %[[VAL_1]] : i32 +// CHECK: } + func.func @test__FortranAioEndIoStatement(%arg0: !fir.ref) -> i32 { + %0 = fir.call @_FortranAioEndIoStatement(%arg0) : (!fir.ref) -> i32 + return %0 : i32 + } +// CHECK-LABEL: func.func @test__FortranAioGetAsynchronousId( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i32 { +// CHECK: %[[VAL_1:.*]] = fir.call @_FortranAioGetAsynchronousId(%[[VAL_0]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref) -> i32 +// CHECK: return %[[VAL_1]] : i32 +// CHECK: } + func.func @test__FortranAioGetAsynchronousId(%arg0: !fir.ref) -> i32 { + %0 = fir.call @_FortranAioGetAsynchronousId(%arg0) : (!fir.ref) -> i32 + return %0 : i32 + } +// CHECK-LABEL: func.func @test__FortranAioGetIoLength( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i64 { +// CHECK: %[[VAL_1:.*]] = fir.call @_FortranAioGetIoLength(%[[VAL_0]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref) -> i64 +// CHECK: return %[[VAL_1]] : i64 +// CHECK: } + func.func @test__FortranAioGetIoLength(%arg0: !fir.ref) -> i64 { + %0 = fir.call @_FortranAioGetIoLength(%arg0) : (!fir.ref) -> i64 + return %0 : i64 + } +// CHECK-LABEL: func.func @test__FortranAioGetIoMsg( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) { +// CHECK: fir.call @_FortranAioGetIoMsg(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> () +// CHECK: return +// CHECK: } + func.func @test__FortranAioGetIoMsg(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) { + fir.call @_FortranAioGetIoMsg(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> () + return + } +// CHECK-LABEL: func.func @test__FortranAioGetNewUnit( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioGetNewUnit(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i32) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioGetNewUnit(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i32) -> i1 { + %0 = fir.call @_FortranAioGetNewUnit(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i32) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioGetSize( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i64 { +// CHECK: %[[VAL_1:.*]] = fir.call @_FortranAioGetSize(%[[VAL_0]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref) -> i64 +// CHECK: return %[[VAL_1]] : i64 +// CHECK: } + func.func @test__FortranAioGetSize(%arg0: !fir.ref) -> i64 { + %0 = fir.call @_FortranAioGetSize(%arg0) : (!fir.ref) -> i64 + return %0 : i64 + } +// CHECK-LABEL: func.func @test__FortranAioInputAscii( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioInputAscii(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioInputAscii(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInputComplex32( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioInputComplex32(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioInputComplex32(%arg0: !fir.ref, %arg1: !fir.ref) -> i1 { + %0 = fir.call @_FortranAioInputComplex32(%arg0, %arg1) : (!fir.ref, !fir.ref) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInputComplex64( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioInputComplex64(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioInputComplex64(%arg0: !fir.ref, %arg1: !fir.ref) -> i1 { + %0 = fir.call @_FortranAioInputComplex64(%arg0, %arg1) : (!fir.ref, !fir.ref) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInputDerivedType( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioInputDerivedType(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {llvm.nosync} : (!fir.ref, !fir.box, !fir.ref>) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioInputDerivedType(%arg0: !fir.ref, %arg1: !fir.box, %arg2: !fir.ref>) -> i1 { + %0 = fir.call @_FortranAioInputDerivedType(%arg0, %arg1, %arg2) : (!fir.ref, !fir.box, !fir.ref>) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInputDescriptor( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioInputDescriptor(%[[VAL_0]], %[[VAL_1]]) {llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.box) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioInputDescriptor(%arg0: !fir.ref, %arg1: !fir.box) -> i1 { + %0 = fir.call @_FortranAioInputDescriptor(%arg0, %arg1) : (!fir.ref, !fir.box) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInputInteger( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i32) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioInputInteger(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i32) -> i1 { + %0 = fir.call @_FortranAioInputInteger(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i32) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInputLogical( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioInputLogical(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioInputLogical(%arg0: !fir.ref, %arg1: !fir.ref) -> i1 { + %0 = fir.call @_FortranAioInputLogical(%arg0, %arg1) : (!fir.ref, !fir.ref) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInputNamelist( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioInputNamelist(%[[VAL_0]], %[[VAL_1]]) {llvm.nosync} : (!fir.ref, !fir.ref>) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioInputNamelist(%arg0: !fir.ref, %arg1: !fir.ref>) -> i1 { + %0 = fir.call @_FortranAioInputNamelist(%arg0, %arg1) : (!fir.ref, !fir.ref>) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInputReal32( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioInputReal32(%arg0: !fir.ref, %arg1: !fir.ref) -> i1 { + %0 = fir.call @_FortranAioInputReal32(%arg0, %arg1) : (!fir.ref, !fir.ref) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInputReal64( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioInputReal64(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioInputReal64(%arg0: !fir.ref, %arg1: !fir.ref) -> i1 { + %0 = fir.call @_FortranAioInputReal64(%arg0, %arg1) : (!fir.ref, !fir.ref) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInquireCharacter( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_4:.*]] = fir.call @_FortranAioInquireCharacter(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_4]] : i1 +// CHECK: } + func.func @test__FortranAioInquireCharacter(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.ref, %arg3: i64) -> i1 { + %0 = fir.call @_FortranAioInquireCharacter(%arg0, %arg1, %arg2, %arg3) : (!fir.ref, i64, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInquireInteger64( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_3:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> i1 { +// CHECK: %[[VAL_4:.*]] = fir.call @_FortranAioInquireInteger64(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]], %[[VAL_3]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.ref, i32) -> i1 +// CHECK: return %[[VAL_4]] : i1 +// CHECK: } + func.func @test__FortranAioInquireInteger64(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.ref, %arg3: i32) -> i1 { + %0 = fir.call @_FortranAioInquireInteger64(%arg0, %arg1, %arg2, %arg3) : (!fir.ref, i64, !fir.ref, i32) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInquireLogical( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioInquireLogical(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i64, !fir.ref) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioInquireLogical(%arg0: !fir.ref, %arg1: i64, %arg2: !fir.ref) -> i1 { + %0 = fir.call @_FortranAioInquireLogical(%arg0, %arg1, %arg2) : (!fir.ref, i64, !fir.ref) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioInquirePendingId( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioInquirePendingId(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i32, !fir.ref) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioInquirePendingId(%arg0: !fir.ref, %arg1: i32, %arg2: !fir.ref) -> i1 { + %0 = fir.call @_FortranAioInquirePendingId(%arg0, %arg1, %arg2) : (!fir.ref, i32, !fir.ref) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputAscii( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioOutputAscii(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioOutputAscii(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioOutputAscii(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputComplex32( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: f32, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: f32) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioOutputComplex32(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, f32, f32) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioOutputComplex32(%arg0: !fir.ref, %arg1: f32, %arg2: f32) -> i1 { + %0 = fir.call @_FortranAioOutputComplex32(%arg0, %arg1, %arg2) : (!fir.ref, f32, f32) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputComplex64( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: f64, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: f64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioOutputComplex64(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, f64, f64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioOutputComplex64(%arg0: !fir.ref, %arg1: f64, %arg2: f64) -> i1 { + %0 = fir.call @_FortranAioOutputComplex64(%arg0, %arg1, %arg2) : (!fir.ref, f64, f64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputDerivedType( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioOutputDerivedType(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {llvm.nosync} : (!fir.ref, !fir.box, !fir.ref>) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioOutputDerivedType(%arg0: !fir.ref, %arg1: !fir.box, %arg2: !fir.ref>) -> i1 { + %0 = fir.call @_FortranAioOutputDerivedType(%arg0, %arg1, %arg2) : (!fir.ref, !fir.box, !fir.ref>) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputDescriptor( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputDescriptor(%[[VAL_0]], %[[VAL_1]]) {llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.box) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputDescriptor(%arg0: !fir.ref, %arg1: !fir.box) -> i1 { + %0 = fir.call @_FortranAioOutputDescriptor(%arg0, %arg1) : (!fir.ref, !fir.box) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputInteger128( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i128) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputInteger128(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i128) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputInteger128(%arg0: !fir.ref, %arg1: i128) -> i1 { + %0 = fir.call @_FortranAioOutputInteger128(%arg0, %arg1) : (!fir.ref, i128) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputInteger16( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i16) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputInteger16(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i16) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputInteger16(%arg0: !fir.ref, %arg1: i16) -> i1 { + %0 = fir.call @_FortranAioOutputInteger16(%arg0, %arg1) : (!fir.ref, i16) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputInteger32( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i32) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputInteger32(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i32) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputInteger32(%arg0: !fir.ref, %arg1: i32) -> i1 { + %0 = fir.call @_FortranAioOutputInteger32(%arg0, %arg1) : (!fir.ref, i32) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputInteger64( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputInteger64(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i64) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputInteger64(%arg0: !fir.ref, %arg1: i64) -> i1 { + %0 = fir.call @_FortranAioOutputInteger64(%arg0, %arg1) : (!fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputInteger8( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i8) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputInteger8(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i8) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputInteger8(%arg0: !fir.ref, %arg1: i8) -> i1 { + %0 = fir.call @_FortranAioOutputInteger8(%arg0, %arg1) : (!fir.ref, i8) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputLogical( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i1) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputLogical(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i1) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputLogical(%arg0: !fir.ref, %arg1: i1) -> i1 { + %0 = fir.call @_FortranAioOutputLogical(%arg0, %arg1) : (!fir.ref, i1) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputNamelist( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref>) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputNamelist(%[[VAL_0]], %[[VAL_1]]) {llvm.nosync} : (!fir.ref, !fir.ref>) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputNamelist(%arg0: !fir.ref, %arg1: !fir.ref>) -> i1 { + %0 = fir.call @_FortranAioOutputNamelist(%arg0, %arg1) : (!fir.ref, !fir.ref>) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputReal32( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: f32) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputReal32(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, f32) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputReal32(%arg0: !fir.ref, %arg1: f32) -> i1 { + %0 = fir.call @_FortranAioOutputReal32(%arg0, %arg1) : (!fir.ref, f32) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioOutputReal64( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: f64) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioOutputReal64(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, f64) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioOutputReal64(%arg0: !fir.ref, %arg1: f64) -> i1 { + %0 = fir.call @_FortranAioOutputReal64(%arg0, %arg1) : (!fir.ref, f64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetAccess( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetAccess(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetAccess(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetAccess(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetAction( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetAction(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetAction(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetAction(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetAdvance( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetAdvance(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetAdvance(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetAdvance(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetAsynchronous( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetAsynchronous(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetAsynchronous(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetAsynchronous(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetBlank( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetBlank(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetBlank(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetBlank(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetCarriagecontrol( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetCarriagecontrol(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetCarriagecontrol(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetCarriagecontrol(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetConvert( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetConvert(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetConvert(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetConvert(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetDecimal( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetDecimal(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetDecimal(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetDecimal(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetDelim( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetDelim(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetDelim(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetDelim(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetEncoding( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetEncoding(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetEncoding(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetEncoding(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetFile( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetFile(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetFile(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetFile(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetForm( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetForm(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetForm(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetForm(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetPad( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetPad(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetPad(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetPad(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetPos( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioSetPos(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i64) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioSetPos(%arg0: !fir.ref, %arg1: i64) -> i1 { + %0 = fir.call @_FortranAioSetPos(%arg0, %arg1) : (!fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetPosition( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetPosition(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetPosition(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetPosition(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetRec( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioSetRec(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i64) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioSetRec(%arg0: !fir.ref, %arg1: i64) -> i1 { + %0 = fir.call @_FortranAioSetRec(%arg0, %arg1) : (!fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetRecl( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_2:.*]] = fir.call @_FortranAioSetRecl(%[[VAL_0]], %[[VAL_1]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, i64) -> i1 +// CHECK: return %[[VAL_2]] : i1 +// CHECK: } + func.func @test__FortranAioSetRecl(%arg0: !fir.ref, %arg1: i64) -> i1 { + %0 = fir.call @_FortranAioSetRecl(%arg0, %arg1) : (!fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetRound( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetRound(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetRound(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetRound(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetSign( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetSign(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetSign(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetSign(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } +// CHECK-LABEL: func.func @test__FortranAioSetStatus( +// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref, +// CHECK-SAME: %[[VAL_2:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: i64) -> i1 { +// CHECK: %[[VAL_3:.*]] = fir.call @_FortranAioSetStatus(%[[VAL_0]], %[[VAL_1]], %[[VAL_2]]) {fir.llvm_memory = #llvm.memory_effects, llvm.nocallback, llvm.nosync} : (!fir.ref, !fir.ref, i64) -> i1 +// CHECK: return %[[VAL_3]] : i1 +// CHECK: } + func.func @test__FortranAioSetStatus(%arg0: !fir.ref, %arg1: !fir.ref, %arg2: i64) -> i1 { + %0 = fir.call @_FortranAioSetStatus(%arg0, %arg1, %arg2) : (!fir.ref, !fir.ref, i64) -> i1 + return %0 : i1 + } + func.func private @_FortranAioBeginBackspace(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginClose(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginEndfile(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginExternalFormattedInput(!fir.ref, i64, !fir.box, i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginExternalFormattedOutput(!fir.ref, i64, !fir.box, i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginExternalListInput(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginExternalListOutput(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginFlush(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInquireFile(!fir.ref, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInquireIoLength(!fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInquireUnit(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInternalArrayFormattedInput(!fir.box, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInternalArrayFormattedOutput(!fir.box, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInternalArrayListInput(!fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInternalArrayListOutput(!fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInternalFormattedInput(!fir.ref, i64, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInternalFormattedOutput(!fir.ref, i64, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInternalListInput(!fir.ref, i64, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginInternalListOutput(!fir.ref, i64, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginOpenNewUnit(!fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginOpenUnit(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginRewind(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginUnformattedInput(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginUnformattedOutput(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginWait(i32, i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioBeginWaitAll(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} + func.func private @_FortranAioCheckUnitNumberInRange128(i128, i1, !fir.ref, i64, !fir.ref, i32) -> i32 attributes {fir.io, fir.runtime} + func.func private @_FortranAioCheckUnitNumberInRange64(i64, i1, !fir.ref, i64, !fir.ref, i32) -> i32 attributes {fir.io, fir.runtime} + func.func private @_FortranAioEnableHandlers(!fir.ref, i1, i1, i1, i1, i1) attributes {fir.io, fir.runtime} + func.func private @_FortranAioEndIoStatement(!fir.ref) -> i32 attributes {fir.io, fir.runtime} + func.func private @_FortranAioGetAsynchronousId(!fir.ref) -> i32 attributes {fir.io, fir.runtime} + func.func private @_FortranAioGetIoLength(!fir.ref) -> i64 attributes {fir.io, fir.runtime} + func.func private @_FortranAioGetIoMsg(!fir.ref, !fir.ref, i64) attributes {fir.io, fir.runtime} + func.func private @_FortranAioGetNewUnit(!fir.ref, !fir.ref, i32) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioGetSize(!fir.ref) -> i64 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputAscii(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputComplex32(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputComplex64(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputDerivedType(!fir.ref, !fir.box, !fir.ref>) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputDescriptor(!fir.ref, !fir.box) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputInteger(!fir.ref, !fir.ref, i32) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputLogical(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputNamelist(!fir.ref, !fir.ref>) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputReal32(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInputReal64(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInquireCharacter(!fir.ref, i64, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInquireInteger64(!fir.ref, i64, !fir.ref, i32) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInquireLogical(!fir.ref, i64, !fir.ref) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioInquirePendingId(!fir.ref, i32, !fir.ref) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputAscii(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputComplex32(!fir.ref, f32, f32) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputComplex64(!fir.ref, f64, f64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputDerivedType(!fir.ref, !fir.box, !fir.ref>) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputDescriptor(!fir.ref, !fir.box) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputInteger128(!fir.ref, i128) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputInteger16(!fir.ref, i16) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputInteger32(!fir.ref, i32) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputInteger64(!fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputInteger8(!fir.ref, i8) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputLogical(!fir.ref, i1) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputNamelist(!fir.ref, !fir.ref>) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputReal32(!fir.ref, f32) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioOutputReal64(!fir.ref, f64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetAccess(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetAction(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetAdvance(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetAsynchronous(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetBlank(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetCarriagecontrol(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetConvert(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetDecimal(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetDelim(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetEncoding(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetFile(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetForm(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetPad(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetPos(!fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetPosition(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetRec(!fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetRecl(!fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetRound(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetSign(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} + func.func private @_FortranAioSetStatus(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +} diff --git a/flang/test/Transforms/verify-known-runtime-functions.fir b/flang/test/Transforms/verify-known-runtime-functions.fir new file mode 100644 index 000000000000..902d701424f6 --- /dev/null +++ b/flang/test/Transforms/verify-known-runtime-functions.fir @@ -0,0 +1,101 @@ +// RUN: echo "module {}" | fir-opt --gen-runtime-calls-for-test | FileCheck %s + +// NOTE: Assertions have been autogenerated by flang/test/Utils/generate-checks-for-runtime-funcs.py + +// The script allows updating Flang LIT test +// flang/test/Transforms/verify-known-runtime-functions.fir, +// which is intended to verify signatures of Fortran runtime +// functions recognized in flang/Optimizer/Transforms/RuntimeFunctions.inc +// table. If new function is added into the table or +// an existing function changes its signature, +// the SetRuntimeCallAttributesPass may need to be updated +// to properly handle it. Once the pass is verified to work, +// one can update this test using the following output: +// echo "module {}" | fir-opt --gen-runtime-calls-for-test | \ +// generate-checks-for-runtime-funcs.py + +// CHECK-NOT: func.func +// CHECK: func.func private @_FortranAioBeginBackspace(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginClose(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginEndfile(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginExternalFormattedInput(!fir.ref, i64, !fir.box, i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginExternalFormattedOutput(!fir.ref, i64, !fir.box, i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginExternalListInput(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginExternalListOutput(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginFlush(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInquireFile(!fir.ref, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInquireIoLength(!fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInquireUnit(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInternalArrayFormattedInput(!fir.box, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInternalArrayFormattedOutput(!fir.box, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInternalArrayListInput(!fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInternalArrayListOutput(!fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInternalFormattedInput(!fir.ref, i64, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInternalFormattedOutput(!fir.ref, i64, !fir.ref, i64, !fir.box, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInternalListInput(!fir.ref, i64, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginInternalListOutput(!fir.ref, i64, !fir.ref>, i64, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginOpenNewUnit(!fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginOpenUnit(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginRewind(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginUnformattedInput(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginUnformattedOutput(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginWait(i32, i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioBeginWaitAll(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioCheckUnitNumberInRange128(i128, i1, !fir.ref, i64, !fir.ref, i32) -> i32 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioCheckUnitNumberInRange64(i64, i1, !fir.ref, i64, !fir.ref, i32) -> i32 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioEnableHandlers(!fir.ref, i1, i1, i1, i1, i1) attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioEndIoStatement(!fir.ref) -> i32 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioGetAsynchronousId(!fir.ref) -> i32 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioGetIoLength(!fir.ref) -> i64 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioGetIoMsg(!fir.ref, !fir.ref, i64) attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioGetNewUnit(!fir.ref, !fir.ref, i32) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioGetSize(!fir.ref) -> i64 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputAscii(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputComplex32(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputComplex64(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputDerivedType(!fir.ref, !fir.box, !fir.ref>) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputDescriptor(!fir.ref, !fir.box) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputInteger(!fir.ref, !fir.ref, i32) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputLogical(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputNamelist(!fir.ref, !fir.ref>) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputReal32(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInputReal64(!fir.ref, !fir.ref) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInquireCharacter(!fir.ref, i64, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInquireInteger64(!fir.ref, i64, !fir.ref, i32) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInquireLogical(!fir.ref, i64, !fir.ref) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioInquirePendingId(!fir.ref, i32, !fir.ref) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputAscii(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputComplex32(!fir.ref, f32, f32) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputComplex64(!fir.ref, f64, f64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputDerivedType(!fir.ref, !fir.box, !fir.ref>) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputDescriptor(!fir.ref, !fir.box) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputInteger128(!fir.ref, i128) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputInteger16(!fir.ref, i16) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputInteger32(!fir.ref, i32) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputInteger64(!fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputInteger8(!fir.ref, i8) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputLogical(!fir.ref, i1) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputNamelist(!fir.ref, !fir.ref>) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputReal32(!fir.ref, f32) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioOutputReal64(!fir.ref, f64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetAccess(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetAction(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetAdvance(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetAsynchronous(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetBlank(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetCarriagecontrol(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetConvert(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetDecimal(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetDelim(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetEncoding(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetFile(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetForm(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetPad(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetPos(!fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetPosition(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetRec(!fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetRecl(!fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetRound(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetSign(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NEXT: func.func private @_FortranAioSetStatus(!fir.ref, !fir.ref, i64) -> i1 attributes {fir.io, fir.runtime} +// CHECK-NOT: func.func diff --git a/flang/test/Utils/generate-checks-for-runtime-funcs.py b/flang/test/Utils/generate-checks-for-runtime-funcs.py new file mode 100755 index 000000000000..f1d476d4e339 --- /dev/null +++ b/flang/test/Utils/generate-checks-for-runtime-funcs.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +"""A script to generate FileCheck statements for Fortran runtime funcs. + +This script can be used to update +flang/test/Transforms/verify-known-runtime-functions.fir +whenever new recognized Fortran runtime functions are added +into flang/Optimizer/Transforms/RuntimeFunctions.inc +or any of the recognized functions changes its signature. +""" + +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +import argparse +import os +import re +import sys + +ADVERT_BEGIN = "// NOTE: Assertions have been autogenerated by " +ADVERT_END = """ +// The script allows updating Flang LIT test +// flang/test/Transforms/verify-known-runtime-functions.fir, +// which is intended to verify signatures of Fortran runtime +// functions recognized in flang/Optimizer/Transforms/RuntimeFunctions.inc +// table. If new function is added into the table or +// an existing function changes its signature, +// the SetRuntimeCallAttributesPass may need to be updated +// to properly handle it. Once the pass is verified to work, +// one can update this test using the following output: +// echo "module {}" | fir-opt --gen-runtime-calls-for-test | \\ +// generate-checks-for-runtime-funcs.py +""" + +CHECK_RE_STR = "func.func.*@_Fortran.*" +CHECK_RE = re.compile(CHECK_RE_STR) + +CHECK_NOT_STR = "// CHECK-NOT: func.func" +CHECK_STR = "// CHECK:" +CHECK_NEXT_STR = "// CHECK-NEXT:" + + +def main(): + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawTextHelpFormatter + ) + parser.add_argument( + "input", nargs="?", type=argparse.FileType("r"), default=sys.stdin + ) + args = parser.parse_args() + input_lines = [l.rstrip() for l in args.input] + args.input.close() + + repo_path = os.path.join(os.path.dirname(__file__), "..", "..", "..") + script_name = os.path.relpath(__file__, repo_path) + autogenerated_note = ADVERT_BEGIN + script_name + "\n" + ADVERT_END + + output = sys.stdout + output.write(autogenerated_note + "\n") + + output_lines = [] + output_lines.append(CHECK_NOT_STR) + check_prefix = CHECK_STR + for input_line in input_lines: + if not input_line: + continue + + m = CHECK_RE.match(input_line.lstrip()) + if m: + output_lines.append(check_prefix + " " + input_line.lstrip()) + check_prefix = CHECK_NEXT_STR + + output_lines.append(CHECK_NOT_STR) + for line in output_lines: + output.write(line + "\n") + + output.close() + + +if __name__ == "__main__": + main()