@@ -4571,8 +4571,8 @@ void IntrinsicLibrary::genRaiseExcept(int excepts, mlir::Value cond) {
45714571 builder.setInsertionPointToStart (&ifOp.getThenRegion ().front ());
45724572 }
45734573 mlir::Type i32Ty = builder.getIntegerType (32 );
4574- genRuntimeCall (
4575- " feraiseexcept " , i32Ty ,
4574+ fir::runtime::genFeraiseexcept (
4575+ builder, loc ,
45764576 fir::runtime::genMapExcept (
45774577 builder, loc, builder.createIntegerConstant (loc, i32Ty, excepts)));
45784578 if (cond)
@@ -4939,8 +4939,8 @@ void IntrinsicLibrary::genIeeeGetFlag(llvm::ArrayRef<fir::ExtendedValue> args) {
49394939 mlir::Value zero = builder.createIntegerConstant (loc, i32Ty, 0 );
49404940 auto [fieldRef, ignore] = getFieldRef (builder, loc, flag);
49414941 mlir::Value field = builder.create <fir::LoadOp>(loc, fieldRef);
4942- mlir::Value excepts = IntrinsicLibrary::genRuntimeCall (
4943- " fetestexcept " , i32Ty ,
4942+ mlir::Value excepts = fir::runtime::genFetestexcept (
4943+ builder, loc ,
49444944 fir::runtime::genMapExcept (
49454945 builder, loc, builder.create <fir::ConvertOp>(loc, i32Ty, field)));
49464946 mlir::Value logicalResult = builder.create <fir::ConvertOp>(
@@ -4963,8 +4963,7 @@ void IntrinsicLibrary::genIeeeGetHaltingMode(
49634963 mlir::Value zero = builder.createIntegerConstant (loc, i32Ty, 0 );
49644964 auto [fieldRef, ignore] = getFieldRef (builder, loc, flag);
49654965 mlir::Value field = builder.create <fir::LoadOp>(loc, fieldRef);
4966- mlir::Value haltSet =
4967- IntrinsicLibrary::genRuntimeCall (" fegetexcept" , i32Ty, {});
4966+ mlir::Value haltSet = fir::runtime::genFegetexcept (builder, loc);
49684967 mlir::Value intResult = builder.create <mlir::arith::AndIOp>(
49694968 loc, haltSet,
49704969 fir::runtime::genMapExcept (
@@ -5712,9 +5711,11 @@ void IntrinsicLibrary::genIeeeSetFlagOrHaltingMode(
57125711 loc, builder.create <fir::ConvertOp>(loc, i1Ty, getBase (args[1 ])),
57135712 /* withElseRegion=*/ true );
57145713 builder.setInsertionPointToStart (&ifOp.getThenRegion ().front ());
5715- genRuntimeCall (isFlag ? " feraiseexcept" : " feenableexcept" , i32Ty, except);
5714+ (isFlag ? fir::runtime::genFeraiseexcept : fir::runtime::genFeenableexcept)(
5715+ builder, loc, builder.create <fir::ConvertOp>(loc, i32Ty, except));
57165716 builder.setInsertionPointToStart (&ifOp.getElseRegion ().front ());
5717- genRuntimeCall (isFlag ? " feclearexcept" : " fedisableexcept" , i32Ty, except);
5717+ (isFlag ? fir::runtime::genFeclearexcept : fir::runtime::genFedisableexcept)(
5718+ builder, loc, builder.create <fir::ConvertOp>(loc, i32Ty, except));
57185719 builder.setInsertionPointAfter (ifOp);
57195720}
57205721
@@ -5805,24 +5806,61 @@ mlir::Value IntrinsicLibrary::genIeeeSignbit(mlir::Type resultType,
58055806fir::ExtendedValue
58065807IntrinsicLibrary::genIeeeSupportFlag (mlir::Type resultType,
58075808 llvm::ArrayRef<fir::ExtendedValue> args) {
5808- // Check if a floating point exception flag is supported. A flag is
5809- // supported either for all type kinds or none. An optional kind argument X
5810- // is therefore ignored. Standard flags are all supported. The nonstandard
5811- // DENORM extension is not supported, at least for now.
5809+ // Check if a floating point exception flag is supported.
58125810 assert (args.size () == 1 || args.size () == 2 );
5811+ mlir::Type i1Ty = builder.getI1Type ();
5812+ mlir::Type i32Ty = builder.getIntegerType (32 );
58135813 auto [fieldRef, fieldTy] = getFieldRef (builder, loc, getBase (args[0 ]));
58145814 mlir::Value flag = builder.create <fir::LoadOp>(loc, fieldRef);
5815- mlir::Value mask = builder.createIntegerConstant ( // values are powers of 2
5815+ mlir::Value standardFlagMask = builder.createIntegerConstant (
58165816 loc, fieldTy,
58175817 _FORTRAN_RUNTIME_IEEE_INVALID | _FORTRAN_RUNTIME_IEEE_DIVIDE_BY_ZERO |
58185818 _FORTRAN_RUNTIME_IEEE_OVERFLOW | _FORTRAN_RUNTIME_IEEE_UNDERFLOW |
58195819 _FORTRAN_RUNTIME_IEEE_INEXACT);
5820- return builder.createConvert (
5821- loc, resultType,
5822- builder.create <mlir::arith::CmpIOp>(
5823- loc, mlir::arith::CmpIPredicate::ne,
5824- builder.create <mlir::arith::AndIOp>(loc, flag, mask),
5825- builder.createIntegerConstant (loc, fieldTy, 0 )));
5820+ mlir::Value isStandardFlag = builder.create <mlir::arith::CmpIOp>(
5821+ loc, mlir::arith::CmpIPredicate::ne,
5822+ builder.create <mlir::arith::AndIOp>(loc, flag, standardFlagMask),
5823+ builder.createIntegerConstant (loc, fieldTy, 0 ));
5824+ fir::IfOp ifOp = builder.create <fir::IfOp>(loc, i1Ty, isStandardFlag,
5825+ /* withElseRegion=*/ true );
5826+ // Standard flags are supported.
5827+ builder.setInsertionPointToStart (&ifOp.getThenRegion ().front ());
5828+ builder.create <fir::ResultOp>(loc, builder.createBool (loc, true ));
5829+
5830+ // TargetCharacteristics information for the nonstandard ieee_denorm flag
5831+ // is not available here. So use a runtime check restricted to possibly
5832+ // supported kinds.
5833+ builder.setInsertionPointToStart (&ifOp.getElseRegion ().front ());
5834+ bool mayBeSupported = false ;
5835+ if (mlir::Value arg1 = getBase (args[1 ])) {
5836+ mlir::Type arg1Ty = arg1.getType ();
5837+ if (fir::ReferenceType refTy = mlir::dyn_cast<fir::ReferenceType>(arg1Ty))
5838+ arg1Ty = refTy.getEleTy ();
5839+ switch (mlir::dyn_cast<mlir::FloatType>(arg1Ty).getWidth ()) {
5840+ case 16 :
5841+ mayBeSupported = arg1Ty.isBF16 (); // kind=3
5842+ break ;
5843+ case 32 : // kind=4
5844+ case 64 : // kind=8
5845+ mayBeSupported = true ;
5846+ break ;
5847+ }
5848+ }
5849+ if (mayBeSupported) {
5850+ mlir::Value isDenorm = builder.create <mlir::arith::CmpIOp>(
5851+ loc, mlir::arith::CmpIPredicate::eq, flag,
5852+ builder.createIntegerConstant (loc, fieldTy,
5853+ _FORTRAN_RUNTIME_IEEE_DENORM));
5854+ mlir::Value result = builder.create <mlir::arith::AndIOp>(
5855+ loc, isDenorm,
5856+ fir::runtime::genSupportHalting (
5857+ builder, loc, builder.create <fir::ConvertOp>(loc, i32Ty, flag)));
5858+ builder.create <fir::ResultOp>(loc, result);
5859+ } else {
5860+ builder.create <fir::ResultOp>(loc, builder.createBool (loc, false ));
5861+ }
5862+ builder.setInsertionPointAfter (ifOp);
5863+ return builder.createConvert (loc, resultType, ifOp.getResult (0 ));
58265864}
58275865
58285866// IEEE_SUPPORT_HALTING
@@ -5838,7 +5876,7 @@ fir::ExtendedValue IntrinsicLibrary::genIeeeSupportHalting(
58385876 return builder.createConvert (
58395877 loc, resultType,
58405878 fir::runtime::genSupportHalting (
5841- builder, loc, { builder.create <fir::ConvertOp>(loc, i32Ty, field)} ));
5879+ builder, loc, builder.create <fir::ConvertOp>(loc, i32Ty, field)));
58425880}
58435881
58445882// IEEE_SUPPORT_ROUNDING
@@ -5874,10 +5912,10 @@ fir::ExtendedValue IntrinsicLibrary::genIeeeSupportStandard(
58745912 // if halting control is supported, as that is the only support component
58755913 // that may not be available.
58765914 assert (args.size () <= 1 );
5877- mlir::Value nearest = builder.createIntegerConstant (
5878- loc, builder.getIntegerType (32 ), _FORTRAN_RUNTIME_IEEE_NEAREST );
5915+ mlir::Value overflow = builder.createIntegerConstant (
5916+ loc, builder.getIntegerType (32 ), _FORTRAN_RUNTIME_IEEE_OVERFLOW );
58795917 return builder.createConvert (
5880- loc, resultType, fir::runtime::genSupportHalting (builder, loc, nearest ));
5918+ loc, resultType, fir::runtime::genSupportHalting (builder, loc, overflow ));
58815919}
58825920
58835921// IEEE_UNORDERED
0 commit comments