Skip to content

Commit ae58b67

Browse files
authored
[flang] Fixed ieee_logb to behave for denormals. (llvm#83518)
For denormals we have to account for the exponent coming from the significand.
1 parent b542501 commit ae58b67

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4195,39 +4195,45 @@ mlir::Value IntrinsicLibrary::genIeeeLogb(mlir::Type resultType,
41954195
builder.create<mlir::arith::BitcastOp>(loc, intType, realVal);
41964196
mlir::Type i1Ty = builder.getI1Type();
41974197

4198-
int exponentBias, significandSize;
4198+
int exponentBias, significandSize, nonSignificandSize;
41994199
switch (bitWidth) {
42004200
case 16:
42014201
if (realType.isF16()) {
42024202
// kind=2: 1 sign bit, 5 exponent bits, 10 significand bits
42034203
exponentBias = (1 << (5 - 1)) - 1; // 15
42044204
significandSize = 10;
4205+
nonSignificandSize = 6;
42054206
break;
42064207
}
42074208
assert(realType.isBF16() && "unknown 16-bit real type");
42084209
// kind=3: 1 sign bit, 8 exponent bits, 7 significand bits
42094210
exponentBias = (1 << (8 - 1)) - 1; // 127
42104211
significandSize = 7;
4212+
nonSignificandSize = 9;
42114213
break;
42124214
case 32:
42134215
// kind=4: 1 sign bit, 8 exponent bits, 23 significand bits
42144216
exponentBias = (1 << (8 - 1)) - 1; // 127
42154217
significandSize = 23;
4218+
nonSignificandSize = 9;
42164219
break;
42174220
case 64:
42184221
// kind=8: 1 sign bit, 11 exponent bits, 52 significand bits
42194222
exponentBias = (1 << (11 - 1)) - 1; // 1023
42204223
significandSize = 52;
4224+
nonSignificandSize = 12;
42214225
break;
42224226
case 80:
42234227
// kind=10: 1 sign bit, 15 exponent bits, 1+63 significand bits
42244228
exponentBias = (1 << (15 - 1)) - 1; // 16383
42254229
significandSize = 64;
4230+
nonSignificandSize = 16 + 1;
42264231
break;
42274232
case 128:
42284233
// kind=16: 1 sign bit, 15 exponent bits, 112 significand bits
42294234
exponentBias = (1 << (15 - 1)) - 1; // 16383
42304235
significandSize = 112;
4236+
nonSignificandSize = 16;
42314237
break;
42324238
default:
42334239
llvm_unreachable("unknown real type");
@@ -4259,6 +4265,11 @@ mlir::Value IntrinsicLibrary::genIeeeLogb(mlir::Type resultType,
42594265
/*withElseRegion=*/true);
42604266
// X is non-zero finite -- result is unbiased exponent of X
42614267
builder.setInsertionPointToStart(&innerIfOp.getThenRegion().front());
4268+
mlir::Value isNormal = genIsFPClass(i1Ty, args, normalTest);
4269+
auto normalIfOp = builder.create<fir::IfOp>(loc, resultType, isNormal,
4270+
/*withElseRegion=*/true);
4271+
// X is normal
4272+
builder.setInsertionPointToStart(&normalIfOp.getThenRegion().front());
42624273
mlir::Value biasedExponent = builder.create<mlir::arith::ShRUIOp>(
42634274
loc, shiftLeftOne,
42644275
builder.createIntegerConstant(loc, intType, significandSize + 1));
@@ -4268,6 +4279,23 @@ mlir::Value IntrinsicLibrary::genIeeeLogb(mlir::Type resultType,
42684279
result = builder.create<fir::ConvertOp>(loc, resultType, result);
42694280
builder.create<fir::ResultOp>(loc, result);
42704281

4282+
// X is denormal -- result is (-exponentBias - ctlz(significand))
4283+
builder.setInsertionPointToStart(&normalIfOp.getElseRegion().front());
4284+
mlir::Value significand = builder.create<mlir::arith::ShLIOp>(
4285+
loc, intVal,
4286+
builder.createIntegerConstant(loc, intType, nonSignificandSize));
4287+
mlir::Value ctlz =
4288+
builder.create<mlir::math::CountLeadingZerosOp>(loc, significand);
4289+
mlir::Type i32Ty = builder.getI32Type();
4290+
result = builder.create<mlir::arith::SubIOp>(
4291+
loc, builder.createIntegerConstant(loc, i32Ty, -exponentBias),
4292+
builder.create<fir::ConvertOp>(loc, i32Ty, ctlz));
4293+
result = builder.create<fir::ConvertOp>(loc, resultType, result);
4294+
builder.create<fir::ResultOp>(loc, result);
4295+
4296+
builder.setInsertionPointToEnd(&innerIfOp.getThenRegion().front());
4297+
builder.create<fir::ResultOp>(loc, normalIfOp.getResult(0));
4298+
42714299
// X is infinity or NaN -- result is +infinity or NaN
42724300
builder.setInsertionPointToStart(&innerIfOp.getElseRegion().front());
42734301
result = builder.create<mlir::arith::ShRUIOp>(loc, shiftLeftOne, one);

0 commit comments

Comments
 (0)