@@ -7593,12 +7593,46 @@ IntrinsicLibrary::genSameTypeAs(mlir::Type resultType,
75937593mlir::Value IntrinsicLibrary::genScale (mlir::Type resultType,
75947594 llvm::ArrayRef<mlir::Value> args) {
75957595 assert (args.size () == 2 );
7596+ mlir::FloatType floatTy = mlir::dyn_cast<mlir::FloatType>(resultType);
7597+ if (!floatTy.isF16 () && !floatTy.isBF16 ()) // kind=4,8,10,16
7598+ return builder.createConvert (
7599+ loc, resultType,
7600+ fir::runtime::genScale (builder, loc, args[0 ], args[1 ]));
75967601
7597- mlir::Value realX = fir::getBase (args[0 ]);
7598- mlir::Value intI = fir::getBase (args[1 ]);
7599-
7600- return builder.createConvert (
7601- loc, resultType, fir::runtime::genScale (builder, loc, realX, intI));
7602+ // Convert kind=2,3 arg X to kind=4. Convert kind=4 result back to kind=2,3.
7603+ mlir::Type i1Ty = builder.getI1Type ();
7604+ mlir::Type f32Ty = mlir::Float32Type::get (builder.getContext ());
7605+ mlir::Value result = builder.createConvert (
7606+ loc, resultType,
7607+ fir::runtime::genScale (
7608+ builder, loc, builder.createConvert (loc, f32Ty, args[0 ]), args[1 ]));
7609+
7610+ // kind=4 runtime::genScale call may not signal kind=2,3 exceptions.
7611+ // If X is finite and result is infinite, signal IEEE_OVERFLOW
7612+ // If X is finite and scale(result, -I) != X, signal IEEE_UNDERFLOW
7613+ fir::IfOp outerIfOp =
7614+ builder.create <fir::IfOp>(loc, genIsFPClass (i1Ty, args[0 ], finiteTest),
7615+ /* withElseRegion=*/ false );
7616+ builder.setInsertionPointToStart (&outerIfOp.getThenRegion ().front ());
7617+ fir::IfOp innerIfOp =
7618+ builder.create <fir::IfOp>(loc, genIsFPClass (i1Ty, result, infiniteTest),
7619+ /* withElseRegion=*/ true );
7620+ builder.setInsertionPointToStart (&innerIfOp.getThenRegion ().front ());
7621+ genRaiseExcept (_FORTRAN_RUNTIME_IEEE_OVERFLOW |
7622+ _FORTRAN_RUNTIME_IEEE_INEXACT);
7623+ builder.setInsertionPointToStart (&innerIfOp.getElseRegion ().front ());
7624+ mlir::Value minusI = builder.create <mlir::arith::MulIOp>(
7625+ loc, args[1 ], builder.createAllOnesInteger (loc, args[1 ].getType ()));
7626+ mlir::Value reverseResult = builder.createConvert (
7627+ loc, resultType,
7628+ fir::runtime::genScale (
7629+ builder, loc, builder.createConvert (loc, f32Ty, result), minusI));
7630+ genRaiseExcept (
7631+ _FORTRAN_RUNTIME_IEEE_UNDERFLOW | _FORTRAN_RUNTIME_IEEE_INEXACT,
7632+ builder.create <mlir::arith::CmpFOp>(loc, mlir::arith::CmpFPredicate::ONE,
7633+ args[0 ], reverseResult));
7634+ builder.setInsertionPointAfter (outerIfOp);
7635+ return result;
76027636}
76037637
76047638// SCAN
0 commit comments