Skip to content

Commit 2b19c53

Browse files
vdonaldsonvar-const
authored andcommitted
[flang] IEEE_SCALB and SCALE - kind=2, kind=3 (llvm#135374)
Implement the kind=2,3 variants of language intrinsic SCALE and intrinsic module procedure IEEE_SCALB, including exception signaling.
1 parent 3dd9a60 commit 2b19c53

File tree

1 file changed

+39
-5
lines changed

1 file changed

+39
-5
lines changed

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7593,12 +7593,46 @@ IntrinsicLibrary::genSameTypeAs(mlir::Type resultType,
75937593
mlir::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

Comments
 (0)