@@ -516,6 +516,7 @@ struct IntrinsicLibrary {
516516 mlir::Value genIbits (mlir::Type, llvm::ArrayRef<mlir::Value>);
517517 mlir::Value genIbset (mlir::Type, llvm::ArrayRef<mlir::Value>);
518518 fir::ExtendedValue genIchar (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
519+ fir::ExtendedValue genFindloc (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
519520 mlir::Value genIeeeIsFinite (mlir::Type, llvm::ArrayRef<mlir::Value>);
520521 template <mlir::arith::CmpIPredicate pred>
521522 fir::ExtendedValue genIeeeTypeCompare (mlir::Type,
@@ -801,6 +802,15 @@ static constexpr IntrinsicHandler handlers[]{
801802 {{{" status" , asValue, handleDynamicOptional}}},
802803 /* isElemental=*/ false },
803804 {" exponent" , &I::genExponent},
805+ {" findloc" ,
806+ &I::genFindloc,
807+ {{{" array" , asBox},
808+ {" value" , asAddr},
809+ {" dim" , asValue},
810+ {" mask" , asBox, handleDynamicOptional},
811+ {" kind" , asValue},
812+ {" back" , asValue, handleDynamicOptional}}},
813+ /* isElemental=*/ false },
804814 {" floor" , &I::genFloor},
805815 {" fraction" , &I::genFraction},
806816 {" get_command" ,
@@ -3181,6 +3191,98 @@ mlir::Value IntrinsicLibrary::genExponent(mlir::Type resultType,
31813191 fir::getBase (args[0 ])));
31823192}
31833193
3194+ // FINDLOC
3195+ fir::ExtendedValue
3196+ IntrinsicLibrary::genFindloc (mlir::Type resultType,
3197+ llvm::ArrayRef<fir::ExtendedValue> args) {
3198+ assert (args.size () == 6 );
3199+
3200+ llvm::StringRef errMsg = " unexpected result for Findloc" ;
3201+
3202+ // Handle required array argument
3203+ mlir::Value array = builder.createBox (loc, args[0 ]);
3204+ unsigned rank = fir::BoxValue (array).rank ();
3205+ assert (rank >= 1 );
3206+
3207+ // Handle required value argument
3208+ mlir::Value val = builder.createBox (loc, args[1 ]);
3209+
3210+ // Check if dim argument is present
3211+ bool absentDim = isStaticallyAbsent (args[2 ]);
3212+
3213+ // Handle optional mask argument
3214+ auto mask = isStaticallyAbsent (args[3 ])
3215+ ? builder.create <fir::AbsentOp>(
3216+ loc, fir::BoxType::get (builder.getI1Type ()))
3217+ : builder.createBox (loc, args[3 ]);
3218+
3219+ // Handle optional kind argument
3220+ auto kind = isStaticallyAbsent (args[4 ])
3221+ ? builder.createIntegerConstant (
3222+ loc, builder.getIndexType (),
3223+ builder.getKindMap ().defaultIntegerKind ())
3224+ : fir::getBase (args[4 ]);
3225+
3226+ // Handle optional back argument
3227+ auto back = isStaticallyAbsent (args[5 ]) ? builder.createBool (loc, false )
3228+ : fir::getBase (args[5 ]);
3229+
3230+ if (!absentDim && rank == 1 ) {
3231+ // If dim argument is present and the array is rank 1, then the result is
3232+ // a scalar (since the the result is rank-1 or 0).
3233+ // Therefore, we use a scalar result descriptor with FindlocDim().
3234+ // Create mutable fir.box to be passed to the runtime for the result.
3235+ fir::MutableBoxValue resultMutableBox =
3236+ fir::factory::createTempMutableBox (builder, loc, resultType);
3237+ mlir::Value resultIrBox =
3238+ fir::factory::getMutableIRBox (builder, loc, resultMutableBox);
3239+ mlir::Value dim = fir::getBase (args[2 ]);
3240+
3241+ fir::runtime::genFindlocDim (builder, loc, resultIrBox, array, val, dim,
3242+ mask, kind, back);
3243+
3244+ // Handle cleanup of allocatable result descriptor and return
3245+ fir::ExtendedValue res =
3246+ fir::factory::genMutableBoxRead (builder, loc, resultMutableBox);
3247+ return res.match (
3248+ [&](const mlir::Value &addr) -> fir::ExtendedValue {
3249+ addCleanUpForTemp (loc, addr);
3250+ return builder.create <fir::LoadOp>(loc, resultType, addr);
3251+ },
3252+ [&](const auto &) -> fir::ExtendedValue {
3253+ fir::emitFatalError (loc, errMsg);
3254+ });
3255+ }
3256+
3257+ // The result will be an array. Create mutable fir.box to be passed to the
3258+ // runtime for the result.
3259+ mlir::Type resultArrayType =
3260+ builder.getVarLenSeqTy (resultType, absentDim ? 1 : rank - 1 );
3261+ fir::MutableBoxValue resultMutableBox =
3262+ fir::factory::createTempMutableBox (builder, loc, resultArrayType);
3263+ mlir::Value resultIrBox =
3264+ fir::factory::getMutableIRBox (builder, loc, resultMutableBox);
3265+
3266+ if (absentDim) {
3267+ fir::runtime::genFindloc (builder, loc, resultIrBox, array, val, mask, kind,
3268+ back);
3269+ } else {
3270+ mlir::Value dim = fir::getBase (args[2 ]);
3271+ fir::runtime::genFindlocDim (builder, loc, resultIrBox, array, val, dim,
3272+ mask, kind, back);
3273+ }
3274+
3275+ return fir::factory::genMutableBoxRead (builder, loc, resultMutableBox)
3276+ .match (
3277+ [&](const fir::ArrayBoxValue &box) -> fir::ExtendedValue {
3278+ addCleanUpForTemp (loc, box.getAddr ());
3279+ return box;
3280+ },
3281+ [&](const auto &) -> fir::ExtendedValue {
3282+ fir::emitFatalError (loc, errMsg);
3283+ });
3284+ }
3285+
31843286// FLOOR
31853287mlir::Value IntrinsicLibrary::genFloor (mlir::Type resultType,
31863288 llvm::ArrayRef<mlir::Value> args) {
0 commit comments