@@ -1191,9 +1191,6 @@ static const CostTblEntry VectorIntrinsicCostTable[]{
1191
1191
{Intrinsic::roundeven, MVT::f64 , 9 },
1192
1192
{Intrinsic::rint, MVT::f32 , 7 },
1193
1193
{Intrinsic::rint, MVT::f64 , 7 },
1194
- {Intrinsic::lrint, MVT::i32 , 1 },
1195
- {Intrinsic::lrint, MVT::i64 , 1 },
1196
- {Intrinsic::llrint, MVT::i64 , 1 },
1197
1194
{Intrinsic::nearbyint, MVT::f32 , 9 },
1198
1195
{Intrinsic::nearbyint, MVT::f64 , 9 },
1199
1196
{Intrinsic::bswap, MVT::i16 , 3 },
@@ -1251,11 +1248,43 @@ RISCVTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
1251
1248
switch (ICA.getID ()) {
1252
1249
case Intrinsic::lrint:
1253
1250
case Intrinsic::llrint:
1254
- // We can't currently lower half or bfloat vector lrint/llrint.
1255
- if (auto *VecTy = dyn_cast<VectorType>(ICA.getArgTypes ()[0 ]);
1256
- VecTy && VecTy->getElementType ()->is16bitFPTy ())
1257
- return InstructionCost::getInvalid ();
1258
- [[fallthrough]];
1251
+ case Intrinsic::lround:
1252
+ case Intrinsic::llround: {
1253
+ auto LT = getTypeLegalizationCost (RetTy);
1254
+ Type *SrcTy = ICA.getArgTypes ().front ();
1255
+ auto SrcLT = getTypeLegalizationCost (SrcTy);
1256
+ if (ST->hasVInstructions () && LT.second .isVector ()) {
1257
+ ArrayRef<unsigned > Ops;
1258
+ unsigned SrcEltSz = DL.getTypeSizeInBits (SrcTy->getScalarType ());
1259
+ unsigned DstEltSz = DL.getTypeSizeInBits (RetTy->getScalarType ());
1260
+ if (LT.second .getVectorElementType () == MVT::bf16 ) {
1261
+ if (!ST->hasVInstructionsBF16Minimal ())
1262
+ return InstructionCost::getInvalid ();
1263
+ if (DstEltSz == 32 )
1264
+ Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFCVT_X_F_V};
1265
+ else
1266
+ Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFWCVT_X_F_V};
1267
+ } else if (LT.second .getVectorElementType () == MVT::f16 &&
1268
+ !ST->hasVInstructionsF16 ()) {
1269
+ if (!ST->hasVInstructionsF16Minimal ())
1270
+ return InstructionCost::getInvalid ();
1271
+ if (DstEltSz == 32 )
1272
+ Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFCVT_X_F_V};
1273
+ else
1274
+ Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_X_F_V};
1275
+
1276
+ } else if (SrcEltSz > DstEltSz) {
1277
+ Ops = {RISCV::VFNCVT_X_F_W};
1278
+ } else if (SrcEltSz < DstEltSz) {
1279
+ Ops = {RISCV::VFWCVT_X_F_V};
1280
+ } else {
1281
+ Ops = {RISCV::VFCVT_X_F_V};
1282
+ }
1283
+ return std::max (SrcLT.first , LT.first ) *
1284
+ getRISCVInstructionCost (Ops, LT.second , CostKind);
1285
+ }
1286
+ break ;
1287
+ }
1259
1288
case Intrinsic::ceil:
1260
1289
case Intrinsic::floor:
1261
1290
case Intrinsic::trunc:
0 commit comments