mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-28 03:26:16 +00:00
[flang] Lower F08 bitwise-reduction intrinsics (IALL, IANY, IPARITY)
This calls the corresponding runtime functions when appropriate. The implementation follows the pattern of the SUM and PRODUCT intrinsics. Differential Revision: https://reviews.llvm.org/D129616
This commit is contained in:
parent
9d259916e1
commit
ebfe8a7411
@ -387,6 +387,7 @@ struct RuntimeTableEntry<RuntimeTableKey<KT>, RuntimeIdentifier<Cs...>> {
|
||||
fir::runtime::RuntimeTableEntry<fir::runtime::RuntimeTableKey<decltype(X)>, \
|
||||
FirAsSequence(X)>
|
||||
#define mkRTKey(X) FirmkKey(RTNAME(X))
|
||||
#define EXPAND_AND_QUOTE_KEY(S) ExpandAndQuoteKey(RTNAME(S))
|
||||
|
||||
/// Get (or generate) the MLIR FuncOp for a given runtime function. Its template
|
||||
/// argument is intended to be of the form: <mkRTKey(runtime function name)>.
|
||||
|
@ -165,6 +165,42 @@ void genSumDim(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value resultBox, mlir::Value arrayBox, mlir::Value dim,
|
||||
mlir::Value maskBox);
|
||||
|
||||
/// Generate call to `IAll` intrinsic runtime routine. This is the version
|
||||
/// that does not take a dim argument.
|
||||
mlir::Value genIAll(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value arrayBox, mlir::Value maskBox,
|
||||
mlir::Value resultBox);
|
||||
|
||||
/// Generate call to `IAllDim` intrinsic runtime routine. This is the version
|
||||
/// that takes arrays of any rank with a dim argument specified.
|
||||
void genIAllDim(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value resultBox, mlir::Value arrayBox, mlir::Value dim,
|
||||
mlir::Value maskBox);
|
||||
|
||||
/// Generate call to `IAny` intrinsic runtime routine. This is the version
|
||||
/// that does not take a dim argument.
|
||||
mlir::Value genIAny(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value arrayBox, mlir::Value maskBox,
|
||||
mlir::Value resultBox);
|
||||
|
||||
/// Generate call to `IAnyDim` intrinsic runtime routine. This is the version
|
||||
/// that takes arrays of any rank with a dim argument specified.
|
||||
void genIAnyDim(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value resultBox, mlir::Value arrayBox, mlir::Value dim,
|
||||
mlir::Value maskBox);
|
||||
|
||||
/// Generate call to `IParity` intrinsic runtime routine. This is the version
|
||||
/// that does not take a dim argument.
|
||||
mlir::Value genIParity(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value arrayBox, mlir::Value maskBox,
|
||||
mlir::Value resultBox);
|
||||
|
||||
/// Generate call to `IParityDim` intrinsic runtime routine. This is the version
|
||||
/// that takes arrays of any rank with a dim argument specified.
|
||||
void genIParityDim(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value resultBox, mlir::Value arrayBox, mlir::Value dim,
|
||||
mlir::Value maskBox);
|
||||
|
||||
} // namespace fir::runtime
|
||||
|
||||
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_REDUCTION_H
|
||||
|
@ -175,10 +175,10 @@ genFuncDim(FD funcDim, mlir::Type resultType, fir::FirOpBuilder &builder,
|
||||
});
|
||||
}
|
||||
|
||||
/// Process calls to Product, Sum intrinsic functions
|
||||
/// Process calls to Product, Sum, IAll, IAny, IParity intrinsic functions
|
||||
template <typename FN, typename FD>
|
||||
static fir::ExtendedValue
|
||||
genProdOrSum(FN func, FD funcDim, mlir::Type resultType,
|
||||
genReduction(FN func, FD funcDim, mlir::Type resultType,
|
||||
fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
Fortran::lower::StatementContext *stmtCtx, llvm::StringRef errMsg,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
@ -500,9 +500,11 @@ struct IntrinsicLibrary {
|
||||
mlir::ArrayRef<mlir::Value> args);
|
||||
void genGetCommandArgument(mlir::ArrayRef<fir::ExtendedValue> args);
|
||||
void genGetEnvironmentVariable(llvm::ArrayRef<fir::ExtendedValue>);
|
||||
fir::ExtendedValue genIall(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
/// Lowering for the IAND intrinsic. The IAND intrinsic expects two arguments
|
||||
/// in the llvm::ArrayRef.
|
||||
mlir::Value genIand(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
fir::ExtendedValue genIany(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
mlir::Value genIbclr(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
mlir::Value genIbits(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
mlir::Value genIbset(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
@ -514,6 +516,7 @@ struct IntrinsicLibrary {
|
||||
mlir::Value genIeor(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
fir::ExtendedValue genIndex(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
mlir::Value genIor(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
fir::ExtendedValue genIparity(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
mlir::Value genIshft(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
mlir::Value genIshftc(mlir::Type, llvm::ArrayRef<mlir::Value>);
|
||||
fir::ExtendedValue genLbound(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
@ -802,7 +805,19 @@ static constexpr IntrinsicHandler handlers[]{
|
||||
{"errmsg", asBox, handleDynamicOptional}}},
|
||||
/*isElemental=*/false},
|
||||
{"iachar", &I::genIchar},
|
||||
{"iall",
|
||||
&I::genIall,
|
||||
{{{"array", asBox},
|
||||
{"dim", asValue},
|
||||
{"mask", asBox, handleDynamicOptional}}},
|
||||
/*isElemental=*/false},
|
||||
{"iand", &I::genIand},
|
||||
{"iany",
|
||||
&I::genIany,
|
||||
{{{"array", asBox},
|
||||
{"dim", asValue},
|
||||
{"mask", asBox, handleDynamicOptional}}},
|
||||
/*isElemental=*/false},
|
||||
{"ibclr", &I::genIbclr},
|
||||
{"ibits", &I::genIbits},
|
||||
{"ibset", &I::genIbset},
|
||||
@ -820,6 +835,12 @@ static constexpr IntrinsicHandler handlers[]{
|
||||
{"back", asValue, handleDynamicOptional},
|
||||
{"kind", asValue}}}},
|
||||
{"ior", &I::genIor},
|
||||
{"iparity",
|
||||
&I::genIparity,
|
||||
{{{"array", asBox},
|
||||
{"dim", asValue},
|
||||
{"mask", asBox, handleDynamicOptional}}},
|
||||
/*isElemental=*/false},
|
||||
{"ishft", &I::genIshft},
|
||||
{"ishftc", &I::genIshftc},
|
||||
{"lbound",
|
||||
@ -3084,6 +3105,15 @@ void IntrinsicLibrary::genGetEnvironmentVariable(
|
||||
}
|
||||
}
|
||||
|
||||
// IALL
|
||||
fir::ExtendedValue
|
||||
IntrinsicLibrary::genIall(mlir::Type resultType,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
return genReduction(fir::runtime::genIAll, fir::runtime::genIAllDim,
|
||||
resultType, builder, loc, stmtCtx,
|
||||
"unexpected result for IALL", args);
|
||||
}
|
||||
|
||||
// IAND
|
||||
mlir::Value IntrinsicLibrary::genIand(mlir::Type resultType,
|
||||
llvm::ArrayRef<mlir::Value> args) {
|
||||
@ -3093,6 +3123,15 @@ mlir::Value IntrinsicLibrary::genIand(mlir::Type resultType,
|
||||
return builder.create<mlir::arith::AndIOp>(loc, arg0, arg1);
|
||||
}
|
||||
|
||||
// IANY
|
||||
fir::ExtendedValue
|
||||
IntrinsicLibrary::genIany(mlir::Type resultType,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
return genReduction(fir::runtime::genIAny, fir::runtime::genIAnyDim,
|
||||
resultType, builder, loc, stmtCtx,
|
||||
"unexpected result for IANY", args);
|
||||
}
|
||||
|
||||
// IBCLR
|
||||
mlir::Value IntrinsicLibrary::genIbclr(mlir::Type resultType,
|
||||
llvm::ArrayRef<mlir::Value> args) {
|
||||
@ -3317,6 +3356,15 @@ mlir::Value IntrinsicLibrary::genIor(mlir::Type resultType,
|
||||
return builder.create<mlir::arith::OrIOp>(loc, args[0], args[1]);
|
||||
}
|
||||
|
||||
// IPARITY
|
||||
fir::ExtendedValue
|
||||
IntrinsicLibrary::genIparity(mlir::Type resultType,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
return genReduction(fir::runtime::genIParity, fir::runtime::genIParityDim,
|
||||
resultType, builder, loc, stmtCtx,
|
||||
"unexpected result for IPARITY", args);
|
||||
}
|
||||
|
||||
// ISHFT
|
||||
mlir::Value IntrinsicLibrary::genIshft(mlir::Type resultType,
|
||||
llvm::ArrayRef<mlir::Value> args) {
|
||||
@ -3824,7 +3872,7 @@ IntrinsicLibrary::genPresent(mlir::Type,
|
||||
fir::ExtendedValue
|
||||
IntrinsicLibrary::genProduct(mlir::Type resultType,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
return genProdOrSum(fir::runtime::genProduct, fir::runtime::genProductDim,
|
||||
return genReduction(fir::runtime::genProduct, fir::runtime::genProductDim,
|
||||
resultType, builder, loc, stmtCtx,
|
||||
"unexpected result for Product", args);
|
||||
}
|
||||
@ -4424,7 +4472,7 @@ IntrinsicLibrary::genSpread(mlir::Type resultType,
|
||||
fir::ExtendedValue
|
||||
IntrinsicLibrary::genSum(mlir::Type resultType,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
return genProdOrSum(fir::runtime::genSum, fir::runtime::genSumDim, resultType,
|
||||
return genReduction(fir::runtime::genSum, fir::runtime::genSumDim, resultType,
|
||||
builder, loc, stmtCtx, "unexpected result for Sum", args);
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,10 @@
|
||||
|
||||
using namespace Fortran::runtime;
|
||||
|
||||
#define STRINGIFY(S) #S
|
||||
#define JOIN2(A, B) A##B
|
||||
#define JOIN3(A, B, C) A##B##C
|
||||
|
||||
/// Placeholder for real*10 version of Maxval Intrinsic
|
||||
struct ForcedMaxvalReal10 {
|
||||
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(MaxvalReal10));
|
||||
@ -368,6 +372,54 @@ struct ForcedSumComplex16 {
|
||||
}
|
||||
};
|
||||
|
||||
/// Placeholder for integer(16) version of IAll Intrinsic
|
||||
struct ForcedIAll16 {
|
||||
static constexpr const char *name = EXPAND_AND_QUOTE_KEY(IAll16);
|
||||
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
|
||||
return [](mlir::MLIRContext *ctx) {
|
||||
auto ty = mlir::IntegerType::get(ctx, 128);
|
||||
auto boxTy =
|
||||
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
|
||||
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
|
||||
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
|
||||
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
|
||||
{ty});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// Placeholder for integer(16) version of IAny Intrinsic
|
||||
struct ForcedIAny16 {
|
||||
static constexpr const char *name = EXPAND_AND_QUOTE_KEY(IAny16);
|
||||
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
|
||||
return [](mlir::MLIRContext *ctx) {
|
||||
auto ty = mlir::IntegerType::get(ctx, 128);
|
||||
auto boxTy =
|
||||
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
|
||||
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
|
||||
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
|
||||
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
|
||||
{ty});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// Placeholder for integer(16) version of IParity Intrinsic
|
||||
struct ForcedIParity16 {
|
||||
static constexpr const char *name = EXPAND_AND_QUOTE_KEY(IParity16);
|
||||
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
|
||||
return [](mlir::MLIRContext *ctx) {
|
||||
auto ty = mlir::IntegerType::get(ctx, 128);
|
||||
auto boxTy =
|
||||
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
|
||||
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
|
||||
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
|
||||
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
|
||||
{ty});
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// Generate call to specialized runtime function that takes a mask and
|
||||
/// dim argument. The All, Any, and Count intrinsics use this pattern.
|
||||
template <typename FN>
|
||||
@ -942,3 +994,78 @@ mlir::Value fir::runtime::genSum(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
|
||||
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
|
||||
}
|
||||
|
||||
// The IAll, IAny and IParity intrinsics have essentially the same
|
||||
// implementation. This macro will generate the function body given the
|
||||
// instrinsic name.
|
||||
#define GEN_IALL_IANY_IPARITY(F) \
|
||||
mlir::Value fir::runtime::JOIN2(gen, F)( \
|
||||
fir::FirOpBuilder & builder, mlir::Location loc, mlir::Value arrayBox, \
|
||||
mlir::Value maskBox, mlir::Value resultBox) { \
|
||||
mlir::func::FuncOp func; \
|
||||
auto ty = arrayBox.getType(); \
|
||||
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty); \
|
||||
auto eleTy = arrTy.cast<fir::SequenceType>().getEleTy(); \
|
||||
auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0); \
|
||||
\
|
||||
if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1))) \
|
||||
func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 1))>(loc, builder); \
|
||||
else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2))) \
|
||||
func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 2))>(loc, builder); \
|
||||
else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4))) \
|
||||
func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 4))>(loc, builder); \
|
||||
else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8))) \
|
||||
func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 8))>(loc, builder); \
|
||||
else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16))) \
|
||||
func = fir::runtime::getRuntimeFunc<JOIN3(Forced, F, 16)>(loc, builder); \
|
||||
else \
|
||||
fir::emitFatalError(loc, "invalid type in " STRINGIFY(F)); \
|
||||
\
|
||||
auto fTy = func.getFunctionType(); \
|
||||
auto sourceFile = fir::factory::locationToFilename(builder, loc); \
|
||||
auto sourceLine = \
|
||||
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2)); \
|
||||
auto args = fir::runtime::createArguments( \
|
||||
builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox); \
|
||||
\
|
||||
return builder.create<fir::CallOp>(loc, func, args).getResult(0); \
|
||||
}
|
||||
|
||||
/// Generate call to `IAllDim` intrinsic runtime routine. This is the version
|
||||
/// that handles any rank array with the dim argument specified.
|
||||
void fir::runtime::genIAllDim(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value resultBox, mlir::Value arrayBox,
|
||||
mlir::Value dim, mlir::Value maskBox) {
|
||||
auto func = fir::runtime::getRuntimeFunc<mkRTKey(IAllDim)>(loc, builder);
|
||||
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
|
||||
}
|
||||
|
||||
/// Generate call to `IAll` intrinsic runtime routine. This is the version
|
||||
/// that does not take a dim argument.
|
||||
GEN_IALL_IANY_IPARITY(IAll)
|
||||
|
||||
/// Generate call to `IAnyDim` intrinsic runtime routine. This is the version
|
||||
/// that handles any rank array with the dim argument specified.
|
||||
void fir::runtime::genIAnyDim(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value resultBox, mlir::Value arrayBox,
|
||||
mlir::Value dim, mlir::Value maskBox) {
|
||||
auto func = fir::runtime::getRuntimeFunc<mkRTKey(IAnyDim)>(loc, builder);
|
||||
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
|
||||
}
|
||||
|
||||
/// Generate call to `IAny` intrinsic runtime routine. This is the version
|
||||
/// that does not take a dim argument.
|
||||
GEN_IALL_IANY_IPARITY(IAny)
|
||||
|
||||
/// Generate call to `IParityDim` intrinsic runtime routine. This is the version
|
||||
/// that handles any rank array with the dim argument specified.
|
||||
void fir::runtime::genIParityDim(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
mlir::Value resultBox, mlir::Value arrayBox,
|
||||
mlir::Value dim, mlir::Value maskBox) {
|
||||
auto func = fir::runtime::getRuntimeFunc<mkRTKey(IParityDim)>(loc, builder);
|
||||
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
|
||||
}
|
||||
|
||||
/// Generate call to `IParity` intrinsic runtime routine. This is the version
|
||||
/// that does not take a dim argument.
|
||||
GEN_IALL_IANY_IPARITY(IParity)
|
||||
|
156
flang/test/Lower/Intrinsics/iall.f90
Normal file
156
flang/test/Lower/Intrinsics/iall.f90
Normal file
@ -0,0 +1,156 @@
|
||||
! RUN: bbc -emit-fir %s -o - | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test_1(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi8>>{{.*}}) -> i8 {
|
||||
integer(1) function iall_test_1(a)
|
||||
integer(1) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi8>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iall_test_1 = iall(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAll1(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i8
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test_2(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi16>>{{.*}}) -> i16 {
|
||||
integer(2) function iall_test_2(a)
|
||||
integer(2) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi16>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iall_test_2 = iall(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAll2(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i16
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test_4(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) -> i32 {
|
||||
integer function iall_test_4(a)
|
||||
integer :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iall_test_4 = iall(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAll4(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test_8(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi64>>{{.*}}) -> i64 {
|
||||
integer(8) function iall_test_8(a)
|
||||
integer(8) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi64>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iall_test_8 = iall(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAll8(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i64
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test_16(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi128>>{{.*}}) -> i128 {
|
||||
integer(16) function iall_test_16(a)
|
||||
integer(16) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi128>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iall_test_16 = iall(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAll16(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i128
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test2(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?x?xi32>>{{.*}}, %[[arg1:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) {
|
||||
subroutine iall_test2(a,r)
|
||||
integer :: a(:,:)
|
||||
integer :: r(:)
|
||||
! CHECK-DAG: %[[c2_i32:.*]] = arith.constant 2 : i32
|
||||
! CHECK-DAG: %[[a0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a0]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
|
||||
! CHECK-DAG: %[[a7:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?x?xi32>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a9:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
r = iall(a,dim=2)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAllDim(%[[a6]], %[[a7]], %[[c2_i32]], %{{.*}}, %{{.*}}, %[[a9]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32, !fir.ref<i8>, i32, !fir.box<none>) -> none
|
||||
! CHECK-DAG: %[[a11:.*]] = fir.load %[[a0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
||||
! CHECK-DAG: %[[a13:.*]] = fir.box_addr %[[a11]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
||||
! CHECK-DAG: fir.freemem %[[a13]]
|
||||
end subroutine
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test_optional(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
integer function iall_test_optional(mask, x)
|
||||
integer :: x(:)
|
||||
logical, optional :: mask(:)
|
||||
iall_test_optional = iall(x, mask=mask)
|
||||
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIAll4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_9]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test_optional_2(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>>
|
||||
integer function iall_test_optional_2(mask, x)
|
||||
integer :: x(:)
|
||||
logical, pointer :: mask(:)
|
||||
iall_test_optional_2 = iall(x, mask=mask)
|
||||
! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>>
|
||||
! CHECK: %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>) -> !fir.ptr<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.ptr<!fir.array<?x!fir.logical<4>>>) -> i64
|
||||
! CHECK: %[[VAL_7:.*]] = arith.constant 0 : i64
|
||||
! CHECK: %[[VAL_8:.*]] = arith.cmpi ne, %[[VAL_6]], %[[VAL_7]] : i64
|
||||
! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>>
|
||||
! CHECK: %[[VAL_10:.*]] = fir.absent !fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_8]], %[[VAL_9]], %[[VAL_10]] : !fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIAll4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_18]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test_optional_3(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10x!fir.logical<4>>>
|
||||
integer function iall_test_optional_3(mask, x)
|
||||
integer :: x(:)
|
||||
logical, optional :: mask(10)
|
||||
iall_test_optional_3 = iall(x, mask=mask)
|
||||
! CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
|
||||
! CHECK: %[[VAL_5:.*]] = fir.is_present %[[VAL_0]] : (!fir.ref<!fir.array<10x!fir.logical<4>>>) -> i1
|
||||
! CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
|
||||
! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_0]](%[[VAL_6]]) : (!fir.ref<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.array<10x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_9:.*]] = arith.select %[[VAL_5]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<10x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<10x!fir.logical<4>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIAll4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_18]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiall_test_optional_4(
|
||||
integer function iall_test_optional_4(x, use_mask)
|
||||
! Test that local allocatable tracked in local variables
|
||||
! are dealt as optional argument correctly.
|
||||
integer :: x(:)
|
||||
logical :: use_mask
|
||||
logical, allocatable :: mask(:)
|
||||
if (use_mask) then
|
||||
allocate(mask(size(x, 1)))
|
||||
call set_mask(mask)
|
||||
! CHECK: fir.call @_QPset_mask
|
||||
end if
|
||||
iall_test_optional_4 = iall(x, mask=mask)
|
||||
! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_3:.*]] : !fir.ref<!fir.heap<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.heap<!fir.array<?x!fir.logical<4>>>) -> i64
|
||||
! CHECK: %[[VAL_22:.*]] = arith.constant 0 : i64
|
||||
! CHECK: %[[VAL_23:.*]] = arith.cmpi ne, %[[VAL_21]], %[[VAL_22]] : i64
|
||||
! CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_4:.*]] : !fir.ref<index>
|
||||
! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_5:.*]] : !fir.ref<index>
|
||||
! CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.heap<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_27:.*]] = fir.shape_shift %[[VAL_24]], %[[VAL_25]] : (index, index) -> !fir.shapeshift<1>
|
||||
! CHECK: %[[VAL_28:.*]] = fir.embox %[[VAL_26]](%[[VAL_27]]) : (!fir.heap<!fir.array<?x!fir.logical<4>>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_29:.*]] = fir.absent !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_23]], %[[VAL_28]], %[[VAL_29]] : !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_30]] : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIAll4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_37]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
156
flang/test/Lower/Intrinsics/iany.f90
Normal file
156
flang/test/Lower/Intrinsics/iany.f90
Normal file
@ -0,0 +1,156 @@
|
||||
! RUN: bbc -emit-fir %s -o - | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test_1(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi8>>{{.*}}) -> i8 {
|
||||
integer(1) function iany_test_1(a)
|
||||
integer(1) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi8>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iany_test_1 = iany(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAny1(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i8
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test_2(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi16>>{{.*}}) -> i16 {
|
||||
integer(2) function iany_test_2(a)
|
||||
integer(2) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi16>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iany_test_2 = iany(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAny2(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i16
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test_4(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) -> i32 {
|
||||
integer function iany_test_4(a)
|
||||
integer :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iany_test_4 = iany(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAny4(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test_8(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi64>>{{.*}}) -> i64 {
|
||||
integer(8) function iany_test_8(a)
|
||||
integer(8) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi64>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iany_test_8 = iany(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAny8(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i64
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test_16(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi128>>{{.*}}) -> i128 {
|
||||
integer(16) function iany_test_16(a)
|
||||
integer(16) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi128>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iany_test_16 = iany(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAny16(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i128
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test2(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?x?xi32>>{{.*}}, %[[arg1:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) {
|
||||
subroutine iany_test2(a,r)
|
||||
integer :: a(:,:)
|
||||
integer :: r(:)
|
||||
! CHECK-DAG: %[[c2_i32:.*]] = arith.constant 2 : i32
|
||||
! CHECK-DAG: %[[a0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a0]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
|
||||
! CHECK-DAG: %[[a7:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?x?xi32>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a9:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
r = iany(a,dim=2)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIAnyDim(%[[a6]], %[[a7]], %[[c2_i32]], %{{.*}}, %{{.*}}, %[[a9]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32, !fir.ref<i8>, i32, !fir.box<none>) -> none
|
||||
! CHECK-DAG: %[[a11:.*]] = fir.load %[[a0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
||||
! CHECK-DAG: %[[a13:.*]] = fir.box_addr %[[a11]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
||||
! CHECK-DAG: fir.freemem %[[a13]]
|
||||
end subroutine
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test_optional(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
integer function iany_test_optional(mask, x)
|
||||
integer :: x(:)
|
||||
logical, optional :: mask(:)
|
||||
iany_test_optional = iany(x, mask=mask)
|
||||
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIAny4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_9]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test_optional_2(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>>
|
||||
integer function iany_test_optional_2(mask, x)
|
||||
integer :: x(:)
|
||||
logical, pointer :: mask(:)
|
||||
iany_test_optional_2 = iany(x, mask=mask)
|
||||
! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>>
|
||||
! CHECK: %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>) -> !fir.ptr<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.ptr<!fir.array<?x!fir.logical<4>>>) -> i64
|
||||
! CHECK: %[[VAL_7:.*]] = arith.constant 0 : i64
|
||||
! CHECK: %[[VAL_8:.*]] = arith.cmpi ne, %[[VAL_6]], %[[VAL_7]] : i64
|
||||
! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>>
|
||||
! CHECK: %[[VAL_10:.*]] = fir.absent !fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_8]], %[[VAL_9]], %[[VAL_10]] : !fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIAny4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_18]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test_optional_3(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10x!fir.logical<4>>>
|
||||
integer function iany_test_optional_3(mask, x)
|
||||
integer :: x(:)
|
||||
logical, optional :: mask(10)
|
||||
iany_test_optional_3 = iany(x, mask=mask)
|
||||
! CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
|
||||
! CHECK: %[[VAL_5:.*]] = fir.is_present %[[VAL_0]] : (!fir.ref<!fir.array<10x!fir.logical<4>>>) -> i1
|
||||
! CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
|
||||
! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_0]](%[[VAL_6]]) : (!fir.ref<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.array<10x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_9:.*]] = arith.select %[[VAL_5]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<10x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<10x!fir.logical<4>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIAny4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_18]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiany_test_optional_4(
|
||||
integer function iany_test_optional_4(x, use_mask)
|
||||
! Test that local allocatable tracked in local variables
|
||||
! are dealt as optional argument correctly.
|
||||
integer :: x(:)
|
||||
logical :: use_mask
|
||||
logical, allocatable :: mask(:)
|
||||
if (use_mask) then
|
||||
allocate(mask(size(x, 1)))
|
||||
call set_mask(mask)
|
||||
! CHECK: fir.call @_QPset_mask
|
||||
end if
|
||||
iany_test_optional_4 = iany(x, mask=mask)
|
||||
! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_3:.*]] : !fir.ref<!fir.heap<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.heap<!fir.array<?x!fir.logical<4>>>) -> i64
|
||||
! CHECK: %[[VAL_22:.*]] = arith.constant 0 : i64
|
||||
! CHECK: %[[VAL_23:.*]] = arith.cmpi ne, %[[VAL_21]], %[[VAL_22]] : i64
|
||||
! CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_4:.*]] : !fir.ref<index>
|
||||
! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_5:.*]] : !fir.ref<index>
|
||||
! CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.heap<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_27:.*]] = fir.shape_shift %[[VAL_24]], %[[VAL_25]] : (index, index) -> !fir.shapeshift<1>
|
||||
! CHECK: %[[VAL_28:.*]] = fir.embox %[[VAL_26]](%[[VAL_27]]) : (!fir.heap<!fir.array<?x!fir.logical<4>>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_29:.*]] = fir.absent !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_23]], %[[VAL_28]], %[[VAL_29]] : !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_30]] : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIAny4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_37]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
156
flang/test/Lower/Intrinsics/iparity.f90
Normal file
156
flang/test/Lower/Intrinsics/iparity.f90
Normal file
@ -0,0 +1,156 @@
|
||||
! RUN: bbc -emit-fir %s -o - | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test_1(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi8>>{{.*}}) -> i8 {
|
||||
integer(1) function iparity_test_1(a)
|
||||
integer(1) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi8>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iparity_test_1 = iparity(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIParity1(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i8
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test_2(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi16>>{{.*}}) -> i16 {
|
||||
integer(2) function iparity_test_2(a)
|
||||
integer(2) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi16>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iparity_test_2 = iparity(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIParity2(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i16
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test_4(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) -> i32 {
|
||||
integer function iparity_test_4(a)
|
||||
integer :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iparity_test_4 = iparity(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIParity4(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test_8(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi64>>{{.*}}) -> i64 {
|
||||
integer(8) function iparity_test_8(a)
|
||||
integer(8) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi64>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iparity_test_8 = iparity(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIParity8(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i64
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test_16(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?xi128>>{{.*}}) -> i128 {
|
||||
integer(16) function iparity_test_16(a)
|
||||
integer(16) :: a(:)
|
||||
! CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a3:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?xi128>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a5:.*]] = fir.convert %[[c0]] : (index) -> i32
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
iparity_test_16 = iparity(a)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIParity16(%[[a3]], %{{.*}}, %{{.*}}, %[[a5]], %[[a6]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i128
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test2(
|
||||
! CHECK-SAME: %[[arg0:.*]]: !fir.box<!fir.array<?x?xi32>>{{.*}}, %[[arg1:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) {
|
||||
subroutine iparity_test2(a,r)
|
||||
integer :: a(:,:)
|
||||
integer :: r(:)
|
||||
! CHECK-DAG: %[[c2_i32:.*]] = arith.constant 2 : i32
|
||||
! CHECK-DAG: %[[a0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
|
||||
! CHECK-DAG: %[[a1:.*]] = fir.absent !fir.box<i1>
|
||||
! CHECK-DAG: %[[a6:.*]] = fir.convert %[[a0]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<!fir.box<none>>
|
||||
! CHECK-DAG: %[[a7:.*]] = fir.convert %[[arg0]] : (!fir.box<!fir.array<?x?xi32>>) -> !fir.box<none>
|
||||
! CHECK-DAG: %[[a9:.*]] = fir.convert %[[a1]] : (!fir.box<i1>) -> !fir.box<none>
|
||||
r = iparity(a,dim=2)
|
||||
! CHECK: %{{.*}} = fir.call @_FortranAIParityDim(%[[a6]], %[[a7]], %[[c2_i32]], %{{.*}}, %{{.*}}, %[[a9]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32, !fir.ref<i8>, i32, !fir.box<none>) -> none
|
||||
! CHECK-DAG: %[[a11:.*]] = fir.load %[[a0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
||||
! CHECK-DAG: %[[a13:.*]] = fir.box_addr %[[a11]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
|
||||
! CHECK-DAG: fir.freemem %[[a13]]
|
||||
end subroutine
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test_optional(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
integer function iparity_test_optional(mask, x)
|
||||
integer :: x(:)
|
||||
logical, optional :: mask(:)
|
||||
iparity_test_optional = iparity(x, mask=mask)
|
||||
! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIParity4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_9]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test_optional_2(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>>
|
||||
integer function iparity_test_optional_2(mask, x)
|
||||
integer :: x(:)
|
||||
logical, pointer :: mask(:)
|
||||
iparity_test_optional_2 = iparity(x, mask=mask)
|
||||
! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>>
|
||||
! CHECK: %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>) -> !fir.ptr<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (!fir.ptr<!fir.array<?x!fir.logical<4>>>) -> i64
|
||||
! CHECK: %[[VAL_7:.*]] = arith.constant 0 : i64
|
||||
! CHECK: %[[VAL_8:.*]] = arith.cmpi ne, %[[VAL_6]], %[[VAL_7]] : i64
|
||||
! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>>
|
||||
! CHECK: %[[VAL_10:.*]] = fir.absent !fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_11:.*]] = arith.select %[[VAL_8]], %[[VAL_9]], %[[VAL_10]] : !fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.logical<4>>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIParity4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_18]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test_optional_3(
|
||||
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10x!fir.logical<4>>>
|
||||
integer function iparity_test_optional_3(mask, x)
|
||||
integer :: x(:)
|
||||
logical, optional :: mask(10)
|
||||
iparity_test_optional_3 = iparity(x, mask=mask)
|
||||
! CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
|
||||
! CHECK: %[[VAL_5:.*]] = fir.is_present %[[VAL_0]] : (!fir.ref<!fir.array<10x!fir.logical<4>>>) -> i1
|
||||
! CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
|
||||
! CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_0]](%[[VAL_6]]) : (!fir.ref<!fir.array<10x!fir.logical<4>>>, !fir.shape<1>) -> !fir.box<!fir.array<10x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_8:.*]] = fir.absent !fir.box<!fir.array<10x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_9:.*]] = arith.select %[[VAL_5]], %[[VAL_7]], %[[VAL_8]] : !fir.box<!fir.array<10x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<10x!fir.logical<4>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIParity4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_18]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
||||
|
||||
! CHECK-LABEL: func @_QPiparity_test_optional_4(
|
||||
integer function iparity_test_optional_4(x, use_mask)
|
||||
! Test that local allocatable tracked in local variables
|
||||
! are dealt as optional argument correctly.
|
||||
integer :: x(:)
|
||||
logical :: use_mask
|
||||
logical, allocatable :: mask(:)
|
||||
if (use_mask) then
|
||||
allocate(mask(size(x, 1)))
|
||||
call set_mask(mask)
|
||||
! CHECK: fir.call @_QPset_mask
|
||||
end if
|
||||
iparity_test_optional_4 = iparity(x, mask=mask)
|
||||
! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_3:.*]] : !fir.ref<!fir.heap<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.heap<!fir.array<?x!fir.logical<4>>>) -> i64
|
||||
! CHECK: %[[VAL_22:.*]] = arith.constant 0 : i64
|
||||
! CHECK: %[[VAL_23:.*]] = arith.cmpi ne, %[[VAL_21]], %[[VAL_22]] : i64
|
||||
! CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_4:.*]] : !fir.ref<index>
|
||||
! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_5:.*]] : !fir.ref<index>
|
||||
! CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.heap<!fir.array<?x!fir.logical<4>>>>
|
||||
! CHECK: %[[VAL_27:.*]] = fir.shape_shift %[[VAL_24]], %[[VAL_25]] : (index, index) -> !fir.shapeshift<1>
|
||||
! CHECK: %[[VAL_28:.*]] = fir.embox %[[VAL_26]](%[[VAL_27]]) : (!fir.heap<!fir.array<?x!fir.logical<4>>>, !fir.shapeshift<1>) -> !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_29:.*]] = fir.absent !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_30:.*]] = arith.select %[[VAL_23]], %[[VAL_28]], %[[VAL_29]] : !fir.box<!fir.array<?x!fir.logical<4>>>
|
||||
! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_30]] : (!fir.box<!fir.array<?x!fir.logical<4>>>) -> !fir.box<none>
|
||||
! CHECK: fir.call @_FortranAIParity4(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_37]]) : (!fir.box<none>, !fir.ref<i8>, i32, i32, !fir.box<none>) -> i32
|
||||
end function
|
Loading…
x
Reference in New Issue
Block a user