@@ -1191,9 +1191,6 @@ static const CostTblEntry VectorIntrinsicCostTable[]{
11911191 {Intrinsic::roundeven, MVT::f64 , 9 },
11921192 {Intrinsic::rint, MVT::f32 , 7 },
11931193 {Intrinsic::rint, MVT::f64 , 7 },
1194- {Intrinsic::lrint, MVT::i32 , 1 },
1195- {Intrinsic::lrint, MVT::i64 , 1 },
1196- {Intrinsic::llrint, MVT::i64 , 1 },
11971194 {Intrinsic::nearbyint, MVT::f32 , 9 },
11981195 {Intrinsic::nearbyint, MVT::f64 , 9 },
11991196 {Intrinsic::bswap, MVT::i16 , 3 },
@@ -1251,11 +1248,45 @@ RISCVTTIImpl::getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
12511248 switch (ICA.getID ()) {
12521249 case Intrinsic::lrint:
12531250 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+ if (ST->hasVInstructions () && LT.second .isVector ()) {
1255+ ArrayRef<unsigned > Ops;
1256+ unsigned DstEltSz =
1257+ DL.getTypeSizeInBits (cast<VectorType>(RetTy)->getElementType ());
1258+ if (LT.second .getVectorElementType () == MVT::bf16 ) {
1259+ if (DstEltSz == 64 && ST->is64Bit ())
1260+ // vfwcvtbf16.f.f.v v9, v8
1261+ // vfcvt.x.f.v v8, v9
1262+ Ops = {RISCV::VFWCVTBF16_F_F_V, RISCV::VFCVT_X_F_V};
1263+ else
1264+ // vfwcvtbf16.f.f.v v9, v8
1265+ // vfwcvt.x.f.v v8, v9
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 (DstEltSz == 64 && ST->is64Bit ())
1270+ // vfwcvt.f.f.v v9, v8
1271+ // vfwcvt.x.f.v v8, v9
1272+ Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFWCVT_X_F_V};
1273+ else
1274+ // vfwcvt.f.f.v v9, v8
1275+ // vfcvt.x.f.v v8, v9
1276+ Ops = {RISCV::VFWCVT_F_F_V, RISCV::VFCVT_X_F_V};
1277+
1278+ } else if (DstEltSz == 32 && ST->is64Bit ()) {
1279+ // vfncvt.x.f.w v10, v8
1280+ // vmv.v.v v8, v10
1281+ Ops = {RISCV::VFNCVT_X_F_W, RISCV::VMV_V_V};
1282+ } else {
1283+ // vfcvt.x.f.v v8, v8
1284+ Ops = {RISCV::VFCVT_X_F_V};
1285+ }
1286+ return LT.first * getRISCVInstructionCost (Ops, LT.second , CostKind);
1287+ }
1288+ break ;
1289+ }
12591290 case Intrinsic::ceil:
12601291 case Intrinsic::floor:
12611292 case Intrinsic::trunc:
0 commit comments