@@ -4195,39 +4195,45 @@ mlir::Value IntrinsicLibrary::genIeeeLogb(mlir::Type resultType,
4195
4195
builder.create <mlir::arith::BitcastOp>(loc, intType, realVal);
4196
4196
mlir::Type i1Ty = builder.getI1Type ();
4197
4197
4198
- int exponentBias, significandSize;
4198
+ int exponentBias, significandSize, nonSignificandSize ;
4199
4199
switch (bitWidth) {
4200
4200
case 16 :
4201
4201
if (realType.isF16 ()) {
4202
4202
// kind=2: 1 sign bit, 5 exponent bits, 10 significand bits
4203
4203
exponentBias = (1 << (5 - 1 )) - 1 ; // 15
4204
4204
significandSize = 10 ;
4205
+ nonSignificandSize = 6 ;
4205
4206
break ;
4206
4207
}
4207
4208
assert (realType.isBF16 () && " unknown 16-bit real type" );
4208
4209
// kind=3: 1 sign bit, 8 exponent bits, 7 significand bits
4209
4210
exponentBias = (1 << (8 - 1 )) - 1 ; // 127
4210
4211
significandSize = 7 ;
4212
+ nonSignificandSize = 9 ;
4211
4213
break ;
4212
4214
case 32 :
4213
4215
// kind=4: 1 sign bit, 8 exponent bits, 23 significand bits
4214
4216
exponentBias = (1 << (8 - 1 )) - 1 ; // 127
4215
4217
significandSize = 23 ;
4218
+ nonSignificandSize = 9 ;
4216
4219
break ;
4217
4220
case 64 :
4218
4221
// kind=8: 1 sign bit, 11 exponent bits, 52 significand bits
4219
4222
exponentBias = (1 << (11 - 1 )) - 1 ; // 1023
4220
4223
significandSize = 52 ;
4224
+ nonSignificandSize = 12 ;
4221
4225
break ;
4222
4226
case 80 :
4223
4227
// kind=10: 1 sign bit, 15 exponent bits, 1+63 significand bits
4224
4228
exponentBias = (1 << (15 - 1 )) - 1 ; // 16383
4225
4229
significandSize = 64 ;
4230
+ nonSignificandSize = 16 + 1 ;
4226
4231
break ;
4227
4232
case 128 :
4228
4233
// kind=16: 1 sign bit, 15 exponent bits, 112 significand bits
4229
4234
exponentBias = (1 << (15 - 1 )) - 1 ; // 16383
4230
4235
significandSize = 112 ;
4236
+ nonSignificandSize = 16 ;
4231
4237
break ;
4232
4238
default :
4233
4239
llvm_unreachable (" unknown real type" );
@@ -4259,6 +4265,11 @@ mlir::Value IntrinsicLibrary::genIeeeLogb(mlir::Type resultType,
4259
4265
/* withElseRegion=*/ true );
4260
4266
// X is non-zero finite -- result is unbiased exponent of X
4261
4267
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 ());
4262
4273
mlir::Value biasedExponent = builder.create <mlir::arith::ShRUIOp>(
4263
4274
loc, shiftLeftOne,
4264
4275
builder.createIntegerConstant (loc, intType, significandSize + 1 ));
@@ -4268,6 +4279,23 @@ mlir::Value IntrinsicLibrary::genIeeeLogb(mlir::Type resultType,
4268
4279
result = builder.create <fir::ConvertOp>(loc, resultType, result);
4269
4280
builder.create <fir::ResultOp>(loc, result);
4270
4281
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
+
4271
4299
// X is infinity or NaN -- result is +infinity or NaN
4272
4300
builder.setInsertionPointToStart (&innerIfOp.getElseRegion ().front ());
4273
4301
result = builder.create <mlir::arith::ShRUIOp>(loc, shiftLeftOne, one);
0 commit comments